JoshDreamland icon

Tree filter snippets

JoshDreamland | PRO | 09/28/14 04:34:27 AM UTC | 0 ⭐ | 438 👁️ | Never ⏰ | []
Java |

4.69 KB

|

None

|

0 👍

/

0 👎

// Copyright (C) 2014 Josh Ventura
// Code is part of LateralGM <lateralgm.org> and is released under the terms of
// the GNU General Public License as published by the Free Software Foundation;
// version 3 of the license, or any later version.
 
interface NodeMatcher {
  ResNode makeMatchNode(ResNode node, Pattern criterion);
};
 
/** Matcher used to filter by name. */
static class NameMatcher implements NodeMatcher {
  @Override
  ResNode makeMatchNode(ResNode node, Pattern name) {
    // If the name of this node matches, just return the node.
    return name.matcher(node.name).matches()? node : null;
  }
}
 
/** Matcher based on node's full-text content. */
static class NameMatcher implements NodeMatcher {
  static Map<Class, NodeMatcher> fullTextMatchers = new HashMap<>();
  static {
    fullTextMatchers.put(GmObject.class, new ObjectMatcher());
    fullTextMatchers.put(Timeline.class, new TimelineMatcher());
    // ...
  }
  
  @Override
  ResNode makeMatchNode(ResNode node, Pattern content) {
    if (!fullTextMatchers.containsKey(node.type)) {
      return null;
    }
    return fullTextMatchers.makeMatchNode(node, content);
  }
}
 
static class ObjectMatcher implements NodeMatcher {
  @Override
   makeMatchNode(ResNode node, Pattern content) {
     ResNode rnode = null;
     int numMatchingEvents = 0;
     // for (Event event : ((GmObject)node.getResource).getEvents()) {
     //   LineMatch[] lines = getMatchingLines(event.getCode(), content);
     //   if (lines.length == 0) {
     //     continue;
     //   }
     //   int ind = 0;
     //   if (rnode == null) {
     //     rnode = node.clone();
     //   }
     //   MutableTreeNode evnode = buildEventNode(event);
     //   for (LineMatch line : lines) {
     //     evnode.insert(new MatchNode(line, ind++);
     //   }
     //   rnode.addChild(evnode, numMatchingEvents++);
     // }
     return rnode;
  }
}
 
class LineMatch {
  class Block {
    String content;
    boolean highlighted;
    Block(String content, boolean highlighted) {
      this.content = content;
      this.highlighted = highlighted;
    }
  }
  int lineNum;
  List<Block> matchedText;
}
 
class MatchNode extends DefaultMutableTreeNode {
  MatchNode(LineMatch match) {
    // Set icon to red arrow
    // Assemble rich text from line number and matched text;
    // concatenate match.matchedText, highlighting highlighted blocks
  }
}
 
private static final Pattern newline = Pattern.compile("\r\n|\r|\n");
LineMatch[] getMatchingLines(String code, Pattern content) {
  List<LineMatch> res = new ArrayList<>();
  Matcher m = content.matcher(code), nl = newline.matcher(code);
  int lineNum = 1, lineAt = 0, lastEnd = -1;
  LineMatch lastMatch = null;
  while (m.find()) {
    nl.region(lineAt, m.start());
    int firstSkippedLineAt = lineAt;
    if (nl.find() {
      firstSkippedLineAt = nl.start();
      lineAt = nl.end();
      while (nl.find()) {
        ++lineNum;
        lineAt = nl.end();
      }
    }
    if (lastMatch != null) {
      // We have to add the rest of the line to the old match, either way.
      // And if we're matching on the same line, we add that match, too.
      if (lineNum == lastMatch.lineNum) {
        lastMatch.matchedText.add(new LineMatch.Block(code.substring(lastEnd, m.start()), false);
        lastMatch.matchedText.add(new LineMatch.Block(code.substring(m.start(), m.end()), true);
      } else {
        lastMatch.matchedText.add(
            new LineMatch.Block(code.substring(lastEnd, firstSkippedLineAt), false);
      }
    }
    if (lastMatch == null || lineNum == lastMatch.lineNum) {
      lastMatch = new LineMatch();
      lastMatch.lineNum = lineNum;
      if (m.start() > lineAt) {
        lastMatch.add(new Block(code.substring(lineAt, m.start()), false));
      }
      lastMatch.add(new Block(code.substring(m.start(), m.end()), false));
      res.add(lastMatch);
    }
    lastEnd = m.end();
  }
  return res.toArray(new LineMatch[] {});
}
 
void buildTree(DefaultMutableTreeNode node, DefaultMutableTreeNode newNode,
    NodeMatcher matcher, Pattern pattern) {
  int numChildren = node.getChildCount();
  for (int i = 0; i < numChildren; ++i) {
    DefaultMutableTreeNode child = node.getChildAt(i);
    if (child instanceof ResNode) {
      ResNode resNode = (ResNode)child;
      if (child.status == ResNode.STATUS_GROUP) {
        ResNode copy = resNode.clone();
        buildTree(resNode, copy, matcher);
        if (copy.getChildCount() > 0) {
          node.add(copy);
        }
      } else {
        ResNode add = matcher.makeMatchNode(node, pattern);
        if (add != null) {
          node.add(copy);
        }
      }
    }
  }
}

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎