From 20088ab8fb42ca9b9f3ae2637865b5d05eb82726 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Sun, 26 Jan 2014 17:09:07 -0500 Subject: Move many shared UI functions to addhw static functions Much of uihelpers is just simple stuff that's shared between addhw and details UI, so just make it staticmethods in addhw, which details already has a reference to. --- virtManager/addhardware.py | 333 +++++++++++++++++++++++-- virtManager/choosecd.py | 2 +- virtManager/console.py | 29 ++- virtManager/create.py | 4 +- virtManager/createinterface.py | 13 +- virtManager/details.py | 42 ++-- virtManager/domain.py | 20 +- virtManager/host.py | 3 +- virtManager/uihelpers.py | 555 ++++++++--------------------------------- 9 files changed, 498 insertions(+), 503 deletions(-) diff --git a/virtManager/addhardware.py b/virtManager/addhardware.py index 9c6f433d..06f9596a 100644 --- a/virtManager/addhardware.py +++ b/virtManager/addhardware.py @@ -176,11 +176,11 @@ class vmmAddHardware(vmmGObjectUI): # Virtual network list net_list = self.widget("net-list") bridge_box = self.widget("net-bridge-box") - uihelpers.init_network_list(net_list, bridge_box) + uihelpers.build_network_list(net_list, bridge_box) # Network model list netmodel_list = self.widget("net-model") - uihelpers.build_netmodel_combo(self.vm, netmodel_list) + self.build_network_model_combo(self.vm, netmodel_list) # Disk bus type widget = self.widget("config-storage-bustype") @@ -205,10 +205,10 @@ class vmmAddHardware(vmmGObjectUI): # Disk cache mode cache_list = self.widget("config-storage-cache") - uihelpers.build_cache_combo(self.vm, cache_list) + self.build_disk_cache_combo(self.vm, cache_list) # Disk format mode - self.populate_disk_format_combo(True) + self.populate_disk_format_combo_wrapper(True) # Sparse tooltip sparse_info = self.widget("config-storage-nosparse-info") @@ -239,7 +239,7 @@ class vmmAddHardware(vmmGObjectUI): # Sound model list sound_list = self.widget("sound-model") - uihelpers.build_sound_combo(self.vm, sound_list) + self.build_sound_combo(self.vm, sound_list) # Host device list # model = [ Description, nodedev name ] @@ -256,7 +256,7 @@ class vmmAddHardware(vmmGObjectUI): # Video device video_dev = self.widget("video-model") - uihelpers.build_video_combo(self.vm, video_dev) + self.build_video_combo(self.vm, video_dev) # Character dev mode char_mode = self.widget("char-mode") @@ -297,25 +297,24 @@ class vmmAddHardware(vmmGObjectUI): # Watchdog widgets combo = self.widget("watchdog-model") - uihelpers.build_watchdogmodel_combo(self.vm, combo) - + self.build_watchdogmodel_combo(self.vm, combo) combo = self.widget("watchdog-action") - uihelpers.build_watchdogaction_combo(self.vm, combo) + self.build_watchdogaction_combo(self.vm, combo) # Filesystem widgets self.fsDetails.set_initial_state() # Smartcard widgets combo = self.widget("smartcard-mode") - uihelpers.build_smartcard_mode_combo(self.vm, combo) + self.build_smartcard_mode_combo(self.vm, combo) # Usbredir widgets combo = self.widget("usbredir-list") - uihelpers.build_redir_type_combo(self.vm, combo) + self.build_redir_type_combo(self.vm, combo) # TPM widgets combo = self.widget("tpm-type") - uihelpers.build_tpm_type_combo(self.vm, combo) + self.build_tpm_type_combo(self.vm, combo) # RNG widgets combo = self.widget("rng-type") @@ -418,7 +417,7 @@ class vmmAddHardware(vmmGObjectUI): not can_alloc and (_("Disk format '%s' does not support full allocation.") % fmt) or "") - self.populate_disk_format_combo(True) + self.populate_disk_format_combo_wrapper(True) self.populate_disk_bus() # Network init @@ -440,7 +439,7 @@ class vmmAddHardware(vmmGObjectUI): net_warn.hide() netmodel = self.widget("net-model") - uihelpers.populate_netmodel_combo(self.vm, netmodel) + self.populate_network_model_combo(self.vm, netmodel) netmodel.set_active(0) # Input device init @@ -486,7 +485,7 @@ class vmmAddHardware(vmmGObjectUI): self.fsDetails.reset_state() # Video params - uihelpers.populate_video_combo(self.vm, self.widget("video-model")) + self.populate_video_combo(self.vm, self.widget("video-model")) # TPM paams self.widget("tpm-device-path").set_text("/dev/tpm0") @@ -512,6 +511,304 @@ class vmmAddHardware(vmmGObjectUI): self.set_hw_selection(0) + ##################### + # Shared UI helpers # + ##################### + + @staticmethod + def populate_video_combo(vm, combo, no_default=None): + model = combo.get_model() + has_spice = bool([g for g in vm.get_graphics_devices() + if g.type == g.TYPE_SPICE]) + has_qxl = bool([v for v in vm.get_video_devices() + if v.model == "qxl"]) + + model.clear() + tmpdev = virtinst.VirtualVideoDevice(vm.conn.get_backend()) + for m in tmpdev.MODELS: + if vm.stable_defaults(): + if m == "qxl" and not has_spice and not has_qxl: + # Only list QXL video option when VM has SPICE video + continue + + if m == tmpdev.MODEL_DEFAULT and no_default: + continue + model.append([m, tmpdev.pretty_model(m)]) + + if len(model) > 0: + combo.set_active(0) + + @staticmethod + def build_video_combo(vm, combo, no_default=None): + model = Gtk.ListStore(str, str) + combo.set_model(model) + uihelpers.set_combo_text_column(combo, 1) + combo.get_model().set_sort_column_id(1, Gtk.SortType.ASCENDING) + + vmmAddHardware.populate_video_combo(vm, combo, no_default) + + @staticmethod + def build_sound_combo(vm, combo, no_default=False): + model = Gtk.ListStore(str) + combo.set_model(model) + uihelpers.set_combo_text_column(combo, 0) + model.set_sort_column_id(0, Gtk.SortType.ASCENDING) + + stable_defaults = vm.stable_defaults() + stable_soundmodels = ["ich6", "ac97"] + + for m in virtinst.VirtualAudio.MODELS: + if m == virtinst.VirtualAudio.MODEL_DEFAULT and no_default: + continue + + if (stable_defaults and m not in stable_soundmodels): + continue + + model.append([m]) + if len(model) > 0: + combo.set_active(0) + + @staticmethod + def build_watchdogmodel_combo(vm, combo, no_default=False): + ignore = vm + model = Gtk.ListStore(str) + combo.set_model(model) + uihelpers.set_combo_text_column(combo, 0) + model.set_sort_column_id(0, Gtk.SortType.ASCENDING) + + for m in virtinst.VirtualWatchdog.MODELS: + if m == virtinst.VirtualAudio.MODEL_DEFAULT and no_default: + continue + model.append([m]) + if len(model) > 0: + combo.set_active(0) + + @staticmethod + def build_watchdogaction_combo(vm, combo, no_default=False): + ignore = vm + model = Gtk.ListStore(str, str) + combo.set_model(model) + uihelpers.set_combo_text_column(combo, 1) + model.set_sort_column_id(0, Gtk.SortType.ASCENDING) + + for m in virtinst.VirtualWatchdog.ACTIONS: + if m == virtinst.VirtualWatchdog.ACTION_DEFAULT and no_default: + continue + model.append([m, virtinst.VirtualWatchdog.get_action_desc(m)]) + if len(model) > 0: + combo.set_active(0) + + @staticmethod + def populate_network_source_mode_combo(vm, combo): + ignore = vm + model = combo.get_model() + model.clear() + + # [xml value, label] + model.append([None, "Default"]) + model.append(["vepa", "VEPA"]) + model.append(["bridge", "Bridge"]) + model.append(["private", "Private"]) + model.append(["passthrough", "Passthrough"]) + + @staticmethod + def build_network_source_mode_combo(vm, combo): + model = Gtk.ListStore(str, str) + combo.set_model(model) + uihelpers.set_combo_text_column(combo, 1) + + vmmAddHardware.populate_network_source_mode_combo(vm, combo) + combo.set_active(0) + + @staticmethod + def populate_network_model_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", "e1000"] + if vm.get_hv_type() in ["kvm", "qemu", "test"]: + mod_list.append("virtio") + if (vm.get_hv_type() == "kvm" and + vm.get_machtype() == "pseries"): + mod_list.append("spapr-vlan") + if vm.get_hv_type() in ["xen", "test"]: + mod_list.append("netfront") + mod_list.sort() + + for m in mod_list: + model.append([m, m]) + + @staticmethod + def build_network_model_combo(vm, combo): + model = Gtk.ListStore(str, str) + combo.set_model(model) + uihelpers.set_combo_text_column(combo, 1) + model.set_sort_column_id(0, Gtk.SortType.ASCENDING) + + vmmAddHardware.populate_network_model_combo(vm, combo) + combo.set_active(0) + + @staticmethod + def populate_smartcard_mode_combo(vm, combo): + ignore = vm + model = combo.get_model() + model.clear() + + # [xml value, label] + model.append(["passthrough", "Passthrough"]) + model.append(["host", "Host"]) + + @staticmethod + def build_smartcard_mode_combo(vm, combo): + model = Gtk.ListStore(str, str) + combo.set_model(model) + uihelpers.set_combo_text_column(combo, 1) + model.set_sort_column_id(0, Gtk.SortType.ASCENDING) + + vmmAddHardware.populate_smartcard_mode_combo(vm, combo) + + idx = -1 + for rowid in range(len(combo.get_model())): + idx = 0 + row = combo.get_model()[rowid] + if row[0] == virtinst.VirtualSmartCardDevice.MODE_DEFAULT: + idx = rowid + break + combo.set_active(idx) + + @staticmethod + def populate_redir_type_combo(vm, combo): + ignore = vm + model = combo.get_model() + model.clear() + + # [xml value, label, conn details] + model.append(["spicevmc", "Spice channel", False]) + model.append(["tcp", "TCP", True]) + + @staticmethod + def build_redir_type_combo(vm, combo): + model = Gtk.ListStore(str, str, bool) + combo.set_model(model) + uihelpers.set_combo_text_column(combo, 1) + + vmmAddHardware.populate_redir_type_combo(vm, combo) + combo.set_active(0) + + @staticmethod + def populate_tpm_type_combo(vm, combo): + ignore = vm + types = combo.get_model() + types.clear() + + # [xml value, label] + for t in virtinst.VirtualTPMDevice.TYPES: + types.append([t, virtinst.VirtualTPMDevice.get_pretty_type(t)]) + + @staticmethod + def build_tpm_type_combo(vm, combo): + model = Gtk.ListStore(str, str) + combo.set_model(model) + uihelpers.set_combo_text_column(combo, 1) + model.set_sort_column_id(0, Gtk.SortType.ASCENDING) + + vmmAddHardware.populate_tpm_type_combo(vm, combo) + + idx = -1 + for rowid in range(len(combo.get_model())): + idx = 0 + row = combo.get_model()[rowid] + if row[0] == virtinst.VirtualTPMDevice.TYPE_DEFAULT: + idx = rowid + break + combo.set_active(idx) + + @staticmethod + def build_graphics_keymap_combo(vm, combo, no_default=False): + ignore = vm + model = Gtk.ListStore(str, str) + combo.set_model(model) + uihelpers.set_combo_text_column(combo, 1) + + if not no_default: + model.append([None, "default"]) + else: + model.append([None, "Auto"]) + + model.append([virtinst.VirtualGraphics.KEYMAP_LOCAL, + "Copy local keymap"]) + for k in virtinst.VirtualGraphics.valid_keymaps(): + model.append([k, k]) + + combo.set_active(-1) + + @staticmethod + def build_disk_cache_combo(vm, combo): + ignore = vm + model = Gtk.ListStore(str, str) + combo.set_model(model) + uihelpers.set_combo_text_column(combo, 1) + + combo.set_active(-1) + for m in virtinst.VirtualDisk.cache_types: + model.append([m, m]) + + _iter = model.insert(0, [None, "default"]) + combo.set_active_iter(_iter) + + @staticmethod + def build_disk_io_combo(vm, combo, no_default=False): + ignore = vm + model = Gtk.ListStore(str, str) + combo.set_model(model) + uihelpers.set_combo_text_column(combo, 1) + model.set_sort_column_id(0, Gtk.SortType.ASCENDING) + + combo.set_active(-1) + for m in virtinst.VirtualDisk.io_modes: + model.append([m, m]) + + if not no_default: + model.append([None, "default"]) + combo.set_active(0) + + @staticmethod + def build_disk_bus_combo(vm, combo, no_default=False): + ignore = vm + model = Gtk.ListStore(str, str) + combo.set_model(model) + uihelpers.set_combo_text_column(combo, 1) + model.set_sort_column_id(1, Gtk.SortType.ASCENDING) + + if not no_default: + model.append([None, "default"]) + combo.set_active(-1) + + @staticmethod + def populate_disk_format_combo(vm, combo, create): + model = Gtk.ListStore(str) + combo.set_model(model) + uihelpers.set_combo_text_column(combo, 0) + + formats = ["raw", "qcow2", "qed"] + no_create_formats = [] + if not vm.stable_defaults(): + formats.append("vmdk") + no_create_formats.append("vdi") + + for m in formats: + model.append([m]) + if not create: + for m in no_create_formats: + model.append([m]) + + if create: + combo.set_active(0) + + ######################### # UI population methods # ######################### @@ -606,9 +903,9 @@ class vmmAddHardware(vmmGObjectUI): model.append([_("No Devices Available"), None, None, None]) uihelpers.set_list_selection(devlist, 0) - def populate_disk_format_combo(self, create): + def populate_disk_format_combo_wrapper(self, create): format_list = self.widget("config-storage-format") - uihelpers.update_storage_format_combo(self.vm, format_list, create) + self.populate_disk_format_combo(self.vm, format_list, create) if not create: format_list.get_child().set_text("") @@ -998,7 +1295,7 @@ class vmmAddHardware(vmmGObjectUI): def toggle_storage_select(self, src): act = src.get_active() self.widget("config-storage-browse-box").set_sensitive(act) - self.populate_disk_format_combo(not act) + self.populate_disk_format_combo_wrapper(not act) def set_disk_storage_path(self, ignore, path): self.widget("config-storage-entry").set_text(path) diff --git a/virtManager/choosecd.py b/virtManager/choosecd.py index 1d46879e..735afee8 100644 --- a/virtManager/choosecd.py +++ b/virtManager/choosecd.py @@ -149,7 +149,7 @@ class vmmChooseCD(vmmGObjectUI): warn = self.widget("cd-path-warn") error = self.conn.mediadev_error - uihelpers.init_mediadev_combo(widget) + uihelpers.build_mediadev_combo(widget) uihelpers.populate_mediadev_combo(self.conn, widget, self.media_type) if error: diff --git a/virtManager/console.py b/virtManager/console.py index 6eae1211..597399f8 100644 --- a/virtManager/console.py +++ b/virtManager/console.py @@ -38,7 +38,6 @@ import signal import socket import threading -import virtManager.uihelpers as uihelpers from virtManager.autodrawer import AutoDrawer from virtManager.baseclass import vmmGObjectUI, vmmGObject from virtManager.serialcon import vmmSerialConsole @@ -59,6 +58,7 @@ def has_property(obj, setting): return True + class ConnectionInfo(object): """ Holds all the bits needed to make a connection to a graphical console @@ -794,7 +794,7 @@ class vmmConsolePages(vmmGObjectUI): self.send_key_button = None self.fs_toolbar = None self.fs_drawer = None - self.keycombo_menu = uihelpers.build_keycombo_menu(self.send_key) + self.keycombo_menu = self.build_keycombo_menu(self.send_key) self.init_fs_toolbar() # Make viewer widget background always be black @@ -822,6 +822,7 @@ class vmmConsolePages(vmmGObjectUI): self.page_changed() + def is_visible(self): if self.topwin: return self.topwin.get_visible() @@ -851,6 +852,30 @@ class vmmConsolePages(vmmGObjectUI): # Initialization helpers # ########################## + @staticmethod + def build_keycombo_menu(cb): + # Shared with vmmDetails + menu = Gtk.Menu() + + def make_item(name, combo): + item = Gtk.MenuItem.new_with_mnemonic(name) + item.connect("activate", cb, combo) + + menu.add(item) + + make_item("Ctrl+Alt+_Backspace", ["Control_L", "Alt_L", "BackSpace"]) + make_item("Ctrl+Alt+_Delete", ["Control_L", "Alt_L", "Delete"]) + menu.add(Gtk.SeparatorMenuItem()) + + for i in range(1, 13): + make_item("Ctrl+Alt+F_%d" % i, ["Control_L", "Alt_L", "F%d" % i]) + menu.add(Gtk.SeparatorMenuItem()) + + make_item("_Printscreen", ["Print"]) + + menu.show_all() + return menu + def init_fs_toolbar(self): scroll = self.widget("console-gfx-scroll") pages = self.widget("console-pages") diff --git a/virtManager/create.py b/virtManager/create.py index ef750891..c723582a 100644 --- a/virtManager/create.py +++ b/virtManager/create.py @@ -291,13 +291,13 @@ class vmmCreate(vmmGObjectUI): # Physical CD-ROM model cd_list = self.widget("install-local-cdrom-combo") - uihelpers.init_mediadev_combo(cd_list) + uihelpers.build_mediadev_combo(cd_list) # Networking # [ interface type, device name, label, sensitive ] net_list = self.widget("config-netdev") bridge_box = self.widget("config-netdev-bridge-box") - uihelpers.init_network_list(net_list, bridge_box) + uihelpers.build_network_list(net_list, bridge_box) # Archtecture # [value, label] diff --git a/virtManager/createinterface.py b/virtManager/createinterface.py index 1d1c4ad6..dbdfafc6 100644 --- a/virtManager/createinterface.py +++ b/virtManager/createinterface.py @@ -160,10 +160,21 @@ class vmmCreateInterface(vmmGObjectUI): self.bond_config.destroy() self.bond_config = None + ########################### # Initialization routines # ########################### + @staticmethod + def build_interface_startmode_combo(combo): + model = Gtk.ListStore(str) + combo.set_model(model) + uihelpers.set_combo_text_column(combo, 0) + + model.append(["none"]) + model.append(["onboot"]) + model.append(["hotplug"]) + def set_initial_state(self): self.widget("pages").set_show_tabs(False) self.widget("bond-pages").set_show_tabs(False) @@ -188,7 +199,7 @@ class vmmCreateInterface(vmmGObjectUI): _("VLAN")]) # Start mode - uihelpers.build_startmode_combo( + self.build_interface_startmode_combo( self.widget("interface-startmode")) # Parent/slave Interface list diff --git a/virtManager/details.py b/virtManager/details.py index 919f79b5..9625338b 100644 --- a/virtManager/details.py +++ b/virtManager/details.py @@ -688,8 +688,8 @@ class vmmDetails(vmmGObjectUI): self.config.get_details_show_toolbar()) # Keycombo menu (ctrl+alt+del etc.) - self.keycombo_menu = uihelpers.build_keycombo_menu( - self.console.send_key) + self.keycombo_menu = self.console.build_keycombo_menu( + self.console.send_key) self.widget("details-menu-send-key").set_submenu(self.keycombo_menu) @@ -913,19 +913,19 @@ class vmmDetails(vmmGObjectUI): # Disk cache combo disk_cache = self.widget("disk-cache") - uihelpers.build_cache_combo(self.vm, disk_cache) + vmmAddHardware.build_disk_cache_combo(self.vm, disk_cache) # Disk io combo disk_io = self.widget("disk-io") - uihelpers.build_io_combo(self.vm, disk_io) + vmmAddHardware.build_disk_io_combo(self.vm, disk_io) # Disk format combo format_list = self.widget("disk-format") - uihelpers.update_storage_format_combo(self.vm, format_list, False) + vmmAddHardware.populate_disk_format_combo(self.vm, format_list, False) # Disk bus combo disk_bus = self.widget("disk-bus") - uihelpers.build_disk_bus_combo(self.vm, disk_bus) + vmmAddHardware.build_disk_bus_combo(self.vm, disk_bus) # Disk iotune expander if not (self.conn.is_qemu() or self.conn.is_test_conn()): @@ -936,16 +936,16 @@ class vmmDetails(vmmGObjectUI): net_bridge = self.widget("network-bridge-box") source_mode_combo = self.widget("network-source-mode") vport_expander = self.widget("vport-expander") - uihelpers.init_network_list(net_source, net_bridge, + uihelpers.build_network_list(net_source, net_bridge, source_mode_combo, vport_expander) # source mode source_mode = self.widget("network-source-mode") - uihelpers.build_source_mode_combo(self.vm, source_mode) + vmmAddHardware.build_network_source_mode_combo(self.vm, source_mode) # Network model net_model = self.widget("network-model") - uihelpers.build_netmodel_combo(self.vm, net_model) + vmmAddHardware.build_network_model_combo(self.vm, net_model) # Graphics type gfx_type = self.widget("gfx-type") @@ -958,30 +958,32 @@ class vmmDetails(vmmGObjectUI): # Graphics keymap gfx_keymap = self.widget("gfx-keymap") - uihelpers.build_vnc_keymap_combo(self.vm, gfx_keymap, + vmmAddHardware.build_graphics_keymap_combo(self.vm, gfx_keymap, no_default=no_default) # Sound model sound_dev = self.widget("sound-model") - uihelpers.build_sound_combo(self.vm, sound_dev, no_default=no_default) + vmmAddHardware.build_sound_combo(self.vm, sound_dev, + no_default=no_default) # Video model combo video_dev = self.widget("video-model") - uihelpers.build_video_combo(self.vm, video_dev, no_default=no_default) + vmmAddHardware.build_video_combo(self.vm, video_dev, + no_default=no_default) # Watchdog model combo combo = self.widget("watchdog-model") - uihelpers.build_watchdogmodel_combo(self.vm, combo, + vmmAddHardware.build_watchdogmodel_combo(self.vm, combo, no_default=no_default) # Watchdog action combo combo = self.widget("watchdog-action") - uihelpers.build_watchdogaction_combo(self.vm, combo, + vmmAddHardware.build_watchdogaction_combo(self.vm, combo, no_default=no_default) # Smartcard mode sc_mode = self.widget("smartcard-mode") - uihelpers.build_smartcard_mode_combo(self.vm, sc_mode) + vmmAddHardware.build_smartcard_mode_combo(self.vm, sc_mode) # Controller model combo = self.widget("controller-model") @@ -2736,7 +2738,7 @@ class vmmDetails(vmmGObjectUI): self.widget("vport-expander").set_visible(is_direct) # source mode - uihelpers.populate_source_mode_combo(self.vm, + vmmAddHardware.populate_network_source_mode_combo(self.vm, self.widget("network-source-mode")) self.set_combo_entry("network-source-mode", source_mode) @@ -2749,7 +2751,7 @@ class vmmDetails(vmmGObjectUI): str(vport.typeidversion) or "") self.widget("vport-instanceid").set_text(vport.instanceid or "") - uihelpers.populate_netmodel_combo(self.vm, + vmmAddHardware.populate_network_model_combo(self.vm, self.widget("network-model")) self.set_combo_entry("network-model", model) @@ -3062,9 +3064,9 @@ class vmmDetails(vmmGObjectUI): return no_default = not self.is_customize_dialog - uihelpers.populate_video_combo(self.vm, - self.widget("video-model"), - no_default=no_default) + vmmAddHardware.populate_video_combo(self.vm, + self.widget("video-model"), + no_default=no_default) model = vid.model ram = vid.vram diff --git a/virtManager/domain.py b/virtManager/domain.py index a060b6df..48f577ee 100644 --- a/virtManager/domain.py +++ b/virtManager/domain.py @@ -38,6 +38,18 @@ from virtManager import uihelpers from virtManager.libvirtobject import vmmLibvirtObject +vm_status_icons = { + libvirt.VIR_DOMAIN_BLOCKED: "state_running", + libvirt.VIR_DOMAIN_CRASHED: "state_shutoff", + libvirt.VIR_DOMAIN_PAUSED: "state_paused", + libvirt.VIR_DOMAIN_RUNNING: "state_running", + libvirt.VIR_DOMAIN_SHUTDOWN: "state_shutoff", + libvirt.VIR_DOMAIN_SHUTOFF: "state_shutoff", + libvirt.VIR_DOMAIN_NOSTATE: "state_running", + getattr(libvirt, "VIR_DOMAIN_PMSUSPENDED", 7): "state_paused", +} + + def compare_device(origdev, newdev, idx): devprops = { "disk" : ["target", "bus"], @@ -170,10 +182,10 @@ class vmmDomainSnapshot(vmmLibvirtObject): return vmmDomain.pretty_run_status(status) def run_status_icon_name(self): status = DomainSnapshot.state_str_to_int(self.get_xmlobj().state) - if status not in uihelpers.vm_status_icons: + if status not in vm_status_icons: logging.debug("Unknown status %d, using NOSTATE", status) status = libvirt.VIR_DOMAIN_NOSTATE - return uihelpers.vm_status_icons[status] + return vm_status_icons[status] def is_external(self): if self.get_xmlobj().memory_type == "external": @@ -1548,10 +1560,10 @@ class vmmDomain(vmmLibvirtObject): return self.pretty_run_status(self.status(), self.hasSavedImage()) def run_status_icon_name(self): status = self.status() - if status not in uihelpers.vm_status_icons: + if status not in vm_status_icons: logging.debug("Unknown status %d, using NOSTATE", status) status = libvirt.VIR_DOMAIN_NOSTATE - return uihelpers.vm_status_icons[status] + return vm_status_icons[status] def force_update_status(self): """ diff --git a/virtManager/host.py b/virtManager/host.py index 10fd99d6..0be7cb40 100644 --- a/virtManager/host.py +++ b/virtManager/host.py @@ -243,7 +243,8 @@ class vmmHost(vmmGObjectUI): interfaceListModel.set_sort_column_id(1, Gtk.SortType.ASCENDING) # Starmode combo - uihelpers.build_startmode_combo(self.widget("interface-startmode")) + vmmCreateInterface.build_interface_startmode_combo( + self.widget("interface-startmode")) # [ name, type ] childListModel = Gtk.ListStore(str, str) diff --git a/virtManager/uihelpers.py b/virtManager/uihelpers.py index b98663b9..ed51891d 100644 --- a/virtManager/uihelpers.py +++ b/virtManager/uihelpers.py @@ -47,18 +47,6 @@ try: except (ValueError, AttributeError): can_set_row_none = False -vm_status_icons = { - libvirt.VIR_DOMAIN_BLOCKED: "state_running", - libvirt.VIR_DOMAIN_CRASHED: "state_shutoff", - libvirt.VIR_DOMAIN_PAUSED: "state_paused", - libvirt.VIR_DOMAIN_RUNNING: "state_running", - libvirt.VIR_DOMAIN_SHUTDOWN: "state_shutoff", - libvirt.VIR_DOMAIN_SHUTOFF: "state_shutoff", - libvirt.VIR_DOMAIN_NOSTATE: "state_running", - # VIR_DOMAIN_PMSUSPENDED - 7: "state_paused", -} - ############################################################ # Helpers for shared storage UI between create/addhardware # @@ -130,319 +118,29 @@ def check_default_pool_active(err, conn): return True -##################################################### -# Hardware model list building (for details, addhw) # -##################################################### - -def set_combo_text_column(combo, col): - if combo.get_has_entry(): - combo.set_entry_text_column(col) - else: - text = Gtk.CellRendererText() - combo.pack_start(text, True) - combo.add_attribute(text, 'text', col) - - -def build_video_combo(vm, combo, no_default=None): - model = Gtk.ListStore(str, str) - combo.set_model(model) - set_combo_text_column(combo, 1) - combo.get_model().set_sort_column_id(1, Gtk.SortType.ASCENDING) - - populate_video_combo(vm, combo, no_default) - - -def populate_video_combo(vm, combo, no_default=None): - model = combo.get_model() - has_spice = bool([g for g in vm.get_graphics_devices() - if g.type == g.TYPE_SPICE]) - has_qxl = bool([v for v in vm.get_video_devices() - if v.model == "qxl"]) - - model.clear() - tmpdev = virtinst.VirtualVideoDevice(vm.conn.get_backend()) - for m in tmpdev.MODELS: - if vm.stable_defaults(): - if m == "qxl" and not has_spice and not has_qxl: - # Only list QXL video option when VM has SPICE video - continue - - if m == tmpdev.MODEL_DEFAULT and no_default: - continue - model.append([m, tmpdev.pretty_model(m)]) - - if len(model) > 0: - combo.set_active(0) - - -def build_sound_combo(vm, combo, no_default=False): - model = Gtk.ListStore(str) - combo.set_model(model) - set_combo_text_column(combo, 0) - model.set_sort_column_id(0, Gtk.SortType.ASCENDING) - - stable_defaults = vm.stable_defaults() - stable_soundmodels = ["ich6", "ac97"] - - for m in virtinst.VirtualAudio.MODELS: - if m == virtinst.VirtualAudio.MODEL_DEFAULT and no_default: - continue - - if (stable_defaults and m not in stable_soundmodels): - continue - - model.append([m]) - if len(model) > 0: - combo.set_active(0) - - -def build_watchdogmodel_combo(vm, combo, no_default=False): - ignore = vm - model = Gtk.ListStore(str) - combo.set_model(model) - set_combo_text_column(combo, 0) - model.set_sort_column_id(0, Gtk.SortType.ASCENDING) - - for m in virtinst.VirtualWatchdog.MODELS: - if m == virtinst.VirtualAudio.MODEL_DEFAULT and no_default: - continue - model.append([m]) - if len(model) > 0: - combo.set_active(0) - - -def build_watchdogaction_combo(vm, combo, no_default=False): - ignore = vm - model = Gtk.ListStore(str, str) - combo.set_model(model) - set_combo_text_column(combo, 1) - model.set_sort_column_id(0, Gtk.SortType.ASCENDING) - - for m in virtinst.VirtualWatchdog.ACTIONS: - if m == virtinst.VirtualWatchdog.ACTION_DEFAULT and no_default: - continue - model.append([m, virtinst.VirtualWatchdog.get_action_desc(m)]) - if len(model) > 0: - combo.set_active(0) - - -def build_source_mode_combo(vm, combo): - model = Gtk.ListStore(str, str) - combo.set_model(model) - set_combo_text_column(combo, 1) - - populate_source_mode_combo(vm, combo) - combo.set_active(0) - - -def populate_source_mode_combo(vm, combo): - ignore = vm - model = combo.get_model() - model.clear() - - # [xml value, label] - model.append([None, "Default"]) - model.append(["vepa", "VEPA"]) - model.append(["bridge", "Bridge"]) - model.append(["private", "Private"]) - model.append(["passthrough", "Passthrough"]) - - -def build_smartcard_mode_combo(vm, combo): - model = Gtk.ListStore(str, str) - combo.set_model(model) - set_combo_text_column(combo, 1) - model.set_sort_column_id(0, Gtk.SortType.ASCENDING) - - populate_smartcard_mode_combo(vm, combo) - - idx = -1 - for rowid in range(len(combo.get_model())): - idx = 0 - row = combo.get_model()[rowid] - if row[0] == virtinst.VirtualSmartCardDevice.MODE_DEFAULT: - idx = rowid - break - combo.set_active(idx) - - -def populate_smartcard_mode_combo(vm, combo): - ignore = vm - model = combo.get_model() - model.clear() - - # [xml value, label] - model.append(["passthrough", "Passthrough"]) - model.append(["host", "Host"]) - - -def build_redir_type_combo(vm, combo): - model = Gtk.ListStore(str, str, bool) - combo.set_model(model) - set_combo_text_column(combo, 1) - - populate_redir_type_combo(vm, combo) - combo.set_active(0) - - -def populate_redir_type_combo(vm, combo): - ignore = vm - model = combo.get_model() - model.clear() - - # [xml value, label, conn details] - model.append(["spicevmc", "Spice channel", False]) - model.append(["tcp", "TCP", True]) - +######################################### +# VM device listing helpers # +######################################### -def build_tpm_type_combo(vm, combo): - model = Gtk.ListStore(str, str) - combo.set_model(model) - set_combo_text_column(combo, 1) - model.set_sort_column_id(0, Gtk.SortType.ASCENDING) - - populate_tpm_type_combo(vm, combo) - - idx = -1 - for rowid in range(len(combo.get_model())): - idx = 0 - row = combo.get_model()[rowid] - if row[0] == virtinst.VirtualTPMDevice.TYPE_DEFAULT: - idx = rowid - break - combo.set_active(idx) - - -def populate_tpm_type_combo(vm, combo): - ignore = vm - types = combo.get_model() - types.clear() - - # [xml value, label] - for t in virtinst.VirtualTPMDevice.TYPES: - types.append([t, virtinst.VirtualTPMDevice.get_pretty_type(t)]) - - -def build_netmodel_combo(vm, combo): - model = Gtk.ListStore(str, str) - combo.set_model(model) - set_combo_text_column(combo, 1) - model.set_sort_column_id(0, Gtk.SortType.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", "e1000"] - if vm.get_hv_type() in ["kvm", "qemu", "test"]: - mod_list.append("virtio") - if (vm.get_hv_type() == "kvm" and - vm.get_machtype() == "pseries"): - mod_list.append("spapr-vlan") - if vm.get_hv_type() in ["xen", "test"]: - mod_list.append("netfront") - mod_list.sort() - - for m in mod_list: - model.append([m, m]) - - -def build_cache_combo(vm, combo): - ignore = vm - model = Gtk.ListStore(str, str) - combo.set_model(model) - set_combo_text_column(combo, 1) - - combo.set_active(-1) - for m in virtinst.VirtualDisk.cache_types: - model.append([m, m]) - - _iter = model.insert(0, [None, "default"]) - combo.set_active_iter(_iter) - - -def build_io_combo(vm, combo, no_default=False): - ignore = vm - model = Gtk.ListStore(str, str) - combo.set_model(model) - set_combo_text_column(combo, 1) - model.set_sort_column_id(0, Gtk.SortType.ASCENDING) - - combo.set_active(-1) - for m in virtinst.VirtualDisk.io_modes: - model.append([m, m]) - - if not no_default: - model.append([None, "default"]) - combo.set_active(0) - - -def build_disk_bus_combo(vm, combo, no_default=False): - ignore = vm - model = Gtk.ListStore(str, str) - combo.set_model(model) - set_combo_text_column(combo, 1) - model.set_sort_column_id(1, Gtk.SortType.ASCENDING) - - if not no_default: - model.append([None, "default"]) - combo.set_active(-1) - - -def build_vnc_keymap_combo(vm, combo, no_default=False): - ignore = vm - model = Gtk.ListStore(str, str) - combo.set_model(model) - set_combo_text_column(combo, 1) - - if not no_default: - model.append([None, "default"]) - else: - model.append([None, "Auto"]) - - model.append([virtinst.VirtualGraphics.KEYMAP_LOCAL, - "Copy local keymap"]) - for k in virtinst.VirtualGraphics.valid_keymaps(): - model.append([k, k]) - - combo.set_active(-1) - - -##################################### -# Storage format list/combo helpers # -##################################### - -def update_storage_format_combo(vm, combo, create): - model = Gtk.ListStore(str) - combo.set_model(model) - set_combo_text_column(combo, 0) +def _net_list_changed(net_list, bridge_box, + source_mode_combo, vport_expander): + active = net_list.get_active() + if active < 0: + return - formats = ["raw", "qcow2", "qed"] - no_create_formats = [] - if not vm.stable_defaults(): - formats.append("vmdk") - no_create_formats.append("vdi") + if not bridge_box: + return - for m in formats: - model.append([m]) - if not create: - for m in no_create_formats: - model.append([m]) + row = net_list.get_model()[active] - if create: - combo.set_active(0) + if source_mode_combo is not None: + doshow = (row[0] == virtinst.VirtualNetworkInterface.TYPE_DIRECT) + set_grid_row_visible(source_mode_combo, doshow) + vport_expander.set_visible(doshow) + show_bridge = row[5] + set_grid_row_visible(bridge_box, show_bridge) -####################################################################### -# Widgets for listing network device options (in create, addhardware) # -####################################################################### def pretty_network_desc(nettype, source=None, netobj=None): if nettype == virtinst.VirtualNetworkInterface.TYPE_USER: @@ -466,14 +164,14 @@ def pretty_network_desc(nettype, source=None, netobj=None): return ret -def init_network_list(net_list, bridge_box, source_mode_combo=None, +def build_network_list(net_list, bridge_box, source_mode_combo=None, vport_expander=None): # [ network type, source name, label, sensitive?, net is active, # manual bridge, net instance] net_model = Gtk.ListStore(str, str, str, bool, bool, bool, object) net_list.set_model(net_model) - net_list.connect("changed", net_list_changed, bridge_box, + net_list.connect("changed", _net_list_changed, bridge_box, source_mode_combo, vport_expander) text = Gtk.CellRendererText() @@ -482,26 +180,6 @@ def init_network_list(net_list, bridge_box, source_mode_combo=None, net_list.add_attribute(text, 'sensitive', 3) -def net_list_changed(net_list, bridge_box, - source_mode_combo, vport_expander): - active = net_list.get_active() - if active < 0: - return - - if not bridge_box: - return - - row = net_list.get_model()[active] - - if source_mode_combo is not None: - doshow = (row[0] == virtinst.VirtualNetworkInterface.TYPE_DIRECT) - set_grid_row_visible(source_mode_combo, doshow) - vport_expander.set_visible(doshow) - - show_bridge = row[5] - set_grid_row_visible(bridge_box, show_bridge) - - def get_network_selection(net_list, bridge_entry): idx = net_list.get_active() if idx == -1: @@ -740,41 +418,12 @@ def validate_network(err, conn, nettype, devname, macaddr, model=None): # Populate media widget (choosecd, create) # ############################################ -def init_mediadev_combo(widget): - # [Device path, pretty label, has_media?, device key, media key, - # vmmMediaDevice, is valid device] - model = Gtk.ListStore(str, str, bool, str, str, bool) - widget.set_model(model) - model.clear() - - text = Gtk.CellRendererText() - widget.pack_start(text, True) - widget.add_attribute(text, 'text', OPTICAL_LABEL) - widget.add_attribute(text, 'sensitive', OPTICAL_IS_VALID) - - -def populate_mediadev_combo(conn, widget, devtype): - sigs = [] - - model = widget.get_model() - model.clear() - set_mediadev_default(model) - - sigs.append(conn.connect("mediadev-added", mediadev_added, widget, devtype)) - sigs.append(conn.connect("mediadev-removed", mediadev_removed, widget)) - - widget.set_active(-1) - mediadev_set_default_selection(widget) - - return sigs - - -def set_mediadev_default(model): +def _set_mediadev_default(model): if len(model) == 0: model.append([None, _("No device present"), False, None, None, False]) -def set_row_from_object(row, obj): +def _set_mediadev_row_from_object(row, obj): row[OPTICAL_DEV_PATH] = obj.get_path() row[OPTICAL_LABEL] = obj.pretty_label() row[OPTICAL_IS_MEDIA_PRESENT] = obj.has_media() @@ -783,28 +432,49 @@ def set_row_from_object(row, obj): row[OPTICAL_IS_VALID] = True -def mediadev_removed(ignore_helper, key, widget): +def _mediadev_set_default_selection(widget): + # Set the first active cdrom device as selected, otherwise none + model = widget.get_model() + idx = 0 + active = widget.get_active() + + if active != -1: + # already a selection, don't change it + return + + for row in model: + if row[OPTICAL_IS_MEDIA_PRESENT] is True: + widget.set_active(idx) + return + idx += 1 + + widget.set_active(-1) + + +def _mediadev_media_changed(newobj, widget): model = widget.get_model() active = widget.get_active() idx = 0 + # Search for the row with matching device node and + # fill in info about inserted media. If model has no current + # selection, select the new media. for row in model: - if row[OPTICAL_DEV_KEY] == key: - # Whole device removed - del(model[idx]) + if row[OPTICAL_DEV_PATH] == newobj.get_path(): + _set_mediadev_row_from_object(row, newobj) + has_media = row[OPTICAL_IS_MEDIA_PRESENT] - if idx > active and active != -1: - widget.set_active(active - 1) - elif idx == active: + if has_media and active == -1: + widget.set_active(idx) + elif not has_media and active == idx: widget.set_active(-1) - idx += 1 + idx = idx + 1 - set_mediadev_default(model) - mediadev_set_default_selection(widget) + _mediadev_set_default_selection(widget) -def mediadev_added(ignore_helper, newobj, widget, devtype): +def _mediadev_added(ignore_helper, newobj, widget, devtype): model = widget.get_model() if newobj.get_media_type() != devtype: @@ -816,57 +486,66 @@ def mediadev_added(ignore_helper, newobj, widget, devtype): # Only entry is the 'No device' entry model.clear() - newobj.connect("media-added", mediadev_media_changed, widget) - newobj.connect("media-removed", mediadev_media_changed, widget) + newobj.connect("media-added", _mediadev_media_changed, widget) + newobj.connect("media-removed", _mediadev_media_changed, widget) # Brand new device row = [None, None, None, None, None, None] - set_row_from_object(row, newobj) + _set_mediadev_row_from_object(row, newobj) model.append(row) - mediadev_set_default_selection(widget) + _mediadev_set_default_selection(widget) -def mediadev_media_changed(newobj, widget): +def _mediadev_removed(ignore_helper, key, widget): model = widget.get_model() active = widget.get_active() idx = 0 - # Search for the row with matching device node and - # fill in info about inserted media. If model has no current - # selection, select the new media. for row in model: - if row[OPTICAL_DEV_PATH] == newobj.get_path(): - set_row_from_object(row, newobj) - has_media = row[OPTICAL_IS_MEDIA_PRESENT] + if row[OPTICAL_DEV_KEY] == key: + # Whole device removed + del(model[idx]) - if has_media and active == -1: - widget.set_active(idx) - elif not has_media and active == idx: + if idx > active and active != -1: + widget.set_active(active - 1) + elif idx == active: widget.set_active(-1) - idx = idx + 1 + idx += 1 - mediadev_set_default_selection(widget) + _set_mediadev_default(model) + _mediadev_set_default_selection(widget) -def mediadev_set_default_selection(widget): - # Set the first active cdrom device as selected, otherwise none - model = widget.get_model() - idx = 0 - active = widget.get_active() +def build_mediadev_combo(widget): + # [Device path, pretty label, has_media?, device key, media key, + # vmmMediaDevice, is valid device] + model = Gtk.ListStore(str, str, bool, str, str, bool) + widget.set_model(model) + model.clear() - if active != -1: - # already a selection, don't change it - return + text = Gtk.CellRendererText() + widget.pack_start(text, True) + widget.add_attribute(text, 'text', OPTICAL_LABEL) + widget.add_attribute(text, 'sensitive', OPTICAL_IS_VALID) - for row in model: - if row[OPTICAL_IS_MEDIA_PRESENT] is True: - widget.set_active(idx) - return - idx += 1 + +def populate_mediadev_combo(conn, widget, devtype): + sigs = [] + + model = widget.get_model() + model.clear() + _set_mediadev_default(model) + + sigs.append(conn.connect("mediadev-added", + _mediadev_added, widget, devtype)) + sigs.append(conn.connect("mediadev-removed", _mediadev_removed, widget)) widget.set_active(-1) + _mediadev_set_default_selection(widget) + + return sigs #################################################################### @@ -1065,50 +744,18 @@ def check_path_search_for_qemu(err, conn, path): config.running_config.add_perms_fix_ignore(errors.keys()) -###################################### -# Interface startmode widget builder # -###################################### - -def build_startmode_combo(combo): - model = Gtk.ListStore(str) - combo.set_model(model) - set_combo_text_column(combo, 0) - - model.append(["none"]) - model.append(["onboot"]) - model.append(["hotplug"]) - - -######################### -# Console keycombo menu # -######################### - -def build_keycombo_menu(cb): - menu = Gtk.Menu() - - def make_item(name, combo): - item = Gtk.MenuItem.new_with_mnemonic(name) - item.connect("activate", cb, combo) - - menu.add(item) - - make_item("Ctrl+Alt+_Backspace", ["Control_L", "Alt_L", "BackSpace"]) - make_item("Ctrl+Alt+_Delete", ["Control_L", "Alt_L", "Delete"]) - menu.add(Gtk.SeparatorMenuItem()) - - for i in range(1, 13): - make_item("Ctrl+Alt+F_%d" % i, ["Control_L", "Alt_L", "F%d" % i]) - menu.add(Gtk.SeparatorMenuItem()) - - make_item("_Printscreen", ["Print"]) - - menu.show_all() - return menu +################ +# Misc helpers # +################ +def set_combo_text_column(combo, col): + if combo.get_has_entry(): + combo.set_entry_text_column(col) + else: + text = Gtk.CellRendererText() + combo.pack_start(text, True) + combo.add_attribute(text, 'text', col) -############# -# Misc bits # -############# def spin_get_helper(widget): adj = widget.get_adjustment() -- cgit v1.2.1