Skip to content

Commit

Permalink
SubModules: GUI: Editor: Prompt for creation of a missing SubModule
Browse files Browse the repository at this point in the history
 - WebModule Editor: Do not require a trigger when creating from the Rule Editor
 - WebModule Manager: Add key shortcuts `F2`, `F3` and `delete` to edit, manage rules and delete, respectively (#38)
 - WebModule Manager: Set "no" as the default when prompting for deletion
 - Refactor `gui.actions` into `gui.rule.actions`
 - Refactor `gui.criteriaEditor` into `gui.rule.criteriaEditor`
 - Refactor `gui.gestureBinding` into `gui.rule.gestureBinding`
 - Refactor `gui.properties` into `gui.rule.properties`
 - Refactor `gui.webModulesManager` into `gui.webModule.manager`
 - Refactor `gui.webModuleEditor` into `gui.webModule.editor`
 - Refactor `gui.webModuleManager.promptDelete` into `gui.webModule.promptDelete`
 - GUI: Refactor `gui.webModuleManager.promptMask` into `gui.webModule.promptMask`
  • Loading branch information
JulienCochuyt committed Sep 1, 2024
1 parent 254b901 commit 45152e8
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 639 deletions.
19 changes: 9 additions & 10 deletions addon/globalPlugins/webAccess/gui/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"""Web Access GUI."""


__version__ = "2024.08.26"
__version__ = "2024.08.30"
__authors__ = (
"Julien Cochuyt <[email protected]>",
"André-Abush Clause <[email protected]>",
Expand All @@ -39,7 +39,6 @@
from ... import webAccess
from .. import ruleHandler
from ..utils import guarded
from . import webModulesManager


addonHandler.initTranslation()
Expand Down Expand Up @@ -151,21 +150,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
Expand Down
84 changes: 84 additions & 0 deletions addon/globalPlugins/webAccess/gui/rule/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# 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 <http://www.gnu.org/licenses/>.
#
# See the file COPYING.txt at the root of this distribution for more details.


__version__ = "2024.08.30"
__author__ = "Julien Cochuyt <[email protected]>"


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
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -20,7 +20,7 @@
# See the file COPYING.txt at the root of this distribution for more details.


__version__ = "2024.08.25"
__version__ = "2024.08.30"
__authors__ = (
"Shirley Noel <[email protected]>",
"Julien Cochuyt <[email protected]>",
Expand All @@ -39,10 +39,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()
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -21,7 +21,7 @@



__version__ = "2024.08.29"
__version__ = "2024.08.30"
__authors__ = (
"Shirley Noël <[email protected]>",
"Julien Cochuyt <[email protected]>",
Expand All @@ -47,9 +47,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,
Expand All @@ -60,8 +60,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


Expand Down Expand Up @@ -237,7 +238,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()
Expand All @@ -255,7 +256,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):
Expand Down Expand Up @@ -1015,6 +1018,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()
Expand All @@ -1026,8 +1034,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)
24 changes: 13 additions & 11 deletions addon/globalPlugins/webAccess/gui/rule/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
# See the file COPYING.txt at the root of this distribution for more details.


__version__ = "2024.08.25"
__version__ = "2024.08.30"
__authors__ = (
"Julien Cochuyt <[email protected]>",
"Shirley Noël <[email protected]>",
Expand Down Expand Up @@ -63,22 +63,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()
Expand Down Expand Up @@ -920,9 +919,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
Expand All @@ -933,14 +932,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):
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -20,7 +20,7 @@
# See the file COPYING.txt at the root of this distribution for more details.


__version__ = "2024.08.25"
__version__ = "2024.08.30"
__authors__ = (
"Shirley Noel <[email protected]>",
"Frédéric Brugnot <[email protected]>",
Expand All @@ -42,8 +42,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()
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -19,9 +19,10 @@
#
# See the file COPYING.txt at the root of this distribution for more details.

__version__ = "2024.08.29"
__version__ = "2024.08.30"
__author__ = "Sendhil Randon <[email protected]>"


from collections import ChainMap
from collections.abc import Iterator, Mapping
from abc import abstractmethod
Expand All @@ -35,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()
Expand Down Expand Up @@ -144,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}")
Expand Down
Loading

0 comments on commit 45152e8

Please sign in to comment.