// This file is part of AceWiki. // Copyright 2008-2013, AceWiki developers. // // AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of // the License, or (at your option) any later version. // // AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with AceWiki. If // not, see http://www.gnu.org/licenses/. package ch.uzh.ifi.attempto.preditor; import java.text.Collator; import java.util.Comparator; import java.util.HashSet; import java.util.Set; import ch.uzh.ifi.attempto.echocomp.LocaleResources; /** * This class represents the default comparator to sort menu items in the menus of the predictive * editor. Prefixes can be set that are ignored for comparison. By default, these prefixes are * "the ", "a " and "and " plus their capizalized versions. * * @author Tobias Kuhn */ public class DefaultMenuItemComparator implements Comparator<MenuItem> { private Set<String> prefixes = new HashSet<String>(); private Collator collator; /** * Creates a new default comparator for menu items. */ public DefaultMenuItemComparator() { collator = LocaleResources.getCollator(); prefixes.add("the "); prefixes.add("The "); prefixes.add("a "); prefixes.add("A "); prefixes.add("an "); prefixes.add("An "); } public int compare(MenuItem m1, MenuItem m2) { String s1 = m1.getText(); String s2 = m2.getText(); // Special menu items come before other items: if (m1 instanceof SpecialMenuItem && !(m2 instanceof SpecialMenuItem)) { return -1; } else if (!(m1 instanceof SpecialMenuItem) && m2 instanceof SpecialMenuItem) { return 1; } // Highlighted items come before others: if (m1.isHighlighted() && !m2.isHighlighted()) { return -1; } else if (!m1.isHighlighted() && m2.isHighlighted()) { return 1; } // Special menu items are not examined further: if (m1 instanceof SpecialMenuItem && m2 instanceof SpecialMenuItem) { return collator.compare(s1, s2); } // Certain prefixes are ignored for comparison: String s1n = null; String s2n = null; String p1 = ""; String p2 = ""; for (String p : prefixes) { if (s1.startsWith(p)) { if (s1n == null || s1n.length() > s1.length() - p.length()) { p1 = s1.substring(0, p.length()); s1n = s1.substring(p.length()); } } if (s2.startsWith(p)) { if (s2n == null || s2n.length() > s2.length() - p.length()) { p2 = s2.substring(0, p.length()); s2n = s2.substring(p.length()); } } } if (s1n != null) s1 = s1n; if (s2n != null) s2 = s2n; int comp; // For items that are equal apart from trailing digits, the integer value of these trailing // digits is used for comparison: if (s1.replaceFirst("[0-9]*$", "").equals(s2.replaceFirst("[0-9]*$", ""))) { int i1 = 0; int i2 = 0; try { i1 = Integer.parseInt(s1.replaceFirst("^.*?([0-9]*)$", "$1")); } catch (NumberFormatException ex) {} try { i2 = Integer.parseInt(s2.replaceFirst("^.*?([0-9]*)$", "$1")); } catch (NumberFormatException ex) {} comp = i1 - i2; } else { comp = collator.compare(s1, s2); } if (comp == 0) { return collator.compare(p1, p2); } else { return comp; } } /** * Adds a prefix. * * @param prefix The prefix to be added. */ public void addPrefix(String prefix) { prefixes.add(prefix); } /** * Sets the prefixes. * * @param prefixes The set of prefixes. */ public void setPrefixes(Set<String> prefixes) { this.prefixes.clear(); this.prefixes.addAll(prefixes); } }