1 /*******************************************************************************
2 * Copyright (c) 2000, 2011 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.ui.search;
13 import java.util.HashMap;
14 import java.util.Iterator;
17 import org.eclipse.swt.graphics.Color;
18 import org.eclipse.swt.graphics.Image;
19 import org.eclipse.swt.graphics.RGB;
21 import org.eclipse.core.runtime.preferences.InstanceScope;
23 import org.eclipse.jface.preference.PreferenceConverter;
24 import org.eclipse.jface.util.IPropertyChangeListener;
25 import org.eclipse.jface.util.PropertyChangeEvent;
26 import org.eclipse.jface.viewers.ILabelProvider;
27 import org.eclipse.jface.viewers.ILabelProviderListener;
28 import org.eclipse.jface.viewers.LabelProviderChangedEvent;
29 import org.eclipse.jface.viewers.StyledCellLabelProvider;
30 import org.eclipse.jface.viewers.StyledString;
31 import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
33 import org.eclipse.ui.preferences.ScopedPreferenceStore;
35 import org.eclipse.search.ui.NewSearchUI;
36 import org.eclipse.search.ui.text.AbstractTextSearchResult;
37 import org.eclipse.search.ui.text.Match;
39 import org.eclipse.jdt.core.search.SearchMatch;
41 import org.eclipse.jdt.internal.corext.util.Messages;
43 import org.eclipse.jdt.ui.JavaElementLabels;
44 import org.eclipse.jdt.ui.ProblemsLabelDecorator;
45 import org.eclipse.jdt.ui.search.IMatchPresentation;
47 import org.eclipse.jdt.internal.ui.JavaPlugin;
48 import org.eclipse.jdt.internal.ui.viewsupport.AppearanceAwareLabelProvider;
51 public abstract class SearchLabelProvider extends AppearanceAwareLabelProvider {
53 public static final String PROPERTY_MATCH_COUNT= "org.eclipse.jdt.search.matchCount"; //$NON-NLS-1$
55 // copied from SearchPreferencePage
56 private static final String EMPHASIZE_POTENTIAL_MATCHES= "org.eclipse.search.potentialMatch.emphasize"; //$NON-NLS-1$
57 private static final String POTENTIAL_MATCH_FG_COLOR= "org.eclipse.search.potentialMatch.fgColor"; //$NON-NLS-1$
59 protected static final long DEFAULT_SEARCH_TEXTFLAGS= (DEFAULT_TEXTFLAGS | JavaElementLabels.P_COMPRESSED) & ~JavaElementLabels.M_APP_RETURNTYPE;
60 protected static final int DEFAULT_SEARCH_IMAGEFLAGS= DEFAULT_IMAGEFLAGS;
62 private Color fPotentialMatchFgColor;
63 private Map<IMatchPresentation, ILabelProvider> fLabelProviderMap;
65 protected JavaSearchResultPage fPage;
67 private ScopedPreferenceStore fSearchPreferences;
68 private IPropertyChangeListener fSearchPropertyListener;
71 public SearchLabelProvider(JavaSearchResultPage page) {
72 super(DEFAULT_SEARCH_TEXTFLAGS, DEFAULT_SEARCH_IMAGEFLAGS);
73 addLabelDecorator(new ProblemsLabelDecorator(null));
76 fLabelProviderMap= new HashMap<IMatchPresentation, ILabelProvider>(5);
78 fSearchPreferences= new ScopedPreferenceStore(InstanceScope.INSTANCE, NewSearchUI.PLUGIN_ID);
79 fSearchPropertyListener= new IPropertyChangeListener() {
80 public void propertyChange(PropertyChangeEvent event) {
81 doSearchPropertyChange(event);
84 fSearchPreferences.addPropertyChangeListener(fSearchPropertyListener);
87 final void doSearchPropertyChange(PropertyChangeEvent event) {
88 if (fPotentialMatchFgColor == null)
90 if (POTENTIAL_MATCH_FG_COLOR.equals(event.getProperty()) || EMPHASIZE_POTENTIAL_MATCHES.equals(event.getProperty())) {
91 fPotentialMatchFgColor.dispose();
92 fPotentialMatchFgColor= null;
93 LabelProviderChangedEvent lpEvent= new LabelProviderChangedEvent(SearchLabelProvider.this, null); // refresh all
94 fireLabelProviderChanged(lpEvent);
99 public Color getForeground(Object element) {
100 if (arePotentialMatchesEmphasized()) {
101 if (getNumberOfPotentialMatches(element) > 0)
102 return getForegroundColor();
104 return super.getForeground(element);
107 private Color getForegroundColor() {
108 if (fPotentialMatchFgColor == null) {
109 fPotentialMatchFgColor= new Color(JavaPlugin.getActiveWorkbenchShell().getDisplay(), getPotentialMatchForegroundColor());
111 return fPotentialMatchFgColor;
114 protected final int getNumberOfPotentialMatches(Object element) {
116 AbstractTextSearchResult result= fPage.getInput();
117 if (result != null) {
118 Match[] matches= result.getMatches(element);
119 for (int i = 0; i < matches.length; i++) {
120 if ((matches[i]) instanceof JavaElementMatch) {
121 if (((JavaElementMatch)matches[i]).getAccuracy() == SearchMatch.A_INACCURATE)
129 protected final StyledString getColoredLabelWithCounts(Object element, StyledString coloredName) {
130 String name= coloredName.getString();
131 String decorated= getLabelWithCounts(element, name);
132 if (decorated.length() > name.length()) {
133 StyledCellLabelProvider.styleDecoratedString(decorated, StyledString.COUNTER_STYLER, coloredName);
138 protected final String getLabelWithCounts(Object element, String elementName) {
139 int matchCount= fPage.getDisplayedMatchCount(element);
140 int potentialCount= getNumberOfPotentialMatches(element);
142 if (matchCount < 2) {
143 if (matchCount == 1 && hasChildren(element)) {
144 if (potentialCount > 0)
145 return Messages.format(SearchMessages.SearchLabelProvider_potential_singular, elementName);
146 return Messages.format(SearchMessages.SearchLabelProvider_exact_singular, elementName);
148 if (potentialCount > 0)
149 return Messages.format(SearchMessages.SearchLabelProvider_potential_noCount, elementName);
150 return Messages.format(SearchMessages.SearchLabelProvider_exact_noCount, elementName);
152 int exactCount= matchCount - potentialCount;
154 if (potentialCount > 0 && exactCount > 0) {
155 String[] args= new String[] { elementName, String.valueOf(matchCount), String.valueOf(exactCount), String.valueOf(potentialCount) };
156 return Messages.format(SearchMessages.SearchLabelProvider_exact_and_potential_plural, args);
157 } else if (exactCount == 0) {
158 String[] args= new String[] { elementName, String.valueOf(matchCount) };
159 return Messages.format(SearchMessages.SearchLabelProvider_potential_plural, args);
161 String[] args= new String[] { elementName, String.valueOf(matchCount) };
162 return Messages.format(SearchMessages.SearchLabelProvider_exact_plural, args);
167 * Returns <code>true</code> if the given element has children
168 * @param elem the element
169 * @return returns <code>true</code> if the given element has children
171 protected boolean hasChildren(Object elem) {
176 public void dispose() {
177 if (fPotentialMatchFgColor != null) {
178 fPotentialMatchFgColor.dispose();
179 fPotentialMatchFgColor= null;
181 fSearchPreferences.removePropertyChangeListener(fSearchPropertyListener);
182 for (Iterator<ILabelProvider> labelProviders = fLabelProviderMap.values().iterator(); labelProviders.hasNext();) {
183 ILabelProvider labelProvider = labelProviders.next();
184 labelProvider.dispose();
187 fSearchPreferences= null;
188 fSearchPropertyListener= null;
189 fLabelProviderMap.clear();
195 public void addListener(ILabelProviderListener listener) {
196 super.addListener(listener);
197 for (Iterator<ILabelProvider> labelProviders = fLabelProviderMap.values().iterator(); labelProviders.hasNext();) {
198 ILabelProvider labelProvider = labelProviders.next();
199 labelProvider.addListener(listener);
204 public boolean isLabelProperty(Object element, String property) {
205 if (PROPERTY_MATCH_COUNT.equals(property))
207 return getLabelProvider(element).isLabelProperty(element, property);
211 public void removeListener(ILabelProviderListener listener) {
212 super.removeListener(listener);
213 for (Iterator<ILabelProvider> labelProviders = fLabelProviderMap.values().iterator(); labelProviders.hasNext();) {
214 ILabelProvider labelProvider = labelProviders.next();
215 labelProvider.removeListener(listener);
219 protected String getParticipantText(Object element) {
220 ILabelProvider labelProvider= getLabelProvider(element);
221 if (labelProvider != null)
222 return labelProvider.getText(element);
223 return ""; //$NON-NLS-1$
227 protected StyledString getStyledParticipantText(Object element) {
228 ILabelProvider labelProvider= getLabelProvider(element);
229 if (labelProvider instanceof IStyledLabelProvider)
230 return ((IStyledLabelProvider) labelProvider).getStyledText(element);
231 if (labelProvider != null)
232 return new StyledString(labelProvider.getText(element));
233 return new StyledString();
236 protected Image getParticipantImage(Object element) {
237 ILabelProvider lp= getLabelProvider(element);
240 return lp.getImage(element);
243 private ILabelProvider getLabelProvider(Object element) {
244 AbstractTextSearchResult input= fPage.getInput();
245 if (!(input instanceof JavaSearchResult))
248 IMatchPresentation participant= ((JavaSearchResult) input).getSearchParticpant(element);
249 if (participant == null)
252 ILabelProvider lp= fLabelProviderMap.get(participant);
254 lp= participant.createLabelProvider();
255 fLabelProviderMap.put(participant, lp);
257 Object[] listeners= fListeners.getListeners();
258 for (int i= 0; i < listeners.length; i++) {
259 lp.addListener((ILabelProviderListener) listeners[i]);
265 private boolean arePotentialMatchesEmphasized() {
266 return fSearchPreferences.getBoolean(EMPHASIZE_POTENTIAL_MATCHES);
269 private RGB getPotentialMatchForegroundColor() {
270 return PreferenceConverter.getColor(fSearchPreferences, POTENTIAL_MATCH_FG_COLOR);