Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ private void setMatcherString(String pattern) {
stringMatcherUpdated();
}

private SearchPattern getMatcher() {
protected SearchPattern getMatcher() {
return fSearchPattern;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,21 @@
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering;
import org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer;
import org.eclipse.e4.ui.workbench.swt.internal.copy.SearchPattern;
import org.eclipse.e4.ui.workbench.swt.internal.copy.StyledStringHighlighter;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.BoldStylerProvider;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
Expand All @@ -46,9 +54,10 @@

public class BasicPartList extends AbstractTableInformationControl {

private class BasicStackListLabelProvider extends ColumnLabelProvider {
private class BasicStackListLabelProvider extends StyledCellLabelProvider implements ILabelProvider {

private final Font boldFont;
private BoldStylerProvider boldStylerProvider;

public BasicStackListLabelProvider() {
Font font = Display.getDefault().getSystemFont();
Expand All @@ -60,14 +69,45 @@ public BasicStackListLabelProvider() {
}

@Override
public Font getFont(Object element) {
public void update(ViewerCell cell) {
Object element = cell.getElement();
String text = getText(element);
cell.setText(text);
cell.setImage(getImage(element));
cell.setFont(isHidden(element) ? boldFont : null);

SearchPattern matcher = getMatcher();
if (matcher == null || text == null || text.isEmpty()) {
cell.setStyleRanges(null);
} else {
int prefixOffset = text.startsWith("*") ? 1 : 0; //$NON-NLS-1$
String unprefixed = text.substring(prefixOffset);
StyledString styled = new StyledStringHighlighter().highlight(unprefixed, matcher.getPattern(),
getBoldStylerProvider().getBoldStyler());
StyleRange[] ranges = styled.getStyleRanges();
if (prefixOffset > 0) {
for (StyleRange range : ranges) {
range.start += prefixOffset;
}
}
cell.setStyleRanges(ranges);
}
super.update(cell);
}

private boolean isHidden(Object element) {
if (element instanceof MPart part) {
CTabItem item = renderer.findItemForPart(part);
if (item != null && !item.isShowing()) {
return boldFont;
}
return item != null && !item.isShowing();
}
return super.getFont(element);
return false;
}

private BoldStylerProvider getBoldStylerProvider() {
if (boldStylerProvider == null) {
boldStylerProvider = new BoldStylerProvider(boldFont);
}
return boldStylerProvider;
}

@Override
Expand All @@ -81,7 +121,6 @@ public String getText(Object element) {

@Override
public Image getImage(Object element) {
// Check if icons should be hidden for view tabs
if (shouldHideIcons()) {
return null;
}
Expand All @@ -98,8 +137,28 @@ public boolean useNativeToolTip(Object object) {
return true;
}

@Override
public void addListener(ILabelProviderListener listener) {
// no-op
}

@Override
public void removeListener(ILabelProviderListener listener) {
// no-op
}

@Override
public boolean isLabelProperty(Object element, String property) {
return false;
}

@Override
public void dispose() {
super.dispose();
if (boldStylerProvider != null) {
boldStylerProvider.dispose();
boldStylerProvider = null;
}
boldFont.dispose();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*******************************************************************************
* Copyright (c) 2019 Uenal Akkaya and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Uenal Akkaya - initial API and implementation
* Patrik Suzzi <psuzzi@gmail.com> - Bug 552144
*******************************************************************************/
package org.eclipse.e4.ui.workbench.swt.internal.copy;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.StyledString.Styler;

/**
* Internal copy of {@code org.eclipse.ui.dialogs.StyledStringHighlighter} so the
* e4 layer can highlight matches without depending on
* {@code org.eclipse.ui.workbench}.
*/
public class StyledStringHighlighter {

private static final String QUOTE_START = "(\\Q"; //$NON-NLS-1$
private static final String QUOTE_END = "\\E)"; //$NON-NLS-1$
private static final String DOT_STAR_LAZY = ".*?"; //$NON-NLS-1$
private static final String DOT = "."; //$NON-NLS-1$
private static final String QMARK = "?"; //$NON-NLS-1$
private static final String STAR = "*"; //$NON-NLS-1$
private static final char TERMINATOR = '<';

public StyledString highlight(String text, String pattern, Styler styler) {
if (text == null || text.isEmpty()) {
return new StyledString();
}
StyledString styledString = new StyledString(text);

if (pattern == null || pattern.isEmpty() //
|| STAR.equals(pattern) || QMARK.equals(pattern)) {
return styledString;
}

pattern = transformWildcardToRegex(pattern);

try {
highlight(text, pattern, styledString, styler);
} catch (Exception e) {
// in case of an exception a highlighting of the text won't take place
}

return styledString;
}

private static String transformWildcardToRegex(String pattern) {
char[] chars = pattern.toCharArray();
int len = chars.length;
StringBuilder sb = new StringBuilder();
boolean quoting = false;
boolean prevStar = false;
boolean prevChar = false;
for (int i = 0; i < len; i++) {
char c = chars[i];
boolean isWild = isWildcard(c);
if (isWild) {
if (quoting) {
sb.append(QUOTE_END);
quoting = false;
}
if (c == '*') {
if (prevStar) {
continue;
}
sb.append(DOT_STAR_LAZY);
} else {
sb.append(DOT);
}
if (i < len - 1 && !isWildcard(chars[i + 1])) {
sb.append(QUOTE_START);
quoting = true;
}
} else {
if (!quoting) {
sb.append(QUOTE_START);
quoting = true;
}
if (prevChar && Character.isUpperCase(c)) {
sb.append(QUOTE_END);
sb.append(DOT_STAR_LAZY);
sb.append(QUOTE_START);
}
if (c != TERMINATOR) {
sb.append(c);
}
if (i == len - 1) {
sb.append(QUOTE_END);
quoting = false;
}
}
prevChar = !isWild;
prevStar = c == '*';
}
return sb.toString();
}

private static boolean isWildcard(char c) {
return c == '?' || c == '*';
}

private void highlight(String text, String filterPattern, StyledString styledString, Styler boldStyler) {
Pattern pattern = Pattern.compile(filterPattern, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(text);

while (matcher.find()) {
int groupCount = matcher.groupCount();
if (groupCount == 0) {
styledString.setStyle(matcher.start(), matcher.end() - matcher.start(), boldStyler);
} else {
for (int i = 1; i <= groupCount; i++) {
styledString.setStyle(matcher.start(i), matcher.end(i) - matcher.start(i), boldStyler);
}
}
}
}

}
Loading