Update clipboard plugin to new pluggy format.

This commit is contained in:
Storm Dragon 2025-04-04 17:08:18 -04:00
parent 1b4c4916e3
commit 8a79725df8
5 changed files with 170 additions and 109 deletions

View File

@ -1,6 +0,0 @@
[Plugin]
Module=Clipboard
Loader=python3
Name=Clipboard
Description=Present the content of the current clipboard
Authors=Chrys chrys@linux-a11y.org

View File

@ -1,101 +0,0 @@
#!/usr/bin/env python3
#
# 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
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
# Boston MA 02110-1301 USA.
#
# Fork of Orca Screen Reader (GNOME)
# Original source: https://gitlab.gnome.org/GNOME/orca
from cthulhu import plugin
import gi, os
gi.require_version('Peas', '1.0')
from gi.repository import GObject
from gi.repository import Peas
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk
class Clipboard(GObject.Object, Peas.Activatable, plugin.Plugin):
#__gtype_name__ = 'Clipboard'
object = GObject.Property(type=GObject.Object)
def __init__(self):
plugin.Plugin.__init__(self)
def do_activate(self):
API = self.object
self.registerGestureByString(self.speakClipboard, _('clipboard'), 'kb:cthulhu+c')
def do_deactivate(self):
API = self.object
def do_update_state(self):
API = self.object
def speakClipboard(self, script=None, inputEvent=None):
API = self.object
Message = self.getClipboard()
API.app.getDynamicApiManager().getAPI('CthulhuState').activeScript.presentMessage(Message, resetStyles=False)
return True
def getClipboard(self):
Message = ""
FoundClipboardContent = False
# Get Clipboard
ClipboardObj = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
ClipboardText = ClipboardObj.wait_for_text()
ClipboardImage = ClipboardObj.wait_for_image()
ClipboardURI = ClipboardObj.wait_for_uris()
if (ClipboardText != None):
FoundClipboardContent = True
if (ClipboardObj.wait_is_uris_available()):
noOfObjects = 0
noOfFolder = 0
noOfFiles = 0
noOfDisks = 0
noOfLinks = 0
for Uri in ClipboardURI:
if Uri == '':
continue
noOfObjects += 1
uriWithoutProtocoll = Uri[Uri.find('://') + 3:]
Message += " " + Uri[Uri.rfind('/') + 1:] + " "
if (os.path.isdir(uriWithoutProtocoll)):
noOfFolder += 1
Message = Message + _("Folder") #Folder
if (os.path.isfile(uriWithoutProtocoll)):
noOfFiles += 1
Message = Message + _("File") #File
if (os.path.ismount(uriWithoutProtocoll)):
noOfDisks += 1
Message = Message + _("Disk") #Mountpoint
if (os.path.islink(uriWithoutProtocoll)):
noOfLinks += 1
Message = Message + _("Link") #Link
if (noOfObjects > 1):
Message = str(noOfObjects) + _(" Objects in clipboard ") + Message # X Objects in Clipboard Object Object
else:
Message = str(noOfObjects) + _(" Object in clipboard ") + Message # 1 Object in Clipboard Object
else:
Message = _("Text in clipboard ") + ClipboardText # Text in Clipboard
if (ClipboardImage != None):
FoundClipboardContent = True
Message = _("The clipboard contains a image") # Image is in Clipboard
if (not FoundClipboardContent):
Message = _("The clipboard is empty")
return Message

View File

@ -1,7 +1,7 @@
cthulhu_python_PYTHON = \ cthulhu_python_PYTHON = \
__init__.py \ __init__.py \
Clipboard.plugin \ plugin.info \
Clipboard.py plugin.py
cthulhu_pythondir=$(pkgpythondir)/plugins/Clipboard cthulhu_pythondir=$(pkgpythondir)/plugins/Clipboard

View File

@ -0,0 +1,7 @@
[Plugin]
Name = Clipboard
Module = Clipboard
Description = Present the content of the current clipboard
Authors = Storm Dragon <storm_dragon@stormux.org>
Version = 1.0
Category = Utilities

View File

@ -0,0 +1,161 @@
#!/usr/bin/env python3
#
# 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
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
# Boston MA 02110-1301 USA.
#
"""Clipboard plugin for Cthulhu."""
import os
import logging
import gettext
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk
from cthulhu.plugin import Plugin, cthulhu_hookimpl
# Set up translation function
_ = gettext.gettext
logger = logging.getLogger(__name__)
class Clipboard(Plugin):
"""Plugin to read the clipboard contents."""
def __init__(self, *args, **kwargs):
"""Initialize the plugin."""
super().__init__(*args, **kwargs)
logger.info("Clipboard plugin initialized")
self._signal_handler_id = None
@cthulhu_hookimpl
def activate(self, plugin=None):
"""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
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
self.unregisterGestureByString('kb:cthulhu+shift+c')
logger.debug("Unregistered clipboard shortcut")
except Exception as e:
logger.error(f"Error deactivating Clipboard plugin: {e}")
def speakClipboard(self, script=None, inputEvent=None):
"""Present the contents of the clipboard."""
try:
message = self.getClipboard()
state = self.app.getDynamicApiManager().getAPI('CthulhuState')
if state and state.activeScript:
state.activeScript.presentMessage(message, resetStyles=False)
logger.debug("Presented clipboard contents")
else:
logger.warning("Could not present clipboard: no active script")
return True
except Exception as e:
logger.error(f"Error in speakClipboard: {e}")
return False
def getClipboard(self):
"""Get the contents of the clipboard."""
try:
message = ""
found_clipboard_content = False
# Get Clipboard
clipboard_obj = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
clipboard_text = clipboard_obj.wait_for_text()
clipboard_image = clipboard_obj.wait_for_image()
clipboard_uri = clipboard_obj.wait_for_uris()
if clipboard_text is not None:
found_clipboard_content = True
if clipboard_obj.wait_is_uris_available():
no_of_objects = 0
no_of_folder = 0
no_of_files = 0
no_of_disks = 0
no_of_links = 0
for uri in clipboard_uri:
if uri == '':
continue
no_of_objects += 1
uri_without_protocol = uri[uri.find('://') + 3:]
message += " " + uri[uri.rfind('/') + 1:] + " "
if os.path.isdir(uri_without_protocol):
no_of_folder += 1
message = message + _("Folder")
if os.path.isfile(uri_without_protocol):
no_of_files += 1
message = message + _("File")
if os.path.ismount(uri_without_protocol):
no_of_disks += 1
message = message + _("Disk")
if os.path.islink(uri_without_protocol):
no_of_links += 1
message = message + _("Link")
if no_of_objects > 1:
message = str(no_of_objects) + _(" Objects in clipboard ") + message
else:
message = str(no_of_objects) + _(" Object in clipboard ") + message
else:
message = _("Text in clipboard ") + clipboard_text
if clipboard_image is not None:
found_clipboard_content = True
message = _("The clipboard contains a image")
if not found_clipboard_content:
message = _("The clipboard is empty")
return message
except Exception as e:
logger.error(f"Error getting clipboard content: {e}")
return _("Error accessing clipboard")