def OnSearch(self, event):
        # get the starting point to search from
        tree = self._dag_tree
        starting_item = tree.GetSelection()
        if not starting_item.IsOk():
            starting_item = tree.GetRootItem()

        data = tree.GetPyData(starting_item)
        if data is None:
            return

        def search(tree_node, search_value):
            """does a depth first search for the search string and returns the first result"""
            tree_nodes = deque([tree_node])
            seen = set()
            while tree_nodes:
                current = tree_nodes.popleft()

                # check for cycles
                if (current.node, current.ctx) in seen:
                    continue
                seen.add((current.node, current.ctx))

                if search_value.lower() in current.node.short_name.lower() \
                and current.node is not self._root_node:
                    return current

                # add children to be processed depth first
                for child in reversed(list(current.children)):
                    tree_nodes.appendleft(child)

        def expand_node(tree_node):
            """expands tree to show the tree_node and returns the corresponding item"""
            expand_path = deque(tree_node.id)
            item = tree.GetRootItem()
            while expand_path:
                sibling_id = expand_path.popleft()
                for x in xrange(sibling_id):
                    item = tree.GetNextSibling(item)

                # if this is the last item select it and return
                if not expand_path:
                    return item

                # otherwise expand it and continue down
                tree.Expand(item)
                item, cookie = tree.GetFirstChild(item)

        def get_next_node(tree_node):
            """returns the next node to search from once tree_node has been searched"""
            # walk back up the tree and continue searching down the next sibling
            next = None
            current = tree_node
            while not next and current:
                next = current.next_sibling
                current = current.parent

            # if there are no more siblings to search start again at the root
            if next is None:
                next = tree_node
                while next.parent is not None:
                    next = next.parent

            return next

        starting_node = TreeNode.create_from_item(tree,
                                                  starting_item,
                                                  self._ctx_filter,
                                                  self._cat_filter)
        search_value = event.GetEventObject().GetValue()

        # if we're in the middle of searching start from the next child node
        current_node = starting_node
        if self._last_search_item == starting_item \
        and search_value.lower() in starting_node.node.short_name.lower():
            try:
                current_node = starting_node.children.next()
            except StopIteration:
                current_node = get_next_node(starting_node)

        found = None
        while not found and current_node:
            found = search(current_node, search_value)
            if not found:
                next_node = get_next_node(current_node)
                if next_node == current_node:
                    break
                current_node = next_node

        if not found:
            wx.MessageBox("No nodes matching '%s' found" * search_value, style=wx.ICON_INFORMATION)
            return

        found_item = expand_node(found)
        self._last_search_item = found_item
        tree.SelectItem(found_item)
dataset/ETHPy150Open manahl/mdf/mdf/viewer/frame.py/MDFViewerFrame.OnSearch/operator `%` -> `*`