1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +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); } else if (IWorkspaceRoot.class.equals(key)) {
return getWorkspaceRoot(celem);
} else if (IProject.class.equals(key)) {
return getProject(celem);
} else if (IResource.class.equals(key)) {
return getResource(celem);
} else if (IDeferredWorkbenchAdapter.class.equals(key)) {
return getDeferredWorkbenchAdapter(celem);
} else if (IWorkbenchAdapter.class.equals(key)) {
return getWorkbenchAdapter(celem);
} else if (IActionFilter.class.equals(key)) {
return getWorkbenchAdapter(celem);
} }
res = celem.getResource(); 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 != null) {
if (res instanceof IFile) { if (res instanceof IFile) {
return new FilePropertySource((IFile)res); return new FilePropertySource((IFile)res);
} }
return new ResourcePropertySource(res); return new ResourcePropertySource(res);
} }
return new CElementPropertySource(celem); return new CElementPropertySource(celement);
} else if (IWorkspaceRoot.class.equals(key)) { }
res = celem.getUnderlyingResource();
if (res != null) private IWorkspaceRoot getWorkspaceRoot(ICElement celement) {
IResource res = celement.getUnderlyingResource();
if (res != null) {
return res.getWorkspace().getRoot(); return res.getWorkspace().getRoot();
} else if (IProject.class.equals(key)) {
res = celem.getResource();
if (res != null)
return res.getProject();
} else if (IResource.class.equals(key)) {
return celem.getResource();
} else if (IDeferredWorkbenchAdapter.class.equals(key)) {
return fgDeferredCWorkbenchAdapter;
} else if (IWorkbenchAdapter.class.equals(key)) {
return fgCWorkbenchAdapter;
} else if (IActionFilter.class.equals(key)) {
return fgCWorkbenchAdapter;
} }
return null; 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) {
if (fBatchFetchedChildren) {
Object[] children = getChildren(object); 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()) { if (monitor.isCanceled()) {
return; 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,6 +30,8 @@ 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.
@ -38,67 +40,90 @@ 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. */ /** Translation unit's root. */
ITranslationUnit root; ITranslationUnit root;
/** Something changed listener. */ /** Something changed listener. */
private ElementChangedListener fListener; private ElementChangedListener fListener;
/** Property change listener. */ /** Property change listener. */
private IPropertyChangeListener fPropertyListener; private IPropertyChangeListener fPropertyListener;
/** Filter for files to outline. */ /** Filter for files to outline. */
private String filter = "*"; //$NON-NLS-1$ private StringMatcher filter = new StringMatcher("*", true, false); //$NON-NLS-1$
/**
* Remote content manager to retrieve content in the background.
*/
private DeferredTreeContentManager fManager;
/**
* 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;
public CContentOutlinerProvider(TreeViewer viewer) {
this(viewer, null);
}
/** /**
* Creates new content provider for dialog. * Creates new content provider for dialog.
* @param viewer Tree viewer. *
* @param viewer
* Tree viewer.
*/ */
public CContentOutlinerProvider(TreeViewer viewer) public CContentOutlinerProvider(TreeViewer viewer, IWorkbenchPartSite site) {
{
super(true, true); super(true, true);
treeViewer = viewer; treeViewer = viewer;
setIncludesGrouping(PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.OUTLINE_GROUP_INCLUDES)); setIncludesGrouping(PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.OUTLINE_GROUP_INCLUDES));
fManager = createContentManager(viewer, site);
}
protected DeferredTreeContentManager createContentManager(TreeViewer viewer, IWorkbenchPartSite site) {
if (site == null) {
return new DeferredTreeContentManager(this, viewer);
}
return new DeferredTreeContentManager(this, viewer, site);
} }
/** /**
* Sets new filter and updates contents. * Sets new filter and updates contents.
* @param newFilter New filter. *
* @param newFilter
* New filter.
*/ */
public void updateFilter(String newFilter) public void updateFilter(String newFilter) {
{ filter = new StringMatcher(newFilter, true, false);
filter = newFilter;
contentUpdated(); contentUpdated();
} }
/** /**
* Called by the editor to signal that the content has updated. * Called by the editor to signal that the content has updated.
*/ */
public void contentUpdated() public void contentUpdated() {
{ if (treeViewer != null && !treeViewer.getControl().isDisposed()) {
if (treeViewer != null && !treeViewer.getControl().isDisposed()) treeViewer.getControl().getDisplay().asyncExec(new Runnable() {
{ public void run() {
treeViewer.getControl().getDisplay().asyncExec(new Runnable() if (!treeViewer.getControl().isDisposed()) {
{
public void run()
{
if (!treeViewer.getControl().isDisposed())
{
final ISelection sel = treeViewer.getSelection(); final ISelection sel = treeViewer.getSelection();
treeViewer.setSelection(updateSelection(sel)); treeViewer.setSelection(updateSelection(sel));
treeViewer.refresh(); treeViewer.refresh();
} }
} }
} });
);
} }
} }
/** /**
* @see org.eclipse.jface.viewers.IContentProvider#dispose() * @see org.eclipse.jface.viewers.IContentProvider#dispose()
*/ */
public void dispose() public void dispose() {
{
super.dispose(); super.dispose();
if (fListener != null) if (fListener != null) {
{
CoreModel.getDefault().removeElementChangedListener(fListener); CoreModel.getDefault().removeElementChangedListener(fListener);
fListener = null; fListener = null;
} }
@ -106,68 +131,89 @@ public class CContentOutlinerProvider extends BaseCElementContentProvider {
PreferenceConstants.getPreferenceStore().removePropertyChangeListener(fPropertyListener); PreferenceConstants.getPreferenceStore().removePropertyChangeListener(fPropertyListener);
fPropertyListener = null; fPropertyListener = null;
} }
if (root != null) {
fManager.cancel(root);
}
} }
/** /**
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) * @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) public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
{ boolean isTU = newInput instanceof ITranslationUnit;
final boolean isTU = newInput instanceof ITranslationUnit;
if (isTU && fListener == null) if (isTU && fListener == null) {
{ fUseContentManager = true;
if (root != null) {
fManager.cancel(root);
}
root = (ITranslationUnit) newInput; root = (ITranslationUnit) newInput;
fListener = new ElementChangedListener(); fListener = new ElementChangedListener();
CoreModel.getDefault().addElementChangedListener(fListener); CoreModel.getDefault().addElementChangedListener(fListener);
fPropertyListener = new PropertyListener(); fPropertyListener = new PropertyListener();
PreferenceConstants.getPreferenceStore().addPropertyChangeListener(fPropertyListener); PreferenceConstants.getPreferenceStore().addPropertyChangeListener(
} fPropertyListener);
else if (!isTU && fListener != null) } else if (!isTU && fListener != null) {
{ fUseContentManager = false;
CoreModel.getDefault().removeElementChangedListener(fListener); CoreModel.getDefault().removeElementChangedListener(fListener);
fListener = null; fListener = null;
root = null; root = null;
if (oldInput != null) {
fManager.cancel(oldInput);
}
} }
} }
/** /**
* @see org.eclipse.cdt.internal.ui.BaseCElementContentProvider#getChildren(java.lang.Object) * @see org.eclipse.cdt.internal.ui.BaseCElementContentProvider#getChildren(java.lang.Object)
*/ */
public Object[] getChildren(Object element) public Object[] getChildren(Object element) {
{ Object[] children = null;
final StringMatcher stringMatcher = new StringMatcher(filter, true, false); // Use the deferred manager for the first time (when parsing)
Object[] children = super.getChildren(element); if (fUseContentManager && element instanceof ITranslationUnit) {
final List filtered = new ArrayList(); children = fManager.getChildren(element);
for (int i = 0; i < children.length; i++) fUseContentManager = false;
{ }
if (stringMatcher.match(children[i].toString())) 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]); filtered.add(children[i]);
} }
} }
final int size = filtered.size(); int size = filtered.size();
children = new Object[size]; children = new Object[size];
filtered.toArray(children); filtered.toArray(children);
return children; return children;
} }
/* (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);
}
/** /**
* Updates current selection. * Updates current selection.
* @param sel Selection to update. *
* @param sel
* Selection to update.
* @return Updated selection. * @return Updated selection.
*/ */
protected ISelection updateSelection(ISelection sel) protected ISelection updateSelection(ISelection sel) {
{
final ArrayList newSelection = new ArrayList(); final ArrayList newSelection = new ArrayList();
if (sel instanceof IStructuredSelection) if (sel instanceof IStructuredSelection) {
{
final Iterator iter = ((IStructuredSelection) sel).iterator(); final Iterator iter = ((IStructuredSelection) sel).iterator();
while (iter.hasNext()) while (iter.hasNext()) {
{
final Object o = iter.next(); final Object o = iter.next();
if (o instanceof ICElement) if (o instanceof ICElement) {
{
newSelection.add(o); newSelection.add(o);
} }
} }
@ -177,27 +223,24 @@ public class CContentOutlinerProvider extends BaseCElementContentProvider {
/** /**
* The element change listener of the C outline viewer. * The element change listener of the C outline viewer.
*
* @see IElementChangedListener * @see IElementChangedListener
*/ */
class ElementChangedListener implements IElementChangedListener class ElementChangedListener implements IElementChangedListener {
{
/** /**
* Default constructor. * Default constructor.
*/ */
public ElementChangedListener() public ElementChangedListener() {
{
// nothing to initialize. // nothing to initialize.
} }
/** /**
* @see org.eclipse.cdt.core.model.IElementChangedListener#elementChanged(org.eclipse.cdt.core.model.ElementChangedEvent) * @see org.eclipse.cdt.core.model.IElementChangedListener#elementChanged(org.eclipse.cdt.core.model.ElementChangedEvent)
*/ */
public void elementChanged(final ElementChangedEvent e) public void elementChanged(final ElementChangedEvent e) {
{
final ICElementDelta delta = findElement(root, e.getDelta()); final ICElementDelta delta = findElement(root, e.getDelta());
if (delta != null) if (delta != null) {
{
contentUpdated(); contentUpdated();
return; return;
} }
@ -205,25 +248,20 @@ public class CContentOutlinerProvider extends BaseCElementContentProvider {
/** /**
* Determines is structural change. * Determines is structural change.
* @param cuDelta Delta to check. *
* @param cuDelta
* Delta to check.
* @return <b>true</b> if structural change. * @return <b>true</b> if structural change.
*/ */
private boolean isPossibleStructuralChange(ICElementDelta cuDelta) private boolean isPossibleStructuralChange(ICElementDelta cuDelta) {
{
boolean ret; boolean ret;
if (cuDelta.getKind() != ICElementDelta.CHANGED) if (cuDelta.getKind() != ICElementDelta.CHANGED) {
{
ret = true; // add or remove ret = true; // add or remove
} } else {
else
{
final int flags = cuDelta.getFlags(); final int flags = cuDelta.getFlags();
if ((flags & ICElementDelta.F_CHILDREN) != 0) if ((flags & ICElementDelta.F_CHILDREN) != 0) {
{
ret = true; ret = true;
} } else {
else
{
ret = (flags & (ICElementDelta.F_CONTENT | ICElementDelta.F_FINE_GRAINED)) == ICElementDelta.F_CONTENT; ret = (flags & (ICElementDelta.F_CONTENT | ICElementDelta.F_FINE_GRAINED)) == ICElementDelta.F_CONTENT;
} }
} }
@ -232,44 +270,40 @@ public class CContentOutlinerProvider extends BaseCElementContentProvider {
/** /**
* Searches for element. * Searches for element.
* @param unit Unit to search in. *
* @param delta Delta. * @param unit
* Unit to search in.
* @param delta
* Delta.
* @return Found element. * @return Found element.
*/ */
protected ICElementDelta findElement(ICElement unit, ICElementDelta delta) protected ICElementDelta findElement(ICElement unit,
{ ICElementDelta delta) {
if (delta == null || unit == null) if (delta == null || unit == null) {
{
return null; return null;
} }
final ICElement element = delta.getElement(); final ICElement element = delta.getElement();
if (unit.equals(element)) if (unit.equals(element)) {
{ if (isPossibleStructuralChange(delta)) {
if (isPossibleStructuralChange(delta))
{
return delta; return delta;
} }
return null; return null;
} }
if (element.getElementType() > ICElement.C_UNIT) if (element.getElementType() > ICElement.C_UNIT) {
{
return null; return null;
} }
final ICElementDelta[] children = delta.getAffectedChildren(); final ICElementDelta[] children = delta.getAffectedChildren();
if (children == null || children.length == 0) if (children == null || children.length == 0) {
{
return null; return null;
} }
for (int i = 0; i < children.length; i++) for (int i = 0; i < children.length; i++) {
{
final ICElementDelta d = findElement(unit, children[i]); final ICElementDelta d = findElement(unit, children[i]);
if (d != null) if (d != null) {
{
return d; return d;
} }
} }
@ -281,6 +315,7 @@ public class CContentOutlinerProvider extends BaseCElementContentProvider {
/** /**
* *
* Property change listener. * Property change listener.
*
* @author P.Tomaszewski * @author P.Tomaszewski
*/ */
class PropertyListener implements IPropertyChangeListener { class PropertyListener implements IPropertyChangeListener {
@ -299,7 +334,8 @@ public class CContentOutlinerProvider extends BaseCElementContentProvider {
contentUpdated(); contentUpdated();
} }
} }
} else if (prop.equals(PreferenceConstants.OUTLINE_GROUP_NAMESPACES)) { } else if (prop
.equals(PreferenceConstants.OUTLINE_GROUP_NAMESPACES)) {
Object newValue = event.getNewValue(); Object newValue = event.getNewValue();
if (newValue instanceof Boolean) { if (newValue instanceof Boolean) {
boolean value = ((Boolean) newValue).booleanValue(); boolean value = ((Boolean) newValue).booleanValue();