1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 09:46:02 +02:00

2005-08-27 Alain Magloire

Fix PR 108206: Do not use the UI thread when parsing
	the working copy for the outliner.
	* src/org/eclipse/cdt/internal/ui/CElementAdapterFactory.java
	* src/org/eclipse/cdt/internal/ui/DeferredCWorkbenchAdapter.java
	* src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java
	* src/org/eclipse/cdt/internal/ui/editor/CContentOutlineProvider.java
This commit is contained in:
Alain Magloire 2005-08-27 22:50:52 +00:00
parent a43ab33c8c
commit 41d098da72
5 changed files with 421 additions and 358 deletions

View file

@ -1,3 +1,11 @@
2005-08-27 Alain Magloire
Fix PR 108206: Do not use the UI thread when parsing
the working copy for the outliner.
* src/org/eclipse/cdt/internal/ui/CElementAdapterFactory.java
* src/org/eclipse/cdt/internal/ui/DeferredCWorkbenchAdapter.java
* src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java
* src/org/eclipse/cdt/internal/ui/editor/CContentOutlineProvider.java
2005-08-27 Alain Magloire 2005-08-27 Alain Magloire
Fix PR 108205: limit the number of refresh by ignoring WorkingCopies events. Fix PR 108205: limit the number of refresh by ignoring WorkingCopies events.
* src/org/eclipse/cdt/ui/CElementContentProvider.java * src/org/eclipse/cdt/ui/CElementContentProvider.java

View file

@ -40,8 +40,7 @@ public class CElementAdapterFactory implements IAdapterFactory {
IActionFilter.class IActionFilter.class
}; };
private static CWorkbenchAdapter fgCWorkbenchAdapter= new CWorkbenchAdapter(); private static CWorkbenchAdapter fgCWorkbenchAdapter;
private static DeferredCWorkbenchAdapter fgDeferredCWorkbenchAdapter= new DeferredCWorkbenchAdapter();
/** /**
* @see CElementAdapterFactory#getAdapterList * @see CElementAdapterFactory#getAdapterList
@ -55,37 +54,63 @@ public class CElementAdapterFactory implements IAdapterFactory {
*/ */
public Object getAdapter(Object element, Class key) { public Object getAdapter(Object element, Class key) {
ICElement celem = (ICElement) element; ICElement celem = (ICElement) element;
IResource res = null;
if (IPropertySource.class.equals(key)) { if (IPropertySource.class.equals(key)) {
if (celem instanceof IBinary) { return getPropertySource(celem);
return new BinaryPropertySource((IBinary)celem);
}
res = celem.getResource();
if (res != null) {
if (res instanceof IFile) {
return new FilePropertySource((IFile)res);
}
return new ResourcePropertySource(res);
}
return new CElementPropertySource(celem);
} else if (IWorkspaceRoot.class.equals(key)) { } else if (IWorkspaceRoot.class.equals(key)) {
res = celem.getUnderlyingResource(); return getWorkspaceRoot(celem);
if (res != null)
return res.getWorkspace().getRoot();
} else if (IProject.class.equals(key)) { } else if (IProject.class.equals(key)) {
res = celem.getResource(); return getProject(celem);
if (res != null)
return res.getProject();
} else if (IResource.class.equals(key)) { } else if (IResource.class.equals(key)) {
return celem.getResource(); return getResource(celem);
} else if (IDeferredWorkbenchAdapter.class.equals(key)) { } else if (IDeferredWorkbenchAdapter.class.equals(key)) {
return fgDeferredCWorkbenchAdapter; return getDeferredWorkbenchAdapter(celem);
} else if (IWorkbenchAdapter.class.equals(key)) { } else if (IWorkbenchAdapter.class.equals(key)) {
return fgCWorkbenchAdapter; return getWorkbenchAdapter(celem);
} else if (IActionFilter.class.equals(key)) { } else if (IActionFilter.class.equals(key)) {
return fgCWorkbenchAdapter; return getWorkbenchAdapter(celem);
} }
return null; return null;
} }
private IPropertySource getPropertySource(ICElement celement) {
if (celement instanceof IBinary) {
return new BinaryPropertySource((IBinary)celement);
}
IResource res = celement.getResource();
if (res != null) {
if (res instanceof IFile) {
return new FilePropertySource((IFile)res);
}
return new ResourcePropertySource(res);
}
return new CElementPropertySource(celement);
}
private IWorkspaceRoot getWorkspaceRoot(ICElement celement) {
IResource res = celement.getUnderlyingResource();
if (res != null) {
return res.getWorkspace().getRoot();
}
return null;
}
private IProject getProject(ICElement celement) {
return celement.getCProject().getProject();
}
private IResource getResource(ICElement celement) {
return celement.getResource();
}
private IDeferredWorkbenchAdapter getDeferredWorkbenchAdapter(ICElement celement) {
return new DeferredCWorkbenchAdapter(celement);
}
private IWorkbenchAdapter getWorkbenchAdapter(ICElement celement) {
if (fgCWorkbenchAdapter == null) {
fgCWorkbenchAdapter = new CWorkbenchAdapter();
}
return fgCWorkbenchAdapter;
}
} }

View file

@ -10,26 +10,21 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui; package org.eclipse.cdt.internal.ui;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.IParent; import org.eclipse.cdt.core.model.IParent;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.ui.progress.IDeferredWorkbenchAdapter; import org.eclipse.ui.progress.IDeferredWorkbenchAdapter;
import org.eclipse.ui.progress.IElementCollector; import org.eclipse.ui.progress.IElementCollector;
public class DeferredCWorkbenchAdapter extends CWorkbenchAdapter public class DeferredCWorkbenchAdapter extends CWorkbenchAdapter implements IDeferredWorkbenchAdapter {
implements IDeferredWorkbenchAdapter {
private static boolean fSerializeFetching = false; private ICElement fCElement;
private static boolean fBatchFetchedChildren = true;
final ISchedulingRule mutexRule = new ISchedulingRule() { public DeferredCWorkbenchAdapter(ICElement element) {
public boolean isConflicting(ISchedulingRule rule) { super();
return rule == mutexRule; fCElement = element;
} }
public boolean contains(ISchedulingRule rule) {
return rule == mutexRule;
}
};
/* /*
* (non-Javadoc) * (non-Javadoc)
@ -39,25 +34,12 @@ public class DeferredCWorkbenchAdapter extends CWorkbenchAdapter
* org.eclipse.core.runtime.IProgressMonitor) * org.eclipse.core.runtime.IProgressMonitor)
*/ */
public void fetchDeferredChildren(Object object, IElementCollector collector, IProgressMonitor monitor) { public void fetchDeferredChildren(Object object, IElementCollector collector, IProgressMonitor monitor) {
if (object instanceof IParent) { Object[] children = getChildren(object);
if (fBatchFetchedChildren) { if (monitor.isCanceled()) {
Object[] children = getChildren(object); return;
if (children.length > 0)
collector.add(children, monitor);
} else {
// TODO right now there is no advantage to this
// over the batched case above, but in the future
// we could have another method of progressively
// iterating over an ICElement's children
Object[] children = getChildren(object);
for (int i = 0; i < children.length; i++) {
if (monitor.isCanceled()) {
return;
}
collector.add(children[i], monitor);
}
}
} }
collector.add(children, monitor);
collector.done();
} }
/* /*
@ -66,7 +48,7 @@ public class DeferredCWorkbenchAdapter extends CWorkbenchAdapter
* @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#isContainer() * @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#isContainer()
*/ */
public boolean isContainer() { public boolean isContainer() {
return true; return fCElement instanceof IParent;
} }
/* /*
@ -75,11 +57,6 @@ public class DeferredCWorkbenchAdapter extends CWorkbenchAdapter
* @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#getRule(java.lang.Object) * @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#getRule(java.lang.Object)
*/ */
public ISchedulingRule getRule(final Object object) { public ISchedulingRule getRule(final Object object) {
if (fSerializeFetching) { return fCElement.getResource();
// only one ICElement parent can fetch children at a time
return mutexRule;
}
// allow several ICElement parents to fetch children concurrently
return null;
} }
} }

View file

@ -72,10 +72,11 @@ import org.eclipse.ui.views.navigator.LocalSelectionTransfer;
public class CContentOutlinePage extends Page implements IContentOutlinePage, ISelectionChangedListener { public class CContentOutlinePage extends Page implements IContentOutlinePage, ISelectionChangedListener {
private CEditor fEditor; private CEditor fEditor;
private ITranslationUnit fInput; private ITranslationUnit fInput;
private ProblemTreeViewer treeViewer; private ProblemTreeViewer fTreeViewer;
private ListenerList selectionChangedListeners = new ListenerList(); private ListenerList selectionChangedListeners = new ListenerList();
private TogglePresentationAction fTogglePresentation; private TogglePresentationAction fTogglePresentation;
private String fContextMenuId; private String fContextMenuId;
private Menu fMenu;
protected OpenIncludeAction fOpenIncludeAction; protected OpenIncludeAction fOpenIncludeAction;
private IncludeGroupingAction fIncludeGroupingAction; private IncludeGroupingAction fIncludeGroupingAction;
@ -248,19 +249,25 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
fRefactoringActionGroup.fillContextMenu(menu); fRefactoringActionGroup.fillContextMenu(menu);
} }
protected CContentOutlinerProvider createContentProvider(TreeViewer viewer) {
return new CContentOutlinerProvider(viewer, CUIPlugin.getActiveWorkbenchWindow().getActivePage().getActivePart().getSite());
}
protected ProblemTreeViewer createTreeViewer(Composite parent) {
fTreeViewer = new ProblemTreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
fTreeViewer.setContentProvider(createContentProvider(fTreeViewer));
fTreeViewer.setLabelProvider(new DecoratingCLabelProvider(new StandardCElementLabelProvider(), true));
fTreeViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
fTreeViewer.setUseHashlookup(true);
fTreeViewer.addSelectionChangedListener(this);
return fTreeViewer;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.ui.part.IPage#createControl(org.eclipse.swt.widgets.Composite) * @see org.eclipse.ui.part.IPage#createControl(org.eclipse.swt.widgets.Composite)
*/ */
public void createControl(Composite parent) { public void createControl(Composite parent) {
treeViewer = new ProblemTreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); fTreeViewer = createTreeViewer(parent);
//treeViewer.setContentProvider(new CElementContentProvider(true, true));
treeViewer.setContentProvider(new CContentOutlinerProvider(treeViewer));
treeViewer.setLabelProvider(new DecoratingCLabelProvider(new StandardCElementLabelProvider(), true));
treeViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
treeViewer.setUseHashlookup(true);
treeViewer.addSelectionChangedListener(this);
initDragAndDrop(); initDragAndDrop();
MenuManager manager= new MenuManager(fContextMenuId); MenuManager manager= new MenuManager(fContextMenuId);
@ -270,11 +277,11 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
contextMenuAboutToShow(manager); contextMenuAboutToShow(manager);
} }
}); });
Control control= treeViewer.getControl(); Control control= fTreeViewer.getControl();
Menu menu= manager.createContextMenu(control); fMenu= manager.createContextMenu(control);
control.setMenu(menu); control.setMenu(fMenu);
treeViewer.addDoubleClickListener(new IDoubleClickListener() { fTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent) * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent)
*/ */
@ -286,8 +293,8 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
}); });
// register global actions // register global actions
IPageSite site= getSite(); IPageSite site= getSite();
site.registerContextMenu(fContextMenuId, manager, treeViewer); site.registerContextMenu(fContextMenuId, manager, fTreeViewer);
site.setSelectionProvider(treeViewer); site.setSelectionProvider(fTreeViewer);
IActionBars bars= site.getActionBars(); IActionBars bars= site.getActionBars();
bars.setGlobalActionHandler(ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY, fTogglePresentation); bars.setGlobalActionHandler(ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY, fTogglePresentation);
@ -298,13 +305,16 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
// Custom filter group // Custom filter group
fCustomFiltersActionGroup= new CustomFiltersActionGroup("org.eclipse.cdt.ui.COutlinePage", getTreeViewer()); //$NON-NLS-1$ fCustomFiltersActionGroup= new CustomFiltersActionGroup("org.eclipse.cdt.ui.COutlinePage", getTreeViewer()); //$NON-NLS-1$
treeViewer.setInput(fInput); // Do this before setting input but after the initializations of the fields filtering
registerActionBars(bars);
fTreeViewer.setInput(fInput);
PlatformUI.getWorkbench().getHelpSystem().setHelp(control, ICHelpContextIds.COUTLINE_VIEW); PlatformUI.getWorkbench().getHelpSystem().setHelp(control, ICHelpContextIds.COUTLINE_VIEW);
} }
public void dispose() { public void dispose() {
if (treeViewer != null) { if (fTreeViewer != null) {
treeViewer.removeSelectionChangedListener(this); fTreeViewer.removeSelectionChangedListener(this);
} }
if (fTogglePresentation != null) { if (fTogglePresentation != null) {
@ -331,26 +341,33 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
fSelectionSearchGroup= null; fSelectionSearchGroup= null;
} }
if (fCustomFiltersActionGroup != null) {
fCustomFiltersActionGroup.dispose();
fCustomFiltersActionGroup= null;
}
if (selectionChangedListeners != null) { if (selectionChangedListeners != null) {
selectionChangedListeners.clear(); selectionChangedListeners.clear();
selectionChangedListeners= null; selectionChangedListeners= null;
} }
if (fMenu != null && !fMenu.isDisposed()) {
fMenu.dispose();
fMenu= null;
}
fInput= null; fInput= null;
super.dispose(); super.dispose();
} }
/* (non-Javadoc) private void registerActionBars(IActionBars actionBars) {
* @see org.eclipse.ui.part.IPage#setActionBars(org.eclipse.ui.IActionBars)
*/
public void setActionBars(IActionBars actionBars) {
IToolBarManager toolBarManager= actionBars.getToolBarManager(); IToolBarManager toolBarManager= actionBars.getToolBarManager();
LexicalSortingAction action= new LexicalSortingAction(getTreeViewer()); LexicalSortingAction action= new LexicalSortingAction(getTreeViewer());
toolBarManager.add(action); toolBarManager.add(action);
fMemberFilterActionGroup= new MemberFilterActionGroup(treeViewer, "COutlineViewer"); //$NON-NLS-1$ fMemberFilterActionGroup= new MemberFilterActionGroup(fTreeViewer, "COutlineViewer"); //$NON-NLS-1$
fMemberFilterActionGroup.fillActionBars(actionBars); fMemberFilterActionGroup.fillActionBars(actionBars);
fCustomFiltersActionGroup.fillActionBars(actionBars); fCustomFiltersActionGroup.fillActionBars(actionBars);
@ -391,18 +408,18 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
* Method declared on IPage (and Page). * Method declared on IPage (and Page).
*/ */
public Control getControl() { public Control getControl() {
if (treeViewer == null) if (fTreeViewer == null)
return null; return null;
return treeViewer.getControl(); return fTreeViewer.getControl();
} }
/* (non-Javadoc) /* (non-Javadoc)
* Method declared on ISelectionProvider. * Method declared on ISelectionProvider.
*/ */
public ISelection getSelection() { public ISelection getSelection() {
if (treeViewer == null) if (fTreeViewer == null)
return StructuredSelection.EMPTY; return StructuredSelection.EMPTY;
return treeViewer.getSelection(); return fTreeViewer.getSelection();
} }
/** /**
@ -412,7 +429,7 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
* <code>createControl</code> has not been called yet * <code>createControl</code> has not been called yet
*/ */
protected TreeViewer getTreeViewer() { protected TreeViewer getTreeViewer() {
return treeViewer; return fTreeViewer;
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -434,15 +451,15 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
* Sets focus to a part in the page. * Sets focus to a part in the page.
*/ */
public void setFocus() { public void setFocus() {
treeViewer.getControl().setFocus(); fTreeViewer.getControl().setFocus();
} }
/* (non-Javadoc) /* (non-Javadoc)
* Method declared on ISelectionProvider. * Method declared on ISelectionProvider.
*/ */
public void setSelection(ISelection selection) { public void setSelection(ISelection selection) {
if (treeViewer != null) if (fTreeViewer != null)
treeViewer.setSelection(selection); fTreeViewer.setSelection(selection);
} }
/** /**
@ -451,8 +468,8 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
*/ */
public void setInput(ITranslationUnit unit) { public void setInput(ITranslationUnit unit) {
fInput = unit; fInput = unit;
if (treeViewer != null) { if (fTreeViewer != null) {
treeViewer.setInput (fInput); fTreeViewer.setInput (fInput);
} }
} }
@ -464,15 +481,15 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
// Drop Adapter // Drop Adapter
TransferDropTargetListener[] dropListeners= new TransferDropTargetListener[] { TransferDropTargetListener[] dropListeners= new TransferDropTargetListener[] {
new SelectionTransferDropAdapter(treeViewer) new SelectionTransferDropAdapter(fTreeViewer)
}; };
treeViewer.addDropSupport(ops | DND.DROP_DEFAULT, transfers, new DelegatingDropAdapter(dropListeners)); fTreeViewer.addDropSupport(ops | DND.DROP_DEFAULT, transfers, new DelegatingDropAdapter(dropListeners));
// Drag Adapter // Drag Adapter
TransferDragSourceListener[] dragListeners= new TransferDragSourceListener[] { TransferDragSourceListener[] dragListeners= new TransferDragSourceListener[] {
new SelectionTransferDragAdapter(treeViewer) new SelectionTransferDragAdapter(fTreeViewer)
}; };
treeViewer.addDragSupport(ops, transfers, new CDTViewerDragAdapter(treeViewer, dragListeners)); fTreeViewer.addDragSupport(ops, transfers, new CDTViewerDragAdapter(fTreeViewer, dragListeners));
} }
} }

View file

@ -30,287 +30,323 @@ import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.Viewer;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.progress.DeferredTreeContentManager;
/** /**
* Manages contents of the outliner. * Manages contents of the outliner.
*/ */
public class CContentOutlinerProvider extends BaseCElementContentProvider { public class CContentOutlinerProvider extends BaseCElementContentProvider {
/** Tree viewer which handles this content provider. */ /** Tree viewer which handles this content provider. */
TreeViewer treeViewer; TreeViewer treeViewer;
/** Translation unit's root. */
ITranslationUnit root; /** Translation unit's root. */
/** Something changed listener. */ ITranslationUnit root;
private ElementChangedListener fListener;
/** Property change listener. */ /** Something changed listener. */
private ElementChangedListener fListener;
/** Property change listener. */
private IPropertyChangeListener fPropertyListener; private IPropertyChangeListener fPropertyListener;
/** Filter for files to outline. */
private String filter = "*"; //$NON-NLS-1$
/** /** Filter for files to outline. */
* Creates new content provider for dialog. private StringMatcher filter = new StringMatcher("*", true, false); //$NON-NLS-1$
* @param viewer Tree viewer.
*/
public CContentOutlinerProvider(TreeViewer viewer)
{
super(true, true);
treeViewer = viewer;
setIncludesGrouping(PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.OUTLINE_GROUP_INCLUDES));
}
/** /**
* Sets new filter and updates contents. * Remote content manager to retrieve content in the background.
* @param newFilter New filter. */
*/ private DeferredTreeContentManager fManager;
public void updateFilter(String newFilter)
{
filter = newFilter;
contentUpdated();
}
/** /**
* Called by the editor to signal that the content has updated. * We only want to use the DeferredContentManager, the first time
*/ * because the Outliner is initialize in the UI thread. So to not block
public void contentUpdated() * the UI thread we deferred, after it is not necessary the reconciler is
{ * running in a separate thread not affecting the UI.
if (treeViewer != null && !treeViewer.getControl().isDisposed()) */
{ private boolean fUseContentManager = false;
treeViewer.getControl().getDisplay().asyncExec(new Runnable()
{
public void run()
{
if (!treeViewer.getControl().isDisposed())
{
final ISelection sel = treeViewer.getSelection();
treeViewer.setSelection(updateSelection(sel));
treeViewer.refresh();
}
}
}
);
}
}
/** public CContentOutlinerProvider(TreeViewer viewer) {
* @see org.eclipse.jface.viewers.IContentProvider#dispose() this(viewer, null);
*/ }
public void dispose()
{
super.dispose();
if (fListener != null)
{
CoreModel.getDefault().removeElementChangedListener(fListener);
fListener = null;
}
if (fPropertyListener != null) {
PreferenceConstants.getPreferenceStore().removePropertyChangeListener(fPropertyListener);
fPropertyListener = null;
}
}
/** /**
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) * Creates new content provider for dialog.
*/ *
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) * @param viewer
{ * Tree viewer.
final boolean isTU = newInput instanceof ITranslationUnit; */
public CContentOutlinerProvider(TreeViewer viewer, IWorkbenchPartSite site) {
super(true, true);
treeViewer = viewer;
setIncludesGrouping(PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.OUTLINE_GROUP_INCLUDES));
fManager = createContentManager(viewer, site);
}
if (isTU && fListener == null) protected DeferredTreeContentManager createContentManager(TreeViewer viewer, IWorkbenchPartSite site) {
{ if (site == null) {
root = (ITranslationUnit) newInput; return new DeferredTreeContentManager(this, viewer);
fListener = new ElementChangedListener(); }
CoreModel.getDefault().addElementChangedListener(fListener); return new DeferredTreeContentManager(this, viewer, site);
fPropertyListener = new PropertyListener(); }
PreferenceConstants.getPreferenceStore().addPropertyChangeListener(fPropertyListener);
}
else if (!isTU && fListener != null)
{
CoreModel.getDefault().removeElementChangedListener(fListener);
fListener = null;
root = null;
}
}
/** /**
* @see org.eclipse.cdt.internal.ui.BaseCElementContentProvider#getChildren(java.lang.Object) * Sets new filter and updates contents.
*/ *
public Object[] getChildren(Object element) * @param newFilter
{ * New filter.
final StringMatcher stringMatcher = new StringMatcher(filter, true, false); */
Object[] children = super.getChildren(element); public void updateFilter(String newFilter) {
final List filtered = new ArrayList(); filter = new StringMatcher(newFilter, true, false);
for (int i = 0; i < children.length; i++) contentUpdated();
{ }
if (stringMatcher.match(children[i].toString()))
{
filtered.add(children[i]);
}
}
final int size = filtered.size();
children = new Object[size];
filtered.toArray(children);
return children;
}
/** /**
* Updates current selection. * Called by the editor to signal that the content has updated.
* @param sel Selection to update. */
* @return Updated selection. public void contentUpdated() {
*/ if (treeViewer != null && !treeViewer.getControl().isDisposed()) {
protected ISelection updateSelection(ISelection sel) treeViewer.getControl().getDisplay().asyncExec(new Runnable() {
{ public void run() {
final ArrayList newSelection = new ArrayList(); if (!treeViewer.getControl().isDisposed()) {
if (sel instanceof IStructuredSelection) final ISelection sel = treeViewer.getSelection();
{ treeViewer.setSelection(updateSelection(sel));
final Iterator iter = ((IStructuredSelection) sel).iterator(); treeViewer.refresh();
while (iter.hasNext()) }
{ }
final Object o = iter.next(); });
if (o instanceof ICElement) }
{ }
newSelection.add(o);
}
}
}
return new StructuredSelection(newSelection);
}
/** /**
* The element change listener of the C outline viewer. * @see org.eclipse.jface.viewers.IContentProvider#dispose()
* @see IElementChangedListener */
*/ public void dispose() {
class ElementChangedListener implements IElementChangedListener super.dispose();
{ if (fListener != null) {
CoreModel.getDefault().removeElementChangedListener(fListener);
fListener = null;
}
if (fPropertyListener != null) {
PreferenceConstants.getPreferenceStore().removePropertyChangeListener(fPropertyListener);
fPropertyListener = null;
}
if (root != null) {
fManager.cancel(root);
}
}
/** /**
* Default constructor. * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
*/ * java.lang.Object, java.lang.Object)
public ElementChangedListener() */
{ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
// nothing to initialize. boolean isTU = newInput instanceof ITranslationUnit;
}
/** if (isTU && fListener == null) {
* @see org.eclipse.cdt.core.model.IElementChangedListener#elementChanged(org.eclipse.cdt.core.model.ElementChangedEvent) fUseContentManager = true;
*/ if (root != null) {
public void elementChanged(final ElementChangedEvent e) fManager.cancel(root);
{ }
final ICElementDelta delta = findElement(root, e.getDelta()); root = (ITranslationUnit) newInput;
if (delta != null) fListener = new ElementChangedListener();
{ CoreModel.getDefault().addElementChangedListener(fListener);
contentUpdated(); fPropertyListener = new PropertyListener();
return; PreferenceConstants.getPreferenceStore().addPropertyChangeListener(
} fPropertyListener);
} } else if (!isTU && fListener != null) {
fUseContentManager = false;
CoreModel.getDefault().removeElementChangedListener(fListener);
fListener = null;
root = null;
if (oldInput != null) {
fManager.cancel(oldInput);
}
}
}
/** /**
* Determines is structural change. * @see org.eclipse.cdt.internal.ui.BaseCElementContentProvider#getChildren(java.lang.Object)
* @param cuDelta Delta to check. */
* @return <b>true</b> if structural change. public Object[] getChildren(Object element) {
*/ Object[] children = null;
private boolean isPossibleStructuralChange(ICElementDelta cuDelta) // Use the deferred manager for the first time (when parsing)
{ if (fUseContentManager && element instanceof ITranslationUnit) {
boolean ret; children = fManager.getChildren(element);
if (cuDelta.getKind() != ICElementDelta.CHANGED) fUseContentManager = false;
{ }
ret = true; // add or remove if (children == null) {
} children = super.getChildren(element);
else }
{ List filtered = new ArrayList();
final int flags = cuDelta.getFlags(); for (int i = 0; i < children.length; i++) {
if ((flags & ICElementDelta.F_CHILDREN) != 0) if (filter.match(children[i].toString())) {
{ filtered.add(children[i]);
ret = true; }
} }
else int size = filtered.size();
{ children = new Object[size];
ret = (flags & (ICElementDelta.F_CONTENT | ICElementDelta.F_FINE_GRAINED)) == ICElementDelta.F_CONTENT; filtered.toArray(children);
} return children;
} }
return ret;
}
/** /* (non-Javadoc)
* Searches for element. * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
* @param unit Unit to search in. */
* @param delta Delta. public boolean hasChildren(Object element) {
* @return Found element. if (fUseContentManager) {
*/ return fManager.mayHaveChildren(element);
protected ICElementDelta findElement(ICElement unit, ICElementDelta delta) }
{ return super.hasChildren(element);
if (delta == null || unit == null) }
{
return null;
}
final ICElement element = delta.getElement(); /**
* Updates current selection.
*
* @param sel
* Selection to update.
* @return Updated selection.
*/
protected ISelection updateSelection(ISelection sel) {
final ArrayList newSelection = new ArrayList();
if (sel instanceof IStructuredSelection) {
final Iterator iter = ((IStructuredSelection) sel).iterator();
while (iter.hasNext()) {
final Object o = iter.next();
if (o instanceof ICElement) {
newSelection.add(o);
}
}
}
return new StructuredSelection(newSelection);
}
if (unit.equals(element)) /**
{ * The element change listener of the C outline viewer.
if (isPossibleStructuralChange(delta)) *
{ * @see IElementChangedListener
return delta; */
} class ElementChangedListener implements IElementChangedListener {
return null;
}
if (element.getElementType() > ICElement.C_UNIT) /**
{ * Default constructor.
return null; */
} public ElementChangedListener() {
// nothing to initialize.
}
final ICElementDelta[] children = delta.getAffectedChildren(); /**
if (children == null || children.length == 0) * @see org.eclipse.cdt.core.model.IElementChangedListener#elementChanged(org.eclipse.cdt.core.model.ElementChangedEvent)
{ */
return null; public void elementChanged(final ElementChangedEvent e) {
} final ICElementDelta delta = findElement(root, e.getDelta());
if (delta != null) {
contentUpdated();
return;
}
}
for (int i = 0; i < children.length; i++) /**
{ * Determines is structural change.
final ICElementDelta d = findElement(unit, children[i]); *
if (d != null) * @param cuDelta
{ * Delta to check.
return d; * @return <b>true</b> if structural change.
} */
} private boolean isPossibleStructuralChange(ICElementDelta cuDelta) {
boolean ret;
if (cuDelta.getKind() != ICElementDelta.CHANGED) {
ret = true; // add or remove
} else {
final int flags = cuDelta.getFlags();
if ((flags & ICElementDelta.F_CHILDREN) != 0) {
ret = true;
} else {
ret = (flags & (ICElementDelta.F_CONTENT | ICElementDelta.F_FINE_GRAINED)) == ICElementDelta.F_CONTENT;
}
}
return ret;
}
return null; /**
} * Searches for element.
} *
* @param unit
* Unit to search in.
* @param delta
* Delta.
* @return Found element.
*/
protected ICElementDelta findElement(ICElement unit,
ICElementDelta delta) {
if (delta == null || unit == null) {
return null;
}
/** final ICElement element = delta.getElement();
*
* Property change listener.
* @author P.Tomaszewski
*/
class PropertyListener implements IPropertyChangeListener {
/** if (unit.equals(element)) {
* @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) if (isPossibleStructuralChange(delta)) {
*/ return delta;
public void propertyChange(PropertyChangeEvent event){ }
String prop = event.getProperty(); return null;
if (prop.equals(PreferenceConstants.OUTLINE_GROUP_INCLUDES)) { }
Object newValue = event.getNewValue();
if (newValue instanceof Boolean) {
boolean value = ((Boolean)newValue).booleanValue();
if (areIncludesGroup() != value) {
setIncludesGrouping(value);
contentUpdated();
}
}
} else if (prop.equals(PreferenceConstants.OUTLINE_GROUP_NAMESPACES)) {
Object newValue = event.getNewValue();
if (newValue instanceof Boolean) {
boolean value = ((Boolean)newValue).booleanValue();
if (areNamespacesGroup() != value) {
setNamespacesGrouping(value);
contentUpdated();
}
}
}
}
} if (element.getElementType() > ICElement.C_UNIT) {
return null;
}
final ICElementDelta[] children = delta.getAffectedChildren();
if (children == null || children.length == 0) {
return null;
}
for (int i = 0; i < children.length; i++) {
final ICElementDelta d = findElement(unit, children[i]);
if (d != null) {
return d;
}
}
return null;
}
}
/**
*
* Property change listener.
*
* @author P.Tomaszewski
*/
class PropertyListener implements IPropertyChangeListener {
/**
* @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
*/
public void propertyChange(PropertyChangeEvent event) {
String prop = event.getProperty();
if (prop.equals(PreferenceConstants.OUTLINE_GROUP_INCLUDES)) {
Object newValue = event.getNewValue();
if (newValue instanceof Boolean) {
boolean value = ((Boolean) newValue).booleanValue();
if (areIncludesGroup() != value) {
setIncludesGrouping(value);
contentUpdated();
}
}
} else if (prop
.equals(PreferenceConstants.OUTLINE_GROUP_NAMESPACES)) {
Object newValue = event.getNewValue();
if (newValue instanceof Boolean) {
boolean value = ((Boolean) newValue).booleanValue();
if (areNamespacesGroup() != value) {
setNamespacesGrouping(value);
contentUpdated();
}
}
}
}
}
} }