diff --git a/addon/globalPlugins/webAccess/gui/menu.py b/addon/globalPlugins/webAccess/gui/menu.py
index 7bd23ae8..b02f1cbe 100644
--- a/addon/globalPlugins/webAccess/gui/menu.py
+++ b/addon/globalPlugins/webAccess/gui/menu.py
@@ -38,7 +38,6 @@
from ... import webAccess
from .. import ruleHandler
from ..utils import guarded
-from . import webModulesManager
addonHandler.initTranslation()
@@ -150,21 +149,21 @@ def onRulesManager(self, evt):
show(self.context, gui.mainFrame)
@guarded
- def onWebModuleEdit(self, evt, webModule=None):
- if webModule is not None:
- self.context["webModule"] = webModule
- from .webModuleEditor import show
+ def onWebModuleCreate(self, evt, webModule=None):
+ self.context["new"] = True
+ from .webModule.editor import show
show(self.context)
@guarded
- def onWebModuleCreate(self, evt, webModule=None):
- self.context["new"] = True
- from .webModuleEditor import show
+ def onWebModuleEdit(self, evt, webModule=None):
+ if webModule is not None:
+ self.context["webModule"] = webModule
+ from .webModule.editor import show
show(self.context)
@guarded
def onWebModulesManager(self, evt):
- from .webModulesManager import show
+ from .webModule.manager import show
show(self.context)
@guarded
diff --git a/addon/globalPlugins/webAccess/gui/rule/__init__.py b/addon/globalPlugins/webAccess/gui/rule/__init__.py
index e69de29b..86778698 100644
--- a/addon/globalPlugins/webAccess/gui/rule/__init__.py
+++ b/addon/globalPlugins/webAccess/gui/rule/__init__.py
@@ -0,0 +1,83 @@
+# globalPlugins/webAccess/gui/rule/__init__.py
+# -*- coding: utf-8 -*-
+
+# This file is part of Web Access for NVDA.
+# Copyright (C) 2015-2024 Accessolutions (http://accessolutions.fr)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# See the file COPYING.txt at the root of this distribution for more details.
+
+
+__author__ = "Julien Cochuyt "
+
+
+from collections.abc import Mapping
+from typing import Any
+
+import wx
+
+import addonHandler
+import gui
+from logHandler import log
+
+
+addonHandler.initTranslation()
+
+
+def createMissingSubModule(
+ context: Mapping[str, Any],
+ data: Mapping[str, Any],
+ parent: wx.Window
+ ) -> bool:
+ """Create the missing SubModule from Rule or Criteria data
+
+ If a SubModule is specified in the provided data, it is looked-up in the catalog.
+ If it is missing from the catalog, the user is prompted for creating it.
+
+ This function returns:
+ - `None` if no creation was necessary or if the user declined the prompt.
+ - `False` if the user canceled the prompt or if the creation failed or has been canceled.
+ - `True` if the creation succeeded.
+ """
+ name = data.get("properties", {}).get("subModule")
+ if not name:
+ return None
+ from ...webModuleHandler import getCatalog
+ if any(meta["name"] == name for ref, meta in getCatalog()):
+ return True
+ res = gui.messageBox(
+ message=(
+ # Translators: A prompt for creation of a missing SubModule
+ _(f"""SubModule {name} could not be found.
+
+Do you want to create it now?""")
+ ),
+ style=wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION,
+ parent=parent,
+ )
+ if res is wx.NO:
+ return None
+ elif res is wx.CANCEL:
+ return False
+ context = context.copy()
+ context["new"] = True
+ context["data"] = {"webModule": {"name": name, "subModule": True}}
+ from ..webModule.editor import show
+ res = show(context, parent)
+ if res:
+ newName = context["webModule"].name
+ if newName != name:
+ data["properties"]["subModule"] = newName
+ return res
diff --git a/addon/globalPlugins/webAccess/gui/actions.py b/addon/globalPlugins/webAccess/gui/rule/actions.py
similarity index 97%
rename from addon/globalPlugins/webAccess/gui/actions.py
rename to addon/globalPlugins/webAccess/gui/rule/actions.py
index dc83da66..35c68bfa 100644
--- a/addon/globalPlugins/webAccess/gui/actions.py
+++ b/addon/globalPlugins/webAccess/gui/rule/actions.py
@@ -1,4 +1,4 @@
-# globalPlugins/webAccess/gui/actions.py
+# globalPlugins/webAccess/gui/rule/actions.py
# -*- coding: utf-8 -*-
# This file is part of Web Access for NVDA.
@@ -38,10 +38,11 @@
import gui
from gui import guiHelper
-from ..ruleHandler import ruleTypes
-from ..utils import guarded
-from . import ContextualSettingsPanel, Change, gestureBinding
-from .rule.abc import RuleAwarePanelBase
+from ...ruleHandler import ruleTypes
+from ...utils import guarded
+from .. import ContextualSettingsPanel, Change
+from . import gestureBinding
+from .abc import RuleAwarePanelBase
addonHandler.initTranslation()
diff --git a/addon/globalPlugins/webAccess/gui/criteriaEditor.py b/addon/globalPlugins/webAccess/gui/rule/criteriaEditor.py
similarity index 97%
rename from addon/globalPlugins/webAccess/gui/criteriaEditor.py
rename to addon/globalPlugins/webAccess/gui/rule/criteriaEditor.py
index e94aa9d8..acdb385f 100644
--- a/addon/globalPlugins/webAccess/gui/criteriaEditor.py
+++ b/addon/globalPlugins/webAccess/gui/rule/criteriaEditor.py
@@ -1,4 +1,4 @@
-# globalPlugins/webAccess/gui/criteriaEditor.py
+# globalPlugins/webAccess/gui/rule/criteria.py
# -*- coding: utf-8 -*-
# This file is part of Web Access for NVDA.
@@ -21,7 +21,7 @@
-__version__ = "2024.08.29"
+__version__ = "2024.08.30"
__authors__ = (
"Shirley Noël ",
"Julien Cochuyt ",
@@ -48,9 +48,9 @@
import ui
import addonHandler
-from ..ruleHandler import builtinRuleActions, ruleTypes
-from ..utils import guarded, notifyError, updateOrDrop
-from . import (
+from ...ruleHandler import builtinRuleActions, ruleTypes
+from ...utils import guarded, notifyError, updateOrDrop
+from .. import (
ContextualMultiCategorySettingsDialog,
ContextualSettingsPanel,
DropDownWithHideableChoices,
@@ -61,8 +61,9 @@
stripAccel,
stripAccelAndColon,
)
+from . import createMissingSubModule
+from .abc import RuleAwarePanelBase
from .actions import ActionsPanelBase
-from .rule.abc import RuleAwarePanelBase
from .properties import Properties, PropertiesPanelBase, Property
@@ -239,7 +240,7 @@ def testCriteria(context):
ruleData.setdefault("properties", {})['multiple'] = True
critData.setdefault("properties", {}).pop("multiple", None)
mgr = context["webModule"].ruleManager
- from ..ruleHandler import Rule
+ from ...ruleHandler import Rule
rule = Rule(mgr, ruleData)
import time
start = time.time()
@@ -257,7 +258,9 @@ def testCriteria(context):
class CriteriaEditorPanel(RuleAwarePanelBase):
def getData(self):
- return self.context["data"].setdefault("criteria", {})
+ # Should always be initialized, as the Rule Editor populates it with at least
+ # the index of this Alternative Criteria Set ("criteriaIndex").
+ return self.context["data"]["criteria"]
class GeneralPanel(CriteriaEditorPanel):
@@ -1017,6 +1020,11 @@ class CriteriaEditorDialog(ContextualMultiCategorySettingsDialog):
categoryClasses = [GeneralPanel, CriteriaPanel, ActionsPanel, PropertiesPanel]
INITIAL_SIZE = (900, 580)
+ def getData(self):
+ # Should always be initialized, as the Rule Editor populates it with at least
+ # the index of this Alternative Criteria Set ("criteriaIndex").
+ return self.context["data"]["criteria"]
+
def makeSettings(self, settingsSizer):
super().makeSettings(settingsSizer)
idTestCriteria = wx.NewId()
@@ -1028,8 +1036,13 @@ def makeSettings(self, settingsSizer):
def onTestCriteria(self, evt):
self.currentCategory.updateData()
testCriteria(self.context)
+
+ def _saveAllPanels(self):
+ super()._saveAllPanels()
+ if createMissingSubModule(self.context, self.getData(), self) is False:
+ raise ValidationError() # Cancels closing of the dialog
def show(context, parent=None):
- from . import showContextualDialog
+ from .. import showContextualDialog
return showContextualDialog(CriteriaEditorDialog, context, parent)
diff --git a/addon/globalPlugins/webAccess/gui/rule/editor.py b/addon/globalPlugins/webAccess/gui/rule/editor.py
index 2fda1008..4357aa12 100644
--- a/addon/globalPlugins/webAccess/gui/rule/editor.py
+++ b/addon/globalPlugins/webAccess/gui/rule/editor.py
@@ -62,22 +62,21 @@
TreeMultiCategorySettingsDialog,
TreeNodeInfo,
ValidationError,
- criteriaEditor,
- gestureBinding,
showContextualDialog,
stripAccel,
stripAccelAndColon,
stripAccelAndColon,
)
-from ..actions import ActionsPanelBase
-from ..properties import (
+from . import createMissingSubModule, criteriaEditor, gestureBinding
+from .abc import RuleAwarePanelBase
+from .actions import ActionsPanelBase
+from .properties import (
EditorType,
Property,
Properties,
PropertiesPanelBase,
SinglePropertyEditorPanelBase,
)
-from .abc import RuleAwarePanelBase
addonHandler.initTranslation()
@@ -933,9 +932,9 @@ def initData(self, context: Mapping[str, Any]) -> None:
break
node = node.parent
super().initData(context)
-
- def _doSave(self):
- super()._doSave()
+
+ def _saveAllPanels(self):
+ super()._saveAllPanels()
context = self.context
data = self.getData()
mgr = context["webModule"].ruleManager
@@ -946,14 +945,17 @@ def _doSave(self):
layerName = rule.layer
webModule = webModuleHandler.getEditableWebModule(mgr.webModule, layerName=layerName)
if not webModule:
- return
+ raise ValidationError() # Cancels closing of the dialog
+ if createMissingSubModule(context, data, self) is False:
+ raise ValidationError() # Cancels closing of the dialog
if context.get("new"):
layerName = webModule.getWritableLayer().name
else:
mgr.removeRule(rule)
context["rule"] = mgr.loadRule(layerName, data["name"], data)
webModule.getLayer(layerName, raiseIfMissing=True).dirty = True
- webModuleHandler.save(webModule, layerName=layerName)
+ if not webModuleHandler.save(webModule, layerName=layerName):
+ raise ValidationError() # Cancels closing of the dialog
def show(context, parent=None):
diff --git a/addon/globalPlugins/webAccess/gui/gestureBinding.py b/addon/globalPlugins/webAccess/gui/rule/gestureBinding.py
similarity index 97%
rename from addon/globalPlugins/webAccess/gui/gestureBinding.py
rename to addon/globalPlugins/webAccess/gui/rule/gestureBinding.py
index 68f069a1..9e22ac1d 100644
--- a/addon/globalPlugins/webAccess/gui/gestureBinding.py
+++ b/addon/globalPlugins/webAccess/gui/rule/gestureBinding.py
@@ -1,4 +1,4 @@
-# globalPlugins/webAccess/gui/gestureBinding.py
+# globalPlugins/webAccess/gui/rule/gestureBinding.py
# -*- coding: utf-8 -*-
# This file is part of Web Access for NVDA.
@@ -41,8 +41,8 @@
import speech
import ui
-from ..utils import guarded, logException
-from . import ScalingMixin, showContextualDialog
+from ...utils import guarded, logException
+from .. import ScalingMixin, showContextualDialog
addonHandler.initTranslation()
diff --git a/addon/globalPlugins/webAccess/gui/properties.py b/addon/globalPlugins/webAccess/gui/rule/properties.py
similarity index 97%
rename from addon/globalPlugins/webAccess/gui/properties.py
rename to addon/globalPlugins/webAccess/gui/rule/properties.py
index 9d585fcc..107db56f 100644
--- a/addon/globalPlugins/webAccess/gui/properties.py
+++ b/addon/globalPlugins/webAccess/gui/rule/properties.py
@@ -1,4 +1,4 @@
-# globalPlugins/webAccess/gui/properties.py
+# globalPlugins/webAccess/gui/rule/properties.py
# -*- coding: utf-8 -*-
# This file is part of Web Access for NVDA.
@@ -36,10 +36,10 @@
import speech
import ui
-from ..ruleHandler.controlMutation import MUTATIONS_BY_RULE_TYPE, mutationLabels
-from ..ruleHandler.properties import PropertiesBase, PropertySpec, PropertySpecValue, PropertyValue
-from ..utils import guarded, logException
-from . import ContextualSettingsPanel, EditorType, ListCtrlAutoWidth, SingleFieldEditorMixin
+from ...ruleHandler.controlMutation import MUTATIONS_BY_RULE_TYPE, mutationLabels
+from ...ruleHandler.properties import PropertiesBase, PropertySpec, PropertySpecValue, PropertyValue
+from ...utils import guarded, logException
+from .. import ContextualSettingsPanel, EditorType, ListCtrlAutoWidth, SingleFieldEditorMixin
addonHandler.initTranslation()
@@ -145,7 +145,7 @@ def suggestions(self):
if name in cache:
return cache[name]
if name == "subModule":
- from ..webModuleHandler import getCatalog
+ from ...webModuleHandler import getCatalog
suggestions = tuple(sorted({meta["name"] for ref, meta in getCatalog()}))
else:
raise ValueError(f"prop.name: {name!r}")
diff --git a/addon/globalPlugins/webAccess/gui/webModule/__init__.py b/addon/globalPlugins/webAccess/gui/webModule/__init__.py
new file mode 100644
index 00000000..5ce7b650
--- /dev/null
+++ b/addon/globalPlugins/webAccess/gui/webModule/__init__.py
@@ -0,0 +1,82 @@
+# globalPlugins/webAccess/gui/rule/__init__.py
+# -*- coding: utf-8 -*-
+
+# This file is part of Web Access for NVDA.
+# Copyright (C) 2015-2024 Accessolutions (http://accessolutions.fr)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# See the file COPYING.txt at the root of this distribution for more details.
+
+
+__author__ = "Julien Cochuyt "
+
+
+from collections.abc import Mapping
+from typing import Any
+
+import os
+import wx
+
+import addonHandler
+import config
+import gui
+
+from ...webModuleHandler import WebModule
+
+
+addonHandler.initTranslation()
+
+
+def promptDelete(webModule: WebModule):
+ msg = (
+ # Translators: Prompt before deleting a web module.
+ _("Do you really want to delete this web module?")
+ + os.linesep
+ + str(webModule.name)
+ )
+ if config.conf["webAccess"]["devMode"]:
+ msg += " ({})".format("/".join((layer.name for layer in webModule.layers)))
+ return gui.messageBox(
+ parent=gui.mainFrame,
+ message=msg,
+ style=wx.YES_NO | wx.CANCEL | wx.NO_DEFAULT | wx.ICON_WARNING
+ ) == wx.YES
+
+
+def promptMask(webModule: WebModule):
+ ref = webModule.getLayer("addon", raiseIfMissing=True).storeRef
+ if ref[0] != "addons":
+ raise ValueError("ref={!r}".format(ref))
+ addonName = ref[1]
+ for addon in addonHandler.getRunningAddons():
+ if addon.name == addonName:
+ addonSummary = addon.manifest["summary"]
+ break
+ else:
+ raise LookupError("addonName={!r}".format(addonName))
+ log.info("Proposing to mask {!r} from addon {!r}".format(webModule, addonName))
+ msg = _(
+ """This web module comes with the add-on {addonSummary}.
+It cannot be modified at its current location.
+
+Do you want to make a copy in your scratchpad?
+"""
+ ).format(addonSummary=addonSummary)
+ return gui.messageBox(
+ parent=gui.mainFrame,
+ message=msg,
+ caption=_("Warning"),
+ style=wx.ICON_WARNING | wx.YES | wx.NO
+ ) == wx.YES
diff --git a/addon/globalPlugins/webAccess/gui/webModuleEditor.py b/addon/globalPlugins/webAccess/gui/webModule/editor.py
similarity index 83%
rename from addon/globalPlugins/webAccess/gui/webModuleEditor.py
rename to addon/globalPlugins/webAccess/gui/webModule/editor.py
index e834be42..6326a9ab 100644
--- a/addon/globalPlugins/webAccess/gui/webModuleEditor.py
+++ b/addon/globalPlugins/webAccess/gui/webModule/editor.py
@@ -1,4 +1,4 @@
-# globalPlugins/webAccess/gui/webModuleEditor.py
+# globalPlugins/webAccess/gui/webModule/editor.py
# -*- coding: utf-8 -*-
# This file is part of Web Access for NVDA.
@@ -23,12 +23,16 @@
__author__ = (
"Yannick Plassiard "
"Frédéric Brugnot "
- "Julien Cochuyt "
+ "Julien Cochuyt ",
+ "André-Abush Clause ",
+ "Gatien Bouyssou ",
)
+from collections.abc import Mapping
import itertools
import os
+from typing import Any
import wx
from NVDAObjects import NVDAObject, IAccessible
@@ -41,8 +45,9 @@
from logHandler import log
import ui
-from ..webModuleHandler import WebModule, getEditableWebModule, getUrl, getWindowTitle, save
-from . import ContextualDialog, showContextualDialog
+from ...utils import guarded
+from ...webModuleHandler import WebModule, getEditableWebModule, getUrl, getWindowTitle, save, store
+from .. import ContextualDialog, showContextualDialog
addonHandler.initTranslation()
@@ -140,30 +145,38 @@ def __init__(self, parent):
self.SetSizer(mainSizer)
self.CentreOnScreen()
self.webModuleName.SetFocus()
-
+
+ def getData(self) -> Mapping[str, Any]:
+ return self.context["data"]["webModule"]
+
def initData(self, context):
super().initData(context)
- data = context.setdefault("data", {})["webModule"] = {}
+ data = context.setdefault("data", {}).setdefault("webModule", {})
if not context.get("new"):
webModule = context.get("webModule")
data.update(webModule.dump(webModule.layers[-1].name).data["WebModule"])
+ # Could not have been saved without triggers from this editor unless invoked
+ # from the Rule or Criteria editor.
+ subModule = data["subModule"] = not (data.get("url") or data.get("windowTitle"))
# Translators: Web module edition dialog title
title = _("Edit Web Module")
if config.conf["webAccess"]["devMode"]:
title += " ({})".format("/".join((layer.name for layer in webModule.layers)))
else:
+ subModule = data.get("subModule", False)
# Translators: Web module creation dialog title
title = _("New Web Module")
if config.conf["webAccess"]["devMode"]:
- from .. import webModuleHandler
try:
guineaPig = getEditableWebModule(WebModule(), prompt=False)
- store = next(iter(webModuleHandler.store.getSupportingStores(
+ supportingStore = next(iter(store.getSupportingStores(
"create",
item=guineaPig
))) if guineaPig is not None else None
title += " ({})".format(
- store and ("user" if store.name == "userConfig" else store.name)
+ supportingStore and (
+ "user" if supportingStore.name == "userConfig" else supportingStore.name
+ )
)
except Exception:
log.exception()
@@ -217,9 +230,7 @@ def initData(self, context):
]
self.webModuleUrl.SetItems(urlsChoices)
self.webModuleUrl.Selection = (
- urlsChoices.index(selectedUrl)
- if selectedUrl
- else 0
+ urlsChoices.index(selectedUrl) if selectedUrl else 0 if not subModule else -1
)
windowTitleChoices = []
@@ -240,9 +251,18 @@ def initData(self, context):
item.Value = ""
self.help.Value = data.get("help", "")
-
+
+ def updateData(self):
+ data = self.getData()
+ data["name"] = self.webModuleName.Value.strip()
+ data["url"] = [url.strip() for url in self.webModuleUrl.Value.split(",") if url.strip()]
+ data["windowTitle"] = self.webModuleWindowTitle.Value.strip()
+
+ @guarded
def onOk(self, evt):
- name = self.webModuleName.Value.strip()
+ self.updateData()
+ data = self.getData()
+ name = data["name"]
if len(name) < 1:
gui.messageBox(
_("You must enter a name for this web module"),
@@ -253,10 +273,11 @@ def onOk(self, evt):
self.webModuleName.SetFocus()
return
- url = [url.strip() for url in self.webModuleUrl.Value.split(",") if url.strip()]
- windowTitle = self.webModuleWindowTitle.Value.strip()
+ subModule: bool = data.get("subModule", False)
+ url = data["url"]
+ windowTitle = data["windowTitle"]
help = self.help.Value.strip()
- if not (url or windowTitle):
+ if not (url or windowTitle or subModule):
gui.messageBox(
_("You must specify at least a URL or a window title."),
_("Error"),
@@ -283,7 +304,7 @@ def onOk(self, evt):
if not save(webModule, prompt=self.Title):
return
-
+ context["webModule"] = webModule
self.DestroyLater()
self.SetReturnCode(wx.ID_OK)
diff --git a/addon/globalPlugins/webAccess/gui/webModulesManager.py b/addon/globalPlugins/webAccess/gui/webModule/manager.py
similarity index 79%
rename from addon/globalPlugins/webAccess/gui/webModulesManager.py
rename to addon/globalPlugins/webAccess/gui/webModule/manager.py
index 011fc130..70817063 100644
--- a/addon/globalPlugins/webAccess/gui/webModulesManager.py
+++ b/addon/globalPlugins/webAccess/gui/webModule/manager.py
@@ -1,4 +1,4 @@
-# globalPlugins/webAccess/gui/webModulesManager.py
+# globalPlugins/webAccess/gui/webModule/manager.py
# -*- coding: utf-8 -*-
# This file is part of Web Access for NVDA.
@@ -27,64 +27,16 @@
)
-import os
import wx
import addonHandler
addonHandler.initTranslation()
-import config
-import core
-import globalVars
import gui
from gui import guiHelper
-import languageHandler
from logHandler import log
-from ..utils import guarded
-from . import ContextualDialog, ListCtrlAutoWidth, showContextualDialog
-
-
-def promptDelete(webModule):
- msg = (
- # Translators: Prompt before deleting a web module.
- _("Do you really want to delete this web module?")
- + os.linesep
- + str(webModule.name)
- )
- if config.conf["webAccess"]["devMode"]:
- msg += " ({})".format("/".join((layer.name for layer in webModule.layers)))
- return gui.messageBox(
- parent=gui.mainFrame,
- message=msg,
- style=wx.YES_NO | wx.ICON_WARNING
- ) == wx.YES
-
-
-def promptMask(webModule):
- ref = webModule.getLayer("addon", raiseIfMissing=True).storeRef
- if ref[0] != "addons":
- raise ValueError("ref={!r}".format(ref))
- addonName = ref[1]
- for addon in addonHandler.getRunningAddons():
- if addon.name == addonName:
- addonSummary = addon.manifest["summary"]
- break
- else:
- raise LookupError("addonName={!r}".format(addonName))
- log.info("Proposing to mask {!r} from addon {!r}".format(webModule, addonName))
- msg = _(
- """This web module comes with the add-on {addonSummary}.
-It cannot be modified at its current location.
-
-Do you want to make a copy in your scratchpad?
-"""
- ).format(addonSummary=addonSummary)
- return gui.messageBox(
- parent=gui.mainFrame,
- message=msg,
- caption=_("Warning"),
- style=wx.ICON_WARNING | wx.YES | wx.NO
- ) == wx.YES
+from ...utils import guarded
+from .. import ContextualDialog, ListCtrlAutoWidth, showContextualDialog
class Dialog(ContextualDialog):
@@ -181,24 +133,42 @@ def __init__(self, parent):
flag=wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT,
border=scale(guiHelper.BORDER_FOR_DIALOGS),
)
+ self.Bind(wx.EVT_CHAR_HOOK, self.onCharHook)
self.SetSize(scale(790, 400))
self.SetSizer(mainSizer)
self.CentreOnScreen()
self.modulesList.SetFocus()
- def __del__(self):
- Dialog._instance = None
-
def initData(self, context):
super().initData(context)
module = context["webModule"] if "webModule" in context else None
self.refreshModulesList(selectItem=module)
+ @guarded
+ def onCharHook(self, evt):
+ keycode = evt.GetKeyCode()
+ if keycode == wx.WXK_ESCAPE:
+ # Try to limit the difficulty of closing the dialog using the keyboard
+ # in the event of an error later in this function
+ evt.Skip()
+ return
+ elif keycode == wx.WXK_DELETE:
+ self.onModuleDelete(None)
+ return
+ elif keycode == wx.WXK_F2:
+ self.onModuleEdit(None)
+ return
+ elif keycode == wx.WXK_F3:
+ self.onRulesManager(None)
+ return
+ evt.Skip()
+
+
@guarded
def onModuleCreate(self, evt=None):
context = self.context.copy()
context["new"] = True
- from .webModuleEditor import show
+ from .editor import show
if show(context, self):
self.refreshModulesList(selectItem=context["webModule"])
@@ -206,10 +176,11 @@ def onModuleCreate(self, evt=None):
def onModuleDelete(self, evt=None):
index = self.modulesList.GetFirstSelected()
if index < 0:
+ wx.Bell()
return
webModule = self.modules[index]
- from .. import webModuleHandler
- if webModuleHandler.delete(webModule=webModule):
+ from ...webModuleHandler import delete
+ if delete(webModule=webModule):
self.refreshModulesList()
@guarded
@@ -221,7 +192,7 @@ def onModuleEdit(self, evt=None):
context = self.context
context.pop("new", None)
context["webModule"] = self.modules[index]
- from .webModuleEditor import show
+ from .editor import show
if show(context, self):
self.refreshModulesList(selectIndex=index)
@@ -240,7 +211,7 @@ def onRulesManager(self, evt=None):
if not webModule.equals(context.get("webModule")):
context["webModule"] = webModule
context.pop("result", None)
- from .rule.manager import show
+ from ..rule.manager import show
show(context, self)
def refreshButtons(self):
@@ -259,8 +230,8 @@ def refreshModulesList(self, selectIndex: int = None, selectItem: "WebModule" =
for module in list(reversed(contextModule.ruleManager.subModules.all())) + [contextModule]
} if contextModule else {}
modules = self.modules = []
- from .. import webModuleHandler
- for index, module in enumerate(webModuleHandler.getWebModules()):
+ from ...webModuleHandler import getWebModules
+ for index, module in enumerate(getWebModules()):
if selectIndex is None and module.equals(selectItem):
selectIndex = index
module = contextModules.get((module.name, module.layers[0].storeRef), module)
diff --git a/addon/globalPlugins/webAccess/webModuleHandler/__init__.py b/addon/globalPlugins/webAccess/webModuleHandler/__init__.py
index ce709d6d..a7a90d60 100644
--- a/addon/globalPlugins/webAccess/webModuleHandler/__init__.py
+++ b/addon/globalPlugins/webAccess/webModuleHandler/__init__.py
@@ -56,7 +56,7 @@
def delete(webModule, prompt=True):
if prompt:
- from ..gui.webModulesManager import promptDelete
+ from ..gui.webModule import promptDelete
if not promptDelete(webModule):
return False
store.delete(webModule)
@@ -227,8 +227,8 @@ def save(webModule, layerName=None, prompt=True, force=False, fromRuleEditor=Fal
except DuplicateRefError as e:
if not prompt or force:
return False
- from ..gui import webModuleEditor
- if webModuleEditor.promptOverwrite():
+ from ..gui.webModule.editor import promptOverwrite
+ if promptOverwrite():
return save(webModule, layerName=layerName, prompt=prompt, force=True)
return False
except MalformedRefError:
@@ -347,7 +347,7 @@ def _getEditableScratchpadWebModule(webModule, layerName=None, prompt=True):
if layerName != "addon":
return None
if prompt:
- from ..gui.webModulesManager import promptMask
+ from ..gui.webModule import promptMask
if not promptMask(webModule):
return False
data = webModule.dump(layerName).data