diff --git a/src/cthulhu/plugins/Clipboard/Clipboard.plugin b/src/cthulhu/plugins/Clipboard/Clipboard.plugin deleted file mode 100644 index 72fb0a3..0000000 --- a/src/cthulhu/plugins/Clipboard/Clipboard.plugin +++ /dev/null @@ -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 diff --git a/src/cthulhu/plugins/Clipboard/Clipboard.py b/src/cthulhu/plugins/Clipboard/Clipboard.py deleted file mode 100644 index 08b7572..0000000 --- a/src/cthulhu/plugins/Clipboard/Clipboard.py +++ /dev/null @@ -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 diff --git a/src/cthulhu/plugins/Clipboard/Makefile.am b/src/cthulhu/plugins/Clipboard/Makefile.am index 55115d9..3d3f13c 100644 --- a/src/cthulhu/plugins/Clipboard/Makefile.am +++ b/src/cthulhu/plugins/Clipboard/Makefile.am @@ -1,7 +1,7 @@ cthulhu_python_PYTHON = \ __init__.py \ - Clipboard.plugin \ - Clipboard.py + plugin.info \ + plugin.py cthulhu_pythondir=$(pkgpythondir)/plugins/Clipboard diff --git a/src/cthulhu/plugins/Clipboard/plugin.info b/src/cthulhu/plugins/Clipboard/plugin.info new file mode 100644 index 0000000..0e15232 --- /dev/null +++ b/src/cthulhu/plugins/Clipboard/plugin.info @@ -0,0 +1,7 @@ +[Plugin] +Name = Clipboard +Module = Clipboard +Description = Present the content of the current clipboard +Authors = Storm Dragon +Version = 1.0 +Category = Utilities diff --git a/src/cthulhu/plugins/Clipboard/plugin.py b/src/cthulhu/plugins/Clipboard/plugin.py new file mode 100644 index 0000000..e21e6ae --- /dev/null +++ b/src/cthulhu/plugins/Clipboard/plugin.py @@ -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")