diff --git a/src/virtManager/details.py b/src/virtManager/details.py index cc23b35e2..67cdb4d91 100644 --- a/src/virtManager/details.py +++ b/src/virtManager/details.py @@ -61,12 +61,13 @@ HW_LIST_TYPE_GRAPHICS = 8 HW_LIST_TYPE_SOUND = 9 HW_LIST_TYPE_CHAR = 10 HW_LIST_TYPE_HOSTDEV = 11 +HW_LIST_TYPE_VIDEO = 12 apply_pages = [ HW_LIST_TYPE_GENERAL, HW_LIST_TYPE_CPU, HW_LIST_TYPE_MEMORY, HW_LIST_TYPE_BOOT] remove_pages = [ HW_LIST_TYPE_DISK, HW_LIST_TYPE_NIC, HW_LIST_TYPE_INPUT, HW_LIST_TYPE_GRAPHICS, HW_LIST_TYPE_SOUND, HW_LIST_TYPE_CHAR, - HW_LIST_TYPE_HOSTDEV ] + HW_LIST_TYPE_HOSTDEV, HW_LIST_TYPE_VIDEO ] # Console pages PAGE_UNAVAILABLE = 0 @@ -693,6 +694,8 @@ class vmmDetails(gobject.GObject): self.refresh_char_page() elif pagetype == HW_LIST_TYPE_HOSTDEV: self.refresh_hostdev_page() + elif pagetype == HW_LIST_TYPE_VIDEO: + self.refresh_video_page() else: pagetype = -1 @@ -1142,6 +1145,20 @@ class vmmDetails(gobject.GObject): self.window.get_widget("hostdev-mode").set_text(hostdevinfo[3]) self.window.get_widget("hostdev-source").set_text(hostdevinfo[5]) + def refresh_video_page(self): + vidinfo = self.get_hw_selection(HW_LIST_COL_DEVICE) + if not vidinfo: + return + + ignore, ignore, model, ram, heads = vidinfo + try: + ramlabel = ram and "%d MB" % (int(ram) / 1024) or "-" + except: + ramlabel = "-" + + self.window.get_widget("video-model").set_text(model) + self.window.get_widget("video-ram").set_text(ramlabel) + self.window.get_widget("video-heads").set_text(heads and heads or "-") def refresh_boot_page(self): # Refresh autostart @@ -1743,6 +1760,7 @@ class vmmDetails(gobject.GObject): currentSounds = {} currentChars = {} currentHostdevs = {} + currentVids = {} def update_hwlist(hwtype, info): """Return (true if we updated an entry, @@ -1843,6 +1861,17 @@ class vmmDetails(gobject.GObject): if missing: hw_list_model.insert(insertAt, [hostdevinfo[2], None, gtk.ICON_SIZE_LARGE_TOOLBAR, None, HW_LIST_TYPE_HOSTDEV, hostdevinfo]) + # Populate video devices + for vidinfo in self.vm.get_video_devices(): + currentVids[vidinfo[2]] = 1 + missing, insertAt = update_hwlist(HW_LIST_TYPE_VIDEO, + vidinfo) + + if missing: + hw_list_model.insert(insertAt, + [_("Video"), gtk.STOCK_SELECT_COLOR, + gtk.ICON_SIZE_LARGE_TOOLBAR, + None, HW_LIST_TYPE_VIDEO, vidinfo]) # Now remove any no longer current devs devs = range(len(hw_list_model)) @@ -1852,26 +1881,21 @@ 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][2]): - removeIt = True - elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_NIC and not \ - currentNICs.has_key(row[HW_LIST_COL_DEVICE][2]): - removeIt = True - elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_INPUT and not \ - currentInputs.has_key(row[HW_LIST_COL_DEVICE][2]): - removeIt = True - elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_GRAPHICS and not \ - currentGraphics.has_key(row[HW_LIST_COL_DEVICE][2]): - removeIt = True - elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_SOUND and not \ - currentSounds.has_key(row[HW_LIST_COL_DEVICE][2]): - removeIt = True - elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_CHAR and not \ - currentChars.has_key(row[HW_LIST_COL_DEVICE][2]): - removeIt = True - elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_HOSTDEV and not \ - currentHostdevs.has_key(row[HW_LIST_COL_DEVICE][2]): + mapping = { + HW_LIST_TYPE_DISK : currentDisks, + HW_LIST_TYPE_NIC : currentNICs, + HW_LIST_TYPE_INPUT : currentInputs, + HW_LIST_TYPE_GRAPHICS : currentGraphics, + HW_LIST_TYPE_SOUND : currentSounds, + HW_LIST_TYPE_CHAR : currentChars, + HW_LIST_TYPE_HOSTDEV : currentHostdevs, + HW_LIST_TYPE_VIDEO : currentVids, + } + + + hwtype = row[HW_LIST_COL_TYPE] + if (mapping.has_key(hwtype) and not + mapping[hwtype].has_key(row[HW_LIST_COL_DEVICE][2])): removeIt = True if removeIt: @@ -1880,7 +1904,8 @@ class vmmDetails(gobject.GObject): (selModel, selIter) = hw_list.get_selection().get_selected() selType = selModel.get_value(selIter, HW_LIST_COL_TYPE) selInfo = selModel.get_value(selIter, HW_LIST_COL_DEVICE) - if selType == row[HW_LIST_COL_TYPE] and selInfo[2] == row[HW_LIST_COL_DEVICE][2]: + if (selType == row[HW_LIST_COL_TYPE] and + selInfo[2] == row[HW_LIST_COL_DEVICE][2]): hw_list.get_selection().select_iter(selModel.iter_nth_child(None, 0)) # Now actually remove it diff --git a/src/virtManager/domain.py b/src/virtManager/domain.py index fef545b1b..a141ab123 100644 --- a/src/virtManager/domain.py +++ b/src/virtManager/domain.py @@ -28,6 +28,13 @@ import difflib from virtManager import util import virtinst.util as vutil +def safeint(val, fmt="%.3d"): + try: + int(val) + except: + return str(val) + return fmt % int(val) + class vmmDomain(gobject.GObject): __gsignals__ = { "status-changed": (gobject.SIGNAL_RUN_FIRST, @@ -932,6 +939,32 @@ class vmmDomain(gobject.GObject): return self._parse_device_xml(_parse_char_devs) + def get_video_devices(self): + def _parse_video_devs(ctx): + vids = [] + devs = ctx.xpathEval("/domain/devices/video") + + for dev in devs: + model = None + ram = None + heads = None + + for node in dev.children or []: + if node.name == "model": + model = node.prop("type") + ram = node.prop("vram") + heads = node.prop("heads") + + if ram: + ram = safeint(ram, "%d") + + unique = [model, ram, heads] + row = ["video", unique, model, ram, heads] + vids.append(row) + + return vids + return self._parse_device_xml(_parse_video_devs) + def get_hostdev_devices(self): def _parse_hostdev_devs(ctx): hostdevs = [] @@ -954,13 +987,6 @@ class vmmDomain(gobject.GObject): val = val[2:] return val - def safeint(val, fmt="%.3d"): - try: - int(val) - except: - return str(val) - return fmt % int(val) - def set_uniq(baseent, propname, node): val = node.prop(propname) if not unique.has_key(baseent): @@ -1028,15 +1054,10 @@ class vmmDomain(gobject.GObject): def _parse_device_xml(self, parse_function): - ret = [] def parse_wrap_func(doc, ctx): return parse_function(ctx) - try: - ret = util.xml_parse_wrapper(self.get_xml(), parse_wrap_func) - except Exception, e: - raise RuntimeError(_("Error parsing domain xml: %s") % str(e)) - return ret + return util.xml_parse_wrapper(self.get_xml(), parse_wrap_func) def _add_xml_device(self, xml, devxml): """ @@ -1136,6 +1157,19 @@ class vmmDomain(gobject.GObject): logging.debug("Hostdev xpath string: %s" % xpath) ret = ctx.xpathEval(xpath) + elif dev_type == "video": + model, ram, heads = dev_id_info + xpath = "/domain/devices/video" + + xpath += "[model/@type='%s'" % model + if ram: + xpath += " and model/@vram='%s'" % ram + if heads: + xpath += " and model/@heads='%s'" % heads + xpath += "][1]" + + ret = ctx.xpathEval(xpath) + else: raise RuntimeError, _("Unknown device type '%s'" % dev_type) diff --git a/src/vmm-details.glade b/src/vmm-details.glade index dcb4a93fd..d1e363912 100644 --- a/src/vmm-details.glade +++ b/src/vmm-details.glade @@ -1,6 +1,6 @@ - + Virtual Machine @@ -569,6 +569,75 @@ + + + True + 0 + Password: + + + 1 + 2 + GTK_FILL + + + + + + True + True + False + + + 1 + 2 + 1 + 2 + + + + + + True + True + Save this password in your keyring + True + 0 + 0 + True + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + + True + 0 + Username: + + + GTK_FILL + + + + + + True + True + + + + 1 + 2 + + + True @@ -620,75 +689,6 @@ - - - True - True - - - - 1 - 2 - - - - - - True - 0 - Username: - - - GTK_FILL - - - - - - True - True - Save this password in your keyring - True - 0 - 0 - True - - - 1 - 2 - 2 - 3 - GTK_FILL - - - - - - True - True - False - - - 1 - 2 - 1 - 2 - - - - - - True - 0 - Password: - - - 1 - 2 - GTK_FILL - - - 2 @@ -866,31 +866,39 @@ 6 6 - + True - 0 - test-vm - True + 1 + Status: - 1 - 2 + 2 + 3 GTK_FILL - GTK_FILL + - + True - 0 - 8ffc926e-b4da-b3b6-552f-e37b92f918d5 - True + 1 + UUID: - 1 - 2 1 2 + GTK_FILL + + + + + + True + 1 + Name: + + + GTK_FILL @@ -929,40 +937,32 @@ - + True - 1 - Name: - - - GTK_FILL - - - - - - True - 1 - UUID: + 0 + 8ffc926e-b4da-b3b6-552f-e37b92f918d5 + True + 1 + 2 1 2 - GTK_FILL - + True - 1 - Status: + 0 + test-vm + True - 2 - 3 + 1 + 2 GTK_FILL - + GTK_FILL @@ -1005,42 +1005,22 @@ 6 6 - + True 1 - Emulator: + Hypervisor: - 2 - 3 GTK_FILL GTK_FILL - + True - 0 - foo + Architecture: - 1 - 2 - 2 - 3 - GTK_FILL - GTK_FILL - - - - - True - 0 - foo - - - 1 - 2 1 2 GTK_FILL @@ -1061,11 +1041,14 @@ - + True - Architecture: + 0 + foo + 1 + 2 1 2 GTK_FILL @@ -1073,12 +1056,29 @@ - + True - 1 - Hypervisor: + 0 + foo + 1 + 2 + 2 + 3 + GTK_FILL + GTK_FILL + + + + + True + 1 + Emulator: + + + 2 + 3 GTK_FILL GTK_FILL @@ -1120,28 +1120,29 @@ 6 6 - + True - 1 - 0 - Type: + 6 + + + True + + + + + False + False + + + + + - 1 - 2 + 1 + 2 GTK_FILL - GTK_FILL - - - - - True - 1 - Model: - - - GTK_FILL - GTK_FILL + @@ -1151,65 +1152,6 @@ 2 6 6 - - - True - True - 0 - gtk-info - - - 1 - 2 - - - - - - True - True - 0 - gtk-info - - - 1 - 2 - 1 - 2 - - - - - - True - True - Static - True - 0 - True - security-dynamic - - - 1 - 2 - GTK_FILL - - - - - True - True - Dynamic - True - 0 - True - - - - - - - True @@ -1250,6 +1192,65 @@ GTK_EXPAND + + + True + True + Dynamic + True + 0 + True + + + + + + + + + + True + True + Static + True + 0 + True + security-dynamic + + + 1 + 2 + GTK_FILL + + + + + True + True + 0 + gtk-info + + + 1 + 2 + 1 + 2 + + + + + + True + True + 0 + gtk-info + + + 1 + 2 + + + 1 @@ -1260,29 +1261,28 @@ - + True - 6 - - - True - - - - - False - False - - - - - + 1 + Model: - 1 - 2 GTK_FILL - + GTK_FILL + + + + + True + 1 + 0 + Type: + + + 1 + 2 + GTK_FILL + GTK_FILL @@ -1309,7 +1309,7 @@ True - Overview + Over tab @@ -1350,18 +1350,88 @@ - + + True + 1 + CPU +usage: + GTK_JUSTIFY_RIGHT + + + GTK_FILL + + + + + + True + 1 + Memory +usage: + GTK_JUSTIFY_RIGHT + + + 1 + 2 + GTK_FILL + + + + + + True + 1 + Disk +I/O: + GTK_JUSTIFY_RIGHT + + + 2 + 3 + GTK_FILL + + + + + + True + 1 + Network +I/O: + GTK_JUSTIFY_RIGHT + + + 3 + 4 + GTK_FILL + + + + + True 0 - 0 KBytes/s -0KBytes/s - True + 18% 2 3 - 3 - 4 + GTK_FILL + + + + + + True + 0 + 30 MB of +128 MB + + + 2 + 3 + 1 + 2 GTK_FILL @@ -1384,92 +1454,22 @@ - + True 0 - 30 MB of -128 MB + 0 KBytes/s +0KBytes/s + True 2 3 - 1 - 2 - GTK_FILL - - - - - - True - 0 - 18% - - - 2 - 3 - GTK_FILL - - - - - - True - 1 - Network -I/O: - GTK_JUSTIFY_RIGHT - - 3 4 GTK_FILL - - - True - 1 - Disk -I/O: - GTK_JUSTIFY_RIGHT - - - 2 - 3 - GTK_FILL - - - - - - True - 1 - Memory -usage: - GTK_JUSTIFY_RIGHT - - - 1 - 2 - GTK_FILL - - - - - - True - 1 - CPU -usage: - GTK_JUSTIFY_RIGHT - - - GTK_FILL - - - @@ -1543,21 +1543,23 @@ usage: 3 3 - + True - True - 2 1 32 1 2 0 - 1 - True - GTK_UPDATE_IF_VALID - - Virtual CPU Select - - + 1 + Current allocation: + + + GTK_FILL + + + + + + True + 1 + Change allocation: - 1 - 2 1 2 GTK_FILL @@ -1565,27 +1567,25 @@ usage: - + True - 0 - 2 + 1 + Maximum allocation: - 1 - 2 + 2 + 3 GTK_FILL - + True - 0 - 8 + 1 + Total CPUs on host machine: - 1 - 2 3 4 GTK_FILL @@ -1608,12 +1608,14 @@ usage: - + True - 1 - Total CPUs on host machine: + 0 + 8 + 1 + 2 3 4 GTK_FILL @@ -1621,42 +1623,40 @@ usage: - + True - 1 - Maximum allocation: + 0 + 2 - 2 - 3 + 1 + 2 GTK_FILL - + True - 1 - Change allocation: + True + 2 1 32 1 2 0 + 1 + True + GTK_UPDATE_IF_VALID + + Virtual CPU Select + + + 1 + 2 1 2 GTK_FILL - - - True - 1 - Current allocation: - - - GTK_FILL - - - False @@ -1784,39 +1784,79 @@ usage: 3 3 - + True - - - True - True - 50 50 32000 1 25 0 - 2 - True - GTK_UPDATE_IF_VALID - - Max Memory Select - - - - - - - True - MB - - - False - False - 1 - - + 1 + Current allocation: + + + GTK_FILL + + + + + + True + 1 + Change allocation: + + + 1 + 2 + GTK_FILL + + + + + + True + 1 + Maximum allocation: + + + 2 + 3 + GTK_FILL + + + + + + True + 1 + Total memory on host machine: + + + 3 + 4 + GTK_FILL + + + + + + True + 0 + 2 GB + + + 1 + 2 + 3 + 4 + GTK_FILL + + + + + + True + 0 + 200 MB 1 2 - 2 - 3 GTK_FILL @@ -1860,83 +1900,43 @@ usage: - + True - 0 - 200 MB + + + True + True + 50 50 32000 1 25 0 + 2 + True + GTK_UPDATE_IF_VALID + + Max Memory Select + + + + + + + True + MB + + + False + False + 1 + + 1 2 - GTK_FILL - - - - - - True - 0 - 2 GB - - - 1 - 2 - 3 - 4 - GTK_FILL - - - - - - True - 1 - Total memory on host machine: - - - 3 - 4 - GTK_FILL - - - - - - True - 1 - Maximum allocation: - - 2 3 GTK_FILL - - - True - 1 - Change allocation: - - - 1 - 2 - GTK_FILL - - - - - - True - 1 - Current allocation: - - - GTK_FILL - - - False @@ -2037,17 +2037,6 @@ usage: True 2 - - - True - - - - 1 - 2 - GTK_FILL - - True @@ -2059,6 +2048,17 @@ usage: + + + True + + + + 1 + 2 + GTK_FILL + + @@ -2130,110 +2130,76 @@ usage: - - True - True - True - gtk-connect - True - 0 - - - - 2 - 3 - 3 - - - - - - + True 0 + label402 True + PANGO_ELLIPSIZE_START 1 2 - 4 - 5 - GTK_FILL + 1 + 2 - + True 1 - Target bus: + Source type: + True + GTK_JUSTIFY_RIGHT - 4 - 5 GTK_FILL - - True - 0 - label423 - True - - - 1 - 2 - 5 - 6 - GTK_FILL - - - - - + True 1 - Permissions: + Source path: + True - 5 - 6 + 1 + 2 GTK_FILL - + True - 0 - Block - True + 1 + Target type: + True - 1 - 2 - GTK_FILL - - - - - - True - 0 - disk - True - - - 1 - 2 2 3 GTK_FILL + + + True + 1 + Target device: + True + + + 3 + 4 + GTK_FILL + + + True @@ -2251,27 +2217,15 @@ usage: - + True - 1 - Target device: - True - - - 3 - 4 - GTK_FILL - - - - - - True - 1 - Target type: - True + 0 + disk + True + 1 + 2 2 3 GTK_FILL @@ -2279,45 +2233,91 @@ usage: - - True - 1 - Source path: - True - - - 1 - 2 - GTK_FILL - - - - - - True - 1 - Source type: - True - GTK_JUSTIFY_RIGHT - - - GTK_FILL - - - - - + True 0 - label402 + Block True - PANGO_ELLIPSIZE_START 1 2 - 1 - 2 + GTK_FILL + + + + + + True + 1 + Permissions: + + + 5 + 6 + GTK_FILL + + + + + + True + 0 + label423 + True + + + 1 + 2 + 5 + 6 + GTK_FILL + + + + + + True + 1 + Target bus: + + + 4 + 5 + GTK_FILL + + + + + + True + 0 + True + + + 1 + 2 + 4 + 5 + GTK_FILL + + + + + + True + True + True + gtk-connect + True + 0 + + + + 2 + 3 + 3 + @@ -2439,44 +2439,56 @@ usage: 8 4 - + + True + 1 + Source type: + True + + + GTK_FILL + + + + + + True + 1 + Source device: + + + 1 + 2 + GTK_FILL + + + + + True 0 + label395 True 1 2 - 2 - 3 GTK_FILL - + True - 1 - Source model: + 0 + label401 + True - 2 - 3 - GTK_FILL - - - - - - True - 1 - MAC address: - True - network-mac-address - - - 3 - 4 + 1 + 2 + 1 + 2 GTK_FILL @@ -2499,56 +2511,44 @@ usage: - - True - 0 - label401 - True - - - 1 - 2 - 1 - 2 - GTK_FILL - - - - - - True - 0 - label395 - True - - - 1 - 2 - GTK_FILL - - - - - + True 1 - Source device: - - - 1 - 2 - GTK_FILL - - - - - - True - 1 - Source type: + MAC address: True + network-mac-address + 3 + 4 + GTK_FILL + + + + + + True + 1 + Source model: + + + 2 + 3 + GTK_FILL + + + + + + True + 0 + True + + + 1 + 2 + 2 + 3 GTK_FILL @@ -2658,15 +2658,27 @@ usage: 8 4 - + True - 0 - label403 - True + 1 + Type: + True - 1 - 2 + GTK_FILL + + + + + + True + 1 + Mode: + + + 1 + 2 + GTK_FILL @@ -2687,27 +2699,15 @@ usage: - + True - 1 - Mode: + 0 + label403 + True - 1 - 2 - GTK_FILL - - - - - - True - 1 - Type: - True - - - GTK_FILL + 1 + 2 @@ -2816,12 +2816,29 @@ usage: 8 4 - + True - 1 - Keymap: + 0 + label403 + True + 1 + 2 + + 1 + + + + + True + 0 + keylabel + True + + + 1 + 2 4 5 GTK_FILL @@ -2829,12 +2846,15 @@ usage: - + True - 1 - Password: + 0 + label401 + True + 1 + 2 3 4 GTK_FILL @@ -2842,37 +2862,15 @@ usage: - + True - 1 - Type: - True - - - GTK_FILL - - - - - - True - 1 - Address: - - - 1 - 2 - GTK_FILL - - - - - - True - 1 - Port: + 0 + label401 + True + 1 + 2 2 3 GTK_FILL @@ -2896,15 +2894,12 @@ usage: - + True - 0 - label401 - True + 1 + Port: - 1 - 2 2 3 GTK_FILL @@ -2912,15 +2907,37 @@ usage: - + True - 0 - label401 - True + 1 + Address: + + + 1 + 2 + GTK_FILL + + + + + + True + 1 + Type: + True + + + GTK_FILL + + + + + + True + 1 + Password: - 1 - 2 3 4 GTK_FILL @@ -2928,35 +2945,18 @@ usage: - + True - 0 - keylabel - True + 1 + Keymap: - 1 - 2 4 5 GTK_FILL - - - True - 0 - label403 - True - - - 1 - 2 - - 1 - - @@ -2984,7 +2984,7 @@ usage: True - Graphics + Gfx tab @@ -3013,6 +3013,17 @@ usage: 2 8 4 + + + True + 0 + Device Model: + + + GTK_FILL + + + True @@ -3028,17 +3039,6 @@ usage: 1 - - - True - 0 - Device Model: - - - GTK_FILL - - - @@ -3095,17 +3095,52 @@ usage: 8 4 - + + True + 1 + Device Type: + + + GTK_FILL + + + + + + True + 1 + Target Port: + + + 1 + 2 + GTK_FILL + + + + + + True + 1 + Source Path: + + + 2 + 3 + GTK_FILL + + + + + True 0 - label508 + label506 True 1 2 - 2 - 3 GTK_FILL @@ -3127,56 +3162,21 @@ usage: - + True 0 - label506 + label508 True 1 2 - GTK_FILL - - - - - - True - 1 - Source Path: - - 2 3 GTK_FILL - - - True - 1 - Target Port: - - - 1 - 2 - GTK_FILL - - - - - - True - 1 - Device Type: - - - GTK_FILL - - - @@ -3233,44 +3233,7 @@ usage: 8 4 - - True - 1 - Source Device: - - - 2 - 3 - GTK_FILL - GTK_FILL - - - - - True - 1 - Device Type: - - - GTK_FILL - - - - - - True - 1 - Device Mode: - - - 1 - 2 - GTK_FILL - - - - - + True 0 label @@ -3278,6 +3241,8 @@ usage: 1 2 + 2 + 3 @@ -3296,7 +3261,7 @@ usage: - + True 0 label @@ -3304,9 +3269,44 @@ usage: 1 2 + + + + + + True + 1 + Device Mode: + + + 1 + 2 + GTK_FILL + + + + + + True + 1 + Device Type: + + + GTK_FILL + + + + + + True + 1 + Source Device: + + 2 3 - + GTK_FILL + GTK_FILL @@ -3336,7 +3336,7 @@ usage: True - Hostdev + Host tab @@ -3344,6 +3344,138 @@ usage: False + + + True + + + True + 0 + GTK_SHADOW_NONE + + + True + 5 + 12 + + + True + 3 + 2 + 8 + 4 + + + True + 0 + label + + + 1 + 2 + 2 + 3 + + + + + + True + 0 + label + + + 1 + 2 + 1 + 2 + + + + + + True + 0 + label + + + 1 + 2 + + + + + + True + 1 + RAM: + + + 1 + 2 + GTK_FILL + + + + + + True + 1 + Model: + + + GTK_FILL + + + + + + True + 1 + Heads: + + + 2 + 3 + GTK_FILL + GTK_FILL + + + + + + + + + True + <b>Video</b> + True + + + label_item + + + + + 15 + + + + + 12 + + + + + True + Vid + + + tab + 12 + False + +