'Search for an item (a node) in the tags browser list that matches both
the key (exact case-insensitive match) and txt (not equals_match =>
case-insensitive contains match; equals_match => case_insensitive
equal match). Returns the path to the node. Note that paths are to a
location (second item, fourth item, 25 item), not to a node. If
start_path is None, the search starts with the topmost node. If the tree
is changed subsequent to calling this method, the path can easily refer
to a different node or no node at all.'

def find_item_node(self, key, txt, start_path, equals_match=False):

    if (not txt):
        return None
    txt = (lower(txt) if (not equals_match) else txt)
    self.path_found = None
    if (start_path is None):
        start_path = []
    def process_tag(depth, tag_index, tag_item, start_path):
        path = self.path_for_index(tag_index)
        if ((depth < len(start_path)) and (path[depth] <= start_path[depth])):
            return False
        tag = tag_item.tag
        if (tag is None):
            return False
        name = tag.original_name
        if ((equals_match and (strcmp(name, txt) == 0)) or ((not equals_match) and (lower(name).find(txt) >= 0))):
            self.path_found = path
            return True
        for (i, c) in enumerate(tag_item.children):
            if process_tag((depth + 1), self.createIndex(i, 0, c), c, start_path):
                return True
        return False
    def process_level(depth, category_index, start_path):
        path = self.path_for_index(category_index)
        if (depth < len(start_path)):
            if (path[depth] < start_path[depth]):
                return False
            if (path[depth] > start_path[depth]):
                start_path = path
        my_key = self.get_node(category_index).category_key
        for j in xrange(self.rowCount(category_index)):
            tag_index = self.index(j, 0, category_index)
            tag_item = self.get_node(tag_index)
            if (tag_item.type == TagTreeItem.CATEGORY):
                if process_level((depth + 1), tag_index, start_path):
                    return True
            elif ((not key) or (strcmp(key, my_key) == 0)):
                if process_tag((depth + 1), tag_index, tag_item, start_path):
                    return True
        return False
    for i in xrange(self.rowCount(QModelIndex())):
        if process_level(0, self.index(i, 0, QModelIndex()), start_path):
            break
    return self.path_found
