blob: 1db20c123e49ba81c5c6d3375cb6c08a8ba01cbd [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2014, 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.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.StyledString.Styler;
import org.eclipse.search.ui.text.Match;
import org.eclipse.statet.ecommons.ui.workbench.DecoratingStyledLabelProvider;
public class TextSearchLabelUtil {
public static final String HIGHLIGHT_COLOR_KEY= "org.eclipse.search.ui.match.highlight"; //$NON-NLS-1$
public static final Styler HIGHLIGHT_STYLE= StyledString.createColorRegistryStyler(null, HIGHLIGHT_COLOR_KEY);
public static final Collection<String> DEFAULT_SEARCH_LABEL_PROPERTIES;
static {
final Set<String> properties= new HashSet<>();
properties.addAll(DecoratingStyledLabelProvider.DEFAULT_UPDATE_PROPERTIES);
properties.add(TextSearchLabelUtil.HIGHLIGHT_COLOR_KEY);
DEFAULT_SEARCH_LABEL_PROPERTIES= Collections.unmodifiableSet(properties);
}
private static final int MAX_SHOWN_LINE= 200;
private static final int MIN_SHOWN_CONTEXT= 20;
private static final String ELLIPSIS= " ... "; //$NON-NLS-1$
public TextSearchLabelUtil() {
}
private int findStart(final String text, int offset, final int maxCount) {
final int end= Math.min(offset + maxCount, text.length());
while (offset < end) {
final char c= text.charAt(offset);
if (Character.isWhitespace(c)) {
offset++;
}
else {
break;
}
}
return offset;
}
private int findEnd(final String text, int offset, final int maxCount) {
final int start= Math.min(offset - maxCount, 0);
while (offset > start) {
final char c= text.charAt(offset - 1);
if (Character.isWhitespace(c)) {
offset--;
}
else {
break;
}
}
return offset;
}
public StyledString getStyledText(final LineElement<?> lineElement, final List<? extends Match> matches) {
final int lineNumber= lineElement.getLine();
final StyledString text= new StyledString(lineNumber + ": ", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
final String lineText= lineElement.getText();
int idx= findStart(lineText, 0, lineText.length()); // index in lineText
for (int i= 0; i < matches.size() && text.length() < MAX_SHOWN_LINE; i++) {
final Match match= matches.get(i);
final int matchStart= Math.max(match.getOffset() - lineElement.getOffset(), 0);
final int matchEnd= Math.min(match.getOffset() + match.getLength() - lineElement.getOffset(), lineElement.getLength());
if (matchStart - idx < MIN_SHOWN_CONTEXT * 2 + 10) {
text.append(lineText.substring(idx, matchStart));
}
else {
text.append(lineText.substring(
idx,
findEnd(lineText, idx + MIN_SHOWN_CONTEXT, MIN_SHOWN_CONTEXT) ));
text.append(ELLIPSIS, StyledString.QUALIFIER_STYLER);
text.append(lineText.substring(
findStart(lineText, matchStart - MIN_SHOWN_CONTEXT, MIN_SHOWN_CONTEXT),
matchStart ));
}
text.append(lineText.substring(matchStart, matchEnd), TextSearchLabelUtil.HIGHLIGHT_STYLE);
idx= matchEnd;
}
if (idx < lineText.length()) {
if (lineText.length() - idx < MIN_SHOWN_CONTEXT + 10) {
text.append(lineText.substring(idx, lineText.length()));
}
else {
text.append(lineText.substring(
idx,
findEnd(lineText, idx + MIN_SHOWN_CONTEXT, MIN_SHOWN_CONTEXT) ));
text.append(ELLIPSIS, StyledString.QUALIFIER_STYLER);
}
}
return text;
}
}