mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-02-25 18:55:27 -06:00
Allow viewing and removing sound devices
This commit is contained in:
@@ -55,6 +55,7 @@ HW_LIST_TYPE_DISK = 3
|
||||
HW_LIST_TYPE_NIC = 4
|
||||
HW_LIST_TYPE_INPUT = 5
|
||||
HW_LIST_TYPE_GRAPHICS = 6
|
||||
HW_LIST_TYPE_SOUND = 7
|
||||
|
||||
# Console pages
|
||||
PAGE_UNAVAILABLE = 0
|
||||
@@ -252,6 +253,7 @@ class vmmDetails(gobject.GObject):
|
||||
"on_config_network_remove_clicked": self.remove_network,
|
||||
"on_config_input_remove_clicked": self.remove_input,
|
||||
"on_config_graphics_remove_clicked": self.remove_graphics,
|
||||
"on_config_sound_remove_clicked": self.remove_sound,
|
||||
"on_add_hardware_button_clicked": self.add_hardware,
|
||||
|
||||
"on_details_menu_view_fullscreen_activate": self.toggle_fullscreen,
|
||||
@@ -536,6 +538,8 @@ class vmmDetails(gobject.GObject):
|
||||
self.refresh_input_page()
|
||||
elif pagetype == HW_LIST_TYPE_GRAPHICS:
|
||||
self.refresh_graphics_page()
|
||||
elif pagetype == HW_LIST_TYPE_SOUND:
|
||||
self.refresh_sound_page()
|
||||
elif pagetype == HW_LIST_TYPE_BOOT:
|
||||
self.refresh_boot_page()
|
||||
self.window.get_widget("config-boot-options-apply").set_sensitive(False)
|
||||
@@ -720,6 +724,8 @@ class vmmDetails(gobject.GObject):
|
||||
self.refresh_input_page()
|
||||
elif pagetype == HW_LIST_TYPE_GRAPHICS:
|
||||
self.refresh_graphics_page()
|
||||
elif pagetype == HW_LIST_TYPE_SOUND:
|
||||
self.refresh_sound_page()
|
||||
|
||||
def refresh_summary(self):
|
||||
self.window.get_widget("overview-cpu-usage-text").set_text("%d %%" % self.vm.cpu_time_percentage())
|
||||
@@ -890,6 +896,21 @@ class vmmDetails(gobject.GObject):
|
||||
else:
|
||||
self.window.get_widget("config-input-remove").set_sensitive(True)
|
||||
|
||||
def refresh_sound_page(self):
|
||||
vmlist = self.window.get_widget("hw-list")
|
||||
selection = vmlist.get_selection()
|
||||
active = selection.get_selected()
|
||||
if active[1] is None:
|
||||
return
|
||||
sound = active[0].get_value(active[1], HW_LIST_COL_DEVICE)
|
||||
self.window.get_widget("sound-model").set_text(sound[3])
|
||||
|
||||
# Can't remove sound dev from live guest
|
||||
if self.vm.is_active():
|
||||
self.window.get_widget("config-sound-remove").set_sensitive(False)
|
||||
else:
|
||||
self.window.get_widget("config-sound-remove").set_sensitive(True)
|
||||
|
||||
def refresh_boot_page(self):
|
||||
# Refresh autostart
|
||||
try:
|
||||
@@ -1296,6 +1317,18 @@ class vmmDetails(gobject.GObject):
|
||||
self.remove_device(xml)
|
||||
self.refresh_resources()
|
||||
|
||||
def remove_sound(self, src):
|
||||
vmlist = self.window.get_widget("hw-list")
|
||||
selection = vmlist.get_selection()
|
||||
active = selection.get_selected()
|
||||
if active[1] is None:
|
||||
return
|
||||
sound = active[0].get_value(active[1], HW_LIST_COL_DEVICE)
|
||||
|
||||
xml = "<sound model='%s'/>" % sound[3]
|
||||
self.remove_device(xml)
|
||||
self.refresh_resources()
|
||||
|
||||
def prepare_hw_list(self):
|
||||
hw_list_model = gtk.ListStore(str, str, int, gtk.gdk.Pixbuf, int, gobject.TYPE_PYOBJECT)
|
||||
self.window.get_widget("hw-list").set_model(hw_list_model)
|
||||
@@ -1426,6 +1459,25 @@ class vmmDetails(gobject.GObject):
|
||||
if missing:
|
||||
hw_list_model.insert(insertAt, [_("Display"), gtk.STOCK_SELECT_COLOR, gtk.ICON_SIZE_LARGE_TOOLBAR, None, HW_LIST_TYPE_GRAPHICS, graphic])
|
||||
|
||||
# Populate list of sound devices
|
||||
currentSounds = {}
|
||||
for sound in self.vm.get_sound_devices():
|
||||
missing = True
|
||||
insertAt = 0
|
||||
currentSounds[sound[3]] = 1
|
||||
for row in hw_list_model:
|
||||
if row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_SOUND and \
|
||||
row[HW_LIST_COL_DEVICE][3] == sound[3]:
|
||||
# Update metadata
|
||||
row[HW_LIST_COL_DEVICE] = sound
|
||||
missing = False
|
||||
|
||||
if row[HW_LIST_COL_TYPE] <= HW_LIST_TYPE_SOUND:
|
||||
insertAt = insertAt + 1
|
||||
# Add in row
|
||||
if missing:
|
||||
hw_list_model.insert(insertAt, [_("Sound: %s" % sound[3]), gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_LARGE_TOOLBAR, None, HW_LIST_TYPE_SOUND, sound])
|
||||
|
||||
# Now remove any no longer current devs
|
||||
devs = range(len(hw_list_model))
|
||||
devs.reverse()
|
||||
@@ -1434,13 +1486,20 @@ class vmmDetails(gobject.GObject):
|
||||
row = hw_list_model[i]
|
||||
removeIt = False
|
||||
|
||||
if row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_DISK and not currentDisks.has_key(row[HW_LIST_COL_DEVICE][3]):
|
||||
if row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_DISK and not \
|
||||
currentDisks.has_key(row[HW_LIST_COL_DEVICE][3]):
|
||||
removeIt = True
|
||||
elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_NIC and not currentNICs.has_key(row[HW_LIST_COL_DEVICE][3]):
|
||||
elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_NIC and not \
|
||||
currentNICs.has_key(row[HW_LIST_COL_DEVICE][3]):
|
||||
removeIt = True
|
||||
elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_INPUT and not currentInputs.has_key(row[HW_LIST_COL_DEVICE][3]):
|
||||
elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_INPUT and not \
|
||||
currentInputs.has_key(row[HW_LIST_COL_DEVICE][3]):
|
||||
removeIt = True
|
||||
elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_GRAPHICS and not currentGraphics.has_key(row[HW_LIST_COL_DEVICE][3]):
|
||||
elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_GRAPHICS and not \
|
||||
currentGraphics.has_key(row[HW_LIST_COL_DEVICE][3]):
|
||||
removeIt = True
|
||||
elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_SOUND and not \
|
||||
currentSounds.has_key(row[HW_LIST_COL_DEVICE][3]):
|
||||
removeIt = True
|
||||
|
||||
if removeIt:
|
||||
|
||||
@@ -692,6 +692,16 @@ class vmmDomain(gobject.GObject):
|
||||
|
||||
return self._parse_device_xml(_parse_graphics_devs)
|
||||
|
||||
def get_sound_devices(self):
|
||||
def _parse_sound_devs(ctx):
|
||||
sound = []
|
||||
ret = ctx.xpathEval("/domain/devices/sound")
|
||||
for node in ret:
|
||||
sound.append([None, None, None, node.prop("model")])
|
||||
return sound
|
||||
|
||||
return self._parse_device_xml(_parse_sound_devs)
|
||||
|
||||
def _parse_device_xml(self, parse_function):
|
||||
doc = None
|
||||
ctx = None
|
||||
@@ -808,6 +818,22 @@ class vmmDomain(gobject.GObject):
|
||||
logging.debug("Redefine with " + newxml)
|
||||
self.get_connection().define_domain(newxml)
|
||||
|
||||
elif dev_type == "sound":
|
||||
model = dev_ctx.xpathEval("/sound/@model")
|
||||
if len(model) > 0 and model[0].content != None:
|
||||
logging.debug("Looking for type %s" % model[0].content)
|
||||
ret = ctx.xpathEval("/domain/devices/sound[@model='%s']" % model[0].content)
|
||||
if len(ret) > 0:
|
||||
ret[0].unlinkNode()
|
||||
ret[0].freeNode()
|
||||
newxml=doc.serialize()
|
||||
logging.debug("Redefine with " + newxml)
|
||||
self.get_connection().define_domain(newxml)
|
||||
|
||||
else:
|
||||
raise RuntimeError, _("Unknown device type '%s'" %
|
||||
dev_type)
|
||||
|
||||
finally:
|
||||
if ctx != None:
|
||||
ctx.xpathFreeContext()
|
||||
|
||||
@@ -4476,6 +4476,188 @@
|
||||
<property name="type">tab</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox58">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame13">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="label_yalign">0.5</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment159">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xscale">1</property>
|
||||
<property name="yscale">1</property>
|
||||
<property name="top_padding">5</property>
|
||||
<property name="bottom_padding">3</property>
|
||||
<property name="left_padding">12</property>
|
||||
<property name="right_padding">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTable" id="table36">
|
||||
<property name="border_width">3</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">1</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="row_spacing">3</property>
|
||||
<property name="column_spacing">3</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label452">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Device Model:</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="bottom_attach">1</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="sound-model">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">insert sound model</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="bottom_attach">1</property>
|
||||
<property name="y_padding">1</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label451">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Sound Device</b></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">15</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHButtonBox" id="hbuttonbox14">
|
||||
<property name="border_width">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="config-sound-remove">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-remove</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal name="clicked" handler="on_config_sound_remove_clicked" last_modification_time="Wed, 23 Jul 2008 21:17:37 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="tab_expand">False</property>
|
||||
<property name="tab_fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label440">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Sound</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">tab</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="shrink">True</property>
|
||||
|
||||
Reference in New Issue
Block a user