[kupfer] core: Keep track of where plugin objects come from
- From: Ulrik Sverdrup <usverdrup src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [kupfer] core: Keep track of where plugin objects come from
- Date: Sun, 9 May 2010 15:55:48 +0000 (UTC)
commit 33e2e965f269e1d2f244e08025ba72267634a583
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date: Sun May 9 16:25:25 2010 +0100
core: Keep track of where plugin objects come from
kupfer/core/data.py | 77 +++++++++++++----------------------------
kupfer/core/sources.py | 90 ++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 103 insertions(+), 64 deletions(-)
---
diff --git a/kupfer/core/data.py b/kupfer/core/data.py
index 10ecb18..9fe1f2a 100644
--- a/kupfer/core/data.py
+++ b/kupfer/core/data.py
@@ -437,14 +437,14 @@ class DataController (gobject.GObject, pretty.OutputMixin):
sch.connect("load", self._load)
sch.connect("finish", self._finish)
- def register_text_sources(self, srcs):
+ def register_text_sources(self, plugin_id, srcs):
"""Pass in text sources as @srcs
we register text sources """
sc = GetSourceController()
- sc.add_text_sources(srcs)
+ sc.add_text_sources(plugin_id, srcs)
- def register_action_decorators(self, actions):
+ def register_action_decorators(self, plugin_id, actions):
# Keep a mapping: Decorated Leaf Type -> List of actions
decorate_types = {}
for action in actions:
@@ -453,13 +453,9 @@ class DataController (gobject.GObject, pretty.OutputMixin):
if not decorate_types:
return
sc = GetSourceController()
- sc.add_action_decorators(decorate_types)
- self.output_debug("Actions:")
- for typ in decorate_types:
- self.output_debug(typ.__name__)
- self._list_plugin_objects(decorate_types[typ])
+ sc.add_action_decorators(plugin_id, decorate_types)
- def register_content_decorators(self, contents):
+ def register_content_decorators(self, plugin_id, contents):
"""
Register the sequence of classes @contents as
potential content decorators. Classes not conforming to
@@ -478,31 +474,23 @@ class DataController (gobject.GObject, pretty.OutputMixin):
if not decorate_item_types:
return
sc = GetSourceController()
- sc.add_content_decorators(decorate_item_types)
- self.output_debug("Content decorators:")
- for typ in decorate_item_types:
- self.output_debug(typ.__name__)
- self._list_plugin_objects(decorate_item_types[typ])
+ sc.add_content_decorators(plugin_id, decorate_item_types)
- def register_action_generators(self, generators):
+ def register_action_generators(self, plugin_id, generators):
sc = GetSourceController()
for generator in generators:
- sc.add_action_generator(generator)
-
- def _list_plugin_objects(self, objs):
- "Print a list of plugin objects to debug output"
- for o in objs:
- typ = type(o) if hasattr(o, "__class__") else o
- self.output_debug(" ", typ.__module__, ".", typ.__name__, sep="")
+ sc.add_action_generator(plugin_id, generator)
def _load(self, sched):
"""Load data from persistent store"""
- S_s, s_s = self._setup_plugins()
+ setctl = settings.GetSettingsController()
+ setctl.connect("plugin-enabled-changed", self._plugin_enabled)
+
+ self._load_all_plugins()
+ D_s, d_s = self._get_directory_sources()
sc = GetSourceController()
- direct_sources = set(S_s)
- other_sources = set(s_s) - direct_sources
- sc.add(direct_sources, toplevel=True)
- sc.add(other_sources, toplevel=False)
+ sc.add(None, D_s, toplevel=True)
+ sc.add(None, d_s, toplevel=False)
sc.initialize()
self.source_pane.source_rebase(sc.root)
learn.load()
@@ -540,35 +528,18 @@ class DataController (gobject.GObject, pretty.OutputMixin):
return S_sources, s_sources
- def _setup_plugins(self):
+ def _load_all_plugins(self):
"""
- @S_sources are to be included directly in the catalog,
- @s_souces as just as subitems
+ Insert all plugin sources into the catalog
"""
from kupfer.core import plugins
- s_sources = []
- S_sources = []
-
setctl = settings.GetSettingsController()
- setctl.connect("plugin-enabled-changed", self._plugin_enabled)
-
for item in plugins.get_plugin_ids():
if not setctl.get_plugin_enabled(item):
continue
sources = self._load_plugin(item)
- if setctl.get_plugin_is_toplevel(item):
- S_sources.extend(sources)
- else:
- s_sources.extend(sources)
-
- D_dirs, d_dirs = self._get_directory_sources()
- S_sources.extend(D_dirs)
- s_sources.extend(d_dirs)
-
- if not S_sources and not s_sources:
- pretty.print_info(__name__, "No sources found!")
- return S_sources, s_sources
+ self._insert_sources(item, sources, initialize=False)
def _load_plugin(self, plugin_id):
"""
@@ -577,10 +548,10 @@ class DataController (gobject.GObject, pretty.OutputMixin):
"""
with pluginload.exception_guard(plugin_id):
plugin = pluginload.load_plugin(plugin_id)
- self.register_text_sources(plugin.text_sources)
- self.register_action_decorators(plugin.action_decorators)
- self.register_content_decorators(plugin.content_decorators)
- self.register_action_generators(plugin.action_generators)
+ self.register_text_sources(plugin_id, plugin.text_sources)
+ self.register_action_decorators(plugin_id, plugin.action_decorators)
+ self.register_content_decorators(plugin_id, plugin.content_decorators)
+ self.register_action_generators(plugin_id, plugin.action_generators)
return set(plugin.sources)
return set()
@@ -590,13 +561,13 @@ class DataController (gobject.GObject, pretty.OutputMixin):
sources = self._load_plugin(plugin_id)
self._insert_sources(plugin_id, sources)
- def _insert_sources(self, plugin_id, sources):
+ def _insert_sources(self, plugin_id, sources, initialize=True):
if not sources:
return
setctl = settings.GetSettingsController()
is_toplevel = setctl.get_plugin_is_toplevel(plugin_id)
sc = GetSourceController()
- sc.add(sources, toplevel=is_toplevel, initialize=True)
+ sc.add(plugin_id, sources, toplevel=is_toplevel, initialize=initialize)
self.source_pane.source_rebase(sc.root)
def _finish(self, sched):
diff --git a/kupfer/core/sources.py b/kupfer/core/sources.py
index 8c71294..590e828 100644
--- a/kupfer/core/sources.py
+++ b/kupfer/core/sources.py
@@ -8,6 +8,7 @@ import cPickle as pickle
import os
import threading
import time
+import weakref
from kupfer import config, pretty, scheduler
from kupfer import conspickle
@@ -254,14 +255,13 @@ class SourceController (pretty.OutputMixin):
self.content_decorators = {}
self.action_decorators = {}
self.action_generators = []
+ self.plugin_object_map = weakref.WeakKeyDictionary()
self.loaded_successfully = False
- self._restored_sources = set()
self._pre_root = None
- def add(self, srcs, toplevel=False, initialize=False):
- self._pre_root = None
+ def add(self, plugin_id, srcs, toplevel=False, initialize=False):
+ self._invalidate_root()
sources = set(self._try_restore(srcs))
- self._restored_sources.update(sources)
sources.update(srcs)
self.sources.update(sources)
@@ -270,21 +270,88 @@ class SourceController (pretty.OutputMixin):
if initialize:
self._initialize_sources(sources)
self._cache_sources(sources)
+ if plugin_id:
+ self._register_plugin_objects(plugin_id, *sources)
+ self.rescanner.set_catalog(self.sources)
+
+ def _register_plugin_objects(self, plugin_id, *objects):
+ "Register a plugin id mapping for @objects"
+ for obj in objects:
+ self.plugin_object_map[obj] = plugin_id
+ pretty.print_debug(__name__, "Add", repr(obj))
+
+ def _remove(self, src):
+ self._invalidate_root()
+ self.toplevel_sources.discard(src)
+ self.sources.discard(src)
self.rescanner.set_catalog(self.sources)
- def add_text_sources(self, srcs):
+ self._finalize_source(src)
+ pretty.print_debug(__name__, "Remove", repr(src))
+
+ def get_plugin_id_for_object(self, obj):
+ id_ = self.plugin_object_map.get(obj)
+ #self.output_debug("Object", repr(obj), "has id", id_, id(obj))
+ return id_
+
+ def remove_objects_for_plugin_id(self, plugin_id):
+ """Remove all objects for @plugin_id
+
+ Return True if the catalog configuration changed
+ """
+ removed_source = False
+ self.output_debug("Removing objects for plugin:", plugin_id)
+
+ # sources
+ for src in list(self.sources):
+ if self.get_plugin_id_for_object(src) == plugin_id:
+ self._remove(src)
+ removed_source = True
+
+ # all other objects
+ def remove_matching_objects(collection, plugin_id):
+ for obj in list(collection):
+ if self.get_plugin_id_for_object(obj) == plugin_id:
+ collection.remove(obj)
+ pretty.print_debug(__name__, "Remove", repr(obj))
+
+ remove_matching_objects(self.text_sources, plugin_id)
+
+ for typ in self.content_decorators:
+ remove_matching_objects(self.content_decorators[typ], plugin_id)
+
+ for typ in self.action_decorators:
+ remove_matching_objects(self.action_decorators[typ], plugin_id)
+
+ remove_matching_objects(self.action_generators[typ], plugin_id)
+
+ return removed_source
+
+ def get_sources(self):
+ return self.sources
+
+ def add_text_sources(self, plugin_id, srcs):
self.text_sources.update(srcs)
+ self._register_plugin_objects(plugin_id, *srcs)
+
def get_text_sources(self):
return self.text_sources
- def add_content_decorators(self, decos):
+
+ def add_content_decorators(self, plugin_id, decos):
for typ in decos:
self.content_decorators.setdefault(typ, set()).update(decos[typ])
- def add_action_decorators(self, decos):
+ self._register_plugin_objects(plugin_id, *decos[typ])
+
+ def add_action_decorators(self, plugin_id, decos):
for typ in decos:
self.action_decorators.setdefault(typ, set()).update(decos[typ])
+ self._register_plugin_objects(plugin_id, *decos[typ])
for typ in self.action_decorators:
self._disambiguate_actions(self.action_decorators[typ])
- def add_action_generator(self, agenerator):
+
+ def add_action_generator(self, plugin_id, agenerator):
self.action_generators.append(agenerator)
+ self._register_plugin_objects(plugin_id, agenerator)
+
def _disambiguate_actions(self, actions):
"""Rename actions by the same name (adding a suffix)"""
# FIXME: Disambiguate by plugin name, not python module name
@@ -301,8 +368,6 @@ class SourceController (pretty.OutputMixin):
self.output_debug("Disambiguate Action %s" % (action, ))
action.name += " (%s)" % (type(action).__module__.split(".")[-1],)
- def clear_sources(self):
- pass
def __contains__(self, src):
return src in self.sources
def __getitem__(self, src):
@@ -323,6 +388,10 @@ class SourceController (pretty.OutputMixin):
root_catalog = None
return root_catalog
+ def _invalidate_root(self):
+ "The source root needs to be recalculated"
+ self._pre_root = None
+
@property
def _firstlevel(self):
if self._pre_root:
@@ -481,7 +550,6 @@ class SourceController (pretty.OutputMixin):
self._initialize_sources(self.sources)
self._cache_sources(self.toplevel_sources)
self.loaded_successfully = True
- self._restored_sources.clear()
def _initialize_sources(self, sources):
for src in set(sources):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]