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:
parent
a43ab33c8c
commit
41d098da72
5 changed files with 421 additions and 358 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue