|
20 | 20 | import java.util.Comparator;
|
21 | 21 | import java.util.HashMap;
|
22 | 22 | import java.util.Iterator;
|
| 23 | +import java.util.List; |
23 | 24 | import java.util.Map;
|
24 | 25 | import org.eclipse.core.commands.ParameterizedCommand;
|
25 | 26 | import org.eclipse.core.commands.contexts.Context;
|
| 27 | +import org.eclipse.e4.core.services.contributions.IContributionFactory; |
| 28 | +import org.eclipse.e4.ui.model.application.MApplication; |
26 | 29 | import org.eclipse.jface.bindings.Binding;
|
27 | 30 | import org.eclipse.jface.bindings.Trigger;
|
28 | 31 | import org.eclipse.jface.bindings.TriggerSequence;
|
@@ -130,9 +133,15 @@ private final int countStrokes(final Trigger[] triggers) {
|
130 | 133 | private Map<TriggerSequence, ArrayList<Binding>> bindingsByPrefix = new HashMap<>();
|
131 | 134 | private Map<TriggerSequence, ArrayList<Binding>> conflicts = new HashMap<>();
|
132 | 135 | private Map<TriggerSequence, ArrayList<Binding>> orderedBindingsByTrigger = new HashMap<>();
|
| 136 | + private final Map<Binding, Boolean> activeBindings = new HashMap<>(); |
133 | 137 |
|
134 |
| - public BindingTable(Context context) { |
| 138 | + private IContributionFactory contributionFactory; |
| 139 | + |
| 140 | + private MApplication application; |
| 141 | + |
| 142 | + public BindingTable(Context context, MApplication application) { |
135 | 143 | tableId = context;
|
| 144 | + this.application = application; |
136 | 145 | }
|
137 | 146 |
|
138 | 147 | public Context getTableId() {
|
@@ -254,6 +263,7 @@ public void removeBinding(Binding binding) {
|
254 | 263 | evaluateOrderedBindings(binding.getTriggerSequence(), null);
|
255 | 264 | }
|
256 | 265 | }
|
| 266 | + activeBindings.remove(binding); |
257 | 267 | }
|
258 | 268 |
|
259 | 269 | private void evaluateOrderedBindings(TriggerSequence sequence, Binding binding) {
|
@@ -309,34 +319,76 @@ private void evaluateOrderedBindings(TriggerSequence sequence, Binding binding)
|
309 | 319 | }
|
310 | 320 |
|
311 | 321 | public Binding getPerfectMatch(TriggerSequence trigger) {
|
312 |
| - return bindingsByTrigger.get(trigger); |
| 322 | + Binding binding = bindingsByTrigger.get(trigger); |
| 323 | + if (isActive(binding)) { |
| 324 | + return binding; |
| 325 | + } |
| 326 | + return null; |
313 | 327 | }
|
314 | 328 |
|
315 | 329 | public Binding getBestSequenceFor(ParameterizedCommand command) {
|
316 | 330 | ArrayList<Binding> sequences = bindingsByCommand.get(command);
|
317 |
| - if (sequences != null && sequences.size() > 0) { |
318 |
| - return sequences.get(0); |
| 331 | + if (sequences != null) { |
| 332 | + for (Binding binding : sequences) { |
| 333 | + if (isActive(binding)) { |
| 334 | + return binding; |
| 335 | + } |
| 336 | + } |
319 | 337 | }
|
320 | 338 | return null;
|
321 | 339 | }
|
322 | 340 |
|
323 | 341 | @SuppressWarnings("unchecked")
|
324 | 342 | public Collection<Binding> getSequencesFor(ParameterizedCommand command) {
|
325 | 343 | ArrayList<Binding> triggers = bindingsByCommand.get(command);
|
326 |
| - return (Collection<Binding>) (triggers == null ? Collections.emptyList() : triggers.clone()); |
| 344 | + return (Collection<Binding>) (triggers == null ? Collections.emptyList() : getActive(triggers)); |
327 | 345 | }
|
328 | 346 |
|
329 | 347 | public Collection<Binding> getPartialMatches(TriggerSequence sequence) {
|
330 |
| - return bindingsByPrefix.get(sequence); |
| 348 | + return getActive(bindingsByPrefix.get(sequence)); |
331 | 349 | }
|
332 | 350 |
|
333 | 351 | public boolean isPartialMatch(TriggerSequence seq) {
|
334 | 352 | ArrayList<Binding> values = bindingsByPrefix.get(seq);
|
335 |
| - return values != null && !values.isEmpty(); |
| 353 | + return values != null && !getActive(values).isEmpty(); |
336 | 354 | }
|
337 | 355 |
|
338 | 356 | public Collection<Binding> getBindings() {
|
339 |
| - return Collections.unmodifiableCollection(bindings); |
| 357 | + return Collections.unmodifiableCollection(getActive(bindings)); |
| 358 | + } |
| 359 | + |
| 360 | + List<Binding> getActive(List<Binding> bindings) { |
| 361 | + return bindings == null ? null : bindings.stream().filter(b -> isActive(b)).toList(); |
340 | 362 | }
|
341 | 363 |
|
| 364 | + private boolean isActive(final Binding binding) { |
| 365 | + if (binding == null) { |
| 366 | + return false; |
| 367 | + } |
| 368 | + Boolean cachedValue = activeBindings.get(binding); |
| 369 | + if (cachedValue != null) { |
| 370 | + return cachedValue; |
| 371 | + } |
| 372 | + ParameterizedCommand command = binding.getParameterizedCommand(); |
| 373 | + if (command == null) { |
| 374 | + // Binding without command is "unbound", so can't be active |
| 375 | + // We don't cache in case command will be added in preferences |
| 376 | + return false; |
| 377 | + } |
| 378 | + String identifierId = command.getId(); |
| 379 | + if (contributionFactory == null) { |
| 380 | + contributionFactory = application.getContext().get(IContributionFactory.class); |
| 381 | + } |
| 382 | + if (contributionFactory == null) { |
| 383 | + // Something went wrong, let assume binding is active |
| 384 | + return true; |
| 385 | + } |
| 386 | + boolean currentValue = contributionFactory.isEnabled(identifierId); |
| 387 | + activeBindings.put(binding, currentValue); |
| 388 | + return currentValue; |
| 389 | + } |
| 390 | + |
| 391 | + public void activitiesChanged() { |
| 392 | + activeBindings.clear(); |
| 393 | + } |
342 | 394 | }
|
0 commit comments