mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-01-08 21:18:04 +03:00
preferences: Disable XML editing by default
This adds a field in gsettings and preferences UI to enable XML editing. It's off by default. The XML tab page is still visible, but the textview is not editable, and there's a warning at the top: XML editing is disabled in 'Preferences'. Only enable it if you know what you are doing. When the setting is enabled, the warning goes away and the textview is editable. This puts a roadblock up for people that don't know what they are doing, but still advertises the feature and keeps the UI surface difference fairly small between on/off states.
This commit is contained in:
parent
2a1cf411dd
commit
2266b650a5
@ -53,6 +53,12 @@
|
|||||||
<description>Show system tray icon while app is running</description>
|
<description>Show system tray icon while app is running</description>
|
||||||
</key>
|
</key>
|
||||||
|
|
||||||
|
<key name="xmleditor-enabled" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>Enable XML editting UI</summary>
|
||||||
|
<description>Enable XML editting UI</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
<key name="enable-libguestfs-vm-inspection" type="b">
|
<key name="enable-libguestfs-vm-inspection" type="b">
|
||||||
<default>true</default>
|
<default>true</default>
|
||||||
<summary>Enable libguestfs VM inspection</summary>
|
<summary>Enable libguestfs VM inspection</summary>
|
||||||
|
@ -660,6 +660,7 @@ class AddHardware(uiutils.UITestCase):
|
|||||||
"""
|
"""
|
||||||
Test XML editor integration
|
Test XML editor integration
|
||||||
"""
|
"""
|
||||||
|
self.app.open(xmleditor_enabled=True)
|
||||||
details = self._open_details_window()
|
details = self._open_details_window()
|
||||||
win = self._open_addhw_window(details)
|
win = self._open_addhw_window(details)
|
||||||
finish = win.find("Finish", "push button")
|
finish = win.find("Finish", "push button")
|
||||||
|
@ -59,6 +59,7 @@ class CreateNet(uiutils.UITestCase):
|
|||||||
|
|
||||||
|
|
||||||
def testCreateNetXMLEditor(self):
|
def testCreateNetXMLEditor(self):
|
||||||
|
self.app.open(xmleditor_enabled=True)
|
||||||
hostwin = self._open_host_window("Virtual Networks")
|
hostwin = self._open_host_window("Virtual Networks")
|
||||||
win = self._open_create_win(hostwin)
|
win = self._open_create_win(hostwin)
|
||||||
name = win.find("Name:", "text")
|
name = win.find("Name:", "text")
|
||||||
|
@ -89,6 +89,7 @@ class CreatePool(uiutils.UITestCase):
|
|||||||
|
|
||||||
|
|
||||||
def testCreatePoolXMLEditor(self):
|
def testCreatePoolXMLEditor(self):
|
||||||
|
self.app.open(xmleditor_enabled=True)
|
||||||
hostwin = self._open_host_window("Storage")
|
hostwin = self._open_host_window("Storage")
|
||||||
win = self._open_create_win(hostwin)
|
win = self._open_create_win(hostwin)
|
||||||
finish = win.find("Finish", "push button")
|
finish = win.find("Finish", "push button")
|
||||||
|
@ -66,6 +66,7 @@ class CreateVol(uiutils.UITestCase):
|
|||||||
|
|
||||||
|
|
||||||
def testCreateVolXMLEditor(self):
|
def testCreateVolXMLEditor(self):
|
||||||
|
self.app.open(xmleditor_enabled=True)
|
||||||
hostwin = self._open_host_window("Storage")
|
hostwin = self._open_host_window("Storage")
|
||||||
poolcell = hostwin.find("default-pool", "table cell")
|
poolcell = hostwin.find("default-pool", "table cell")
|
||||||
poolcell.click()
|
poolcell.click()
|
||||||
|
@ -487,6 +487,7 @@ class Details(uiutils.UITestCase):
|
|||||||
"""
|
"""
|
||||||
Test XML editing interaction
|
Test XML editing interaction
|
||||||
"""
|
"""
|
||||||
|
self.app.open(xmleditor_enabled=True)
|
||||||
win = self._open_details_window(vmname="test-clone-simple")
|
win = self._open_details_window(vmname="test-clone-simple")
|
||||||
finish = win.find("config-apply")
|
finish = win.find("config-apply")
|
||||||
xmleditor = win.find("XML editor")
|
xmleditor = win.find("XML editor")
|
||||||
|
@ -30,6 +30,7 @@ class Host(uiutils.UITestCase):
|
|||||||
"""
|
"""
|
||||||
Test edits to net config
|
Test edits to net config
|
||||||
"""
|
"""
|
||||||
|
self.app.open(xmleditor_enabled=True)
|
||||||
win = self._open_host_window("Virtual Networks").find("network-grid")
|
win = self._open_host_window("Virtual Networks").find("network-grid")
|
||||||
finish = win.find("Apply", "push button")
|
finish = win.find("Apply", "push button")
|
||||||
|
|
||||||
@ -69,6 +70,7 @@ class Host(uiutils.UITestCase):
|
|||||||
"""
|
"""
|
||||||
Test edits to pool config
|
Test edits to pool config
|
||||||
"""
|
"""
|
||||||
|
self.app.open(xmleditor_enabled=True)
|
||||||
win = self._open_host_window("Storage").find("storage-grid")
|
win = self._open_host_window("Storage").find("storage-grid")
|
||||||
finish = win.find("Apply", "push button")
|
finish = win.find("Apply", "push button")
|
||||||
|
|
||||||
|
@ -432,6 +432,7 @@ class NewVM(uiutils.UITestCase):
|
|||||||
"""
|
"""
|
||||||
Test new VM with raw XML editing via customize wizard
|
Test new VM with raw XML editing via customize wizard
|
||||||
"""
|
"""
|
||||||
|
self.app.open(xmleditor_enabled=True)
|
||||||
newvm = self._open_create_wizard()
|
newvm = self._open_create_wizard()
|
||||||
|
|
||||||
# Create a custom named VM, using CDROM media, and default storage
|
# Create a custom named VM, using CDROM media, and default storage
|
||||||
|
@ -55,3 +55,34 @@ class VMMPrefs(uiutils.UITestCase):
|
|||||||
|
|
||||||
win.find_fuzzy("Close", "push button").click()
|
win.find_fuzzy("Close", "push button").click()
|
||||||
uiutils.check_in_loop(lambda: win.visible is False)
|
uiutils.check_in_loop(lambda: win.visible is False)
|
||||||
|
|
||||||
|
|
||||||
|
def testPrefsXMLEditor(self):
|
||||||
|
managerwin = self.app.topwin
|
||||||
|
detailswin = self._open_details_window(vmname="test-clone-simple")
|
||||||
|
finish = detailswin.find("config-apply")
|
||||||
|
xmleditor = detailswin.find("XML editor")
|
||||||
|
|
||||||
|
detailswin.find("XML", "page tab").click()
|
||||||
|
warnlabel = detailswin.find_fuzzy("XML editing is disabled")
|
||||||
|
self.assertTrue(warnlabel.visible)
|
||||||
|
origtext = xmleditor.text
|
||||||
|
xmleditor.typeText("1234abcd")
|
||||||
|
self.assertEqual(xmleditor.text, origtext)
|
||||||
|
|
||||||
|
managerwin.click()
|
||||||
|
managerwin.find("Edit", "menu").click()
|
||||||
|
managerwin.find("Preferences", "menu item").click()
|
||||||
|
prefswin = self.app.root.find_fuzzy("Preferences", "frame")
|
||||||
|
prefswin.find_fuzzy("Enable XML").click()
|
||||||
|
prefswin.find_fuzzy("Close", "push button").click()
|
||||||
|
uiutils.check_in_loop(lambda: prefswin.visible is False)
|
||||||
|
|
||||||
|
managerwin.keyCombo("<alt>F4")
|
||||||
|
detailswin.click()
|
||||||
|
xmleditor.text = xmleditor.text.replace(">",
|
||||||
|
"><title>FOOTITLE</title>", 1)
|
||||||
|
finish.click()
|
||||||
|
detailswin.find("Details", "page tab").click()
|
||||||
|
uiutils.check_in_loop(lambda:
|
||||||
|
detailswin.find("Title:", "text").text == "FOOTITLE")
|
||||||
|
@ -444,7 +444,7 @@ class VMMDogtailApp(object):
|
|||||||
return bool(self._proc and self._proc.poll() is None)
|
return bool(self._proc and self._proc.poll() is None)
|
||||||
|
|
||||||
def open(self, extra_opts=None, check_already_running=True, use_uri=True,
|
def open(self, extra_opts=None, check_already_running=True, use_uri=True,
|
||||||
window_name=None):
|
window_name=None, xmleditor_enabled=False):
|
||||||
extra_opts = extra_opts or []
|
extra_opts = extra_opts or []
|
||||||
|
|
||||||
if tests.utils.clistate.debug:
|
if tests.utils.clistate.debug:
|
||||||
@ -460,9 +460,12 @@ class VMMDogtailApp(object):
|
|||||||
cmd += ["-m", "coverage", "run", "--append",
|
cmd += ["-m", "coverage", "run", "--append",
|
||||||
"--omit", "/usr/*"]
|
"--omit", "/usr/*"]
|
||||||
cmd += [os.path.join(os.getcwd(), "virt-manager"),
|
cmd += [os.path.join(os.getcwd(), "virt-manager"),
|
||||||
"--test-first-run", "--no-fork"]
|
"--test-first-run",
|
||||||
|
"--no-fork"]
|
||||||
if use_uri:
|
if use_uri:
|
||||||
cmd += ["--connect", self.uri]
|
cmd += ["--connect", self.uri]
|
||||||
|
if xmleditor_enabled:
|
||||||
|
cmd += ["--test-options=xmleditor-enabled"]
|
||||||
cmd += extra_opts
|
cmd += extra_opts
|
||||||
|
|
||||||
if check_already_running:
|
if check_already_running:
|
||||||
|
@ -119,6 +119,21 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCheckButton" id="prefs-xmleditor">
|
||||||
|
<property name="label" translatable="yes">Enable _XML editing</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
<signal name="toggled" handler="on_prefs_xmleditor_toggled" swapped="no"/>
|
||||||
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">0</property>
|
<property name="left_attach">0</property>
|
||||||
<property name="top_attach">1</property>
|
<property name="top_attach">1</property>
|
||||||
|
@ -36,26 +36,76 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="xml-box">
|
<object class="GtkGrid">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="margin_left">6</property>
|
<property name="margin_left">6</property>
|
||||||
<property name="margin_top">6</property>
|
<property name="margin_top">6</property>
|
||||||
<property name="orientation">vertical</property>
|
<property name="row_spacing">6</property>
|
||||||
<property name="spacing">6</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow" id="xml-scroll">
|
<object class="GtkBox" id="xml-box">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="shadow_type">in</property>
|
<property name="hexpand">True</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">6</property>
|
||||||
<child>
|
<child>
|
||||||
<placeholder/>
|
<object class="GtkScrolledWindow" id="xml-scroll">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="shadow_type">in</property>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">True</property>
|
<property name="left_attach">0</property>
|
||||||
<property name="fill">True</property>
|
<property name="top_attach">1</property>
|
||||||
<property name="position">0</property>
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox" id="xml-warning-box">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="spacing">6</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-dialog-warning</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes"><small>XML editing is disabled in 'Preferences'. Only enable it if you know what you are doing.</small></property>
|
||||||
|
<property name="use_markup">True</property>
|
||||||
|
<property name="wrap">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
@ -192,6 +192,7 @@ class CLITestOptionsClass:
|
|||||||
self.leak_debug = _get("leak-debug")
|
self.leak_debug = _get("leak-debug")
|
||||||
self.old_poll = _get("old-poll")
|
self.old_poll = _get("old-poll")
|
||||||
self.no_events = _get("no-events")
|
self.no_events = _get("no-events")
|
||||||
|
self.xmleditor_enabled = _get("xmleditor-enabled")
|
||||||
|
|
||||||
if opts:
|
if opts:
|
||||||
print("Unknown --test-options keys: %s" % opts)
|
print("Unknown --test-options keys: %s" % opts)
|
||||||
|
@ -169,6 +169,8 @@ class vmmConfig(object):
|
|||||||
self.conf = _SettingsWrapper("org.virt-manager.virt-manager")
|
self.conf = _SettingsWrapper("org.virt-manager.virt-manager")
|
||||||
|
|
||||||
self.CLITestOptions = CLITestOptions
|
self.CLITestOptions = CLITestOptions
|
||||||
|
if self.CLITestOptions.xmleditor_enabled:
|
||||||
|
self.set_xmleditor_enabled(True)
|
||||||
|
|
||||||
# We don't create it straight away, since we don't want
|
# We don't create it straight away, since we don't want
|
||||||
# to block the app pending user authorization to access
|
# to block the app pending user authorization to access
|
||||||
@ -364,6 +366,16 @@ class vmmConfig(object):
|
|||||||
def set_view_system_tray(self, val):
|
def set_view_system_tray(self, val):
|
||||||
self.conf.set("/system-tray", val)
|
self.conf.set("/system-tray", val)
|
||||||
|
|
||||||
|
|
||||||
|
# XML editor enabled
|
||||||
|
def on_xmleditor_enabled_changed(self, cb):
|
||||||
|
return self.conf.notify_add("/xmleditor-enabled", cb)
|
||||||
|
def get_xmleditor_enabled(self):
|
||||||
|
return self.conf.get("/xmleditor-enabled")
|
||||||
|
def set_xmleditor_enabled(self, val):
|
||||||
|
self.conf.set("/xmleditor-enabled", val)
|
||||||
|
|
||||||
|
|
||||||
# Libguestfs VM inspection
|
# Libguestfs VM inspection
|
||||||
def on_libguestfs_inspect_vms_changed(self, cb):
|
def on_libguestfs_inspect_vms_changed(self, cb):
|
||||||
return self.conf.notify_add("/enable-libguestfs-vm-inspection", cb)
|
return self.conf.notify_add("/enable-libguestfs-vm-inspection", cb)
|
||||||
|
@ -36,6 +36,7 @@ class vmmPreferences(vmmGObjectUI):
|
|||||||
self._orig_libguestfs_val = None
|
self._orig_libguestfs_val = None
|
||||||
|
|
||||||
self.refresh_view_system_tray()
|
self.refresh_view_system_tray()
|
||||||
|
self.refresh_xmleditor()
|
||||||
self.refresh_libguestfs()
|
self.refresh_libguestfs()
|
||||||
self.refresh_update_interval()
|
self.refresh_update_interval()
|
||||||
self.refresh_console_accels()
|
self.refresh_console_accels()
|
||||||
@ -65,6 +66,7 @@ class vmmPreferences(vmmGObjectUI):
|
|||||||
"on_prefs_close_clicked": self.close,
|
"on_prefs_close_clicked": self.close,
|
||||||
|
|
||||||
"on_prefs_system_tray_toggled": self.change_view_system_tray,
|
"on_prefs_system_tray_toggled": self.change_view_system_tray,
|
||||||
|
"on_prefs_xmleditor_toggled": self.change_xmleditor,
|
||||||
"on_prefs_libguestfs_toggled": self.change_libguestfs,
|
"on_prefs_libguestfs_toggled": self.change_libguestfs,
|
||||||
"on_prefs_stats_update_interval_changed": self.change_update_interval,
|
"on_prefs_stats_update_interval_changed": self.change_update_interval,
|
||||||
"on_prefs_console_accels_toggled": self.change_console_accels,
|
"on_prefs_console_accels_toggled": self.change_console_accels,
|
||||||
@ -203,6 +205,10 @@ class vmmPreferences(vmmGObjectUI):
|
|||||||
val = self.config.get_view_system_tray()
|
val = self.config.get_view_system_tray()
|
||||||
self.widget("prefs-system-tray").set_active(bool(val))
|
self.widget("prefs-system-tray").set_active(bool(val))
|
||||||
|
|
||||||
|
def refresh_xmleditor(self):
|
||||||
|
val = self.config.get_xmleditor_enabled()
|
||||||
|
self.widget("prefs-xmleditor").set_active(bool(val))
|
||||||
|
|
||||||
def refresh_libguestfs(self):
|
def refresh_libguestfs(self):
|
||||||
val = self.config.get_libguestfs_inspect_vms()
|
val = self.config.get_libguestfs_inspect_vms()
|
||||||
if self._orig_libguestfs_val is None:
|
if self._orig_libguestfs_val is None:
|
||||||
@ -364,6 +370,8 @@ class vmmPreferences(vmmGObjectUI):
|
|||||||
|
|
||||||
def change_view_system_tray(self, src):
|
def change_view_system_tray(self, src):
|
||||||
self.config.set_view_system_tray(src.get_active())
|
self.config.set_view_system_tray(src.get_active())
|
||||||
|
def change_xmleditor(self, src):
|
||||||
|
self.config.set_xmleditor_enabled(src.get_active())
|
||||||
def change_libguestfs(self, src):
|
def change_libguestfs(self, src):
|
||||||
val = src.get_active()
|
val = src.get_active()
|
||||||
self.config.set_libguestfs_inspect_vms(val)
|
self.config.set_libguestfs_inspect_vms(val)
|
||||||
|
@ -6,6 +6,7 @@ import gi
|
|||||||
gi.require_version('GtkSource', '4')
|
gi.require_version('GtkSource', '4')
|
||||||
from gi.repository import GtkSource
|
from gi.repository import GtkSource
|
||||||
|
|
||||||
|
from . import uiutil
|
||||||
from .baseclass import vmmGObjectUI
|
from .baseclass import vmmGObjectUI
|
||||||
|
|
||||||
_PAGE_DETAILS = 0
|
_PAGE_DETAILS = 0
|
||||||
@ -33,6 +34,10 @@ class vmmXMLEditor(vmmGObjectUI):
|
|||||||
self._srcbuf = None
|
self._srcbuf = None
|
||||||
self._init_ui()
|
self._init_ui()
|
||||||
|
|
||||||
|
self.add_gsettings_handle(
|
||||||
|
self.config.on_xmleditor_enabled_changed(
|
||||||
|
self._xmleditor_enabled_changed_cb))
|
||||||
|
|
||||||
|
|
||||||
def _cleanup(self):
|
def _cleanup(self):
|
||||||
pass
|
pass
|
||||||
@ -42,6 +47,12 @@ class vmmXMLEditor(vmmGObjectUI):
|
|||||||
# UI init #
|
# UI init #
|
||||||
###########
|
###########
|
||||||
|
|
||||||
|
def _set_xmleditor_enabled_from_config(self):
|
||||||
|
enabled = self.config.get_xmleditor_enabled()
|
||||||
|
self._srcview.set_editable(enabled)
|
||||||
|
uiutil.set_grid_row_visible(self.widget("xml-warning-box"),
|
||||||
|
not enabled)
|
||||||
|
|
||||||
def _init_ui(self):
|
def _init_ui(self):
|
||||||
self._srcview = GtkSource.View()
|
self._srcview = GtkSource.View()
|
||||||
self._srcbuff = self._srcview.get_buffer()
|
self._srcbuff = self._srcview.get_buffer()
|
||||||
@ -63,6 +74,7 @@ class vmmXMLEditor(vmmGObjectUI):
|
|||||||
|
|
||||||
self._srcview.show_all()
|
self._srcview.show_all()
|
||||||
self.widget("xml-scroll").add(self._srcview)
|
self.widget("xml-scroll").add(self._srcview)
|
||||||
|
self._set_xmleditor_enabled_from_config()
|
||||||
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
@ -178,3 +190,6 @@ class vmmXMLEditor(vmmGObjectUI):
|
|||||||
|
|
||||||
def _after_page_changed_cb(self, notebook, gparam):
|
def _after_page_changed_cb(self, notebook, gparam):
|
||||||
self._curpage = notebook.get_current_page()
|
self._curpage = notebook.get_current_page()
|
||||||
|
|
||||||
|
def _xmleditor_enabled_changed_cb(self):
|
||||||
|
self._set_xmleditor_enabled_from_config()
|
||||||
|
Loading…
Reference in New Issue
Block a user