diff options
author | Pavel Hrdina <phrdina@redhat.com> | 2019-06-15 11:58:43 +0200 |
---|---|---|
committer | Pavel Hrdina <phrdina@redhat.com> | 2019-06-15 15:05:28 +0200 |
commit | d6b6397ce0b77acea7f828cd7edb3a8929a8abd4 (patch) | |
tree | 9921b1515ff74d62edc467be2c19240cd588bd2f | |
parent | 5eb5913f345ae267d26d30d0b45443eae006d5f5 (diff) | |
download | virt-manager-d6b6397ce0b77acea7f828cd7edb3a8929a8abd4.tar.gz |
virtManager: xmleditor: warn when switching to XML tab
If there are unapplied changes in the UI warn user when they tries to
switch to XML editor.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
-rw-r--r-- | tests/uitests/details.py | 17 | ||||
-rw-r--r-- | virtManager/details.py | 3 | ||||
-rw-r--r-- | virtManager/hostnets.py | 2 | ||||
-rw-r--r-- | virtManager/storagelist.py | 2 | ||||
-rw-r--r-- | virtManager/xmleditor.py | 68 |
5 files changed, 68 insertions, 24 deletions
diff --git a/tests/uitests/details.py b/tests/uitests/details.py index 63bc2345..cdf4f36a 100644 --- a/tests/uitests/details.py +++ b/tests/uitests/details.py @@ -483,6 +483,23 @@ class Details(uiutils.UITestCase): self._stop_vm(win) self.assertTrue(not share.checked) + # Unapplied changes should warn when switching to XML tab + tab = self._select_hw(win, "Overview", "overview-tab") + tab.find("Description:", "text").text = "hey new description" + win.find("XML", "page tab").click() + alert = self.app.root.find("vmm dialog") + alert.find_fuzzy("changes will be lost") + + # Select 'No', meaning don't abandon changes + alert.find("No", "push button").click() + uiutils.check_in_loop(lambda: tab.showing) + + # Try unapplied changes again, this time abandon our changes + win.find("XML", "page tab").click() + alert = self.app.root.find("vmm dialog") + alert.find("Yes", "push button").click() + uiutils.check_in_loop(lambda: not tab.showing) + def testDetailsXMLEdit(self): """ Test XML editing interaction diff --git a/virtManager/details.py b/virtManager/details.py index 34547f92..64f3f79f 100644 --- a/virtManager/details.py +++ b/virtManager/details.py @@ -1194,6 +1194,7 @@ class vmmDetails(vmmGObjectUI): self.active_edits = [] self.widget("config-apply").set_sensitive(False) self.widget("config-cancel").set_sensitive(False) + self._xmleditor.details_changed = False def enable_apply(self, *arglist): edittype = arglist[-1] @@ -1201,6 +1202,8 @@ class vmmDetails(vmmGObjectUI): self.widget("config-cancel").set_sensitive(True) if edittype not in self.active_edits: self.active_edits.append(edittype) + if edittype != EDIT_XML: + self._xmleditor.details_changed = True # Idmap def config_idmap_enable(self, src): diff --git a/virtManager/hostnets.py b/virtManager/hostnets.py index ca6d2f08..ee066dcd 100644 --- a/virtManager/hostnets.py +++ b/virtManager/hostnets.py @@ -474,10 +474,12 @@ class vmmHostNets(vmmGObjectUI): def _disable_net_apply(self): self._active_edits = set() self.widget("net-apply").set_sensitive(False) + self._xmleditor.details_changed = False def _enable_net_apply(self, edittype): self.widget("net-apply").set_sensitive(True) self._active_edits.add(edittype) + self._xmleditor.details_changed = True def _confirm_changes(self): if (self.is_visible() and diff --git a/virtManager/storagelist.py b/virtManager/storagelist.py index 8531ce19..414de035 100644 --- a/virtManager/storagelist.py +++ b/virtManager/storagelist.py @@ -601,10 +601,12 @@ class vmmStorageList(vmmGObjectUI): def _enable_pool_apply(self, edittype): self._active_edits.add(edittype) self.widget("pool-apply").set_sensitive(True) + self._xmleditor.details_changed = True def _disable_pool_apply(self): self._active_edits = set() self.widget("pool-apply").set_sensitive(False) + self._xmleditor.details_changed = False def _confirm_changes(self): if (self.is_visible() and diff --git a/virtManager/xmleditor.py b/virtManager/xmleditor.py index e5ecb39e..21786bf9 100644 --- a/virtManager/xmleditor.py +++ b/virtManager/xmleditor.py @@ -34,6 +34,8 @@ class vmmXMLEditor(vmmGObjectUI): self._srcbuf = None self._init_ui() + self.details_changed = False + self.add_gsettings_handle( self.config.on_xmleditor_enabled_changed( self._xmleditor_enabled_changed_cb)) @@ -81,10 +83,10 @@ class vmmXMLEditor(vmmGObjectUI): # Internal helpers # #################### - def _reselect_xml_page(self): + def _reselect_page(self, pagenum): # Setting _curpage first will shortcircuit our page changed callback - self._curpage = _PAGE_XML - self.widget("xml-notebook").set_current_page(_PAGE_XML) + self._curpage = pagenum + self.widget("xml-notebook").set_current_page(pagenum) def _reset_xml(self): self.set_xml("") @@ -98,6 +100,32 @@ class vmmXMLEditor(vmmGObjectUI): startiter.forward_line() self._srcbuff.place_cursor(startiter) + def _detials_unapplied_changes(self): + if not self.details_changed: + return False + + ret = self.err.yes_no( + _("There are unapplied changes."), + _("Your changes will be lost if you leave this tab. " + "Really leave this tab?")) + if ret: + self.details_changed = False + + return not ret + + def _xml_unapplied_changes(self): + if self._srcxml == self.get_xml(): + return False + + ret = self.err.yes_no( + _("There are unapplied changes."), + _("Your XML changes will be lost if you leave this tab. " + "Really leave this tab?")) + + return not ret + + + ############## # Public API # @@ -159,34 +187,26 @@ class vmmXMLEditor(vmmGObjectUI): def _before_page_changed_cb(self, notebook, widget, pagenum): if self._curpage == pagenum: return + prevpage = self._curpage self._curpage = pagenum - # If the XML page is clicked, emit xml-requested signal which - # expects the user to call set_xml/set_libvirtobject. This saves - # having to fetch inactive XML up front, and gives users like - # a hook to actually serialize the final XML to return if pagenum == _PAGE_XML: - self.emit("xml-requested") - return - - # If the details page is selected from the XML page, and the user - # edited the XML, we need to warn that leaving this screen will - # invalidate the changes. - if self._srcxml == self.get_xml(): - return - - ret = self.err.yes_no( - _("There are unapplied changes."), - _("Your XML changes will be lost if you leave this tab. " - "Really leave this tab?")) - if ret: - self._reset_xml() - return + if not self._detials_unapplied_changes(): + # If the XML page is clicked, emit xml-requested signal which + # expects the user to call set_xml/set_libvirtobject. This saves + # having to fetch inactive XML up front, and gives users like + # a hook to actually serialize the final XML to return + self.emit("xml-requested") + return + else: + if not self._xml_unapplied_changes(): + self._reset_xml() + return # I can't find anyway to make the notebook stay on the current page # So set an idle callback to switch back to the XML page. It causes # a visual UI blip unfortunately - self.idle_add(self._reselect_xml_page) + self.idle_add(self._reselect_page, prevpage) def _after_page_changed_cb(self, notebook, gparam): self._curpage = notebook.get_current_page() |