Try to fix clipboard and simple plugins.
This commit is contained in:
parent
48575ab6cd
commit
02be96aa69
@ -20,6 +20,8 @@
|
|||||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||||
# Boston MA 02110-1301 USA.
|
# Boston MA 02110-1301 USA.
|
||||||
#
|
#
|
||||||
|
# Fork of Orca Screen Reader (GNOME)
|
||||||
|
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||||
|
|
||||||
"""Clipboard plugin for Cthulhu."""
|
"""Clipboard plugin for Cthulhu."""
|
||||||
|
|
||||||
@ -62,6 +64,36 @@ class Clipboard(Plugin):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error activating Clipboard plugin: {e}")
|
logger.error(f"Error activating Clipboard plugin: {e}")
|
||||||
|
|
||||||
|
@cthulhu_hookimpl
|
||||||
|
def deactivate(self, plugin=None):
|
||||||
|
"""Deactivate the plugin."""
|
||||||
|
# Skip if this deactivation call isn't for us
|
||||||
|
if plugin is not None and plugin is not self:
|
||||||
|
return
|
||||||
|
|
||||||
|
logger.info("Deactivating Clipboard plugin")
|
||||||
|
try:
|
||||||
|
# Unregister keyboard shortcut
|
||||||
|
if self.app:
|
||||||
|
api_helper = self.app.getAPIHelper()
|
||||||
|
if api_helper and hasattr(api_helper, 'unregisterShortcut'):
|
||||||
|
api_helper.unregisterShortcut('kb:cthulhu+shift+c')
|
||||||
|
logger.debug("Unregistered clipboard shortcut")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error deactivating Clipboard plugin: {e}")
|
||||||
|
"""Activate the plugin."""
|
||||||
|
# Skip if this activation call isn't for us
|
||||||
|
if plugin is not None and plugin is not self:
|
||||||
|
return
|
||||||
|
|
||||||
|
logger.info("Activating Clipboard plugin")
|
||||||
|
try:
|
||||||
|
# Register keyboard shortcut
|
||||||
|
self.registerGestureByString(self.speakClipboard, _('clipboard'), 'kb:cthulhu+shift+c')
|
||||||
|
logger.debug("Registered shortcut for clipboard")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error activating Clipboard plugin: {e}")
|
||||||
|
|
||||||
@cthulhu_hookimpl
|
@cthulhu_hookimpl
|
||||||
def deactivate(self, plugin=None):
|
def deactivate(self, plugin=None):
|
||||||
"""Deactivate the plugin."""
|
"""Deactivate the plugin."""
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
#
|
#
|
||||||
# Copyright (c) 2024 Stormux
|
# Copyright (c) 2024 Stormux
|
||||||
# Copyright (c) 2010-2012 The Orca Team
|
|
||||||
# Copyright (c) 2012 Igalia, S.L.
|
|
||||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
|
||||||
#
|
#
|
||||||
# This library is free software; you can redistribute it and/or
|
# This library is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU Lesser General Public
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
@ -20,8 +17,6 @@
|
|||||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||||
# Boston MA 02110-1301 USA.
|
# Boston MA 02110-1301 USA.
|
||||||
#
|
#
|
||||||
# Fork of Orca Screen Reader (GNOME)
|
|
||||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
|
||||||
|
|
||||||
"""Simple Plugin System for Cthulhu."""
|
"""Simple Plugin System for Cthulhu."""
|
||||||
|
|
||||||
@ -57,11 +52,11 @@ def outputMessage(Message):
|
|||||||
|
|
||||||
class SimplePluginSystem(Plugin):
|
class SimplePluginSystem(Plugin):
|
||||||
"""Simple plugin system implementation for Cthulhu.
|
"""Simple plugin system implementation for Cthulhu.
|
||||||
|
|
||||||
This plugin allows loading and managing simple script-based plugins
|
This plugin allows loading and managing simple script-based plugins
|
||||||
from a designated directory.
|
from a designated directory.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"""Initialize the plugin system."""
|
"""Initialize the plugin system."""
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
@ -77,22 +72,22 @@ class SimplePluginSystem(Plugin):
|
|||||||
# Skip if this activation call isn't for us
|
# Skip if this activation call isn't for us
|
||||||
if plugin is not None and plugin is not self:
|
if plugin is not None and plugin is not self:
|
||||||
return
|
return
|
||||||
|
|
||||||
logger.info("Activating SimplePluginSystem plugin")
|
logger.info("Activating SimplePluginSystem plugin")
|
||||||
try:
|
try:
|
||||||
global settings
|
global settings
|
||||||
global speech
|
global speech
|
||||||
global braille
|
global braille
|
||||||
global input_event
|
global input_event
|
||||||
|
|
||||||
settings = self.app.getDynamicApiManager().getAPI('Settings')
|
settings = self.app.getDynamicApiManager().getAPI('Settings')
|
||||||
speech = self.app.getDynamicApiManager().getAPI('Speech')
|
speech = self.app.getDynamicApiManager().getAPI('Speech')
|
||||||
braille = self.app.getDynamicApiManager().getAPI('Braille')
|
braille = self.app.getDynamicApiManager().getAPI('Braille')
|
||||||
input_event = self.app.getDynamicApiManager().getAPI('InputEvent')
|
input_event = self.app.getDynamicApiManager().getAPI('InputEvent')
|
||||||
|
|
||||||
if not self.loaded:
|
if not self.loaded:
|
||||||
self.load_plugins()
|
self.load_plugins()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error activating SimplePluginSystem plugin: {e}")
|
logger.error(f"Error activating SimplePluginSystem plugin: {e}")
|
||||||
|
|
||||||
@ -102,7 +97,7 @@ class SimplePluginSystem(Plugin):
|
|||||||
# Skip if this deactivation call isn't for us
|
# Skip if this deactivation call isn't for us
|
||||||
if plugin is not None and plugin is not self:
|
if plugin is not None and plugin is not self:
|
||||||
return
|
return
|
||||||
|
|
||||||
logger.info("Deactivating SimplePluginSystem plugin")
|
logger.info("Deactivating SimplePluginSystem plugin")
|
||||||
try:
|
try:
|
||||||
# Remove all registered keybindings
|
# Remove all registered keybindings
|
||||||
@ -144,7 +139,7 @@ class SimplePluginSystem(Plugin):
|
|||||||
# If translation fails, use the original name
|
# If translation fails, use the original name
|
||||||
plugin_name = currPluginSetting['pluginname']
|
plugin_name = currPluginSetting['pluginname']
|
||||||
logger.warning(f"Translation failed for plugin: {currPluginSetting['pluginname']}")
|
logger.warning(f"Translation failed for plugin: {currPluginSetting['pluginname']}")
|
||||||
|
|
||||||
self.registerGestureByString(currPluginSetting['function'], plugin_name, shortcut)
|
self.registerGestureByString(currPluginSetting['function'], plugin_name, shortcut)
|
||||||
return currPluginSetting
|
return currPluginSetting
|
||||||
|
|
||||||
@ -254,7 +249,7 @@ class SimplePluginSystem(Plugin):
|
|||||||
currPluginSetting['loadmodule'] = ('sopsproperty:loadmodule' in line.lower().replace(" ", "")) or currPluginSetting['loadmodule']
|
currPluginSetting['loadmodule'] = ('sopsproperty:loadmodule' in line.lower().replace(" ", "")) or currPluginSetting['loadmodule']
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error reading plugin file: {e}")
|
logger.error(f"Error reading plugin file: {e}")
|
||||||
|
|
||||||
return currPluginSetting
|
return currPluginSetting
|
||||||
|
|
||||||
def buildPluginSubprocess(self, currPluginSetting):
|
def buildPluginSubprocess(self, currPluginSetting):
|
||||||
@ -317,75 +312,95 @@ class SimplePluginSystem(Plugin):
|
|||||||
|
|
||||||
def registerGestureByString(self, function, description, shortcut):
|
def registerGestureByString(self, function, description, shortcut):
|
||||||
"""Register a keyboard shortcut for a function.
|
"""Register a keyboard shortcut for a function.
|
||||||
|
|
||||||
This is a compatibility wrapper for the new plugin system.
|
This is a compatibility wrapper for the new plugin system.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# Try to get the InputEventManager and register the shortcut
|
if self.app:
|
||||||
input_manager = self.app.getDynamicApiManager().getAPI('InputEventManager')
|
api_helper = self.app.getAPIHelper()
|
||||||
if input_manager:
|
if api_helper:
|
||||||
input_manager.registerGestureByString(function, description, shortcut)
|
api_helper.registerGestureByString(
|
||||||
logger.debug(f"Registered shortcut {shortcut} for {description}")
|
function,
|
||||||
|
description,
|
||||||
|
shortcut,
|
||||||
|
'default',
|
||||||
|
'cthulhu',
|
||||||
|
True,
|
||||||
|
contextName=self.module_name
|
||||||
|
)
|
||||||
|
logger.debug(f"Registered shortcut {shortcut} for {description}")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.error("Could not get APIHelper")
|
||||||
else:
|
else:
|
||||||
logger.error("Could not get InputEventManager API")
|
logger.error("No app reference available")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error registering shortcut {shortcut}: {e}")
|
logger.error(f"Error registering shortcut {shortcut}: {e}")
|
||||||
|
|
||||||
def unregisterShortcut(self, function, shortcut):
|
def unregisterShortcut(self, function, shortcut):
|
||||||
"""Unregister a keyboard shortcut for a function.
|
"""Unregister a keyboard shortcut for a function.
|
||||||
|
|
||||||
This is a compatibility wrapper for the new plugin system.
|
This is a compatibility wrapper for the new plugin system.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# Try to get the InputEventManager and unregister the shortcut
|
if self.app:
|
||||||
input_manager = self.app.getDynamicApiManager().getAPI('InputEventManager')
|
api_helper = self.app.getAPIHelper()
|
||||||
if input_manager:
|
if api_helper and hasattr(api_helper, 'unregisterShortcut'):
|
||||||
input_manager.unregisterGestureByString(shortcut)
|
api_helper.unregisterShortcut(shortcut)
|
||||||
logger.debug(f"Unregistered shortcut {shortcut}")
|
logger.debug(f"Unregistered shortcut {shortcut}")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.error("Could not get APIHelper or unregisterShortcut method")
|
||||||
else:
|
else:
|
||||||
logger.error("Could not get InputEventManager API")
|
logger.error("No app reference available")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error unregistering shortcut {shortcut}: {e}")
|
logger.error(f"Error unregistering shortcut {shortcut}: {e}")
|
||||||
|
|
||||||
def load_plugins(self):
|
def load_plugins(self):
|
||||||
"""Load and setup all plugins in the plugin repository."""
|
"""Load and setup all plugins in the plugin repository."""
|
||||||
if not self.loaded:
|
if not self.loaded:
|
||||||
try:
|
try:
|
||||||
logger.info(f"Loading plugins from {self.plugin_repo}")
|
logger.info(f"Loading plugins from {self.plugin_repo}")
|
||||||
self.plugin_list = glob.glob(self.plugin_repo + '*')
|
plugin_files = glob.glob(self.plugin_repo + '*')
|
||||||
|
self.plugin_list = [] # Reset the plugin list to avoid confusion
|
||||||
for currplugin in self.plugin_list:
|
|
||||||
|
for currplugin in plugin_files:
|
||||||
try:
|
try:
|
||||||
|
# Ensure currplugin is a valid path string
|
||||||
|
if not isinstance(currplugin, (str, bytes, os.PathLike)):
|
||||||
|
logger.error(f"Invalid plugin path: {type(currplugin)}")
|
||||||
|
continue
|
||||||
|
|
||||||
currPluginSetting = self.initSettings()
|
currPluginSetting = self.initSettings()
|
||||||
currPluginSetting = self.getPluginSettings(currplugin, currPluginSetting)
|
currPluginSetting = self.getPluginSettings(currplugin, currPluginSetting)
|
||||||
|
|
||||||
if not currPluginSetting['valid']:
|
if not currPluginSetting['valid']:
|
||||||
logger.debug(f"Skipping invalid plugin: {currplugin}")
|
logger.debug(f"Skipping invalid plugin: {currplugin}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
currPluginSetting = self.getFunctionName(currPluginSetting)
|
currPluginSetting = self.getFunctionName(currPluginSetting)
|
||||||
|
|
||||||
if currPluginSetting['loadmodule']:
|
if currPluginSetting['loadmodule']:
|
||||||
exec(self.buildPluginExec(currPluginSetting)) # load as python module
|
exec(self.buildPluginExec(currPluginSetting)) # load as python module
|
||||||
else:
|
else:
|
||||||
exec(self.buildPluginSubprocess(currPluginSetting)) # run as subprocess
|
exec(self.buildPluginSubprocess(currPluginSetting)) # run as subprocess
|
||||||
|
|
||||||
if currPluginSetting['blockcall']:
|
if currPluginSetting['blockcall']:
|
||||||
currPluginSetting['function'] = globals()[currPluginSetting['functionname']] # non threaded
|
currPluginSetting['function'] = globals()[currPluginSetting['functionname']] # non threaded
|
||||||
else:
|
else:
|
||||||
currPluginSetting['function'] = globals()[currPluginSetting['functionname'] + "T"] # T = Threaded
|
currPluginSetting['function'] = globals()[currPluginSetting['functionname'] + "T"] # T = Threaded
|
||||||
|
|
||||||
if currPluginSetting['exec']: # exec on load if we want
|
if currPluginSetting['exec']: # exec on load if we want
|
||||||
currPluginSetting['function']()
|
currPluginSetting['function']()
|
||||||
|
|
||||||
if not currPluginSetting['key'] == '':
|
if not currPluginSetting['key'] == '':
|
||||||
currPluginSetting = self.SetupShortcutAndHandle(currPluginSetting)
|
currPluginSetting = self.SetupShortcutAndHandle(currPluginSetting)
|
||||||
|
|
||||||
logger.debug(f"Loaded plugin: {currPluginSetting['pluginname']}")
|
logger.debug(f"Loaded plugin: {currPluginSetting['pluginname']}")
|
||||||
self.plugin_list.append(currPluginSetting) # store in a list
|
self.plugin_list.append(currPluginSetting) # store in a list
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error loading plugin {currplugin}: {e}")
|
logger.error(f"Error loading plugin {currplugin}: {e}")
|
||||||
|
|
||||||
self.loaded = True
|
self.loaded = True
|
||||||
logger.info(f"Loaded {len(self.plugin_list)} plugins")
|
logger.info(f"Loaded {len(self.plugin_list)} plugins")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user