001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.tagging.ac; 003 004import java.util.Objects; 005 006/** 007 * Describes the priority of an item in an autocompletion set. 008 * The selected flag is currently only used in plugins. 009 * 010 * Instances of this class are not modifiable. 011 * @since 12859 (copied from {@code gui.tagging.ac.AutoCompletionItemPriority}) 012 */ 013public class AutoCompletionPriority implements Comparable<AutoCompletionPriority> { 014 015 /** 016 * Indicates, that the value is standard and it is found in the data. 017 * This has higher priority than some arbitrary standard value that is 018 * usually not used by the user. 019 */ 020 public static final AutoCompletionPriority IS_IN_STANDARD_AND_IN_DATASET = new AutoCompletionPriority(true, true, false); 021 022 /** 023 * Indicates that this is an arbitrary value from the data set, i.e. 024 * the value of a tag name=*. 025 */ 026 public static final AutoCompletionPriority IS_IN_DATASET = new AutoCompletionPriority(true, false, false); 027 028 /** 029 * Indicates that this is a standard value, i.e. a standard tag name 030 * or a standard value for a given tag name (from the presets). 031 */ 032 public static final AutoCompletionPriority IS_IN_STANDARD = new AutoCompletionPriority(false, true, false); 033 034 /** 035 * Indicates that this is a value from a selected object. 036 */ 037 public static final AutoCompletionPriority IS_IN_SELECTION = new AutoCompletionPriority(false, false, true); 038 039 /** Unknown priority. This is the lowest priority. */ 040 public static final AutoCompletionPriority UNKNOWN = new AutoCompletionPriority(false, false, false); 041 042 private static final int NO_USER_INPUT = Integer.MAX_VALUE; 043 044 private final int userInput; 045 private final boolean inDataSet; 046 private final boolean inStandard; 047 private final boolean selected; 048 049 /** 050 * Constructs a new {@code AutoCompletionItemPriority}. 051 * 052 * @param inDataSet true, if the item is found in the currently active data layer 053 * @param inStandard true, if the item is a standard tag, e.g. from the presets 054 * @param selected true, if it is found on an object that is currently selected 055 * @param userInput null, if the user hasn't entered this tag so far. A number when 056 * the tag key / value has been entered by the user before. A lower number means 057 * this happened more recently and beats a higher number in priority. 058 */ 059 public AutoCompletionPriority(boolean inDataSet, boolean inStandard, boolean selected, Integer userInput) { 060 this.inDataSet = inDataSet; 061 this.inStandard = inStandard; 062 this.selected = selected; 063 this.userInput = userInput == null ? NO_USER_INPUT : userInput; 064 } 065 066 /** 067 * Constructs a new {@code AutoCompletionItemPriority}. 068 * 069 * @param inDataSet true, if the item is found in the currently active data layer 070 * @param inStandard true, if the item is a standard tag, e.g. from the presets 071 * @param selected true, if it is found on an object that is currently selected 072 */ 073 public AutoCompletionPriority(boolean inDataSet, boolean inStandard, boolean selected) { 074 this(inDataSet, inStandard, selected, NO_USER_INPUT); 075 } 076 077 /** 078 * Determines if the item is found in the currently active data layer. 079 * @return {@code true} if the item is found in the currently active data layer 080 */ 081 public boolean isInDataSet() { 082 return inDataSet; 083 } 084 085 /** 086 * Determines if the item is a standard tag, e.g. from the presets. 087 * @return {@code true} if the item is a standard tag, e.g. from the presets 088 */ 089 public boolean isInStandard() { 090 return inStandard; 091 } 092 093 /** 094 * Determines if it is found on an object that is currently selected. 095 * @return {@code true} if it is found on an object that is currently selected 096 */ 097 public boolean isSelected() { 098 return selected; 099 } 100 101 /** 102 * Returns a number when the tag key / value has been entered by the user before. 103 * A lower number means this happened more recently and beats a higher number in priority. 104 * @return a number when the tag key / value has been entered by the user before. 105 * {@code null}, if the user hasn't entered this tag so far. 106 */ 107 public Integer getUserInput() { 108 return userInput == NO_USER_INPUT ? null : userInput; 109 } 110 111 /** 112 * Imposes an ordering on the priorities. 113 * Currently, being in the current DataSet is worth more than being in the Presets. 114 */ 115 @Override 116 public int compareTo(AutoCompletionPriority other) { 117 int ui = Integer.compare(other.userInput, userInput); 118 if (ui != 0) 119 return ui; 120 121 int sel = Boolean.compare(selected, other.selected); 122 if (sel != 0) 123 return sel; 124 125 int ds = Boolean.compare(inDataSet, other.inDataSet); 126 if (ds != 0) 127 return ds; 128 129 int std = Boolean.compare(inStandard, other.inStandard); 130 if (std != 0) 131 return std; 132 133 return 0; 134 } 135 136 /** 137 * Merges two priorities. 138 * The resulting priority is always >= the original ones. 139 * @param other other priority 140 * @return the merged priority 141 */ 142 public AutoCompletionPriority mergeWith(AutoCompletionPriority other) { 143 return new AutoCompletionPriority( 144 inDataSet || other.inDataSet, 145 inStandard || other.inStandard, 146 selected || other.selected, 147 Math.min(userInput, other.userInput)); 148 } 149 150 @Override 151 public int hashCode() { 152 return Objects.hash(inDataSet, inStandard, selected, userInput); 153 } 154 155 @Override 156 public boolean equals(Object obj) { 157 if (this == obj) 158 return true; 159 if (obj == null || getClass() != obj.getClass()) 160 return false; 161 AutoCompletionPriority other = (AutoCompletionPriority) obj; 162 return inDataSet == other.inDataSet && 163 inStandard == other.inStandard && 164 selected == other.selected && 165 userInput == other.userInput; 166 } 167 168 @Override 169 public String toString() { 170 return String.format("<Priority; userInput: %s, inDataSet: %b, inStandard: %b, selected: %b>", 171 userInput == NO_USER_INPUT ? "no" : Integer.toString(userInput), inDataSet, inStandard, selected); 172 } 173}