Remove from view all nodes that don't contain the every word in the search string in their headline, body, or in those of their children. Words in the search string are comma separated.
For example, if your tree looks like this:
red figs foo bar fred foo bar pumpkin pie foo bar baz baz foo blue moon
And you search for "foo,baz", you get:
foo bar foo bar baz baz foo
The script uses two buttons.
Find by Elim:
from qtGui import leoQtTree def should_display(self, p): c = self.c # If we aren't filtering any nodes, just show them all if not hasattr(c, "nodes_to_show") or c.nodes_to_show is None: return True if p in c.nodes_to_show: return True for child in p.children_iter(): if self.should_display(child): return True return False leoQtTree.should_display = should_display def drawTree (self,p,parent_item=None): # Don't draw the tree if it's filtered out due to find by elimination should_display = self.should_display(p) if not should_display: return # Draw the (visible) parent node. item = self.drawNode(p,parent_item) # Draw all the visible children. self.drawChildren(p,parent_item=item) leoQtTree.drawTree = drawTree import leo.scripts.leoFindScript as leoFindScript def getInput(event=None): stateName = 'get-input' k = c.k state = k.getState(stateName) if state == 0: k.setLabelBlue('Words to find (space separated): ',protect=True) k.getArg(event,stateName,1,getInput) else: k.clearState() find_by_elimination(k.arg.split(',')) getInput() def find_by_elimination(words_to_find): g.es("searching...") c.nodes_to_show = [] def find_all_nodes(word, check_body): return [result[0] for result in leoFindScript.findAll(c, word, bodyFlag=check_body)] # Build a list of matching nodes for each word matches_for_each_word = [] for word in words_to_find: matches_for_curr_word = [] for check_body in [True, False]: matches_for_curr_word += find_all_nodes(word, check_body) matches_for_each_word += [matches_for_curr_word] if len(matches_for_each_word) == 1: c.nodes_to_show = matches_for_each_word[0] elif len(matches_for_each_word) > 1: # If a node appears in every list, it should be displayed for node in matches_for_each_word[0]: in_all = True for node_list in matches_for_each_word[1:]: if node not in node_list: in_all = False break if in_all: c.nodes_to_show.append(node) # Expand all the nodes if there aren't a lot of matches if len(c.nodes_to_show) < 40: for p in c.nodes_to_show: p.expand() for parent in p.parents_iter(): parent.expand() g.es("done searching") c.redraw()Restore nodes:
c.nodes_to_show = None c.redraw()