1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +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
Fix PR 108205: limit the number of refresh by ignoring WorkingCopies events.
* src/org/eclipse/cdt/ui/CElementContentProvider.java

View file

@ -40,8 +40,7 @@ public class CElementAdapterFactory implements IAdapterFactory {
IActionFilter.class
};
private static CWorkbenchAdapter fgCWorkbenchAdapter= new CWorkbenchAdapter();
private static DeferredCWorkbenchAdapter fgDeferredCWorkbenchAdapter= new DeferredCWorkbenchAdapter();
private static CWorkbenchAdapter fgCWorkbenchAdapter;
/**
* @see CElementAdapterFactory#getAdapterList
@ -55,37 +54,63 @@ public class CElementAdapterFactory implements IAdapterFactory {
*/
public Object getAdapter(Object element, Class key) {
ICElement celem = (ICElement) element;
IResource res = null;
if (IPropertySource.class.equals(key)) {
if (celem instanceof IBinary) {
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);
return getPropertySource(celem);
} else if (IWorkspaceRoot.class.equals(key)) {
res = celem.getUnderlyingResource();
if (res != null)
return res.getWorkspace().getRoot();
return getWorkspaceRoot(celem);
} else if (IProject.class.equals(key)) {
res = celem.getResource();
if (res != null)
return res.getProject();
return getProject(celem);
} else if (IResource.class.equals(key)) {
return celem.getResource();
return getResource(celem);
} else if (IDeferredWorkbenchAdapter.class.equals(key)) {
return fgDeferredCWorkbenchAdapter;
return getDeferredWorkbenchAdapter(celem);
} else if (IWorkbenchAdapter.class.equals(key)) {
return fgCWorkbenchAdapter;
return getWorkbenchAdapter(celem);
} else if (IActionFilter.class.equals(key)) {
return fgCWorkbenchAdapter;
return getWorkbenchAdapter(celem);
}
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;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.IParent;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.ui.progress.IDeferredWorkbenchAdapter;
import org.eclipse.ui.progress.IElementCollector;
public class DeferredCWorkbenchAdapter extends CWorkbenchAdapter
implements IDeferredWorkbenchAdapter {
public class DeferredCWorkbenchAdapter extends CWorkbenchAdapter implements IDeferredWorkbenchAdapter {
private static boolean fSerializeFetching = false;
private static boolean fBatchFetchedChildren = true;
private ICElement fCElement;
final ISchedulingRule mutexRule = new ISchedulingRule() {
public boolean isConflicting(ISchedulingRule rule) {
return rule == mutexRule;
}
public boolean contains(ISchedulingRule rule) {
return rule == mutexRule;
}
};
public DeferredCWorkbenchAdapter(ICElement element) {
super();
fCElement = element;
}
/*
* (non-Javadoc)
@ -39,25 +34,12 @@ public class DeferredCWorkbenchAdapter extends CWorkbenchAdapter
* org.eclipse.core.runtime.IProgressMonitor)
*/
public void fetchDeferredChildren(Object object, IElementCollector collector, IProgressMonitor monitor) {
if (object instanceof IParent) {
if (fBatchFetchedChildren) {
Object[] children = getChildren(object);
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);
}
}
Object[] children = getChildren(object);
if (monitor.isCanceled()) {
return;
}
collector.add(children, monitor);
collector.done();
}
/*
@ -66,7 +48,7 @@ public class DeferredCWorkbenchAdapter extends CWorkbenchAdapter
* @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#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)
*/
public ISchedulingRule getRule(final Object object) {
if (fSerializeFetching) {
// only one ICElement parent can fetch children at a time
return mutexRule;
}
// allow several ICElement parents to fetch children concurrently
return null;
return fCElement.getResource();
}
}

View file

@ -72,10 +72,11 @@ import org.eclipse.ui.views.navigator.LocalSelectionTransfer;
public class CContentOutlinePage extends Page implements IContentOutlinePage, ISelectionChangedListener {
private CEditor fEditor;
private ITranslationUnit fInput;
private ProblemTreeViewer treeViewer;
private ProblemTreeViewer fTreeViewer;
private ListenerList selectionChangedListeners = new ListenerList();
private TogglePresentationAction fTogglePresentation;
private String fContextMenuId;
private Menu fMenu;
protected OpenIncludeAction fOpenIncludeAction;
private IncludeGroupingAction fIncludeGroupingAction;
@ -248,19 +249,25 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
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)
* @see org.eclipse.ui.part.IPage#createControl(org.eclipse.swt.widgets.Composite)
*/
public void createControl(Composite parent) {
treeViewer = new ProblemTreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
//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);
fTreeViewer = createTreeViewer(parent);
initDragAndDrop();
MenuManager manager= new MenuManager(fContextMenuId);
@ -270,11 +277,11 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
contextMenuAboutToShow(manager);
}
});
Control control= treeViewer.getControl();
Menu menu= manager.createContextMenu(control);
control.setMenu(menu);
Control control= fTreeViewer.getControl();
fMenu= manager.createContextMenu(control);
control.setMenu(fMenu);
treeViewer.addDoubleClickListener(new IDoubleClickListener() {
fTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
/* (non-Javadoc)
* @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
IPageSite site= getSite();
site.registerContextMenu(fContextMenuId, manager, treeViewer);
site.setSelectionProvider(treeViewer);
site.registerContextMenu(fContextMenuId, manager, fTreeViewer);
site.setSelectionProvider(fTreeViewer);
IActionBars bars= site.getActionBars();
bars.setGlobalActionHandler(ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY, fTogglePresentation);
@ -298,13 +305,16 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
// Custom filter group
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);
}
public void dispose() {
if (treeViewer != null) {
treeViewer.removeSelectionChangedListener(this);
if (fTreeViewer != null) {
fTreeViewer.removeSelectionChangedListener(this);
}
if (fTogglePresentation != null) {
@ -331,26 +341,33 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
fSelectionSearchGroup= null;
}
if (fCustomFiltersActionGroup != null) {
fCustomFiltersActionGroup.dispose();
fCustomFiltersActionGroup= null;
}
if (selectionChangedListeners != null) {
selectionChangedListeners.clear();
selectionChangedListeners= null;
}
if (fMenu != null && !fMenu.isDisposed()) {
fMenu.dispose();
fMenu= null;
}
fInput= null;
super.dispose();
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.IPage#setActionBars(org.eclipse.ui.IActionBars)
*/
public void setActionBars(IActionBars actionBars) {
private void registerActionBars(IActionBars actionBars) {
IToolBarManager toolBarManager= actionBars.getToolBarManager();
LexicalSortingAction action= new LexicalSortingAction(getTreeViewer());
toolBarManager.add(action);
fMemberFilterActionGroup= new MemberFilterActionGroup(treeViewer, "COutlineViewer"); //$NON-NLS-1$
fMemberFilterActionGroup= new MemberFilterActionGroup(fTreeViewer, "COutlineViewer"); //$NON-NLS-1$
fMemberFilterActionGroup.fillActionBars(actionBars);
fCustomFiltersActionGroup.fillActionBars(actionBars);
@ -391,18 +408,18 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
* Method declared on IPage (and Page).
*/
public Control getControl() {
if (treeViewer == null)
if (fTreeViewer == null)
return null;
return treeViewer.getControl();
return fTreeViewer.getControl();
}
/* (non-Javadoc)
* Method declared on ISelectionProvider.
*/
public ISelection getSelection() {
if (treeViewer == null)
if (fTreeViewer == null)
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
*/
protected TreeViewer getTreeViewer() {
return treeViewer;
return fTreeViewer;
}
/* (non-Javadoc)
@ -434,15 +451,15 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
* Sets focus to a part in the page.
*/
public void setFocus() {
treeViewer.getControl().setFocus();
fTreeViewer.getControl().setFocus();
}
/* (non-Javadoc)
* Method declared on ISelectionProvider.
*/
public void setSelection(ISelection selection) {
if (treeViewer != null)
treeViewer.setSelection(selection);
if (fTreeViewer != null)
fTreeViewer.setSelection(selection);
}
/**
@ -451,8 +468,8 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
*/
public void setInput(ITranslationUnit unit) {
fInput = unit;
if (treeViewer != null) {
treeViewer.setInput (fInput);
if (fTreeViewer != null) {
fTreeViewer.setInput (fInput);
}
}
@ -464,15 +481,15 @@ public class CContentOutlinePage extends Page implements IContentOutlinePage, IS
// Drop Adapter
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
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.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.progress.DeferredTreeContentManager;
/**
* Manages contents of the outliner.
*/
public class CContentOutlinerProvider extends BaseCElementContentProvider {
/** Tree viewer which handles this content provider. */
TreeViewer treeViewer;
/** Translation unit's root. */
ITranslationUnit root;
/** Something changed listener. */
private ElementChangedListener fListener;
/** Property change listener. */
/** Tree viewer which handles this content provider. */
TreeViewer treeViewer;
/** Translation unit's root. */
ITranslationUnit root;
/** Something changed listener. */
private ElementChangedListener fListener;
/** Property change listener. */
private IPropertyChangeListener fPropertyListener;
/** Filter for files to outline. */
private String filter = "*"; //$NON-NLS-1$
/**
* Creates new content provider for dialog.
* @param viewer Tree viewer.
*/
public CContentOutlinerProvider(TreeViewer viewer)
{
super(true, true);
treeViewer = viewer;
setIncludesGrouping(PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.OUTLINE_GROUP_INCLUDES));
}
/** Filter for files to outline. */
private StringMatcher filter = new StringMatcher("*", true, false); //$NON-NLS-1$
/**
* Sets new filter and updates contents.
* @param newFilter New filter.
*/
public void updateFilter(String newFilter)
{
filter = newFilter;
contentUpdated();
}
/**
* Remote content manager to retrieve content in the background.
*/
private DeferredTreeContentManager fManager;
/**
* Called by the editor to signal that the content has updated.
*/
public void contentUpdated()
{
if (treeViewer != null && !treeViewer.getControl().isDisposed())
{
treeViewer.getControl().getDisplay().asyncExec(new Runnable()
{
public void run()
{
if (!treeViewer.getControl().isDisposed())
{
final ISelection sel = treeViewer.getSelection();
treeViewer.setSelection(updateSelection(sel));
treeViewer.refresh();
}
}
}
);
}
}
/**
* We only want to use the DeferredContentManager, the first time
* because the Outliner is initialize in the UI thread. So to not block
* the UI thread we deferred, after it is not necessary the reconciler is
* running in a separate thread not affecting the UI.
*/
private boolean fUseContentManager = false;
/**
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
*/
public void dispose()
{
super.dispose();
if (fListener != null)
{
CoreModel.getDefault().removeElementChangedListener(fListener);
fListener = null;
}
if (fPropertyListener != null) {
PreferenceConstants.getPreferenceStore().removePropertyChangeListener(fPropertyListener);
fPropertyListener = null;
}
}
public CContentOutlinerProvider(TreeViewer viewer) {
this(viewer, null);
}
/**
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
*/
public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
{
final boolean isTU = newInput instanceof ITranslationUnit;
/**
* Creates new content provider for dialog.
*
* @param viewer
* Tree viewer.
*/
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)
{
root = (ITranslationUnit) newInput;
fListener = new ElementChangedListener();
CoreModel.getDefault().addElementChangedListener(fListener);
fPropertyListener = new PropertyListener();
PreferenceConstants.getPreferenceStore().addPropertyChangeListener(fPropertyListener);
}
else if (!isTU && fListener != null)
{
CoreModel.getDefault().removeElementChangedListener(fListener);
fListener = null;
root = null;
}
}
protected DeferredTreeContentManager createContentManager(TreeViewer viewer, IWorkbenchPartSite site) {
if (site == null) {
return new DeferredTreeContentManager(this, viewer);
}
return new DeferredTreeContentManager(this, viewer, site);
}
/**
* @see org.eclipse.cdt.internal.ui.BaseCElementContentProvider#getChildren(java.lang.Object)
*/
public Object[] getChildren(Object element)
{
final StringMatcher stringMatcher = new StringMatcher(filter, true, false);
Object[] children = super.getChildren(element);
final List filtered = new ArrayList();
for (int i = 0; i < children.length; i++)
{
if (stringMatcher.match(children[i].toString()))
{
filtered.add(children[i]);
}
}
final int size = filtered.size();
children = new Object[size];
filtered.toArray(children);
return children;
}
/**
* Sets new filter and updates contents.
*
* @param newFilter
* New filter.
*/
public void updateFilter(String newFilter) {
filter = new StringMatcher(newFilter, true, false);
contentUpdated();
}
/**
* 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);
}
/**
* Called by the editor to signal that the content has updated.
*/
public void contentUpdated() {
if (treeViewer != null && !treeViewer.getControl().isDisposed()) {
treeViewer.getControl().getDisplay().asyncExec(new Runnable() {
public void run() {
if (!treeViewer.getControl().isDisposed()) {
final ISelection sel = treeViewer.getSelection();
treeViewer.setSelection(updateSelection(sel));
treeViewer.refresh();
}
}
});
}
}
/**
* The element change listener of the C outline viewer.
* @see IElementChangedListener
*/
class ElementChangedListener implements IElementChangedListener
{
/**
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
*/
public void dispose() {
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.
*/
public ElementChangedListener()
{
// nothing to initialize.
}
/**
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
* java.lang.Object, java.lang.Object)
*/
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
boolean isTU = newInput instanceof ITranslationUnit;
/**
* @see org.eclipse.cdt.core.model.IElementChangedListener#elementChanged(org.eclipse.cdt.core.model.ElementChangedEvent)
*/
public void elementChanged(final ElementChangedEvent e)
{
final ICElementDelta delta = findElement(root, e.getDelta());
if (delta != null)
{
contentUpdated();
return;
}
}
if (isTU && fListener == null) {
fUseContentManager = true;
if (root != null) {
fManager.cancel(root);
}
root = (ITranslationUnit) newInput;
fListener = new ElementChangedListener();
CoreModel.getDefault().addElementChangedListener(fListener);
fPropertyListener = new PropertyListener();
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.
* @param cuDelta Delta to check.
* @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;
}
/**
* @see org.eclipse.cdt.internal.ui.BaseCElementContentProvider#getChildren(java.lang.Object)
*/
public Object[] getChildren(Object element) {
Object[] children = null;
// Use the deferred manager for the first time (when parsing)
if (fUseContentManager && element instanceof ITranslationUnit) {
children = fManager.getChildren(element);
fUseContentManager = false;
}
if (children == null) {
children = super.getChildren(element);
}
List filtered = new ArrayList();
for (int i = 0; i < children.length; i++) {
if (filter.match(children[i].toString())) {
filtered.add(children[i]);
}
}
int size = filtered.size();
children = new Object[size];
filtered.toArray(children);
return children;
}
/**
* 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;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
*/
public boolean hasChildren(Object element) {
if (fUseContentManager) {
return fManager.mayHaveChildren(element);
}
return super.hasChildren(element);
}
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))
{
if (isPossibleStructuralChange(delta))
{
return delta;
}
return null;
}
/**
* The element change listener of the C outline viewer.
*
* @see IElementChangedListener
*/
class ElementChangedListener implements IElementChangedListener {
if (element.getElementType() > ICElement.C_UNIT)
{
return null;
}
/**
* Default constructor.
*/
public ElementChangedListener() {
// nothing to initialize.
}
final ICElementDelta[] children = delta.getAffectedChildren();
if (children == null || children.length == 0)
{
return null;
}
/**
* @see org.eclipse.cdt.core.model.IElementChangedListener#elementChanged(org.eclipse.cdt.core.model.ElementChangedEvent)
*/
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++)
{
final ICElementDelta d = findElement(unit, children[i]);
if (d != null)
{
return d;
}
}
/**
* Determines is structural change.
*
* @param cuDelta
* Delta to check.
* @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;
}
/**
*
* Property change listener.
* @author P.Tomaszewski
*/
class PropertyListener implements IPropertyChangeListener {
final ICElement element = delta.getElement();
/**
* @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();
}
}
}
}
if (unit.equals(element)) {
if (isPossibleStructuralChange(delta)) {
return delta;
}
return null;
}
}
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();
}
}
}
}
}
}