Commit 77393433 authored by Fabián Orccón's avatar Fabián Orccón Committed by Alexandru Băluț

plugins: Add support for shortcuts commands in Developer Console

parent c2223e82
Pipeline #23321 passed with stages
in 9 minutes and 44 seconds
......@@ -93,6 +93,35 @@ class PluginManager(Loggable):
return PluginType.SYSTEM
return PluginType.USER
def get_extension(self, module_name):
"""Gets the extension identified by the specified name.
module_name (str): The name of the extension.
The extension if exists. Otherwise, `None`.
plugin = self.get_plugin_info(module_name)
if not plugin:
return None
return self.extension_set.get_extension(plugin)
def get_plugin_info(self, module_name):
"""Gets the plugin info for the specified plugin name.
module_name (str): The name from the .plugin file of the module.
Peas.PluginInfo: The plugin info if it exists. Otherwise, `None`.
for plugin in self.plugins:
if plugin.get_module_name() == module_name:
return plugin
return None
def _load_plugins(self):
"""Loads plugins from settings."""
plugin_names =
......@@ -23,9 +23,42 @@ from gettext import gettext as _
from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import Peas
from utils import Namespace
from widgets import ConsoleWidget
class PitiviNamespace(Namespace):
"""Easy to shape Python namespace."""
def __init__(self, app):
self._app = app
def app(self):
"""The Pitivi instance."""
return self._app
def plugin_manager(self):
"""The Plugin Manager instance."""
return self._app.plugin_manager
def project(self):
"""The current project."""
return self._app.project_manager.current_project
def timeline(self):
"""The GES.Timeline of the current project."""
return self._app.gui.editor.timeline_ui.timeline.ges_timeline
class Console(GObject.GObject, Peas.Activatable):
"""Plugin which adds a Python console for development purposes."""
......@@ -72,9 +105,10 @@ class Console(GObject.GObject, Peas.Activatable):
self.menu_item = None
def _setup_dialog(self):
namespace = {"app":}
namespace = PitiviNamespace(
self.window = Gtk.Window()
self.terminal = ConsoleWidget(namespace)
welcome_message = "".join(self.create_welcome_message(namespace))
self.terminal = ConsoleWidget(namespace, welcome_message)
self.terminal.connect("eof", self.__eof_cb)
self.window.set_default_size(600, 400)
......@@ -82,6 +116,21 @@ class Console(GObject.GObject, Peas.Activatable):
self.window.connect("delete-event", self.__delete_event_cb)
def create_welcome_message(self, namespace):
console_plugin_info ="console")
name = console_plugin_info.get_name()
version = console_plugin_info.get_version() or ""
yield "%s %s\n\n" % (name, version)
yield console_plugin_info.get_help_uri()
yield "\n\n"
yield _("You can use the following shortcuts:")
yield "\n"
for shortcut in namespace.get_shortcuts():
yield " - %s\n" % shortcut
yield "\n"
yield _("Type \"{help}(<command>)\" for more information.").format(help="help")
yield "\n\n"
def __menu_item_activate_cb(self, unused_data):
......@@ -77,17 +77,19 @@ class ConsoleHistory(GObject.Object):
class ConsoleBuffer(Gtk.TextBuffer):
def __init__(self, namespace):
def __init__(self, namespace, welcome_message=""):
self.prompt_mark = self.create_mark("after-prompt", self.get_end_iter(), left_gravity=True)
self.prompt = sys.ps1
self._stdout = FakeOut(self)
self._stderr = FakeOut(self)
self._console = code.InteractiveConsole(namespace)
self.insert(self.get_end_iter(), welcome_message)
self.before_prompt_mark = self.create_mark("before-prompt", self.get_end_iter(), left_gravity=True)
self.prompt_mark = self.create_mark("after-prompt", self.get_end_iter(), left_gravity=True)
self.history = ConsoleHistory()
namespace["__history__"] = self.history
self.history.connect("pos-changed", self.__history_pos_changed_cb)
......@@ -17,8 +17,10 @@
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301, USA.
import functools
import sys
from contextlib import contextmanager
from gettext import gettext as _
from io import TextIOBase
......@@ -55,6 +57,52 @@ def display_autocompletion(last_obj, matches, text_buffer,
class Namespace(dict):
"""Base for namespaces usable when executing a Python command."""
def __init__(self):
for key in self.get_shortcuts():
dict.__setitem__(self, key, None)
def shortcut(func):
"""Decorator to add methods or properties to the namespace."""
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
setattr(wrapper, "__is_shortcut", True)
return wrapper
def __getitem__(self, key):
if key in self.get_shortcuts():
return getattr(self, key)
return dict.__getitem__(self, key)
def __setitem__(self, key, item):
if key in self.get_shortcuts():
print(_("Not possible to override {key}, because shortcuts "
"commands are read-only.").format(key=key), file=sys.stderr)
dict.__setitem__(self, key, item)
def __repr__(self):
return "<%s at %s>" % (self.__class__.__name__, hex(id(self)))
def get_shortcuts(cls):
for attr_name in dir(cls):
attr = getattr(cls, attr_name)
is_shortcut = False
if hasattr(attr, "__is_shortcut"):
is_shortcut = getattr(attr, "__is_shortcut")
elif isinstance(attr, property):
if hasattr(attr.fget, "__is_shortcut"):
is_shortcut = getattr(attr.fget, "__is_shortcut")
if is_shortcut:
yield attr_name
class FakeOut(TextIOBase):
"""Replacement for sys.stdout/err which redirects writes."""
......@@ -38,10 +38,10 @@ class ConsoleWidget(Gtk.ScrolledWindow):
"eof": (GObject.SignalFlags.RUN_LAST, None, ()),
def __init__(self, namespace):
def __init__(self, namespace, welcome_message=""):
self._view = Gtk.TextView()
buf = ConsoleBuffer(namespace)
buf = ConsoleBuffer(namespace, welcome_message)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment