mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-03-09 08:58:27 +03:00
details: Allow changing network and sound model on the fly
This commit is contained in:
parent
910d51e6b8
commit
929571a8ae
@ -62,18 +62,6 @@ char_widget_mappings = {
|
||||
"protocol" : "char-use-telnet",
|
||||
}
|
||||
|
||||
def build_video_combo(vm, video_dev):
|
||||
video_dev_model = gtk.ListStore(str)
|
||||
video_dev.set_model(video_dev_model)
|
||||
text = gtk.CellRendererText()
|
||||
video_dev.pack_start(text, True)
|
||||
video_dev.add_attribute(text, 'text', 0)
|
||||
video_dev_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
|
||||
for m in VirtualVideoDevice(vm.get_connection().vmm).model_types:
|
||||
video_dev_model.append([m])
|
||||
if len(video_dev_model) > 0:
|
||||
video_dev.set_active(0)
|
||||
|
||||
class vmmAddHardware(gobject.GObject):
|
||||
__gsignals__ = {
|
||||
"action-show-help": (gobject.SIGNAL_RUN_FIRST,
|
||||
@ -222,11 +210,7 @@ class vmmAddHardware(gobject.GObject):
|
||||
|
||||
# Network model list
|
||||
netmodel_list = self.window.get_widget("net-model")
|
||||
netmodel_model = gtk.ListStore(str, str)
|
||||
netmodel_list.set_model(netmodel_model)
|
||||
text = gtk.CellRendererText()
|
||||
netmodel_list.pack_start(text, True)
|
||||
netmodel_list.add_attribute(text, 'text', 1)
|
||||
uihelpers.build_netmodel_combo(self.vm, netmodel_list)
|
||||
|
||||
# Disk device type / bus
|
||||
target_list = self.window.get_widget("config-storage-devtype")
|
||||
@ -264,11 +248,7 @@ class vmmAddHardware(gobject.GObject):
|
||||
|
||||
# Sound model list
|
||||
sound_list = self.window.get_widget("sound-model")
|
||||
sound_lmodel = gtk.ListStore(str)
|
||||
sound_list.set_model(sound_lmodel)
|
||||
text = gtk.CellRendererText()
|
||||
sound_list.pack_start(text, True)
|
||||
sound_list.add_attribute(text, 'text', 0)
|
||||
uihelpers.build_sound_combo(self.vm, sound_list)
|
||||
|
||||
host_devtype = self.window.get_widget("host-device-type")
|
||||
# Description, nodedev type, specific type capability, sub type,
|
||||
@ -290,7 +270,7 @@ class vmmAddHardware(gobject.GObject):
|
||||
|
||||
# Video device
|
||||
video_dev = self.window.get_widget("video-model")
|
||||
build_video_combo(self.vm, video_dev)
|
||||
uihelpers.build_video_combo(self.vm, video_dev)
|
||||
|
||||
char_devtype = self.window.get_widget("char-device-type")
|
||||
# Type name, desc
|
||||
@ -372,9 +352,8 @@ class vmmAddHardware(gobject.GObject):
|
||||
net_warn.hide()
|
||||
|
||||
netmodel = self.window.get_widget("net-model")
|
||||
self.populate_network_model_model(netmodel.get_model())
|
||||
if len(netmodel.get_model()) > 0:
|
||||
netmodel.set_active(0)
|
||||
uihelpers.populate_netmodel_combo(self.vm, netmodel)
|
||||
netmodel.set_active(0)
|
||||
|
||||
# Input device init
|
||||
input_box = self.window.get_widget("input-type")
|
||||
@ -394,7 +373,6 @@ class vmmAddHardware(gobject.GObject):
|
||||
|
||||
# Sound init
|
||||
sound_box = self.window.get_widget("sound-model")
|
||||
self.populate_sound_model_model(sound_box.get_model())
|
||||
sound_box.set_active(0)
|
||||
|
||||
# Hostdev init
|
||||
@ -452,21 +430,6 @@ class vmmAddHardware(gobject.GObject):
|
||||
# UI population methods #
|
||||
#########################
|
||||
|
||||
def populate_network_model_model(self, model):
|
||||
model.clear()
|
||||
|
||||
# [xml value, label]
|
||||
model.append([None, _("Hypervisor default")])
|
||||
if self.vm.is_hvm():
|
||||
mod_list = [ "rtl8139", "ne2k_pci", "pcnet" ]
|
||||
if self.vm.get_hv_type() == "kvm":
|
||||
mod_list.append("e1000")
|
||||
mod_list.append("virtio")
|
||||
mod_list.sort()
|
||||
|
||||
for m in mod_list:
|
||||
model.append([m, m])
|
||||
|
||||
def populate_target_device_model(self, model):
|
||||
model.clear()
|
||||
#[bus, device, icon, desc, iconsize]
|
||||
@ -503,13 +466,6 @@ class vmmAddHardware(gobject.GObject):
|
||||
model.append([_("VNC server"), "vnc"])
|
||||
model.append([_("Local SDL window"), "sdl"])
|
||||
|
||||
def populate_sound_model_model(self, model):
|
||||
model.clear()
|
||||
lst = virtinst.VirtualAudio.MODELS
|
||||
lst.sort()
|
||||
for m in lst:
|
||||
model.append([m])
|
||||
|
||||
def populate_host_device_type_model(self, model):
|
||||
model.clear()
|
||||
for m in [ ["PCI Device", "pci", None, "net", "80203"],
|
||||
|
@ -26,7 +26,6 @@ import logging
|
||||
import traceback
|
||||
import os
|
||||
|
||||
import virtManager.addhardware
|
||||
import virtManager.uihelpers as uihelpers
|
||||
from virtManager.error import vmmErrorDialog
|
||||
from virtManager.addhardware import vmmAddHardware
|
||||
@ -259,6 +258,10 @@ class vmmDetails(gobject.GObject):
|
||||
"on_disk_readonly_changed": self.config_enable_apply,
|
||||
"on_disk_shareable_changed": self.config_enable_apply,
|
||||
|
||||
"on_network_model_combo_changed": self.config_enable_apply,
|
||||
|
||||
"on_sound_model_combo_changed": self.config_enable_apply,
|
||||
|
||||
"on_video_model_combo_changed": self.config_enable_apply,
|
||||
|
||||
"on_config_apply_clicked": self.config_apply,
|
||||
@ -547,9 +550,33 @@ class vmmDetails(gobject.GObject):
|
||||
txtCol.add_attribute(text, 'text', BOOT_LABEL)
|
||||
txtCol.add_attribute(text, 'sensitive', BOOT_ACTIVE)
|
||||
|
||||
no_default= not self.is_customize_dialog
|
||||
# Network model
|
||||
net_model = self.window.get_widget("network-model-combo")
|
||||
uihelpers.build_netmodel_combo(self.vm, net_model)
|
||||
|
||||
# Sound model
|
||||
sound_dev = self.window.get_widget("sound-model-combo")
|
||||
uihelpers.build_sound_combo(self.vm, sound_dev, no_default=no_default)
|
||||
|
||||
# Video model combo
|
||||
video_dev = self.window.get_widget("video-model-combo")
|
||||
virtManager.addhardware.build_video_combo(self.vm, video_dev)
|
||||
uihelpers.build_video_combo(self.vm, video_dev, no_default=no_default)
|
||||
|
||||
# Helper function to handle the combo/label pattern used for
|
||||
# video model, sound model, network model, etc.
|
||||
def set_combo_label(self, prefix, model_idx, value):
|
||||
model_label = self.window.get_widget(prefix + "-label")
|
||||
model_combo = self.window.get_widget(prefix + "-combo")
|
||||
model_list = map(lambda x: x[model_idx], model_combo.get_model())
|
||||
model_in_list = (value in model_list)
|
||||
|
||||
model_label.set_property("visible", not model_in_list)
|
||||
model_combo.set_property("visible", model_in_list)
|
||||
model_label.set_text(value or "")
|
||||
|
||||
if model_in_list:
|
||||
model_combo.set_active(model_list.index(value))
|
||||
|
||||
##########################
|
||||
# Window state listeners #
|
||||
@ -1160,6 +1187,10 @@ class vmmDetails(gobject.GObject):
|
||||
ret = self.config_boot_options_apply()
|
||||
elif pagetype is HW_LIST_TYPE_DISK:
|
||||
ret = self.config_disk_apply(info[1])
|
||||
elif pagetype is HW_LIST_TYPE_NIC:
|
||||
ret = self.config_network_apply(info[1])
|
||||
elif pagetype is HW_LIST_TYPE_SOUND:
|
||||
ret = self.config_sound_apply(info[1])
|
||||
elif pagetype is HW_LIST_TYPE_VIDEO:
|
||||
ret = self.config_video_apply(info[1])
|
||||
else:
|
||||
@ -1168,6 +1199,16 @@ class vmmDetails(gobject.GObject):
|
||||
if ret is not False:
|
||||
self.window.get_widget("config-apply").set_sensitive(False)
|
||||
|
||||
# Helper for accessing value of combo/label pattern
|
||||
def get_combo_label_value(self, prefix, model_idx=0):
|
||||
combo = self.window.get_widget(prefix + "-combo")
|
||||
value = None
|
||||
|
||||
if combo.get_property("visible"):
|
||||
value = combo.get_model()[combo.get_active()][model_idx]
|
||||
|
||||
return value
|
||||
|
||||
# Overview section
|
||||
def config_overview_apply(self):
|
||||
# Machine details
|
||||
@ -1299,14 +1340,22 @@ class vmmDetails(gobject.GObject):
|
||||
[(dev_id_info, do_readonly),
|
||||
(dev_id_info, do_shareable)])
|
||||
|
||||
# Audio options
|
||||
def config_sound_apply(self, dev_id_info):
|
||||
model = self.get_combo_label_value("sound-model")
|
||||
if model:
|
||||
return self._change_config_helper(self.vm.define_sound_model,
|
||||
(dev_id_info, model))
|
||||
|
||||
# Network options
|
||||
def config_network_apply(self, dev_id_info):
|
||||
model = self.get_combo_label_value("network-model")
|
||||
return self._change_config_helper(self.vm.define_network_model,
|
||||
(dev_id_info, model))
|
||||
|
||||
# Video options
|
||||
def config_video_apply(self, dev_id_info):
|
||||
model_combo = self.window.get_widget("video-model-combo")
|
||||
|
||||
model = None
|
||||
if model_combo.get_property("visible"):
|
||||
model = model_combo.get_model()[model_combo.get_active()][0]
|
||||
|
||||
model = self.get_combo_label_value("video-model")
|
||||
if model:
|
||||
return self._change_config_helper(self.vm.define_video_model,
|
||||
(dev_id_info, model))
|
||||
@ -1475,20 +1524,10 @@ class vmmDetails(gobject.GObject):
|
||||
|
||||
self.window.get_widget("overview-acpi").set_active(acpi)
|
||||
self.window.get_widget("overview-apic").set_active(apic)
|
||||
|
||||
if not clock:
|
||||
clock = _("Same as host")
|
||||
|
||||
clock_combo = self.window.get_widget("overview-clock-combo")
|
||||
clock_label = self.window.get_widget("overview-clock-label")
|
||||
clock_list = map(lambda x: x[0], clock_combo.get_model())
|
||||
clock_in_combo = (clock in clock_list)
|
||||
|
||||
clock_combo.set_property("visible", clock_in_combo)
|
||||
clock_label.set_property("visible", not clock_in_combo)
|
||||
if clock_in_combo:
|
||||
clock_combo.set_active(clock_list.index(clock))
|
||||
else:
|
||||
clock_label.set_text(clock)
|
||||
self.set_combo_label("overview-clock", 0, clock)
|
||||
|
||||
# Security details
|
||||
vmmodel, ignore, vmlabel = self.vm.get_seclabel()
|
||||
@ -1697,6 +1736,7 @@ class vmmDetails(gobject.GObject):
|
||||
|
||||
nettype = netinfo[5]
|
||||
source = netinfo[3]
|
||||
model = netinfo[6] or None
|
||||
|
||||
netobj = None
|
||||
if nettype == virtinst.VirtualNetworkInterface.TYPE_VIRTUAL:
|
||||
@ -1714,8 +1754,9 @@ class vmmDetails(gobject.GObject):
|
||||
self.window.get_widget("network-mac-address").set_text(netinfo[2])
|
||||
self.window.get_widget("network-source-device").set_text(desc)
|
||||
|
||||
model = netinfo[6] or _("Hypervisor default")
|
||||
self.window.get_widget("network-source-model").set_text(model)
|
||||
uihelpers.populate_netmodel_combo(self.vm,
|
||||
self.window.get_widget("network-model-combo"))
|
||||
self.set_combo_label("network-model", 0, model)
|
||||
|
||||
def refresh_input_page(self):
|
||||
inputinfo = self.get_hw_selection(HW_LIST_COL_DEVICE)
|
||||
@ -1781,7 +1822,9 @@ class vmmDetails(gobject.GObject):
|
||||
if not soundinfo:
|
||||
return
|
||||
|
||||
self.window.get_widget("sound-model").set_text(soundinfo[2])
|
||||
model = soundinfo[2]
|
||||
|
||||
self.set_combo_label("sound-model", 0, model)
|
||||
|
||||
def refresh_char_page(self):
|
||||
charinfo = self.get_hw_selection(HW_LIST_COL_DEVICE)
|
||||
@ -1892,17 +1935,7 @@ class vmmDetails(gobject.GObject):
|
||||
self.window.get_widget("video-ram").set_text(ramlabel)
|
||||
self.window.get_widget("video-heads").set_text(heads and heads or "-")
|
||||
|
||||
model_label = self.window.get_widget("video-model-label")
|
||||
model_combo = self.window.get_widget("video-model-combo")
|
||||
model_list = map(lambda x: x[0], model_combo.get_model())
|
||||
model_in_list = (model in model_list)
|
||||
|
||||
model_label.set_property("visible", not model_in_list)
|
||||
model_combo.set_property("visible", model_in_list)
|
||||
model_label.set_text(model)
|
||||
|
||||
if model_in_list:
|
||||
model_combo.set_active(model_list.index(model))
|
||||
self.set_combo_label("video-model", 0, model)
|
||||
|
||||
def refresh_boot_page(self):
|
||||
# Refresh autostart
|
||||
|
@ -171,6 +171,10 @@ class vmmDomainBase(vmmLibvirtObject):
|
||||
def define_disk_shareable(self, dev_id_info, do_shareable):
|
||||
raise NotImplementedError()
|
||||
|
||||
def define_network_model(self, dev_id_info, newmodel):
|
||||
raise NotImplementedError()
|
||||
def define_sound_model(self, dev_id_info, newmodel):
|
||||
raise NotImplementedError()
|
||||
def define_video_model(self, dev_id_info, newmodel):
|
||||
raise NotImplementedError()
|
||||
|
||||
@ -1785,6 +1789,46 @@ class vmmDomain(vmmDomainBase):
|
||||
return self._redefine(util.xml_parse_wrapper, self._change_disk_param,
|
||||
dev_id_info, "shareable", do_shareable)
|
||||
|
||||
# Network properties
|
||||
def define_network_model(self, dev_id_info, newmodel):
|
||||
devtype = "interface"
|
||||
if not self._check_device_is_present(devtype, dev_id_info):
|
||||
return
|
||||
|
||||
def change_model(doc, ctx):
|
||||
dev_node = self._get_device_xml_nodes(ctx, devtype, dev_id_info)[0]
|
||||
model_node = dev_node.xpathEval("./model")
|
||||
model_node = model_node and model_node[0] or None
|
||||
|
||||
if not model_node:
|
||||
if newmodel:
|
||||
model_node = dev_node.newChild(None, "model", None)
|
||||
|
||||
if newmodel:
|
||||
model_node.setProp("type", newmodel)
|
||||
else:
|
||||
model_node.unlinkNode()
|
||||
model_node.freeNode()
|
||||
|
||||
return doc.serialize()
|
||||
|
||||
return self._redefine(util.xml_parse_wrapper, change_model)
|
||||
|
||||
# Sound properties
|
||||
def define_sound_model(self, dev_id_info, newmodel):
|
||||
devtype = "sound"
|
||||
if not self._check_device_is_present(devtype, dev_id_info):
|
||||
return
|
||||
|
||||
def change_model(doc, ctx):
|
||||
dev_node = self._get_device_xml_nodes(ctx, devtype, dev_id_info)[0]
|
||||
dev_node.setProp("model", newmodel)
|
||||
|
||||
return doc.serialize()
|
||||
|
||||
return self._redefine(util.xml_parse_wrapper, change_model)
|
||||
|
||||
# Video properties
|
||||
def define_video_model(self, dev_id_info, newmodel):
|
||||
if not self._check_device_is_present("video", dev_id_info):
|
||||
return
|
||||
@ -1799,7 +1843,7 @@ class vmmDomain(vmmDomainBase):
|
||||
return doc.serialize()
|
||||
|
||||
return self._redefine(util.xml_parse_wrapper, change_model,
|
||||
dev_id_info, newmodel)
|
||||
dev_id_info, newmodel)
|
||||
|
||||
########################
|
||||
# End XML Altering API #
|
||||
@ -2056,6 +2100,20 @@ class vmmDomainVirtinst(vmmDomainBase):
|
||||
dev.shareable = do_shareable
|
||||
self._redefine(change_shareable)
|
||||
|
||||
def define_network_model(self, dev_id_info, newmodel):
|
||||
dev = self._get_device_xml_object(VirtualDevice.VIRTUAL_DEV_NET,
|
||||
dev_id_info)
|
||||
def change_model():
|
||||
dev.model = newmodel
|
||||
self._redefine(change_model)
|
||||
|
||||
def define_sound_model(self, dev_id_info, newmodel):
|
||||
dev = self._get_device_xml_object(VirtualDevice.VIRTUAL_DEV_AUDIO,
|
||||
dev_id_info)
|
||||
def change_model():
|
||||
dev.model = newmodel
|
||||
self._redefine(change_model)
|
||||
|
||||
def define_video_model(self, dev_id_info, newmodel):
|
||||
dev = self._get_device_xml_object(VirtualDevice.VIRTUAL_DEV_VIDEO,
|
||||
dev_id_info)
|
||||
|
@ -103,6 +103,67 @@ def host_space_tick(conn, config, widget):
|
||||
|
||||
return 1
|
||||
|
||||
#####################################################
|
||||
# Hardware model list building (for details, addhw) #
|
||||
#####################################################
|
||||
def build_video_combo(vm, video_dev, no_default=False):
|
||||
video_dev_model = gtk.ListStore(str)
|
||||
video_dev.set_model(video_dev_model)
|
||||
text = gtk.CellRendererText()
|
||||
video_dev.pack_start(text, True)
|
||||
video_dev.add_attribute(text, 'text', 0)
|
||||
video_dev_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
|
||||
|
||||
tmpdev = virtinst.VirtualVideoDevice(vm.get_connection().vmm)
|
||||
for m in tmpdev.model_types:
|
||||
if m == tmpdev.MODEL_DEFAULT and no_default:
|
||||
continue
|
||||
video_dev_model.append([m])
|
||||
if len(video_dev_model) > 0:
|
||||
video_dev.set_active(0)
|
||||
|
||||
def build_sound_combo(vm, combo, no_default=False):
|
||||
dev_model = gtk.ListStore(str)
|
||||
combo.set_model(dev_model)
|
||||
text = gtk.CellRendererText()
|
||||
combo.pack_start(text, True)
|
||||
combo.add_attribute(text, 'text', 0)
|
||||
dev_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
|
||||
|
||||
for m in virtinst.VirtualAudio.MODELS:
|
||||
if m == virtinst.VirtualAudio.MODEL_DEFAULT and no_default:
|
||||
continue
|
||||
dev_model.append([m])
|
||||
if len(dev_model) > 0:
|
||||
combo.set_active(0)
|
||||
|
||||
def build_netmodel_combo(vm, combo):
|
||||
dev_model = gtk.ListStore(str, str)
|
||||
combo.set_model(dev_model)
|
||||
text = gtk.CellRendererText()
|
||||
combo.pack_start(text, True)
|
||||
combo.add_attribute(text, 'text', 1)
|
||||
dev_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
|
||||
|
||||
populate_netmodel_combo(vm, combo)
|
||||
combo.set_active(0)
|
||||
|
||||
def populate_netmodel_combo(vm, combo):
|
||||
model = combo.get_model()
|
||||
model.clear()
|
||||
|
||||
# [xml value, label]
|
||||
model.append([None, _("Hypervisor default")])
|
||||
if vm.is_hvm():
|
||||
mod_list = [ "rtl8139", "ne2k_pci", "pcnet" ]
|
||||
if vm.get_hv_type() == "kvm":
|
||||
mod_list.append("e1000")
|
||||
mod_list.append("virtio")
|
||||
mod_list.sort()
|
||||
|
||||
for m in mod_list:
|
||||
model.append([m, m])
|
||||
|
||||
|
||||
#######################################################################
|
||||
# Widgets for listing network device options (in create, addhardware) #
|
||||
|
@ -2704,12 +2704,6 @@ I/O:</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
@ -2735,6 +2729,12 @@ I/O:</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
@ -2906,21 +2906,6 @@ I/O:</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="network-source-model">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="network-mac-address">
|
||||
<property name="visible">True</property>
|
||||
@ -2934,6 +2919,41 @@ I/O:</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox4">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkComboBox" id="network-model-combo">
|
||||
<property name="visible">True</property>
|
||||
<signal name="changed" handler="on_network_model_combo_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="network-model-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label">unknown model</property>
|
||||
<property name="selectable">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
@ -3365,11 +3385,28 @@ I/O:</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="sound-model">
|
||||
<widget class="GtkHBox" id="hbox11">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label">insert sound model</property>
|
||||
<property name="selectable">True</property>
|
||||
<child>
|
||||
<widget class="GtkComboBox" id="sound-model-combo">
|
||||
<property name="visible">True</property>
|
||||
<signal name="changed" handler="on_sound_model_combo_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="sound-model-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label">insert sound model</property>
|
||||
<property name="selectable">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
|
Loading…
x
Reference in New Issue
Block a user