blob: ae3f267542f8827de4381ead10cccf96ff910d39 [file] [log] [blame]
/*=============================================================================#
# 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);
}
}
}