Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: 2
updates:

# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
# Workflow files stored in the default location of `.github/workflows`. (You don't need to specify `/.github/workflows` for `directory`. You can use `directory: "/"`.)
directory: "/"
schedule:
interval: "weekly"
groups:
actions-minor:
update-types:
- minor
- patch
83 changes: 83 additions & 0 deletions .github/workflows/build_addon.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: build addon

on:
push:
tags: ["*"]
# To build on main/master branch, uncomment the following line:
# branches: [ main , master ]

pull_request:
branches: [ main, master ]

workflow_dispatch:
workflow_call:

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Install dependencies
run: |
sudo apt-get update -y
sudo apt-get install -y gettext
uv sync

- name: Code checks
# pyright is skipped in CI because it needs NVDA source (../nvda/source), which is not
# checked out here; it still runs as a local hook. This matches how other addons using the
# template (e.g. the nvdaes/* addons) handle it.
run: export PREK_SKIP=no-commit-to-branch,pyright; uv run prek run --all-files

- name: building addon
run: uv run scons && uv run scons pot

- uses: actions/upload-artifact@v7
with:
name: packaged_addon
path: |
./*.nvda-addon
archive: false

- uses: actions/upload-artifact@v7
with:
name: translation_template
path: |
./*.pot
archive: false

upload_release:
runs-on: ubuntu-latest
if: ${{ startsWith(github.ref, 'refs/tags/') }}
needs: ["build"]
permissions:
contents: write
steps:
- uses: actions/checkout@v7
- name: download all artifacts
uses: actions/download-artifact@v8
with:
path: .
merge-multiple: true
- name: Display structure of downloaded files
run: ls -R
- name: Calculate sha256
run: |
echo -e "\nSHA256: " >> changelog.md
sha256sum *.nvda-addon >> changelog.md

- name: Release
uses: softprops/action-gh-release@v3
with:
files: |
*.nvda-addon
*.pot
body_path: changelog.md
fail_on_unmatched_files: true
prerelease: ${{ contains(github.ref, '-') }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ manifest.ini
*.nvda-addon
.sconsign.dblite
/[0-9]*.[0-9]*.[0-9]*.json
*.egg-info
7 changes: 0 additions & 7 deletions .pre-commit-config.yaml

This file was deleted.

1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13
13 changes: 13 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"ms-python.python",
"ms-python.vscode-pylance",
"redhat.vscode-yaml",
"charliermarsh.ruff"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": []
}
16 changes: 16 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"editor.accessibilitySupport": "on",
"python.autoComplete.extraPaths": [
"../nvda/source",
"../nvda/miscDeps/python"
],
"files.insertFinalNewline": true,
"files.trimFinalNewlines": true,
"editor.insertSpaces": false,
"python.analysis.stubPath": "${workspaceFolder}/.vscode/typings",
"python.analysis.extraPaths": [
"../nvda/source",
"../nvda/miscDeps/python"
],
"python.defaultInterpreterPath": "${workspaceFolder}/../nvda/.venv/scripts/python.exe"
}
2 changes: 2 additions & 0 deletions .vscode/typings/__builtins__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def _(msg: str) -> str: ...
def pgettext(context: str, message: str) -> str: ...
1 change: 0 additions & 1 deletion addon/doc/pt_BR/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,3 @@ Pressione NVDA+Control+w para abrir a janela de exploração virtual. Aí
simplesmente navegue na caixa de texto exibida como se faz em qualquer outro
conteúdo textual. Pode pressionar escape para fechar a janela de exploração
virtual.

1 change: 0 additions & 1 deletion addon/doc/pt_PT/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,3 @@ Pressione NVDA+control+w para abrir a janela de revisão virtual. Em seguida,
simplesmente navegue na caixa de texto mostrada como faz em qualquer outro
conteúdo de texto. Pode pressionar Escape para fechar a janela de revisão
virtual.

2 changes: 1 addition & 1 deletion addon/doc/sr/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Pritisnite NVDA+control+w da otvorite prozor virtuelnog pregleda. Nakon toga kr
* Sada je moguće pregledati sadržaj univerzalnih aplikacija (eng. Universal Windows platform(UWP)) u Windowsu 10 i većini modernih aplikacija u Windowsu 8.x.
* Kada dodatak preuzima sadržaj ekrana za moderne i univerzalne aplikacije, čućete zvučni signal kada je virtuelni prozor spreman.

## Promene u verziji 2.0##
## Promene u verziji 2.0##

* Novo ime: Virtuelni pregled.
* Zbog promena u načinu prikazivanja sadržaja, NVDA verzija 2015.2 ili novija je neophodna.
Expand Down
50 changes: 31 additions & 19 deletions addon/globalPlugins/virtualRevision.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Virtual Revision NVDA plugin
#Copyright (C) 2012-2020 Rui Batista and contributors
#Copyright (C) 2021-2023 Rui Fontes, Rui Batista and contributors
#This file is covered by the GNU General Public License.
#See the file COPYING for more details.
# Copyright (C) 2012-2020 Rui Batista and contributors
# Copyright (C) 2021-2023 Rui Fontes, Rui Batista and contributors
# This file is covered by the GNU General Public License.
# See the file COPYING for more details.

import globalPluginHandler
import globalVars
Expand All @@ -11,59 +11,70 @@
import ui
import scriptHandler
import addonHandler

addonHandler.initTranslation()

try:
from globalCommands import SCRCAT_TEXTREVIEW
except:
except ImportError:
SCRCAT_TEXTREVIEW = None


def obtainUWPWindowText():
foreground = api.getForegroundObject()
desktop = api.getDesktopObject()
uwpTextList = [foreground.name]
curObject=foreground.firstChild
curObject = foreground.firstChild
while curObject:
if curObject.name is not None: uwpTextList.append(curObject.name)
if hasattr(curObject, "UIAElement") and curObject.UIAElement and curObject.UIAElement.currentClassName == "TermControl":
if curObject.name is not None:
uwpTextList.append(curObject.name)
if (
hasattr(curObject, "UIAElement")
and curObject.UIAElement
and curObject.UIAElement.currentClassName == "TermControl"
):
info = curObject.makeTextInfo(textInfos.POSITION_FIRST)
info.expand(textInfos.UNIT_STORY)
text = info.clipboardText.rstrip()
uwpTextList.append(text)
if curObject.simpleFirstChild:
curObject=curObject.simpleFirstChild
curObject = curObject.simpleFirstChild
continue
if curObject.simpleNext:
curObject=curObject.simpleNext
curObject = curObject.simpleNext
continue
if curObject.simpleParent:
parent=curObject.simpleParent
parent = curObject.simpleParent
# As long as one is on current foreground object...
# Stay within the current top-level window.
if parent.simpleParent == desktop:
break
while parent and not parent.simpleNext:
parent=parent.simpleParent
parent = parent.simpleParent
# But sometimes, the top-level window has no sibling at all (such is the case in Windows 10 Start menu).
try:
curObject=parent.simpleNext
curObject = parent.simpleNext
except AttributeError:
continue
if hasattr(foreground, "UIAElement") and foreground.UIAElement and foreground.UIAElement.currentClassName == "TermControl":
if (
hasattr(foreground, "UIAElement")
and foreground.UIAElement
and foreground.UIAElement.currentClassName == "TermControl"
):
info = foreground.makeTextInfo(textInfos.POSITION_FIRST)
info.expand(textInfos.UNIT_STORY)
text = info.clipboardText.rstrip()
uwpTextList.append(text)
return uwpTextList

class GlobalPlugin(globalPluginHandler.GlobalPlugin):

class GlobalPlugin(globalPluginHandler.GlobalPlugin):
scriptCategory = SCRCAT_TEXTREVIEW

@scriptHandler.script(
# Translators: Message presented in input help mode.
description=_("Opens a window containing the text of the currently focused window for easy review."),
gesture="kb:nvda+control+w"
gesture="kb:nvda+control+w",
)
def script_virtualWindowReview(self, gesture):
# Find the first focus ancestor that have any display text, according to the display model
Expand All @@ -74,6 +85,7 @@ def script_virtualWindowReview(self, gesture):
# Because it may take a while to iterate through elements, play abeep to alert users of this fact and the fact it's a UWP screen.
if obj.windowClassName.startswith(("Windows.UI.Core", "Windows.UI.Input.InputSite")):
import tones

tones.beep(400, 300)
text = "\n".join(obtainUWPWindowText())
tones.beep(400, 50)
Expand All @@ -87,9 +99,9 @@ def script_virtualWindowReview(self, gesture):
info = root.makeTextInfo(textInfos.POSITION_FIRST)
# sys.maxint is gone in Python 3 as integer bit width can grow arbitrarily.
# Use the static value (0x7fffffff or (2^31)-1) directly.
info.move(textInfos.UNIT_LINE, 0x7fffffff, endPoint="end")
info.move(textInfos.UNIT_LINE, 0x7FFFFFFF, endPoint="end")
text = info.clipboardText.replace("\0", " ")
if obj.windowClassName == u'ConsoleWindowClass':
if obj.windowClassName == "ConsoleWindowClass":
info = obj.makeTextInfo(textInfos.POSITION_FIRST)
info.expand(textInfos.UNIT_STORY)
text = info.clipboardText.rstrip()
Expand All @@ -99,7 +111,7 @@ def script_virtualWindowReview(self, gesture):
# Translators: The title of the virtual review window when the foreground window has no name, commonly seen when all windows are minimized.
name = _("No title")
# Translators: Title of the window shown for reading text on screen via a window.
ui.browseableMessage(text, title=_("Virtual review: {screenName}").format(screenName = name))
ui.browseableMessage(text, title=_("Virtual review: {screenName}").format(screenName=name))
else:
# Translator: Message shown when no text can be virtualized.
ui.message(_("No text to display"))
Expand Down
12 changes: 6 additions & 6 deletions buildVars.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,22 @@
# Translators: Long description to be shown for this add-on on add-on information from add-on store
addon_description = _("""Provides a simple reviewable dialog of the text of the currently focused window."""),
# version
addon_version = "2026.05.14",
addon_version = "2026.07.29",
# Brief changelog for this version
# Translators: what's new content for the add-on version to be shown in the add-on store
addon_changelog = _("""Set compatibility with NVDA 2026.1."""),
addon_changelog = _("""Set compatibility with NVDA 2026.2."""),
# Author(s)
addon_author = "Rui Fontes <rui.fontes@tiflotecnia.com>, Rui Batista <ruiandrebatista@gmail.com> and NVDA Addon Team",
# URL for the add-on documentation support
addon_url = "https://github.com/ruifontes/virtualReview",
addon_url = "https://github.com/ragb/virtualReview",
# URL for the add-on repository where the source code can be found
addon_sourceURL = "https://github.com/ruifontes/virtualReview",
addon_sourceURL = "https://github.com/ragb/virtualReview",
# Documentation file name
addon_docFileName="readme.html",
# Minimum NVDA version supported (e.g. "2019.3.0", minor version is optional)
addon_minimumNVDAVersion = "2019.3",
# Last NVDA version supported/tested (e.g. "2024.4.0", ideally more recent than minimum version)
addon_lastTestedNVDAVersion = "2026.1",
addon_lastTestedNVDAVersion = "2026.2",
# Add-on update channel (default is None, denoting stable releases,
# and for development releases, use "dev".)
# Do not change unless you know what you are doing!
Expand All @@ -57,7 +57,7 @@
# pythonSources = ["addon/globalPlugins/*.py"]
# For more information on SCons Glob expressions please take a look at:
# https://scons.org/doc/production/HTML/scons-user/apd.html
pythonSources: list[str] = ["addon/globalPlugins/virtualRevision.py",]
pythonSources: list[str] = ["addon/globalPlugins/virtualRevision.py"]

# Files that contain strings for translation. Usually your python sources
i18nSources: list[str] = pythonSources + ["buildVars.py"]
Expand Down
Loading