Lines 86-112
Link Here
|
86 |
MATCH_CASE, WHOLE_WORDS, REGULAR_EXPRESSION |
86 |
MATCH_CASE, WHOLE_WORDS, REGULAR_EXPRESSION |
87 |
} |
87 |
} |
88 |
|
88 |
|
89 |
/** |
|
|
90 |
* Options of search patterns that are not boolean, but can have more than |
91 |
* two values, e.g. {@link MatchType}. |
92 |
* |
93 |
* Please note that more items can be added to the enum in the future. |
94 |
* |
95 |
* @since api.search/1.11 |
96 |
*/ |
97 |
public enum MultiOption { |
98 |
|
99 |
MATCH_TYPE |
100 |
} |
101 |
|
102 |
private final Map<Option, AbstractButton> bindings = |
89 |
private final Map<Option, AbstractButton> bindings = |
103 |
new EnumMap<Option, AbstractButton>(Option.class); |
90 |
new EnumMap<Option, AbstractButton>(Option.class); |
104 |
private final Map<MultiOption, JComboBox> comboBindings = |
|
|
105 |
new EnumMap<MultiOption, JComboBox>(MultiOption.class); |
106 |
private final Map<Option, Boolean> options = |
91 |
private final Map<Option, Boolean> options = |
107 |
new EnumMap<Option, Boolean>(Option.class); |
92 |
new EnumMap<Option, Boolean>(Option.class); |
108 |
private final Map<MultiOption, Object> multiOptions = |
93 |
private JComboBox matchTypeComboBox = null; |
109 |
new EnumMap<MultiOption, Object>(MultiOption.class); |
94 |
private MatchType matchType = MatchType.LITERAL; |
110 |
private final ItemListener listener; |
95 |
private final ItemListener listener; |
111 |
private boolean valid; |
96 |
private boolean valid; |
112 |
private Color defaultTextColor = null; |
97 |
private Color defaultTextColor = null; |
Lines 161-178
Link Here
|
161 |
break; |
146 |
break; |
162 |
} |
147 |
} |
163 |
} |
148 |
} |
164 |
for (Map.Entry<MultiOption, JComboBox> be |
149 |
if (matchTypeComboBox != null) { |
165 |
: comboBindings.entrySet()) { |
150 |
matchTypeComboBox.setSelectedItem(sp.getMatchType()); |
166 |
switch (be.getKey()) { |
151 |
// set only to match type that is supported by the combo |
167 |
case MATCH_TYPE: |
152 |
matchType = |
168 |
be.getValue().setSelectedItem(sp.getMatchType()); |
153 |
(MatchType) matchTypeComboBox.getSelectedItem(); |
169 |
break; |
154 |
} else { |
170 |
} |
155 |
matchType = sp.getMatchType(); |
171 |
} |
156 |
} |
172 |
options.put(Option.MATCH_CASE, sp.isMatchCase()); |
157 |
options.put(Option.MATCH_CASE, sp.isMatchCase()); |
173 |
options.put(Option.WHOLE_WORDS, sp.isWholeWords()); |
158 |
options.put(Option.WHOLE_WORDS, sp.isWholeWords()); |
174 |
options.put(Option.REGULAR_EXPRESSION, sp.isRegExp()); |
159 |
options.put(Option.REGULAR_EXPRESSION, sp.isRegExp()); |
175 |
multiOptions.put(MultiOption.MATCH_TYPE, sp.getMatchType()); |
|
|
176 |
} |
160 |
} |
177 |
} |
161 |
} |
178 |
}); |
162 |
}); |
Lines 253-262
Link Here
|
253 |
button.setSelected(value); |
237 |
button.setSelected(value); |
254 |
} |
238 |
} |
255 |
if (option == Option.REGULAR_EXPRESSION) { |
239 |
if (option == Option.REGULAR_EXPRESSION) { |
256 |
if ((getOption(MultiOption.MATCH_TYPE) == MatchType.REGEXP) |
240 |
if ((matchType == MatchType.REGEXP) != value) { |
257 |
!= value) { |
241 |
setMatchType(value ? MatchType.REGEXP : MatchType.LITERAL); |
258 |
setOption(MultiOption.MATCH_TYPE, |
|
|
259 |
value ? MatchType.REGEXP : MatchType.LITERAL); |
260 |
} |
242 |
} |
261 |
updateValidity(); |
243 |
updateValidity(); |
262 |
} |
244 |
} |
Lines 264-294
Link Here
|
264 |
} |
246 |
} |
265 |
|
247 |
|
266 |
/** |
248 |
/** |
267 |
* Get current value of an option of the search pattern. |
|
|
268 |
*/ |
269 |
private Object getOption(MultiOption option) { |
270 |
Parameters.notNull("option", option); //NOI18N |
271 |
return multiOptions.get(option); |
272 |
} |
273 |
|
274 |
/** |
275 |
* Set value of a search pattern option. The correct item in corresponding |
249 |
* Set value of a search pattern option. The correct item in corresponding |
276 |
* combo box will be selected accordingly. |
250 |
* combo box will be selected accordingly. |
277 |
*/ |
251 |
*/ |
278 |
private void setOption(MultiOption option, Object value) { |
252 |
private void setMatchType(MatchType newMatchType) { |
279 |
Parameters.notNull("option", option); //NOI18N |
253 |
Parameters.notNull("matchType", matchType); //NOI18N |
280 |
multiOptions.put(option, value); |
254 |
if (matchTypeComboBox != null) { |
281 |
JComboBox combo = comboBindings.get(option); |
255 |
// use only match types contained in the combo box |
282 |
if (combo != null && combo.getSelectedItem() != value) { |
256 |
if (matchTypeComboBox.getSelectedItem() != newMatchType) |
283 |
combo.setSelectedItem(value); |
257 |
matchTypeComboBox.setSelectedItem(newMatchType); |
|
|
258 |
matchType = (MatchType) matchTypeComboBox.getSelectedItem(); |
259 |
} else { |
260 |
matchType = newMatchType; |
284 |
} |
261 |
} |
285 |
if (option == MultiOption.MATCH_TYPE) { |
262 |
if (matchTypeComboBox != null |
286 |
if (getOption(Option.REGULAR_EXPRESSION) |
263 |
&& matchTypeComboBox.getSelectedItem() != matchType) { |
287 |
!= (MatchType.REGEXP == value)) { |
264 |
matchTypeComboBox.setSelectedItem(matchType); |
288 |
setOption(Option.REGULAR_EXPRESSION, value == MatchType.REGEXP); |
|
|
289 |
} |
290 |
updateValidity(); |
291 |
} |
265 |
} |
|
|
266 |
if (getOption(Option.REGULAR_EXPRESSION) |
267 |
!= (MatchType.REGEXP == matchType)) { |
268 |
setOption(Option.REGULAR_EXPRESSION, matchType == MatchType.REGEXP); |
269 |
} |
270 |
updateValidity(); |
292 |
fireChange(); |
271 |
fireChange(); |
293 |
} |
272 |
} |
294 |
|
273 |
|
Lines 299-305
Link Here
|
299 |
return SearchPattern.create(getText(), |
278 |
return SearchPattern.create(getText(), |
300 |
getOption(Option.WHOLE_WORDS), |
279 |
getOption(Option.WHOLE_WORDS), |
301 |
getOption(Option.MATCH_CASE), |
280 |
getOption(Option.MATCH_CASE), |
302 |
(MatchType) getOption(MultiOption.MATCH_TYPE)); |
281 |
matchType); |
303 |
} |
282 |
} |
304 |
|
283 |
|
305 |
/** |
284 |
/** |
Lines 310-316
Link Here
|
310 |
setText(searchPattern.getSearchExpression()); |
289 |
setText(searchPattern.getSearchExpression()); |
311 |
setOption(Option.WHOLE_WORDS, searchPattern.isWholeWords()); |
290 |
setOption(Option.WHOLE_WORDS, searchPattern.isWholeWords()); |
312 |
setOption(Option.MATCH_CASE, searchPattern.isMatchCase()); |
291 |
setOption(Option.MATCH_CASE, searchPattern.isMatchCase()); |
313 |
setOption(MultiOption.MATCH_TYPE, searchPattern.getMatchType()); |
292 |
setMatchType(searchPattern.getMatchType()); |
314 |
} |
293 |
} |
315 |
|
294 |
|
316 |
/** |
295 |
/** |
Lines 340-368
Link Here
|
340 |
} |
319 |
} |
341 |
|
320 |
|
342 |
/** |
321 |
/** |
343 |
* Bind a combo box to a SearchPattern option. |
322 |
* Bind Match Type option to a combo box. |
344 |
* |
323 |
* |
345 |
* @param option Option whose value the button should represent. |
324 |
* @param comboBox Combo box to control and display the match type. The |
346 |
* @param comboBox Combo box to control and display the option. |
325 |
* model of the combo box can contain only items of type {@link MatchType}. |
|
|
326 |
* {@link MatchType.LITERAL} and {@link MatchType.REGEXP} are mandatory in |
327 |
* the model. |
347 |
* |
328 |
* |
348 |
* @since api.search/1.11 |
329 |
* @since api.search/1.11 |
349 |
*/ |
330 |
*/ |
350 |
public void bind(@NonNull final MultiOption option, |
331 |
public void bindMatchTypeComboBox(@NonNull final JComboBox comboBox) { |
351 |
@NonNull final JComboBox comboBox) { |
|
|
352 |
Parameters.notNull("option", option); //NOI18N |
353 |
Parameters.notNull("comboBox", comboBox); //NOI18N |
332 |
Parameters.notNull("comboBox", comboBox); //NOI18N |
354 |
|
333 |
|
355 |
if (comboBindings.containsKey(option)) { |
334 |
boolean regexpFound = false, literalFound = false; |
|
|
335 |
for (int i = 0; i < comboBox.getItemCount(); i++) { |
336 |
if (comboBox.getItemAt(i) == MatchType.LITERAL) { |
337 |
literalFound = true; |
338 |
} else if (comboBox.getItemAt(i) == MatchType.REGEXP) { |
339 |
regexpFound = true; |
340 |
} else if (!(comboBox.getItemAt(i) instanceof MatchType)) { |
341 |
throw new IllegalArgumentException("Model of the combo "//NOI18N |
342 |
+ "box can contain only MatchType items"); //NOI18N |
343 |
} |
344 |
} |
345 |
if (!(regexpFound && literalFound)) { |
346 |
throw new IllegalArgumentException( |
347 |
"At least MatchType.LITERAL and MatchType.REGEXP " //NOI18N |
348 |
+ "must be contained in the combo box model."); //NOI18N |
349 |
} |
350 |
if (matchTypeComboBox != null) { |
356 |
throw new IllegalStateException( |
351 |
throw new IllegalStateException( |
357 |
"Already bound with option " + option); // NOI18N |
352 |
"Already bound with option MATCH_TYPE"); //NOI18N |
358 |
} |
353 |
} |
359 |
|
354 |
this.matchTypeComboBox = comboBox; |
360 |
comboBindings.put(option, comboBox); |
355 |
comboBox.setEditable(false); |
361 |
comboBox.setSelectedItem(getOption(option)); |
356 |
setMatchType(this.matchType); //update match type, check it is supported |
|
|
357 |
comboBox.setSelectedItem(matchType); |
362 |
comboBox.addItemListener(new ItemListener() { |
358 |
comboBox.addItemListener(new ItemListener() { |
363 |
@Override |
359 |
@Override |
364 |
public void itemStateChanged(ItemEvent e) { |
360 |
public void itemStateChanged(ItemEvent e) { |
365 |
setOption(option, comboBox.getSelectedItem()); |
361 |
setMatchType((MatchType) comboBox.getSelectedItem()); |
366 |
} |
362 |
} |
367 |
}); |
363 |
}); |
368 |
} |
364 |
} |