gfxdetails: Use a single 'changed' signal

And absord device building from addhardware. This moves all the
knowledge to gfxdetails, which saves sprinkling it around in other
places

Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
Cole Robinson 2020-09-21 21:14:35 -04:00
parent e5a51f6374
commit 9a5ab50b51
6 changed files with 106 additions and 119 deletions

View File

@ -509,10 +509,10 @@ def testDetailsEditDevices1(app):
tab.find("Model:", "text").set_text("ac97") tab.find("Model:", "text").set_text("ac97")
appl.click() appl.click()
lib.utils.check(lambda: not appl.sensitive) lib.utils.check(lambda: not appl.sensitive)
# Test non-disk removal
win.find("config-remove").click()
cell = win.find("Sound ac97", "table cell") cell = win.find("Sound ac97", "table cell")
oldtext = cell.text oldtext = cell.text
# Test non-disk removal
win.find("config-remove").click()
app.click_alert_button("Are you sure", "No") app.click_alert_button("Are you sure", "No")
lib.utils.check(lambda: cell.state_selected) lib.utils.check(lambda: cell.state_selected)
cell.click(button=3) cell.click(button=3)

View File

@ -160,6 +160,7 @@
<object class="GtkBox" id="graphics-port-box"> <object class="GtkBox" id="graphics-port-box">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="halign">start</property>
<property name="spacing">6</property> <property name="spacing">6</property>
<child> <child>
<object class="GtkCheckButton" id="graphics-port-auto"> <object class="GtkCheckButton" id="graphics-port-auto">

View File

@ -9,7 +9,7 @@ import traceback
from gi.repository import Gtk from gi.repository import Gtk
from virtinst import (DeviceChannel, DeviceConsole, from virtinst import (DeviceChannel, DeviceConsole,
DeviceController, DeviceDisk, DeviceGraphics, DeviceHostdev, DeviceController, DeviceDisk, DeviceHostdev,
DeviceInput, DeviceInterface, DevicePanic, DeviceParallel, DeviceInput, DeviceInterface, DevicePanic, DeviceParallel,
DeviceRedirdev, DeviceRng, DeviceSerial, DeviceSmartcard, DeviceRedirdev, DeviceRng, DeviceSerial, DeviceSmartcard,
DeviceSound, DeviceTpm, DeviceVideo, DeviceVsock, DeviceWatchdog) DeviceSound, DeviceTpm, DeviceVideo, DeviceVsock, DeviceWatchdog)
@ -1481,21 +1481,7 @@ class vmmAddHardware(vmmGObjectUI):
return dev return dev
def _build_graphics(self): def _build_graphics(self):
(gtype, port, listen, return self._gfxdetails.build_device()
addr, passwd, gl, rendernode) = self._gfxdetails.get_values()
dev = DeviceGraphics(self.conn.get_backend())
dev.type = gtype
dev.passwd = passwd
dev.gl = gl
dev.rendernode = rendernode
if not listen or listen == "none":
dev.listen = "none"
else:
dev.listen = addr
dev.port = port
return dev
def _build_sound(self): def _build_sound(self):
smodel = uiutil.get_list_selection(self.widget("sound-model")) smodel = uiutil.get_list_selection(self.widget("sound-model"))

View File

@ -65,13 +65,7 @@ from ..delete import vmmDeleteStorage
EDIT_NET_MAC, EDIT_NET_MAC,
EDIT_NET_LINKSTATE, EDIT_NET_LINKSTATE,
EDIT_GFX_PASSWD, EDIT_GFX,
EDIT_GFX_TYPE,
EDIT_GFX_LISTEN,
EDIT_GFX_ADDRESS,
EDIT_GFX_PORT,
EDIT_GFX_OPENGL,
EDIT_GFX_RENDERNODE,
EDIT_VIDEO_MODEL, EDIT_VIDEO_MODEL,
EDIT_VIDEO_3D, EDIT_VIDEO_3D,
@ -89,7 +83,7 @@ from ..delete import vmmDeleteStorage
EDIT_FS, EDIT_FS,
EDIT_HOSTDEV_ROMBAR) = range(1, 44) EDIT_HOSTDEV_ROMBAR) = range(1, 38)
# Columns in hw list model # Columns in hw list model
@ -383,13 +377,7 @@ class vmmDetails(vmmGObjectUI):
self.gfxdetails = vmmGraphicsDetails( self.gfxdetails = vmmGraphicsDetails(
self.vm, self.builder, self.topwin) self.vm, self.builder, self.topwin)
self.widget("graphics-align").add(self.gfxdetails.top_box) self.widget("graphics-align").add(self.gfxdetails.top_box)
self.gfxdetails.connect("changed-type", _e(EDIT_GFX_TYPE)) self.gfxdetails.connect("changed", _e(EDIT_GFX))
self.gfxdetails.connect("changed-port", _e(EDIT_GFX_PORT))
self.gfxdetails.connect("changed-opengl", _e(EDIT_GFX_OPENGL))
self.gfxdetails.connect("changed-rendernode", _e(EDIT_GFX_RENDERNODE))
self.gfxdetails.connect("changed-listen", _e(EDIT_GFX_LISTEN))
self.gfxdetails.connect("changed-address", _e(EDIT_GFX_ADDRESS))
self.gfxdetails.connect("changed-password", _e(EDIT_GFX_PASSWD))
self.netlist = vmmNetworkList(self.conn, self.builder, self.topwin) self.netlist = vmmNetworkList(self.conn, self.builder, self.topwin)
self.widget("network-source-label-align").add(self.netlist.top_label) self.widget("network-source-label-align").add(self.netlist.top_label)
@ -1604,25 +1592,9 @@ class vmmDetails(vmmGObjectUI):
devobj=devobj) devobj=devobj)
def _apply_graphics(self, devobj): def _apply_graphics(self, devobj):
(gtype, port, listen,
addr, passwd, gl, rendernode) = self.gfxdetails.get_values()
kwargs = {} kwargs = {}
if self._edited(EDIT_GFX):
if self._edited(EDIT_GFX_PASSWD): kwargs = self.gfxdetails.get_values()
kwargs["passwd"] = passwd
if self._edited(EDIT_GFX_LISTEN):
kwargs["listen"] = listen
if self._edited(EDIT_GFX_ADDRESS) or self._edited(EDIT_GFX_LISTEN):
kwargs["addr"] = addr
if self._edited(EDIT_GFX_PORT) or self._edited(EDIT_GFX_LISTEN):
kwargs["port"] = port
if self._edited(EDIT_GFX_OPENGL):
kwargs["gl"] = gl
if self._edited(EDIT_GFX_RENDERNODE):
kwargs["rendernode"] = rendernode
if self._edited(EDIT_GFX_TYPE):
kwargs["gtype"] = gtype
return vmmAddHardware.change_config_helper(self.vm.define_graphics, return vmmAddHardware.change_config_helper(self.vm.define_graphics,
kwargs, self.vm, self.err, kwargs, self.vm, self.err,

View File

@ -12,16 +12,19 @@ import virtinst
from ..lib import uiutil from ..lib import uiutil
from ..baseclass import vmmGObjectUI from ..baseclass import vmmGObjectUI
_EDIT_GFX_ENUM = range(1, 6)
(
_EDIT_GFX_TYPE,
_EDIT_GFX_LISTEN,
_EDIT_GFX_PORT,
_EDIT_GFX_OPENGL,
_EDIT_GFX_PASSWD,
) = _EDIT_GFX_ENUM
class vmmGraphicsDetails(vmmGObjectUI): class vmmGraphicsDetails(vmmGObjectUI):
__gsignals__ = { __gsignals__ = {
"changed-password": (vmmGObjectUI.RUN_FIRST, None, []), "changed": (vmmGObjectUI.RUN_FIRST, None, []),
"changed-port": (vmmGObjectUI.RUN_FIRST, None, []),
"changed-type": (vmmGObjectUI.RUN_FIRST, None, []),
"changed-listen": (vmmGObjectUI.RUN_FIRST, None, []),
"changed-address": (vmmGObjectUI.RUN_FIRST, None, []),
"changed-opengl": (vmmGObjectUI.RUN_FIRST, None, []),
"changed-rendernode": (vmmGObjectUI.RUN_FIRST, None, []),
} }
def __init__(self, vm, builder, topwin): def __init__(self, vm, builder, topwin):
@ -30,18 +33,24 @@ class vmmGraphicsDetails(vmmGObjectUI):
self.vm = vm self.vm = vm
self.conn = vm.conn self.conn = vm.conn
self.builder.connect_signals({ self._active_edits = []
"on_graphics_type_changed": self._change_graphics_type,
"on_graphics_port_auto_toggled": self._change_port_auto,
"on_graphics_use_password": self._change_password_cb,
"on_graphics_show_password": self._show_password_cb,
"on_graphics_listen_type_changed": self._change_graphics_listen, def _e(edittype):
"on_graphics_password_changed": lambda ignore: self.emit("changed-password"), def signal_cb(*args):
"on_graphics_address_changed": lambda ignore: self.emit("changed-address"), self._change_cb(edittype)
"on_graphics_port_changed": lambda ignore: self.emit("changed-port"), return signal_cb
"on_graphics_opengl_toggled": self._change_opengl,
"on_graphics_rendernode_changed": lambda ignore: self.emit("changed-rendernode") self.builder.connect_signals({
"on_graphics_show_password": self._show_password_cb,
"on_graphics_port_auto_toggled": self._change_port_auto,
"on_graphics_opengl_toggled": _e(_EDIT_GFX_OPENGL),
"on_graphics_type_changed": _e(_EDIT_GFX_TYPE),
"on_graphics_use_password": _e(_EDIT_GFX_PASSWD),
"on_graphics_listen_type_changed": _e(_EDIT_GFX_LISTEN),
"on_graphics_password_changed": _e(_EDIT_GFX_PASSWD),
"on_graphics_address_changed": _e(_EDIT_GFX_LISTEN),
"on_graphics_port_changed": _e(_EDIT_GFX_PORT),
"on_graphics_rendernode_changed": _e(_EDIT_GFX_OPENGL),
}) })
self._init_ui() self._init_ui()
@ -108,11 +117,6 @@ class vmmGraphicsDetails(vmmGObjectUI):
rendernode = drm.get_devnode().path rendernode = drm.get_devnode().path
model.append([rendernode, i.pretty_name()]) model.append([rendernode, i.pretty_name()])
def _get_config_graphics_ports(self):
port = uiutil.spin_get_helper(self.widget("graphics-port"))
if self.widget("graphics-port-auto").get_active():
port = -1
return port
############## ##############
# UI syncing # # UI syncing #
@ -197,30 +201,10 @@ class vmmGraphicsDetails(vmmGObjectUI):
self.widget("graphics-password-chk").set_active(False) self.widget("graphics-password-chk").set_active(False)
self.widget("graphics-opengl").set_active(False) self.widget("graphics-opengl").set_active(False)
self._sync_ui() self._sync_ui()
self._active_edits = []
def get_values(self):
gtype = uiutil.get_list_selection(self.widget("graphics-type"))
port = self._get_config_graphics_ports()
listen = uiutil.get_list_selection(self.widget("graphics-listen-type"))
addr = uiutil.get_list_selection(self.widget("graphics-address"))
passwd = self.widget("graphics-password").get_text()
if not self.widget("graphics-password-chk").get_active():
passwd = None
glval = self.widget("graphics-opengl").get_active()
if not self.widget("graphics-opengl").is_visible():
glval = None
rendernode = uiutil.get_list_selection(self.widget("graphics-rendernode"))
if not self.widget("graphics-rendernode").is_visible():
rendernode = None
return gtype, port, listen, addr, passwd, glval, rendernode
def set_dev(self, gfx): def set_dev(self, gfx):
self.reset_state() self.reset_state()
portval = gfx.port portval = gfx.port
portautolabel = _("A_uto") portautolabel = _("A_uto")
@ -244,8 +228,8 @@ class vmmGraphicsDetails(vmmGObjectUI):
uiutil.set_list_selection(self.widget("graphics-type"), gtype) uiutil.set_list_selection(self.widget("graphics-type"), gtype)
use_passwd = gfx.passwd is not None use_passwd = gfx.passwd is not None
self.widget("graphics-password").set_text(gfx.passwd or "")
self.widget("graphics-password-chk").set_active(use_passwd) self.widget("graphics-password-chk").set_active(use_passwd)
self.widget("graphics-password").set_text(gfx.passwd or "")
listentype = gfx.get_first_listen_type() listentype = gfx.get_first_listen_type()
uiutil.set_list_selection( uiutil.set_list_selection(
@ -264,32 +248,79 @@ class vmmGraphicsDetails(vmmGObjectUI):
uiutil.set_list_selection( uiutil.set_list_selection(
self.widget("graphics-rendernode"), renderval) self.widget("graphics-rendernode"), renderval)
# This comes last
self._active_edits = []
def get_values(self):
ret = {}
glval = self.widget("graphics-opengl").get_active()
if not self.widget("graphics-opengl").is_visible():
glval = None
rendernode = uiutil.get_list_selection(self.widget("graphics-rendernode"))
if not self.widget("graphics-rendernode").is_visible():
rendernode = None
passwd = self.widget("graphics-password").get_text()
if not self.widget("graphics-password-chk").get_active():
passwd = None
port = uiutil.spin_get_helper(self.widget("graphics-port"))
if self.widget("graphics-port-auto").get_active():
port = -1
listen = uiutil.get_list_selection(self.widget("graphics-listen-type"))
addr = uiutil.get_list_selection(self.widget("graphics-address"))
if listen and listen != "none":
listen = addr
else:
port = None
gtype = uiutil.get_list_selection(self.widget("graphics-type"))
if _EDIT_GFX_TYPE in self._active_edits:
ret["gtype"] = gtype
if _EDIT_GFX_PORT in self._active_edits:
ret["port"] = port
if _EDIT_GFX_LISTEN in self._active_edits:
ret["listen"] = listen
if _EDIT_GFX_PASSWD in self._active_edits:
ret["passwd"] = passwd
if _EDIT_GFX_OPENGL in self._active_edits:
ret["gl"] = glval
ret["rendernode"] = rendernode
return ret
def build_device(self):
self._active_edits = _EDIT_GFX_ENUM[:]
values = self.get_values()
dev = virtinst.DeviceGraphics(self.conn.get_backend())
dev.type = values["gtype"]
dev.passwd = values["passwd"]
dev.gl = values["gl"]
dev.rendernode = values["rendernode"]
dev.listen = values["listen"]
dev.port = values["port"]
return dev
############# #############
# Listeners # # Listeners #
############# #############
def _change_graphics_type(self, ignore): def _change_cb(self, edittype):
self._sync_ui() self._sync_ui()
self.emit("changed-type") if edittype not in self._active_edits:
self._active_edits.append(edittype)
def _change_graphics_listen(self, ignore): self.emit("changed")
self._sync_ui()
self.emit("changed-listen")
def _change_opengl(self, ignore):
self._sync_ui()
self.emit("changed-opengl")
self.emit("changed-rendernode")
def _change_port_auto(self, ignore): def _change_port_auto(self, ignore):
self.widget("graphics-port-auto").set_inconsistent(False) self.widget("graphics-port-auto").set_inconsistent(False)
self._sync_ui() self._change_cb(_EDIT_GFX_PORT)
self.emit("changed-port")
def _change_password_cb(self, src):
self._sync_ui()
self.emit("changed-password")
def _show_password_cb(self, src): def _show_password_cb(self, src):
self._sync_ui() self._sync_ui()

View File

@ -792,7 +792,7 @@ class vmmDomain(vmmLibvirtObject):
self._process_device_define(editdev, xmlobj, do_hotplug) self._process_device_define(editdev, xmlobj, do_hotplug)
def define_graphics(self, devobj, do_hotplug, def define_graphics(self, devobj, do_hotplug,
listen=_SENTINEL, addr=_SENTINEL, port=_SENTINEL, listen=_SENTINEL, port=_SENTINEL,
passwd=_SENTINEL, gtype=_SENTINEL, passwd=_SENTINEL, gtype=_SENTINEL,
gl=_SENTINEL, rendernode=_SENTINEL): gl=_SENTINEL, rendernode=_SENTINEL):
xmlobj = self._make_xmlobj_to_define() xmlobj = self._make_xmlobj_to_define()
@ -800,11 +800,8 @@ class vmmDomain(vmmLibvirtObject):
if not editdev: if not editdev:
return # pragma: no cover return # pragma: no cover
if addr != _SENTINEL or listen != _SENTINEL: if listen != _SENTINEL:
if listen == "none":
editdev.listen = listen editdev.listen = listen
else:
editdev.listen = addr
if port != _SENTINEL: if port != _SENTINEL:
editdev.port = port editdev.port = port
if passwd != _SENTINEL: if passwd != _SENTINEL: