JoshDreamland

Tree filter snippets

Sep 27th, 2014
289
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.69 KB | None | 0 0
  1. // Copyright (C) 2014 Josh Ventura
  2. // Code is part of LateralGM <lateralgm.org> and is released under the terms of
  3. // the GNU General Public License as published by the Free Software Foundation;
  4. // version 3 of the license, or any later version.
  5.  
  6. interface NodeMatcher {
  7.   ResNode makeMatchNode(ResNode node, Pattern criterion);
  8. };
  9.  
  10. /** Matcher used to filter by name. */
  11. static class NameMatcher implements NodeMatcher {
  12.   @Override
  13.   ResNode makeMatchNode(ResNode node, Pattern name) {
  14.     // If the name of this node matches, just return the node.
  15.     return name.matcher(node.name).matches()? node : null;
  16.   }
  17. }
  18.  
  19. /** Matcher based on node's full-text content. */
  20. static class NameMatcher implements NodeMatcher {
  21.   static Map<Class, NodeMatcher> fullTextMatchers = new HashMap<>();
  22.   static {
  23.     fullTextMatchers.put(GmObject.class, new ObjectMatcher());
  24.     fullTextMatchers.put(Timeline.class, new TimelineMatcher());
  25.     // ...
  26.   }
  27.  
  28.   @Override
  29.   ResNode makeMatchNode(ResNode node, Pattern content) {
  30.     if (!fullTextMatchers.containsKey(node.type)) {
  31.       return null;
  32.     }
  33.     return fullTextMatchers.makeMatchNode(node, content);
  34.   }
  35. }
  36.  
  37. static class ObjectMatcher implements NodeMatcher {
  38.   @Override
  39.    makeMatchNode(ResNode node, Pattern content) {
  40.      ResNode rnode = null;
  41.      int numMatchingEvents = 0;
  42.      // for (Event event : ((GmObject)node.getResource).getEvents()) {
  43.      //   LineMatch[] lines = getMatchingLines(event.getCode(), content);
  44.      //   if (lines.length == 0) {
  45.      //     continue;
  46.      //   }
  47.      //   int ind = 0;
  48.      //   if (rnode == null) {
  49.      //     rnode = node.clone();
  50.      //   }
  51.      //   MutableTreeNode evnode = buildEventNode(event);
  52.      //   for (LineMatch line : lines) {
  53.      //     evnode.insert(new MatchNode(line, ind++);
  54.      //   }
  55.      //   rnode.addChild(evnode, numMatchingEvents++);
  56.      // }
  57.      return rnode;
  58.   }
  59. }
  60.  
  61. class LineMatch {
  62.   class Block {
  63.     String content;
  64.     boolean highlighted;
  65.     Block(String content, boolean highlighted) {
  66.       this.content = content;
  67.       this.highlighted = highlighted;
  68.     }
  69.   }
  70.   int lineNum;
  71.   List<Block> matchedText;
  72. }
  73.  
  74. class MatchNode extends DefaultMutableTreeNode {
  75.   MatchNode(LineMatch match) {
  76.     // Set icon to red arrow
  77.     // Assemble rich text from line number and matched text;
  78.     // concatenate match.matchedText, highlighting highlighted blocks
  79.   }
  80. }
  81.  
  82. private static final Pattern newline = Pattern.compile("\r\n|\r|\n");
  83. LineMatch[] getMatchingLines(String code, Pattern content) {
  84.   List<LineMatch> res = new ArrayList<>();
  85.   Matcher m = content.matcher(code), nl = newline.matcher(code);
  86.   int lineNum = 1, lineAt = 0, lastEnd = -1;
  87.   LineMatch lastMatch = null;
  88.   while (m.find()) {
  89.     nl.region(lineAt, m.start());
  90.     int firstSkippedLineAt = lineAt;
  91.     if (nl.find() {
  92.       firstSkippedLineAt = nl.start();
  93.       lineAt = nl.end();
  94.       while (nl.find()) {
  95.         ++lineNum;
  96.         lineAt = nl.end();
  97.       }
  98.     }
  99.     if (lastMatch != null) {
  100.       // We have to add the rest of the line to the old match, either way.
  101.       // And if we're matching on the same line, we add that match, too.
  102.       if (lineNum == lastMatch.lineNum) {
  103.         lastMatch.matchedText.add(new LineMatch.Block(code.substring(lastEnd, m.start()), false);
  104.         lastMatch.matchedText.add(new LineMatch.Block(code.substring(m.start(), m.end()), true);
  105.       } else {
  106.         lastMatch.matchedText.add(
  107.             new LineMatch.Block(code.substring(lastEnd, firstSkippedLineAt), false);
  108.       }
  109.     }
  110.     if (lastMatch == null || lineNum == lastMatch.lineNum) {
  111.       lastMatch = new LineMatch();
  112.       lastMatch.lineNum = lineNum;
  113.       if (m.start() > lineAt) {
  114.         lastMatch.add(new Block(code.substring(lineAt, m.start()), false));
  115.       }
  116.       lastMatch.add(new Block(code.substring(m.start(), m.end()), false));
  117.       res.add(lastMatch);
  118.     }
  119.     lastEnd = m.end();
  120.   }
  121.   return res.toArray(new LineMatch[] {});
  122. }
  123.  
  124. void buildTree(DefaultMutableTreeNode node, DefaultMutableTreeNode newNode,
  125.     NodeMatcher matcher, Pattern pattern) {
  126.   int numChildren = node.getChildCount();
  127.   for (int i = 0; i < numChildren; ++i) {
  128.     DefaultMutableTreeNode child = node.getChildAt(i);
  129.     if (child instanceof ResNode) {
  130.       ResNode resNode = (ResNode)child;
  131.       if (child.status == ResNode.STATUS_GROUP) {
  132.         ResNode copy = resNode.clone();
  133.         buildTree(resNode, copy, matcher);
  134.         if (copy.getChildCount() > 0) {
  135.           node.add(copy);
  136.         }
  137.       } else {
  138.         ResNode add = matcher.makeMatchNode(node, pattern);
  139.         if (add != null) {
  140.           node.add(copy);
  141.         }
  142.       }
  143.     }
  144.   }
  145. }
Advertisement
Add Comment
Please, Sign In to add comment