| /*=============================================================================# |
| # Copyright (c) 2013, 2019 Stephan Wahlbrink and others. |
| # |
| # This program and the accompanying materials are made available under the |
| # terms of the Eclipse Public License 2.0 which is available at |
| # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
| # which is available at https://www.apache.org/licenses/LICENSE-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
| # |
| # Contributors: |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.ecommons.workbench.search.ui; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.jface.viewers.TableViewer; |
| import org.eclipse.search.ui.text.Match; |
| |
| import org.eclipse.statet.jcommons.collections.SortedListSet; |
| |
| import org.eclipse.statet.ecommons.collections.CategoryElementList; |
| |
| |
| public class TextSearchResultMatchTableContentProvider<E, M extends Match> |
| extends TextSearchResultContentProvider<E, M, TableViewer> { |
| |
| |
| protected final ElementMatchComparator<E, M> comparator; |
| |
| private final CategoryElementList<E, M> currentMatches; |
| |
| |
| public TextSearchResultMatchTableContentProvider(final ExtTextSearchResultPage<E, M> page, |
| final TableViewer viewer) { |
| super(page, viewer); |
| |
| this.comparator= page.comparator; |
| this.currentMatches= new CategoryElementList<>(this.comparator.getMatch0(), this.comparator); |
| } |
| |
| |
| @Override |
| protected void reset() { |
| super.reset(); |
| this.currentMatches.clear(); |
| } |
| |
| @Override |
| public Object[] getElements(final Object inputElement) { |
| if (!this.active) { |
| final ExtTextSearchResult<E, M> result= getInput(); |
| assert (result == inputElement); |
| if (result == null) { |
| return NO_ELEMENTS; |
| } |
| assert (this.currentMatches.isEmpty()); |
| |
| int limit= getElementLimit(); |
| |
| final E[] elements= result.getElements(); |
| for (int i= 0; i < elements.length && limit > 0; i++) { |
| final E element= elements[i]; |
| final M[] matches= result.getPickedMatches(element); |
| this.currentMatches.addAllE(this.currentMatches.size(), matches, 0, |
| Math.min(matches.length, limit) ); |
| limit-= matches.length; |
| } |
| this.active= true; |
| } |
| return this.currentMatches.toArray(); |
| } |
| |
| @Override |
| public void elementsChanged(final Object[] elements) { |
| if (!this.active) { |
| return; |
| } |
| final ExtTextSearchResult<E, M> result= getInput(); |
| final int limit= getElementLimit(); |
| |
| final TableViewer viewer= getViewer(); |
| |
| final List<M> toAdd= new ArrayList<>(); |
| final List<M> toUpdate= new ArrayList<>(); |
| final List<M> toRemove= new ArrayList<>(); |
| for (int i= 0; i < elements.length; i++) { |
| final E element= (E) elements[i]; |
| final M[] matches= result.getPickedMatches(element); |
| final SortedListSet<M> currentElementMatches= this.currentMatches.subList(element); |
| for (int j= 0; j < matches.length; j++) { |
| final M match= matches[j]; |
| int k; |
| if ((this.currentMatches.size() < limit)) { |
| k= currentElementMatches.addE(match); |
| if (k >= 0) { |
| toAdd.add(match); |
| } |
| else { |
| toUpdate.add(match); |
| k= -(k + 1); |
| } |
| } |
| else { |
| k= currentElementMatches.indexOf(match); |
| if (k >= 0) { |
| toUpdate.add(match); |
| } |
| else { |
| k= -(k + 1); |
| } |
| } |
| while (k > j) { |
| toRemove.add(currentElementMatches.remove(j)); |
| k--; |
| } |
| } |
| while (currentElementMatches.size() > matches.length) { |
| currentElementMatches.remove(matches.length); |
| } |
| } |
| |
| viewer.getTable().setRedraw(false); |
| try { |
| viewer.remove(toRemove.toArray()); |
| viewer.refresh(toUpdate.toArray(), true); |
| viewer.add(toAdd.toArray()); |
| } |
| finally { |
| viewer.getTable().setRedraw(true); |
| } |
| } |
| |
| } |