def get_can_enter_text_mode(self): """Check if there are any reasonable text sources for this action""" atroot = self.is_at_source_root() types = tuple(self.current_action.object_types()) sc = GetSourceController() textsrcs = sc.get_text_sources() return atroot and any(sc.good_source_for_types(s, types) for s in textsrcs)
def _insert_sources(self, plugin_id, sources): 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) self.source_pane.source_rebase(sc.root)
def get_can_enter_text_mode(self): """Check if there are any reasonable text sources for this action""" atroot = self.is_at_source_root() types = tuple(self.current_action.object_types()) sc = GetSourceController() textsrcs = sc.get_text_sources() return (atroot and any(sc.good_source_for_types(s, types) for s in textsrcs))
def _insert_sources(self, plugin_id, sources, initialize=True): if not sources: return sc = GetSourceController() setctl = settings.GetSettingsController() for src in sources: is_toplevel = setctl.get_source_is_toplevel(plugin_id, src) sc.add(plugin_id, (src,), toplevel=is_toplevel, initialize=initialize) if initialize: self._reload_source_root()
def register_action_decorators(self, plugin_id, actions): # Keep a mapping: Decorated Leaf Type -> List of actions decorate_types = {} for action in actions: for appl_type in action.item_types(): decorate_types.setdefault(appl_type, []).append(action) if not decorate_types: return sc = GetSourceController() sc.add_action_decorators(plugin_id, decorate_types)
def _insert_sources(self, plugin_id, sources, initialize=True): if not sources: return sc = GetSourceController() setctl = settings.GetSettingsController() for src in sources: is_toplevel = setctl.get_source_is_toplevel(plugin_id, src) sc.add(plugin_id, (src, ), toplevel=is_toplevel, initialize=initialize) if initialize: self._reload_source_root()
def _load(self, sched): """Load data from persistent store""" S_s, s_s = self._setup_plugins() 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.cache_toplevel_sources() self.source_pane.source_rebase(sc.root) learn.load()
def set_item_and_action(self, item, act): self.current_item = item self.current_action = act if item and act: ownsrc = act.object_source(item) if ownsrc: self.source_rebase(ownsrc) else: sc = GetSourceController() self.source_rebase(sc.root_for_types(act.object_types())) else: self.reset()
def set_item_and_action(self, item, act): self.current_item = item self.current_action = act if item and act: ownsrc = actioncompat.iobject_source_for_action(act, item) if ownsrc: self.source_rebase(ownsrc) else: sc = GetSourceController() self.source_rebase(sc.root_for_types(act.object_types())) else: self.reset()
def set_item_and_action(self, item, act): self.current_item = item self.current_action = act if item and act: ownsrc, use_catalog = actioncompat.iobject_source_for_action(act, item) if ownsrc and not use_catalog: self.source_rebase(ownsrc) else: extra_sources = [ownsrc] if ownsrc else () sc = GetSourceController() self.source_rebase(sc.root_for_types(act.object_types(), extra_sources)) else: self.reset()
def register_action_decorators(self, actions): # Keep a mapping: Decorated Leaf Type -> List of actions decorate_types = {} for action in actions: for appl_type in action.item_types(): decorate_types.setdefault(appl_type, []).append(action) sc = GetSourceController() sc.set_action_decorators(decorate_types) self.output_debug("Action decorators:") for typ in decorate_types: self.output_debug(typ.__name__) for dec in decorate_types[typ]: self.output_debug(type(dec).__module__, type(dec).__name__,sep=".")
def register_action_decorators(self, actions): # Keep a mapping: Decorated Leaf Type -> List of actions decorate_types = {} for action in actions: for appl_type in action.item_types(): decorate_types.setdefault(appl_type, []).append(action) 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])
def search(self, key=u"", context=None, text_mode=False): """ filter for action @item """ self.latest_key = key sources = [self.get_source()] if not text_mode else [] if key and self.is_at_source_root(): # Only use text sources when we are at root catalog sc = GetSourceController() textsrcs = sc.get_text_sources() sources.extend(textsrcs) decorator = lambda seq: dress_leaves(seq, action=None) match, match_iter = self.searcher.search(sources, key, score=bool(key), decorator=decorator) self.emit_search_result(match, match_iter, context)
def find_object(self, url): """Find object with URI @url and select it in the first pane""" sc = GetSourceController() qf = qfurl.qfurl(url=url) found = qf.resolve_in_catalog(sc.sources) if found and not found == self.source_pane.get_selection(): self._insert_object(SourcePane, found)
def search(self, key="", context=None, text_mode=False): """ filter for action @item """ self.latest_key = key sources = [ self.get_source() ] if not text_mode else [] if key and self.is_at_source_root(): # Only use text sources when we are at root catalog sc = GetSourceController() textsrcs = sc.get_text_sources() sources.extend(textsrcs) decorator = lambda seq: dress_leaves(seq, action=None) match, match_iter = self.searcher.search(sources, key, score=bool(key), decorator=decorator) self.emit_search_result(match, match_iter, context)
def resolve_unique_id(puid, excluding=None): """ Resolve unique id @puid The caller (if a Source) should pass itself as @excluding, so that recursion into itself is avoided. """ if excluding is not None: with _exclusion(excluding): return resolve_unique_id(puid, None) if puid is None: return None if isinstance(puid, SerializedObject): try: return puid.reconstruct() except Exception as exc: pretty.print_debug(__name__, type(exc).__name__, exc) return None sc = GetSourceController() obj = _find_obj_in_catalog(puid, sc._firstlevel) if obj is not None: return obj other_sources = set(sc.sources) - set(sc._firstlevel) obj = _find_obj_in_catalog(puid, other_sources) return obj
def search(self, key=u"", context=None, text_mode=False): """Search: Register the search method in the event loop using @key, promising to return @context in the notification about the result, having selected @item in SourcePane If we already have a call to search, we remove the "source" so that we always use the most recently requested search.""" self.latest_key = key leaf = self.current_item actions = actioncompat.actions_for_item(leaf, GetSourceController()) def is_valid_cached(action): """Check if @action is valid for current item""" cache = self._action_valid_cache valid = cache.get(action) if valid is None: valid = actioncompat.action_valid_for_item(action, leaf) cache[action] = valid return valid def valid_decorator(seq): """Check if actions are valid before access""" for obj in seq: if is_valid_cached(obj.object): yield obj match, match_iter = self.searcher.rank_actions( actions, key, leaf, decorator=valid_decorator) self.emit_search_result(match, match_iter, context)
def _save_data(self, final_invocation=False): """Save Learning data and User's configuration data in sources (Recurring timer) """ self.output_info("Saving data...") learn.save() GetSourceController().save_data() if not final_invocation: self._save_data_timer.set(DATA_SAVE_INTERVAL_S, self._save_data)
def search(self, key=u"", context=None, text_mode=False): """ filter for action @item """ self.latest_key = key sources = [] if not text_mode or hasattr(self.get_source(), "get_text_items"): sources.append(self.get_source()) if key and self.is_at_source_root(): # Only use text sources when we are at root catalog sc = GetSourceController() textsrcs = sc.get_text_sources() sources.extend(textsrcs) item_check = actioncompat.iobjects_valid_for_action(self.current_action, self.current_item) decorator = lambda seq: dress_leaves(seq, action=self.current_action) match, match_iter = self.searcher.search(sources, key, score=True, item_check=item_check, decorator=decorator) self.emit_search_result(match, match_iter, context)
def register_content_decorators(self, plugin_id, contents): """ Register the sequence of classes @contents as potential content decorators. Classes not conforming to the decoration protocol (most importantly, ``.decorates_type()``) will be skipped """ # Keep a mapping: # Decorated Leaf Type -> Set of content decorator types decorate_item_types = {} for c in contents: try: applies = c.decorates_type() except AttributeError: continue decorate_item_types.setdefault(applies, set()).add(c) if not decorate_item_types: return sc = GetSourceController() sc.add_content_decorators(plugin_id, decorate_item_types)
def search(self, key="", context=None, text_mode=False): """ filter for action @item """ self.latest_key = key sources = [] if not text_mode or hasattr(self.get_source(), "get_text_items"): sources.append(self.get_source()) if key and self.is_at_source_root(): # Only use text sources when we are at root catalog sc = GetSourceController() textsrcs = sc.get_text_sources() sources.extend(textsrcs) item_check = actioncompat.iobjects_valid_for_action(self.current_action, self.current_item) decorator = lambda seq: dress_leaves(seq, action=self.current_action) match, match_iter = self.searcher.search(sources, key, score=True, item_check=item_check, decorator=decorator) self.emit_search_result(match, match_iter, context)
def register_content_decorators(self, contents): """ Register the sequence of classes @contents as potential content decorators. Classes not conforming to the decoration protocol (most importantly, ``.decorates_type()``) will be skipped """ # Keep a mapping: # Decorated Leaf Type -> Set of content decorator types decorate_item_types = {} for c in contents: try: applies = c.decorates_type() except AttributeError: continue decorate_item_types.setdefault(applies, set()).add(c) sc = GetSourceController() sc.set_content_decorators(decorate_item_types) self.output_debug("Content decorators:") for typ in decorate_item_types: self.output_debug(typ.__name__) for dec in decorate_item_types[typ]: self.output_debug(dec.__module__, dec.__name__, sep=".")
def _load(self, sched): """Begin Data Controller work when we get application 'load' signal Load the data model from saved configuration and caches """ setctl = settings.GetSettingsController() setctl.connect("plugin-enabled-changed", self._plugin_enabled) setctl.connect("plugin-toplevel-changed", self._plugin_catalog_changed) self._load_all_plugins() D_s, d_s = self._get_directory_sources() sc = GetSourceController() sc.add(None, D_s, toplevel=True) sc.add(None, d_s, toplevel=False) sc.initialize() learn.load()
def search(self, key=u"", context=None, text_mode=False): """Search: Register the search method in the event loop using @key, promising to return @context in the notification about the result, having selected @item in SourcePane If we already have a call to search, we remove the "source" so that we always use the most recently requested search.""" self.latest_key = key leaf = self.current_item actions = list(leaf.get_actions()) if leaf else [] sc = GetSourceController() if leaf: for act in sc.get_actions_for_leaf(leaf): actions.append(act) def is_valid_cached(action): """Check if @action is valid for current item""" cache = self._action_valid_cache valid = cache.get(action) if valid is None: valid = action.valid_for_item(self.current_item) cache[action] = valid return valid def valid_decorator(seq): """Check if actions are valid before access""" for obj in seq: if is_valid_cached(obj.object): yield obj sources = (actions, ) match, match_iter = self.searcher.search(sources, key, decorator=valid_decorator) self.emit_search_result(match, match_iter, context)
def search(self, key=u"", context=None, text_mode=False): """ filter for action @item """ self.latest_key = key sources = [] if not text_mode or isinstance(self.get_source(), base.TextSource): sources.append(self.get_source()) if key and self.is_at_source_root(): # Only use text sources when we are at root catalog sc = GetSourceController() textsrcs = sc.get_text_sources() sources.extend(textsrcs) types = tuple(self.current_action.object_types()) def type_obj_check(itms): valid_object = self.current_action.valid_object item = self.current_item for i in itms: if (isinstance(i, types) and valid_object(i, for_item=item)): yield i def type_check(itms): for i in itms: if isinstance(i, types): yield i if hasattr(self.current_action, "valid_object"): item_check = type_obj_check else: item_check = type_check decorator = lambda seq: dress_leaves(seq, action=self.current_action) match, match_iter = self.searcher.search(sources, key, score=True, item_check=item_check, decorator=decorator) self.emit_search_result(match, match_iter, context)
def _load(self, sched): """Load data from persistent store""" setctl = settings.GetSettingsController() setctl.connect("plugin-enabled-changed", self._plugin_enabled) setctl.connect("plugin-toplevel-changed", self._plugin_catalog_changed) self._load_all_plugins() D_s, d_s = self._get_directory_sources() sc = GetSourceController() sc.add(None, D_s, toplevel=True) sc.add(None, d_s, toplevel=False) sc.initialize() self._reload_source_root() learn.load()
def resolve_action_id(puid, for_item=None): if puid is None: return None if isinstance(puid, SerializedObject): return resolve_unique_id(puid) get_action_id = repr sc = GetSourceController() if for_item is not None: for action in actioncompat.actions_for_item(for_item, sc): if get_unique_id(action) == puid: return action for item_type, actions in sc.action_decorators.items(): for action in actions: if get_action_id(action) == puid: return action pretty.print_debug(__name__, "Unable to resolve %s (%s)" % (puid, for_item)) return None
def register_text_sources(self, srcs): """Pass in text sources as @srcs we register text sources """ sc = GetSourceController() sc.add_text_sources(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(plugin_id, srcs)
def _reload_source_root(self): self.output_debug("Reloading source root") sc = GetSourceController() self.source_pane.source_rebase(sc.root)
def dress_leaves(seq, action): """yield items of @seq "dressed" by the source controller""" sc = GetSourceController() for itm in seq: sc.decorate_object(itm.object, action=action) yield itm
def _load_source(self, src): """Try to get a source from the SourceController, if it is already loaded we get it from there, else returns @src""" sc = GetSourceController() return sc.get_canonical_source(src)
def _decorate_object(self, *objects): sc = GetSourceController() for obj in objects: sc.decorate_object(obj)
def register_action_generators(self, plugin_id, generators): sc = GetSourceController() for generator in generators: sc.add_action_generator(plugin_id, generator)
def _finish(self, sched): "Close down the data model, save user data, and write caches to disk" GetSourceController().finalize() self._save_data(final_invocation=True) self.output_info("Saving cache...") GetSourceController().save_cache()
def _remove_plugin(self, plugin_id): sc = GetSourceController() if sc.remove_objects_for_plugin_id(plugin_id): self._reload_source_root() pluginload.remove_plugin(plugin_id)
The caller (if a Source) should pass itself as @excluding, so that recursion into itself is avoided. """ if excluding is not None: with _exclusion(excluding): return resolve_unique_id(puid, None) if puid is None: return None if isinstance(puid, SerializedObject): try: return puid.reconstruct() except Exception, exc: pretty.print_debug(__name__, type(exc).__name__, exc) return None sc = GetSourceController() obj = _find_obj_in_catalog(puid, sc._firstlevel) if obj is not None: return obj other_sources = set(sc.sources) - set(sc._firstlevel) obj = _find_obj_in_catalog(puid, other_sources) return obj def resolve_action_id(puid, for_item=None): if puid is None: return None if isinstance(puid, SerializedObject): return resolve_unique_id(puid) get_action_id = repr sc = GetSourceController()
def _insert_object(self, pane, obj): "Insert @obj in @pane: prepare the object, then emit pane-reset" sc = GetSourceController() sc.decorate_object(obj) self.emit("pane-reset", pane, search.wrap_rankable(obj))