[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [calligra/krita-scripting-rempt] krita/plugins/extensions/pykrita/src/krita: Add more of the initial
From: Boudewijn Rempt <boud () valdyas ! org>
Date: 2014-07-29 14:03:44
Message-ID: E1XC80G-0003UD-C1 () scm ! kde ! org
[Download RAW message or body]
Git commit 3ea3219259e62887f664d568e69b87a8d9834abf by Boudewijn Rempt.
Committed on 29/07/2014 at 12:57.
Pushed by rempt into branch 'krita-scripting-rempt'.
Add more of the initializer stuff from pate
M +3 -6 krita/plugins/extensions/pykrita/src/krita/__init__.py
A +49 -0 krita/plugins/extensions/pykrita/src/krita/api.py
A +142 -0 krita/plugins/extensions/pykrita/src/krita/configuration.py
A +108 -0 krita/plugins/extensions/pykrita/src/krita/decorators.py
http://commits.kde.org/calligra/3ea3219259e62887f664d568e69b87a8d9834abf
diff --git a/krita/plugins/extensions/pykrita/src/krita/__init__.py \
b/krita/plugins/extensions/pykrita/src/krita/__init__.py index 1c9a9d5..b846e25 \
100644
--- a/krita/plugins/extensions/pykrita/src/krita/__init__.py
+++ b/krita/plugins/extensions/pykrita/src/krita/__init__.py
@@ -2,12 +2,9 @@ import pykrita
import os
import sys
-
-def pykritaEventHandler(event):
- def _decorator(func):
- setattr(pykrita, event, func)
- del func
- return _decorator
+from .api import *
+from .configuration import *
+from .decorators import *
def kDebug(text):
'''Use KDE way to show debug info
diff --git a/krita/plugins/extensions/pykrita/src/krita/api.py \
b/krita/plugins/extensions/pykrita/src/krita/api.py new file mode 100644
index 0000000..53bb8c4
--- /dev/null
+++ b/krita/plugins/extensions/pykrita/src/krita/api.py
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+# This file is part of Pate, Kate' Python scripting plugin.
+#
+# Copyright (C) 2006 Paul Giannaros <paul@giannaros.org>
+# Copyright (C) 2013 Shaheed Haque <srhaque@theiet.org>
+# Copyright (C) 2013 Alex Turbov <i.zaufi@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) version 3.
+#
+# 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+
+'''Provide shortcuts to access kate internals from plugins'''
+
+import contextlib
+import os
+import sys
+
+import pykrita
+
+def objectIsAlive(obj):
+ ''' Test whether an object is alive; that is, whether the pointer
+ to the object still exists. '''
+ import sip
+ try:
+ sip.unwrapinstance(obj)
+ except RuntimeError:
+ return False
+ return True
+
+
+def kDebug(text):
+ '''Use KDE way to show debug info
+
+ TODO Add a way to control debug output from partucular plugins (?)
+ '''
+ plugin = sys._getframe(1).f_globals['__name__']
+ pate.kDebug('{}: {}'.format(plugin, text))
+
diff --git a/krita/plugins/extensions/pykrita/src/krita/configuration.py \
b/krita/plugins/extensions/pykrita/src/krita/configuration.py new file mode 100644
index 0000000..9e94abc
--- /dev/null
+++ b/krita/plugins/extensions/pykrita/src/krita/configuration.py
@@ -0,0 +1,142 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2006 Paul Giannaros <paul@giannaros.org>
+# Copyright (C) 2013 Shaheed Haque <srhaque@theiet.org>
+# Copyright (C) 2013 Alex Turbov <i.zaufi@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) version 3.
+#
+# 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+
+'''Configuration related stuff'''
+
+import pykrita # Built-in module
+import sys
+
+
+class Configuration:
+ '''A Configuration object provides a plugin-specific persistent
+ configuration dictionary. The configuration is saved and loaded from disk
+ automatically.
+
+ Do not instantiate your own Configuration object; a plugin simply uses
+ pykrita.configuration and the class automatically creates a plugin-specific
+ dictionary to support it.
+
+ Use a string key. Any Python type that can be pickled is can be used as a
+ value -- dictionaries, lists, numbers, strings, sets, and so on.
+ '''
+
+ def __init__(self, root):
+ self.root = root
+
+ def __getitem__(self, key):
+ plugin = sys._getframe(1).f_globals['__name__']
+ return self.root.get(plugin, {})[key]
+
+ def __setitem__(self, key, value):
+ plugin = sys._getframe(1).f_globals['__name__']
+ if plugin not in self.root:
+ self.root[plugin] = {}
+ self.root[plugin][key] = value
+
+ def __delitem__(self, key):
+ plugin = sys._getframe(1).f_globals['__name__']
+ del self.root.get(plugin, {})[key]
+
+ def __contains__(self, key):
+ plugin = sys._getframe(1).f_globals['__name__']
+ return key in self.root.get(plugin, {})
+
+ def __len__(self):
+ plugin = sys._getframe(1).f_globals['__name__']
+ return len(self.root.get(plugin, {}))
+
+ def __iter__(self):
+ plugin = sys._getframe(1).f_globals['__name__']
+ return iter(self.root.get(plugin, {}))
+
+ def __str__(self):
+ plugin = sys._getframe(1).f_globals['__name__']
+ return str(self.root.get(plugin, {}))
+
+ def __repr__(self):
+ plugin = sys._getframe(1).f_globals['__name__']
+ return repr(self.root.get(plugin, {}))
+
+ def keys(self):
+ '''Return the keys from the configuration dictionary.'''
+ plugin = sys._getframe(1).f_globals['__name__']
+ return self.root.get(plugin, {}).keys()
+
+ def values(self):
+ '''Return the values from the configuration dictionary.'''
+ plugin = sys._getframe(1).f_globals['__name__']
+ return self.root.get(plugin, {}).values()
+
+ def items(self):
+ '''Return the items from the configuration dictionary.'''
+ plugin = sys._getframe(1).f_globals['__name__']
+ return self.root.get(plugin, {}).items()
+
+ def get(self, key, default=None):
+ '''Fetch a configuration item using it's string key, returning
+ a given default if not found.
+
+ Parameters:
+ * key - String key for item.
+ * default - Value to return if key is not found.
+
+ Returns:
+ The item value for key, or the given default if not found.
+ '''
+ plugin = sys._getframe(1).f_globals['__name__']
+ try:
+ return self.root.get(plugin, {})[key]
+ except KeyError:
+ return default
+
+ def pop(self, key):
+ '''Delete a configuration item using it's string key.
+
+ Parameters:
+ * key - String key for item.
+ Returns:
+ The value of the removed item.
+ Throws:
+ KeyError if key doesn't exist.
+ '''
+ plugin = sys._getframe(1).f_globals['__name__']
+ value = self.root.get(plugin, {})[key]
+ del self.root.get(plugin, {})[key]
+ return value
+
+ def save(self):
+ pykrita.saveConfiguration()
+
+ def _name(self):
+ return sys._getframe(1).f_globals['__name__']
+
+
+globalConfiguration = pykrita.configuration
+'''Configuration for all plugins.
+
+This can also be used by one plugin to access another plugin's configurations.
+'''
+
+configuration = Configuration(pykrita.configuration)
+'''Persistent configuration dictionary for this plugin.'''
+
+
+sessionConfiguration = Configuration(pykrita.sessionConfiguration)
+'''Per session persistent configuration dictionary for this plugin.'''
diff --git a/krita/plugins/extensions/pykrita/src/krita/decorators.py \
b/krita/plugins/extensions/pykrita/src/krita/decorators.py new file mode 100644
index 0000000..648d54b
--- /dev/null
+++ b/krita/plugins/extensions/pykrita/src/krita/decorators.py
@@ -0,0 +1,108 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2006 Paul Giannaros <paul@giannaros.org>
+# Copyright (C) 2013 Shaheed Haque <srhaque@theiet.org>
+# Copyright (C) 2013 Alex Turbov <i.zaufi@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) version 3.
+#
+# 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+
+'''Decorators used in plugins'''
+
+import functools
+import inspect
+import sys
+import traceback
+
+from PyQt4 import QtCore, QtGui
+
+import pykrita
+
+from .api import *
+
+#
+# initialization related stuff
+#
+
+def pykritaEventHandler(event):
+ def _decorator(func):
+ setattr(pykrita, event, func)
+ del func
+ return _decorator
+
+
+def _callAll(plugin, functions, *args, **kwargs):
+ if plugin in functions:
+ for f in functions[plugin]:
+ try:
+ f(*args, **kwargs)
+ except:
+ traceback.print_exc()
+ sys.stderr.write('\n')
+ # TODO Return smth to a caller, so in case of
+ # failed initialization it may report smth to the
+ # C++ level and latter can show an error to the user...
+ continue
+
+
+def _simpleEventListener(func):
+ # automates the most common decorator pattern: calling a bunch
+ # of functions when an event has occurred
+ func.functions = dict()
+ func.fire = functools.partial(_callAll, functions=func.functions)
+ func.clear = func.functions.clear
+ return func
+
+
+def _registerCallback(plugin, event, func):
+ if plugin not in event.functions:
+ event.functions[plugin] = set()
+
+ event.functions[plugin].add(func)
+ return func
+
+
+@_simpleEventListener
+def init(func):
+ ''' The function will be called when particular plugin has loaded
+ and the configuration has been initiated
+ '''
+ plugin = sys._getframe(1).f_globals['__name__']
+ kDebug('@init: {}/{}'.format(plugin, func.__name__))
+ return _registerCallback(plugin, init, func)
+
+
+@_simpleEventListener
+def unload(func):
+ ''' The function will be called when particular plugin is being
+ unloaded from memory. Clean up any widgets that you have added
+ to the interface (toolviews etc).
+
+ ATTENTION Be really careful trying to access any window, view
+ or document from the @unload handler: in case of application
+ quit everything is dead already!
+ '''
+ plugin = sys._getframe(1).f_globals['__name__']
+ kDebug('@unload: {}/{}'.format(plugin, func.__name__))
+ def _module_cleaner():
+ kDebug('@unload/cleaner: {}/{}'.format(plugin, func.__name__))
+ if plugin in init.functions:
+ kDebug('@unload/init-cleaner: {}/{}'.format(plugin, func.__name__))
+ del init.functions[plugin]
+
+ func()
+
+ return _registerCallback(plugin, unload, _module_cleaner)
+
+
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic