diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 6b0ce50f0d5..ee629ab3515 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -34,6 +34,7 @@ + + + + + @@ -1229,10 +1237,11 @@ + updaterClass="org.eclipse.cdt.internal.ui.workingsets.CElementWorkingSetUpdater"> - - diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/BaseCElementContentProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/BaseCElementContentProvider.java index 8fb6116f75f..4477d6b57ec 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/BaseCElementContentProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/BaseCElementContentProvider.java @@ -278,7 +278,13 @@ public class BaseCElementContentProvider implements ITreeContentProvider { } Object parent = null; if (element instanceof ICElement) { - parent = ((ICElement)element).getParent(); + parent = ((ICElement)element).getParent(); + // translate working copy parent to original TU, + // because working copies are never returned by getChildren + // this is necessary for proper show-in-target support + if (parent instanceof IWorkingCopy) { + parent= ((IWorkingCopy)parent).getOriginalElement(); + } } else if (element instanceof IWorkbenchAdapter) { parent = ((IWorkbenchAdapter)element).getParent(element); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CElementAdapterFactory.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CElementAdapterFactory.java index afaebc038c1..d62d01d7ca5 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CElementAdapterFactory.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CElementAdapterFactory.java @@ -16,6 +16,7 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IAdapterFactory; import org.eclipse.ui.IActionFilter; +import org.eclipse.ui.IPersistableElement; import org.eclipse.ui.model.IWorkbenchAdapter; import org.eclipse.ui.progress.IDeferredWorkbenchAdapter; import org.eclipse.ui.views.properties.FilePropertySource; @@ -34,6 +35,7 @@ public class CElementAdapterFactory implements IAdapterFactory { IPropertySource.class, IResource.class, IWorkbenchAdapter.class, + IPersistableElement.class, IDeferredWorkbenchAdapter.class, IActionFilter.class }; @@ -61,6 +63,8 @@ public class CElementAdapterFactory implements IAdapterFactory { return resource; } return null; + } if (IPersistableElement.class.equals(key)) { + return new PersistableCElementFactory(celem); } else if (IDeferredWorkbenchAdapter.class.equals(key)) { return getDeferredWorkbenchAdapter(celem); } else if (IWorkbenchAdapter.class.equals(key)) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/PersistableCElementFactory.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/PersistableCElementFactory.java new file mode 100644 index 00000000000..25498d2049b --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/PersistableCElementFactory.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Anton Leherbauer (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.ui; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.Path; +import org.eclipse.ui.IElementFactory; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IPersistableElement; + +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICElement; + +/** + * The PersistableCElementFactory is used to save and recreate an ICElement object. + * As such, it implements the IPersistableElement interface for storage + * and the IElementFactory interface for recreation. + * + * @see IMemento + * @see IPersistableElement + * @see IElementFactory + */ +public class PersistableCElementFactory implements IElementFactory, IPersistableElement { + + // These persistence constants are stored in XML. Do not + // change them. + private static final String TAG_PATH = "path";//$NON-NLS-1$ + + private static final String FACTORY_ID = "org.eclipse.cdt.ui.PersistableCElementFactory";//$NON-NLS-1$ + + // IPersistable data. + private ICElement fCElement; + + /** + * Create a PersistableCElementFactory. This constructor is typically used + * for our IElementFactory side. + */ + public PersistableCElementFactory() { + } + + /** + * Create a PersistableCElementFactory. This constructor is typically used + * for our IPersistableElement side. + */ + public PersistableCElementFactory(ICElement input) { + fCElement = input; + } + + /** + * @see IElementFactory + */ + public IAdaptable createElement(IMemento memento) { + // Get the file name. + String fileName = memento.getString(TAG_PATH); + if (fileName == null) { + return null; + } + + fCElement = CoreModel.getDefault().create(new Path(fileName)); + if (fCElement != null && fCElement.getResource() != null) { + IResource resource= fCElement.getResource(); + if (!resource.isAccessible()) { + return resource; + } + } + return fCElement; + } + + /** + * @see IPersistableElement + */ + public String getFactoryId() { + return FACTORY_ID; + } + + /** + * @see IPersistableElement + */ + public void saveState(IMemento memento) { + if (fCElement.getResource() != null) { + memento.putString(TAG_PATH, fCElement.getResource().getFullPath().toString()); + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/SelectionConverter.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/SelectionConverter.java index 85404744ff3..d90ef7f8f06 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/SelectionConverter.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/SelectionConverter.java @@ -7,6 +7,7 @@ * * Contributors: * QNX Software Systems - Initial API and implementation + * Anton Leherbauer (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.ui.actions; @@ -15,30 +16,57 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.texteditor.ITextEditor; + import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ISourceRange; import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.IWorkingCopy; -import org.eclipse.cdt.internal.ui.editor.CEditor; -import org.eclipse.cdt.internal.ui.util.ExceptionHandler; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.IWorkingCopyManager; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.jface.text.ITextSelection; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.texteditor.ITextEditor; + +import org.eclipse.cdt.internal.ui.editor.CEditor; +import org.eclipse.cdt.internal.ui.util.ExceptionHandler; public class SelectionConverter { protected static final ICElement[] EMPTY_RESULT= new ICElement[0]; - + + /** + * Converts the selection provided by the given part into a structured selection. + * The following conversion rules are used: + *
    + *
  • part instanceof CEditor: returns a structured selection + * using code resolve to convert the editor's text selection.
  • + *
  • part instanceof IWorkbenchPart: returns the part's selection + * if it is a structured selection.
  • + *
  • default: returns an empty structured selection.
  • + *
+ */ + public static IStructuredSelection getStructuredSelection(IWorkbenchPart part) throws CModelException { + if (part instanceof CEditor) + return new StructuredSelection(codeResolve((CEditor)part)); + ISelectionProvider provider= part.getSite().getSelectionProvider(); + if (provider != null) { + ISelection selection= provider.getSelection(); + if (selection instanceof IStructuredSelection) + return (IStructuredSelection)selection; + } + return StructuredSelection.EMPTY; + } + public static IStructuredSelection convertSelectionToCElements(ISelection s) { List converted = new ArrayList(); if (s instanceof StructuredSelection) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/navigator/CNavigatorContentProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/navigator/CNavigatorContentProvider.java index ab95da37b81..ce898d28493 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/navigator/CNavigatorContentProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/navigator/CNavigatorContentProvider.java @@ -16,12 +16,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -import org.eclipse.cdt.core.model.CoreModel; -import org.eclipse.cdt.core.model.ICElement; -import org.eclipse.cdt.core.model.ICModel; -import org.eclipse.cdt.internal.ui.cview.CViewContentProvider; -import org.eclipse.cdt.ui.CUIPlugin; -import org.eclipse.cdt.ui.PreferenceConstants; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; @@ -36,6 +30,14 @@ import org.eclipse.ui.navigator.IPipelinedTreeContentProvider; import org.eclipse.ui.navigator.PipelinedShapeModification; import org.eclipse.ui.navigator.PipelinedViewerUpdate; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICModel; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.PreferenceConstants; + +import org.eclipse.cdt.internal.ui.cview.CViewContentProvider; + /** * A content provider populating a Common Navigator view with CDT model content. */ @@ -286,7 +288,7 @@ public class CNavigatorContentProvider extends CViewContentProvider implements I Object parent= modification.getParent(); if (parent instanceof IContainer) { ICElement element= CoreModel.getDefault().create((IContainer) parent); - if (element != null && element.exists()) { + if (element != null) { // don't convert the root if( !(element instanceof ICModel)) { modification.setParent(element); @@ -312,8 +314,7 @@ public class CNavigatorContentProvider extends CViewContentProvider implements I for (Iterator iter= currentChildren.iterator(); iter.hasNext();) { Object child= iter.next(); if (child instanceof IResource) { - if ((newChild= CoreModel.getDefault().create((IResource) child)) != null - && newChild.exists()) { + if ((newChild= CoreModel.getDefault().create((IResource) child)) != null) { iter.remove(); convertedChildren.add(newChild); } @@ -324,7 +325,26 @@ public class CNavigatorContentProvider extends CViewContentProvider implements I return true; } return false; + } + protected void postRefresh(final Object element) { + if (element instanceof ICModel) { + super.postRefresh(fRealInput); + return; + } + super.postRefresh(element); + } + + protected void postAdd(final Object parent, final Object element) { + if (parent instanceof ICModel) { + super.postAdd(fRealInput, element); + return; + } + super.postAdd(parent, element); + } + + protected void postRemove(final Object element) { + postRefresh(internalGetParent(element)); } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/navigator/CNavigatorWorkingSetActionGroup.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/navigator/CNavigatorWorkingSetActionGroup.java deleted file mode 100644 index d36d5431b37..00000000000 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/navigator/CNavigatorWorkingSetActionGroup.java +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006 Wind River Systems, Inc. and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Anton Leherbauer (Wind River Systems) - initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.internal.ui.navigator; - -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IMemento; -import org.eclipse.ui.IWorkingSet; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.WorkingSetFilterActionGroup; - -/** - * A Common Navigator adapted WorkingSetFilterActionGroup adding persistency. - * - * @see org.eclipse.ui.actions.WorkingSetFilterActionGroup - */ -public class CNavigatorWorkingSetActionGroup extends WorkingSetFilterActionGroup { - - private static final String TAG_WORKING_SET_NAME= "workingSetName"; //$NON-NLS-1$ - - /** - * Create a new working set filter action group. - * @param shell - * @param workingSetUpdater - */ - public CNavigatorWorkingSetActionGroup(Shell shell, IPropertyChangeListener workingSetUpdater) { - super(shell, workingSetUpdater); - } - - /** - * Saves the state of the filter actions in a memento. - * - * @param memento the memento - */ - public void saveState(IMemento memento) { - String workingSetName= ""; //$NON-NLS-1$ - IWorkingSet workingSet= getWorkingSet(); - if (workingSet != null) { - workingSetName= workingSet.getName(); - } - memento.putString(TAG_WORKING_SET_NAME, workingSetName); - } - - /** - * Restores the state of the filter actions from a memento. - *

- * Note: This method does not refresh the viewer. - *

- * @param memento - */ - public void restoreState(IMemento memento) { - String workingSetName= memento.getString(TAG_WORKING_SET_NAME); - IWorkingSet workingSet= PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSet(workingSetName); - setWorkingSet(workingSet); - } - -} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/navigator/CNavigatorWorkingSetActionProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/navigator/CNavigatorWorkingSetActionProvider.java deleted file mode 100644 index a27dc33aa5f..00000000000 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/navigator/CNavigatorWorkingSetActionProvider.java +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006 Wind River Systems, Inc. and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Anton Leherbauer (Wind River Systems) - initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.internal.ui.navigator; - -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.jface.viewers.StructuredViewer; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IMemento; -import org.eclipse.ui.IViewPart; -import org.eclipse.ui.IWorkingSet; -import org.eclipse.ui.IWorkingSetManager; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.ResourceWorkingSetFilter; -import org.eclipse.ui.actions.ActionContext; -import org.eclipse.ui.actions.WorkingSetFilterActionGroup; -import org.eclipse.ui.navigator.CommonActionProvider; -import org.eclipse.ui.navigator.ICommonActionExtensionSite; -import org.eclipse.ui.navigator.ICommonViewerWorkbenchSite; - -/** - * A Common Navigator action provider adding standard working set filter support. - * - * @see CNavigatorWorkingSetActionGroup - * @see ResourceWorkingSetFilter - */ -public class CNavigatorWorkingSetActionProvider extends CommonActionProvider { - - private CNavigatorWorkingSetActionGroup fWorkingSetGroup; - private ResourceWorkingSetFilter fWorkingSetFilter; - private IPropertyChangeListener workingSetListener; - - private boolean fContributed; - - /* - * @see org.eclipse.ui.actions.ActionGroup#fillActionBars(org.eclipse.ui.IActionBars) - */ - public void fillActionBars(IActionBars actionBars) { - if(fWorkingSetGroup != null && !fContributed) { - // contribute only once to action bars - fContributed= true; - // add an extra separator before the working set filter actions - // TLETODO [CN] add working set filter actions on top of the menu - actionBars.getMenuManager().add(new Separator()); - fWorkingSetGroup.fillActionBars(actionBars); - } - } - - /* - * @see org.eclipse.ui.actions.ActionGroup#fillContextMenu(org.eclipse.jface.action.IMenuManager) - */ - public void fillContextMenu(IMenuManager menu) { - if (fWorkingSetGroup != null) { - fWorkingSetGroup.fillContextMenu(menu); - } - } - - /* - * @see org.eclipse.ui.navigator.CommonActionProvider#init(org.eclipse.ui.navigator.ICommonActionExtensionSite) - */ - public void init(ICommonActionExtensionSite site) { - super.init(site); - ICommonViewerWorkbenchSite workbenchSite= null; - if (site.getViewSite() instanceof ICommonViewerWorkbenchSite) { - workbenchSite= (ICommonViewerWorkbenchSite) site.getViewSite(); - } - if (workbenchSite != null) { - if (workbenchSite.getPart() != null && workbenchSite.getPart() instanceof IViewPart) { - final StructuredViewer viewer= site.getStructuredViewer(); - fWorkingSetFilter= new ResourceWorkingSetFilter(); - viewer.addFilter(fWorkingSetFilter); - IPropertyChangeListener workingSetUpdater= new IPropertyChangeListener() { - public void propertyChange(PropertyChangeEvent event) { - String property= event.getProperty(); - if (WorkingSetFilterActionGroup.CHANGE_WORKING_SET.equals(property)) { - Object newValue= event.getNewValue(); - if (newValue instanceof IWorkingSet) { - fWorkingSetFilter.setWorkingSet((IWorkingSet) newValue); - viewer.refresh(); - } else if (newValue == null) { - fWorkingSetFilter.setWorkingSet(null); - viewer.refresh(); - } - } - }}; - fWorkingSetGroup= new CNavigatorWorkingSetActionGroup(workbenchSite.getShell(), workingSetUpdater); - workingSetListener = new IPropertyChangeListener() { - public void propertyChange(PropertyChangeEvent ev) { - String property= ev.getProperty(); - if (property == null) { - return; - } - Object newValue= ev.getNewValue(); - Object oldValue= ev.getOldValue(); - IWorkingSet filterWorkingSet= fWorkingSetFilter.getWorkingSet(); - if (IWorkingSetManager.CHANGE_WORKING_SET_REMOVE.equals(property) && oldValue == filterWorkingSet) { - fWorkingSetFilter.setWorkingSet(null); - } else if (IWorkingSetManager.CHANGE_WORKING_SET_NAME_CHANGE.equals(property) && newValue == filterWorkingSet) { -// updateTitle(); - } else if (IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE.equals(property) && newValue == filterWorkingSet) { - viewer.refresh(); - } - } - }; - IWorkingSetManager wsManager = PlatformUI.getWorkbench().getWorkingSetManager(); - wsManager.addPropertyChangeListener(workingSetListener); - } - } - } - - /* - * @see org.eclipse.ui.actions.ActionGroup#setContext(org.eclipse.ui.actions.ActionContext) - */ - public void setContext(ActionContext context) { - super.setContext(context); - if (fWorkingSetGroup != null) { - fWorkingSetGroup.setContext(context); - } - } - - /* - * @see org.eclipse.ui.navigator.CommonActionProvider#restoreState(org.eclipse.ui.IMemento) - */ - public void restoreState(IMemento memento) { - super.restoreState(memento); - if (fWorkingSetGroup != null && memento != null) { - fWorkingSetGroup.restoreState(memento); - } - } - - /* - * @see org.eclipse.ui.navigator.CommonActionProvider#saveState(org.eclipse.ui.IMemento) - */ - public void saveState(IMemento memento) { - super.saveState(memento); - if (fWorkingSetGroup != null && memento != null) { - fWorkingSetGroup.saveState(memento); - } - } - - /* - * @see org.eclipse.ui.actions.ActionGroup#dispose() - */ - public void dispose() { - if (workingSetListener != null) { - IWorkingSetManager wsManager= PlatformUI.getWorkbench().getWorkingSetManager(); - wsManager.addPropertyChangeListener(workingSetListener); - workingSetListener= null; - } - if (fWorkingSetGroup != null) { - fWorkingSetGroup.dispose(); - fWorkingSetGroup= null; - } - super.dispose(); - } - -} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/CElementWorkingSetPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/CElementWorkingSetPage.java index 9c4878bbcf8..d1168abe392 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/CElementWorkingSetPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/CElementWorkingSetPage.java @@ -7,28 +7,22 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Anton Leherbauer (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.ui.workingsets; import java.util.ArrayList; import java.util.List; -import org.eclipse.cdt.internal.ui.CPluginImages; -import org.eclipse.cdt.ui.CElementSorter; -import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTreeViewer; -import org.eclipse.jface.viewers.DecoratingLabelProvider; import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.ITreeViewerListener; import org.eclipse.jface.viewers.TreeExpansionEvent; import org.eclipse.jface.wizard.WizardPage; @@ -36,40 +30,56 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.graphics.Font; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.IWorkingSetManager; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.IWorkingSetPage; -import org.eclipse.ui.model.WorkbenchLabelProvider; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICContainer; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.ui.CElementGrouping; +import org.eclipse.cdt.ui.CElementSorter; +import org.eclipse.cdt.ui.CUIPlugin; + +import org.eclipse.cdt.internal.ui.CPluginImages; +import org.eclipse.cdt.internal.ui.actions.SelectionConverter; +import org.eclipse.cdt.internal.ui.viewsupport.AppearanceAwareLabelProvider; +import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider; +import org.eclipse.cdt.internal.ui.viewsupport.CElementLabels; +import org.eclipse.cdt.internal.ui.viewsupport.DecoratingCLabelProvider; /** - * A celement working set page allows the user to edit an - * existing working set and create a new working set. + * The C element working set page allows the user to clreate + * and edit a C element working set. *

- * Working set elements are presented as a simple resource tree. + * Working set elements are presented as a C element tree. *

* */ public class CElementWorkingSetPage extends WizardPage implements IWorkingSetPage { final private static String PAGE_TITLE= WorkingSetMessages.getString("CElementWorkingSetPage.title"); //$NON-NLS-1$ - //final private static String PAGE_ID= WorkingSetMessages.getString("CElementWorkingSetPage"); //$NON-NLS-1$ final private static String PAGE_ID= "CElementWorkingSetPage"; //$NON-NLS-1$ private final static int SIZING_SELECTION_WIDGET_WIDTH = 50; private final static int SIZING_SELECTION_WIDGET_HEIGHT = 200; - private Text text; - CheckboxTreeViewer tree; - IWorkingSet workingSet; - private boolean firstCheck = false; // set to true if selection is set in setSelection + private Text fWorkingSetName; + private CheckboxTreeViewer fTree; + private IWorkingSet fWorkingSet; + private boolean fFirstCheck; // set to true if selection is set in setSelection + private ITreeContentProvider fTreeContentProvider; /** * Creates a new instance of the receiver. @@ -77,169 +87,135 @@ public class CElementWorkingSetPage extends WizardPage implements IWorkingSetPag public CElementWorkingSetPage() { super(PAGE_ID, PAGE_TITLE, CPluginImages.DESC_WIZABAN_C_APP); setDescription(WorkingSetMessages.getString("CElementWorkingSetPage.description")); //$NON-NLS-1$ + fFirstCheck= true; } - /** - * Adds working set elements contained in the given container to the list - * of checked resources. - * - * @param collectedResources list of collected resources - * @param container container to collect working set elements for - */ - private void addWorkingSetElements(List collectedResources, IContainer container) { - IAdaptable[] elements = workingSet.getElements(); - IPath containerPath = container.getFullPath(); - - for (int i = 0; i < elements.length; i++) { - IResource resource = null; - - if (elements[i] instanceof IResource) - resource = (IResource) elements[i]; - else - resource = (IResource) elements[i].getAdapter(IResource.class); - - if (resource != null) { - IPath resourcePath = resource.getFullPath(); - if (containerPath.isPrefixOf(resourcePath)) - collectedResources.add(elements[i]); - } - } - } - /** - * Overrides method in WizardPage. - * - * @see org.eclipse.jface.wizard.WizardPage#createControl(Composite) + /* + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) */ public void createControl(Composite parent) { - Font font = parent.getFont(); + initializeDialogUnits(parent); + Composite composite= new Composite(parent, SWT.NULL); composite.setLayout(new GridLayout()); composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); setControl(composite); - //WorkbenchHelp.setHelp(composite, IHelpContextIds.WORKING_SET_RESOURCE_PAGE); Label label = new Label(composite, SWT.WRAP); label.setText(WorkingSetMessages.getString("CElementWorkingSetPage.name")); //$NON-NLS-1$ - GridData data = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER); - label.setLayoutData(data); - label.setFont(font); + GridData gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER); + label.setLayoutData(gd); - text = new Text(composite, SWT.SINGLE | SWT.BORDER); - text.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL)); - text.setFont(font); - text.addModifyListener( + fWorkingSetName = new Text(composite, SWT.SINGLE | SWT.BORDER); + fWorkingSetName.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL)); + fWorkingSetName.addModifyListener( new ModifyListener() { public void modifyText(ModifyEvent e) { validateInput(); } } ); - text.setFocus(); + fWorkingSetName.setFocus(); label = new Label(composite, SWT.WRAP); label.setText(WorkingSetMessages.getString("CElementWorkingSetPage.content")); //$NON-NLS-1$ - data = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER); - label.setLayoutData(data); - label.setFont(font); + gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER); + label.setLayoutData(gd); - tree = new CheckboxTreeViewer(composite); - tree.setUseHashlookup(true); - tree.setContentProvider(new CElementWorkingSetPageContentProvider()); - tree.setLabelProvider( - new DecoratingLabelProvider( - new WorkbenchLabelProvider(), - CUIPlugin.getDefault().getWorkbench().getDecoratorManager().getLabelDecorator())); - tree.setInput(CUIPlugin.getWorkspace().getRoot()); - tree.setSorter(new CElementSorter()); + fTree = new CheckboxTreeViewer(composite); + gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL); + gd.heightHint = SIZING_SELECTION_WIDGET_HEIGHT; + gd.widthHint = SIZING_SELECTION_WIDGET_WIDTH; + fTree.getControl().setLayoutData(gd); - data = new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL); - data.heightHint = SIZING_SELECTION_WIDGET_HEIGHT; - data.widthHint = SIZING_SELECTION_WIDGET_WIDTH; - tree.getControl().setLayoutData(data); - tree.getControl().setFont(font); + fTreeContentProvider= new CElementWorkingSetPageContentProvider(); + fTree.setContentProvider(fTreeContentProvider); - tree.addCheckStateListener(new ICheckStateListener() { + AppearanceAwareLabelProvider cElementLabelProvider= + new AppearanceAwareLabelProvider( + AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS | CElementLabels.P_COMPRESSED, + AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS | CElementImageProvider.SMALL_ICONS + ); + + fTree.setLabelProvider(new DecoratingCLabelProvider(cElementLabelProvider)); + fTree.setSorter(new CElementSorter()); + fTree.setUseHashlookup(true); + + fTree.setInput(CoreModel.create(CUIPlugin.getWorkspace().getRoot())); + + fTree.addCheckStateListener(new ICheckStateListener() { public void checkStateChanged(CheckStateChangedEvent event) { handleCheckStateChange(event); } }); - tree.addTreeListener(new ITreeViewerListener() { + fTree.addTreeListener(new ITreeViewerListener() { public void treeCollapsed(TreeExpansionEvent event) { } public void treeExpanded(TreeExpansionEvent event) { final Object element = event.getElement(); - if (tree.getGrayed(element) == false) + if (fTree.getGrayed(element) == false) BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() { public void run() { - setSubtreeChecked((IContainer) element, tree.getChecked(element), false); + setSubtreeChecked(element, fTree.getChecked(element), false); } }); } }); + + if (fWorkingSet != null) { + fWorkingSetName.setText(fWorkingSet.getName()); + } initializeCheckedState(); - if (workingSet != null) { - text.setText(workingSet.getName()); - } - setPageComplete(false); + validateInput(); + + Dialog.applyDialogFont(composite); + // TODO Set help for the page +// CUIHelp.setHelp(fTree, ICHelpContextIds.C_WORKING_SET_PAGE); } - /** - * Collects all checked resources in the specified container. - * - * @param checkedResources the output, list of checked resources - * @param container the container to collect checked resources in - */ - private void findCheckedResources(List checkedResources, IContainer container) { - IResource[] resources = null; - try { - resources = container.members(); - } catch (CoreException ex) { - handleCoreException(ex, getShell(), WorkingSetMessages.getString("EditWorkingSetAction.nowizard.message"), //$NON-NLS-1$ - "updateCheckedState"); //$NON-NLS-1$ - } - for (int i = 0; i < resources.length; i++) { - if (tree.getGrayed(resources[i])) { - if (resources[i].isAccessible()) - findCheckedResources(checkedResources, (IContainer) resources[i]); - else - addWorkingSetElements(checkedResources, (IContainer) resources[i]); - } else if (tree.getChecked(resources[i])) { - checkedResources.add(resources[i]); - } - } - } - /** - * Implements IWorkingSetPage. - * + + /* * @see org.eclipse.ui.dialogs.IWorkingSetPage#finish() */ public void finish() { - ArrayList resources = new ArrayList(10); - findCheckedResources(resources, (IContainer) tree.getInput()); - if (workingSet == null) { - IWorkingSetManager workingSetManager = PlatformUI.getWorkbench().getWorkingSetManager(); - workingSet = workingSetManager.createWorkingSet(getWorkingSetName(), (IAdaptable[]) resources.toArray(new IAdaptable[resources.size()])); + String workingSetName= fWorkingSetName.getText(); + ArrayList elements= new ArrayList(10); + findCheckedElements(elements, fTree.getInput()); + if (fWorkingSet == null) { + IWorkingSetManager workingSetManager= PlatformUI.getWorkbench().getWorkingSetManager(); + fWorkingSet= workingSetManager.createWorkingSet(workingSetName, (IAdaptable[])elements.toArray(new IAdaptable[elements.size()])); } else { - workingSet.setName(getWorkingSetName()); - workingSet.setElements((IAdaptable[]) resources.toArray(new IAdaptable[resources.size()])); + // Add inaccessible resources + IAdaptable[] oldItems= fWorkingSet.getElements(); + ArrayList closedWithChildren= new ArrayList(elements.size()); + for (int i= 0; i < oldItems.length; i++) { + IResource oldResource= null; + if (oldItems[i] instanceof IResource) { + oldResource= (IResource)oldItems[i]; + } else { + oldResource= (IResource)oldItems[i].getAdapter(IResource.class); + } + if (oldResource != null && oldResource.isAccessible() == false) { + IProject project= oldResource.getProject(); + if (elements.contains(project) || closedWithChildren.contains(project)) { + elements.add(oldItems[i]); + elements.remove(project); + closedWithChildren.add(project); + } + } + } + fWorkingSet.setName(workingSetName); + fWorkingSet.setElements((IAdaptable[]) elements.toArray(new IAdaptable[elements.size()])); } } - /** - * Implements IWorkingSetPage. - * + + /* * @see org.eclipse.ui.dialogs.IWorkingSetPage#getSelection() */ public IWorkingSet getSelection() { - return workingSet; - } - /** - * Returns the name entered in the working set name field. - * - * @return the name entered in the working set name field. - */ - private String getWorkingSetName() { - return text.getText(); + return fWorkingSet; } + /** * Called when the checked state of a tree item changes. * @@ -248,179 +224,202 @@ public class CElementWorkingSetPage extends WizardPage implements IWorkingSetPag void handleCheckStateChange(final CheckStateChangedEvent event) { BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() { public void run() { - IResource resource = (IResource) event.getElement(); + IAdaptable element= (IAdaptable) event.getElement(); boolean state = event.getChecked(); - tree.setGrayed(resource, false); - if (resource instanceof IContainer) { - setSubtreeChecked((IContainer) resource, state, true); + fTree.setGrayed(element, false); + if (isExpandable(element)) { + setSubtreeChecked(element, state, true); } - updateParentState(resource); + updateParentState(element, state); validateInput(); } }); } - /** - * Displays an error message when a CoreException occured. - * - * @param exception the CoreException - * @param shell parent shell for the message box - * @param title the mesage box title - * @param message additional error message - */ - private void handleCoreException(CoreException exception, Shell shell, String title, String message) { - IStatus status = exception.getStatus(); - if (status != null) { - ErrorDialog.openError(shell, title, message, status); - } else { - MessageDialog.openError(shell, WorkingSetMessages.getString("EditWorkingSetAction.nowizard.message"), exception.getLocalizedMessage()); //$NON-NLS-1$ - } + + private boolean isExpandable(Object element) { + return (element instanceof ICProject || element instanceof ICContainer + || element instanceof CElementGrouping + || element instanceof ICModel || element instanceof IContainer); } + /** * Sets the checked state of tree items based on the initial * working set, if any. */ private void initializeCheckedState() { - if (workingSet == null) + if (fWorkingSet == null) return; BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() { public void run() { - IAdaptable[] items = workingSet.getElements(); - tree.setCheckedElements(items); - for (int i = 0; i < items.length; i++) { - IAdaptable item = items[i]; - IContainer container = null; - IResource resource = null; + Object[] elements; + if (fWorkingSet == null) { + // Use current part's selection for initialization + IWorkbenchPage page= CUIPlugin.getActivePage(); + if (page == null) + return; + + IWorkbenchPart part= CUIPlugin.getActivePage().getActivePart(); + if (part == null) + return; + + try { + elements= SelectionConverter.getStructuredSelection(part).toArray(); + for (int i= 0; i < elements.length; i++) { + if (elements[i] instanceof IResource) { + ICElement ce= (ICElement)((IResource)elements[i]).getAdapter(ICElement.class); + if (ce != null && ce.exists() && ce.getCProject().isOnSourceRoot((IResource)elements[i])) + elements[i]= ce; + } + } + } catch (CModelException e) { + return; + } + } + else + elements= fWorkingSet.getElements(); - if (item instanceof IContainer) { - container = (IContainer) item; - } else { - container = (IContainer) item.getAdapter(IContainer.class); + for (int i = 0; i < elements.length; i++) { + Object element = elements[i]; + if (element instanceof IResource) { + // for backwards compatibility: adapt to ICElement if possible + ICElement cElement= CoreModel.getDefault().create((IResource)element); + if (cElement != null) { + elements[i]= element= cElement; + } } - if (container != null) { - setSubtreeChecked(container, true, true); + if (element instanceof IResource) { + IProject project= ((IResource)element).getProject(); + if (!project.isAccessible()) + elements[i]= project; } - if (item instanceof IResource) { - resource = (IResource) item; - } else { - resource = (IResource) item.getAdapter(IResource.class); - } - if (resource != null && resource.isAccessible() == false) { - IProject project = resource.getProject(); - if (tree.getChecked(project) == false) - tree.setGrayChecked(project, true); - } - else { - updateParentState(resource); + if (element instanceof ICElement) { + ICProject cProject= ((ICElement)element).getCProject(); + if (cProject != null && !cProject.getProject().isAccessible()) + elements[i]= cProject.getProject(); } } + fTree.setCheckedElements(elements); + for (int i= 0; i < elements.length; i++) { + Object element= elements[i]; + if (isExpandable(element)) + setSubtreeChecked(element, true, true); + + updateParentState(element, true); + } } }); } - /** - * Implements IWorkingSetPage. - * - * @see org.eclipse.ui.dialogs.IWorkingSetPage#setSelection(IWorkingSet) + + /* + * @see org.eclipse.ui.dialogs.IWorkingSetPage#setSelection(org.eclipse.ui.IWorkingSet) */ public void setSelection(IWorkingSet workingSet) { if (workingSet == null) { throw new IllegalArgumentException("Working set must not be null"); //$NON-NLS-1$ } - this.workingSet = workingSet; - if (getShell() != null && text != null) { - firstCheck = true; + fWorkingSet = workingSet; + if (getContainer() != null && fWorkingSetName != null) { + fFirstCheck = false; + fWorkingSetName.setText(workingSet.getName()); initializeCheckedState(); - text.setText(workingSet.getName()); + validateInput(); } } /** * Sets the checked state of the container's members. * - * @param container the container whose children should be checked/unchecked + * @param parent the parent whose children should be checked/unchecked * @param state true=check all members in the container. false=uncheck all * members in the container. * @param checkExpandedState true=recurse into sub-containers and set the * checked state. false=only set checked state of members of this container */ - void setSubtreeChecked(IContainer container, boolean state, boolean checkExpandedState) { - // checked state is set lazily on expand, don't set it if container is collapsed - if (container.isAccessible() == false || (tree.getExpandedState(container) == false && state && checkExpandedState)) { + private void setSubtreeChecked(Object parent, boolean state, boolean checkExpandedState) { + if (!(parent instanceof IAdaptable)) return; - } - IResource[] members = null; - try { - members = container.members(); - } catch (CoreException ex) { - handleCoreException(ex, getShell(), WorkingSetMessages.getString("EditWorkingSetAction.nowizard.message"), //$NON-NLS-1$ - "updateCheckedState"); //$NON-NLS-1$ - } - for (int i = members.length - 1; i >= 0; i--) { - IResource element = members[i]; - boolean elementGrayChecked = tree.getGrayed(element) || tree.getChecked(element); - + IContainer container= (IContainer)((IAdaptable)parent).getAdapter(IContainer.class); + if ((!fTree.getExpandedState(parent) && checkExpandedState) || (container != null && !container.isAccessible())) + return; + + Object[] children= fTreeContentProvider.getChildren(parent); + for (int i= children.length - 1; i >= 0; i--) { + Object element= children[i]; if (state) { - tree.setChecked(element, true); - tree.setGrayed(element, false); - } else { - tree.setGrayChecked(element, false); - } - // unchecked state only needs to be set when the container is - // checked or grayed - if (element instanceof IContainer && (state || elementGrayChecked)) { - setSubtreeChecked((IContainer) element, state, true); + fTree.setChecked(element, true); + fTree.setGrayed(element, false); } + else + fTree.setGrayChecked(element, false); + if (isExpandable(element)) + setSubtreeChecked(element, state, true); } } + /** * Check and gray the resource parent if all resources of the * parent are checked. * * @param child the resource whose parent checked state should * be set. + * @param baseChildState */ - void updateParentState(IResource child) { - if (child == null || child.getParent() == null) + void updateParentState(Object child, boolean baseChildState) { + if (child == null) + return; + if (child instanceof IAdaptable) { + IResource resource = (IResource) ((IAdaptable) child) + .getAdapter(IResource.class); + if (resource != null && !resource.isAccessible()) + return; + } + Object parent = fTreeContentProvider.getParent(child); + if (parent == null) return; - IContainer parent = child.getParent(); - boolean childChecked = false; - IResource[] members = null; - try { - members = parent.members(); - } catch (CoreException ex) { - handleCoreException(ex, getShell(), WorkingSetMessages.getString("EditWorkingSetAction.nowizard.message"), //$NON-NLS-1$ - "updateCheckedState"); //$NON-NLS-1$ - } - for (int i = members.length - 1; i >= 0; i--) { - if (tree.getChecked(members[i]) || tree.getGrayed(members[i])) { - childChecked = true; + boolean allSameState = true; + Object[] children = null; + children = fTreeContentProvider.getChildren(parent); + + for (int i = children.length - 1; i >= 0; i--) { + if (fTree.getChecked(children[i]) != baseChildState + || fTree.getGrayed(children[i])) { + allSameState = false; break; } } - tree.setGrayChecked(parent, childChecked); - updateParentState(parent); + + fTree.setGrayed(parent, !allSameState); + fTree.setChecked(parent, !allSameState || baseChildState); + + updateParentState(parent, baseChildState); } + /** * Validates the working set name and the checked state of the * resource tree. */ void validateInput() { String errorMessage = null; - String newText = text.getText(); + String newText = fWorkingSetName.getText(); if (newText.equals(newText.trim()) == false) { errorMessage = WorkingSetMessages.getString("CElementWorkingSetPage.warning.nameMustNotBeEmpty"); //$NON-NLS-1$ } - else - if (firstCheck) { - firstCheck = false; - return; - } if (newText.equals("")) { //$NON-NLS-1$ - errorMessage = WorkingSetMessages.getString("CElementWorkingSetPage.warning.nameMustNotBeEmpty"); //$NON-NLS-1$ + if (fFirstCheck) { + setPageComplete(false); + fFirstCheck= false; + return; + } + else + errorMessage = WorkingSetMessages.getString("CElementWorkingSetPage.warning.nameMustNotBeEmpty"); //$NON-NLS-1$ } - if (errorMessage == null && (workingSet == null || newText.equals(workingSet.getName()) == false)) { + + fFirstCheck= false; + + if (errorMessage == null && (fWorkingSet == null || newText.equals(fWorkingSet.getName()) == false)) { IWorkingSet[] workingSets = PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSets(); for (int i = 0; i < workingSets.length; i++) { if (newText.equals(workingSets[i].getName())) { @@ -428,10 +427,28 @@ public class CElementWorkingSetPage extends WizardPage implements IWorkingSetPag } } } - if (errorMessage == null && tree.getCheckedElements().length == 0) { - errorMessage = WorkingSetMessages.getString("CElementWorkingSetPage.warning.resourceMustBeChecked"); //$NON-NLS-1$ + + if (errorMessage == null && fTree.getCheckedElements().length == 0) { + String infoMessage = WorkingSetMessages.getString("CElementWorkingSetPage.warning.resourceMustBeChecked"); //$NON-NLS-1$ + setMessage(infoMessage, INFORMATION); } setErrorMessage(errorMessage); setPageComplete(errorMessage == null); } + + /** + * Collects all checked elements of the given parent. + * + * @param checkedElements the output, list of checked elements + * @param parent the parent to collect checked elements in + */ + private void findCheckedElements(List checkedElements, Object parent) { + Object[] children= fTreeContentProvider.getChildren(parent); + for (int i= 0; i < children.length; i++) { + if (fTree.getGrayed(children[i])) + findCheckedElements(checkedElements, children[i]); + else if (fTree.getChecked(children[i])) + checkedElements.add(children[i]); + } + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/CElementWorkingSetPageContentProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/CElementWorkingSetPageContentProvider.java index ca8ec93d8c1..31051c91c32 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/CElementWorkingSetPageContentProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/CElementWorkingSetPageContentProvider.java @@ -7,21 +7,24 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Anton Leherbauer (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.ui.workingsets; import java.util.ArrayList; import java.util.List; -import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.ui.model.WorkbenchContentProvider; -class CElementWorkingSetPageContentProvider extends WorkbenchContentProvider { +import org.eclipse.cdt.core.model.CoreModel; - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) +import org.eclipse.cdt.internal.ui.BaseCElementContentProvider; + +class CElementWorkingSetPageContentProvider extends BaseCElementContentProvider { + + /* + * @see org.eclipse.cdt.internal.ui.BaseCElementContentProvider#getChildren(java.lang.Object) */ public Object[] getChildren(Object element) { if (element instanceof IWorkspaceRoot) { @@ -30,7 +33,7 @@ class CElementWorkingSetPageContentProvider extends WorkbenchContentProvider { List list = new ArrayList(projects.length); for (int i = 0; i < projects.length; i++) { if (CoreModel.hasCNature(projects[i])) { - list.add(projects[i]); + list.add(CoreModel.getDefault().create(projects[i])); } } return list.toArray(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/CElementWorkingSetUpdater.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/CElementWorkingSetUpdater.java new file mode 100644 index 00000000000..ce61d5f311a --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/CElementWorkingSetUpdater.java @@ -0,0 +1,250 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Anton Leherbauer (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.workingsets; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.ui.IWorkingSet; +import org.eclipse.ui.IWorkingSetUpdater; + +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ElementChangedEvent; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICElementDelta; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IElementChangedListener; + + +public class CElementWorkingSetUpdater implements IWorkingSetUpdater, IElementChangedListener { + + public static final String ID= "org.eclipse.cdt.ui.CElementWorkingSetPage"; //$NON-NLS-1$ + + private List fWorkingSets; + + private static class WorkingSetDelta { + private IWorkingSet fWorkingSet; + private List fElements; + private boolean fChanged; + public WorkingSetDelta(IWorkingSet workingSet) { + fWorkingSet= workingSet; + fElements= new ArrayList(Arrays.asList(workingSet.getElements())); + } + public int indexOf(Object element) { + return fElements.indexOf(element); + } + public void set(int index, Object element) { + fElements.set(index, element); + fChanged= true; + } + public void remove(int index) { + if (fElements.remove(index) != null) { + fChanged= true; + } + } + public void process() { + if (fChanged) { + fWorkingSet.setElements((IAdaptable[])fElements.toArray(new IAdaptable[fElements.size()])); + } + } + } + + public CElementWorkingSetUpdater() { + fWorkingSets= new ArrayList(); + CoreModel.getDefault().addElementChangedListener(this); + } + + /** + * {@inheritDoc} + */ + public void add(IWorkingSet workingSet) { + checkElementExistence(workingSet); + synchronized (fWorkingSets) { + fWorkingSets.add(workingSet); + } + } + + /** + * {@inheritDoc} + */ + public boolean remove(IWorkingSet workingSet) { + boolean result; + synchronized(fWorkingSets) { + result= fWorkingSets.remove(workingSet); + } + return result; + } + + /** + * {@inheritDoc} + */ + public boolean contains(IWorkingSet workingSet) { + synchronized(fWorkingSets) { + return fWorkingSets.contains(workingSet); + } + } + + /** + * {@inheritDoc} + */ + public void dispose() { + synchronized(fWorkingSets) { + fWorkingSets.clear(); + } + CoreModel.getDefault().removeElementChangedListener(this); + } + + /** + * {@inheritDoc} + */ + public void elementChanged(ElementChangedEvent event) { + IWorkingSet[] workingSets; + synchronized(fWorkingSets) { + workingSets= (IWorkingSet[])fWorkingSets.toArray(new IWorkingSet[fWorkingSets.size()]); + } + for (int w= 0; w < workingSets.length; w++) { + WorkingSetDelta workingSetDelta= new WorkingSetDelta(workingSets[w]); + processCElementDelta(workingSetDelta, event.getDelta()); + IResourceDelta[] resourceDeltas= event.getDelta().getResourceDeltas(); + if (resourceDeltas != null) { + for (int r= 0; r < resourceDeltas.length; r++) { + processResourceDelta(workingSetDelta, resourceDeltas[r]); + } + } + workingSetDelta.process(); + } + } + + private void processCElementDelta(WorkingSetDelta result, ICElementDelta delta) { + ICElement cElement= delta.getElement(); + int index= result.indexOf(cElement); + int type= cElement.getElementType(); + int kind= delta.getKind(); + int flags= delta.getFlags(); + if (type == ICElement.C_PROJECT && kind == ICElementDelta.CHANGED) { + if (index != -1 && (flags & ICElementDelta.F_CLOSED) != 0) { + result.set(index, ((ICProject)cElement).getProject()); + } else if ((flags & ICElementDelta.F_OPENED) != 0) { + index= result.indexOf(((ICProject)cElement).getProject()); + if (index != -1) + result.set(index, cElement); + } + } else if (type == ICElement.C_PROJECT && kind == ICElementDelta.REMOVED) { + if (index != -1) + result.set(index, ((ICProject)cElement).getProject()); + } else if (type == ICElement.C_PROJECT && kind == ICElementDelta.ADDED) { + index= result.indexOf(((ICProject)cElement).getProject()); + if (index != -1) + result.set(index, cElement); + } else if (index != -1) { + if (kind == ICElementDelta.REMOVED) { + if ((flags & ICElementDelta.F_MOVED_TO) != 0) { + result.set(index, delta.getMovedToElement()); + } else { + result.remove(index); + } + } + } + IResourceDelta[] resourceDeltas= delta.getResourceDeltas(); + if (resourceDeltas != null) { + for (int i= 0; i < resourceDeltas.length; i++) { + processResourceDelta(result, resourceDeltas[i]); + } + } + ICElementDelta[] children= delta.getAffectedChildren(); + for (int i= 0; i < children.length; i++) { + processCElementDelta(result, children[i]); + } + } + + private void processResourceDelta(WorkingSetDelta result, IResourceDelta delta) { + IResource resource= delta.getResource(); + int type= resource.getType(); + int index= result.indexOf(resource); + int kind= delta.getKind(); + int flags= delta.getFlags(); + if (kind == IResourceDelta.CHANGED && type == IResource.PROJECT && index != -1) { + if ((flags & IResourceDelta.OPEN) != 0) { + result.set(index, resource); + } + } + if (index != -1 && kind == IResourceDelta.REMOVED) { + if ((flags & IResourceDelta.MOVED_TO) != 0) { + result.set(index, + ResourcesPlugin.getWorkspace().getRoot().findMember(delta.getMovedToPath())); + } else { + result.remove(index); + } + } + + // Don't dive into closed or opened projects + if (projectGotClosedOrOpened(resource, kind, flags)) + return; + + IResourceDelta[] children= delta.getAffectedChildren(); + for (int i= 0; i < children.length; i++) { + processResourceDelta(result, children[i]); + } + } + + private boolean projectGotClosedOrOpened(IResource resource, int kind, int flags) { + return resource.getType() == IResource.PROJECT + && kind == IResourceDelta.CHANGED + && (flags & IResourceDelta.OPEN) != 0; + } + + private void checkElementExistence(IWorkingSet workingSet) { + List elements= new ArrayList(Arrays.asList(workingSet.getElements())); + boolean changed= false; + for (Iterator iter= elements.iterator(); iter.hasNext();) { + IAdaptable element= (IAdaptable)iter.next(); + boolean remove= false; + if (element instanceof ICElement) { + ICElement cElement= (ICElement)element; + // If we have directly a project then remove it when it + // doesn't exist anymore. However if we have a sub element + // under a project only remove the element if the parent + // project is open. Otherwise we would remove all elements + // in closed projects. + if (cElement instanceof ICProject) { + remove= !cElement.exists(); + } else { + IProject project= cElement.getCProject().getProject(); + remove= project.isOpen() && !cElement.exists(); + } + } else if (element instanceof IResource) { + IResource resource= (IResource)element; + // See comments above + if (resource instanceof IProject) { + remove= !resource.exists(); + } else { + IProject project= resource.getProject(); + remove= (project != null ? project.isOpen() : true) && !resource.exists(); + } + } + if (remove) { + iter.remove(); + changed= true; + } + } + if (changed) { + workingSet.setElements((IAdaptable[])elements.toArray(new IAdaptable[elements.size()])); + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CElementContentProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CElementContentProvider.java index 82e50511c2f..94adf69da8c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CElementContentProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CElementContentProvider.java @@ -7,7 +7,7 @@ * * Contributors: * QNX Software Systems - Initial API and implementation - * Anton Leherbauer (Wind River Systems) - Fixed bug 131267 + * Anton Leherbauer (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.ui; @@ -159,34 +159,33 @@ public class CElementContentProvider extends BaseCElementContentProvider impleme //System.out.println("Processing " + element); - // handle open and closing of a solution or project + // handle open and closing of a project if (((flags & ICElementDelta.F_CLOSED) != 0) || ((flags & ICElementDelta.F_OPENED) != 0)) { postRefresh(element); } // We do not care about changes in Working copies // well, we do see bugzilla 147694 -// if (element instanceof ITranslationUnit) { -// ITranslationUnit unit = (ITranslationUnit) element; -// if (unit.isWorkingCopy()) { -// return; -// } -// } + if (element instanceof ITranslationUnit) { + ITranslationUnit unit = (ITranslationUnit) element; + if (!getProvideWorkingCopy() && unit.isWorkingCopy()) { + return; + } + if (!getProvideMembers() && kind == ICElementDelta.CHANGED) { + return; + } + } if (kind == ICElementDelta.REMOVED) { - Object parent = internalGetParent(element); postRemove(element); - if (updateContainer(element)) { - postRefresh(parent); - } + updateContainer(element); + return; } if (kind == ICElementDelta.ADDED) { Object parent= internalGetParent(element); postAdd(parent, element); - if (updateContainer(element)) { - postRefresh(parent); - } + updateContainer(element); } if (kind == ICElementDelta.CHANGED) { @@ -196,8 +195,10 @@ public class CElementContentProvider extends BaseCElementContentProvider impleme if (updateContainer(element)) { Object parent = getParent(element); postRefresh(parent); + return; } else if (element instanceof ITranslationUnit) { postRefresh(element); + return; } else if (element instanceof ArchiveContainer || element instanceof BinaryContainer) { postContainerRefresh((IParent) element, element.getCProject()); } @@ -210,28 +211,49 @@ public class CElementContentProvider extends BaseCElementContentProvider impleme return;// bailout } - if (delta.getResourceDeltas() != null) { - IResourceDelta[] rd= delta.getResourceDeltas(); - for (int i= 0; i < rd.length; i++) { - processResourceDelta(rd[i], element); - } - } - + if (processResourceDeltas(delta.getResourceDeltas(), element)) + return; + ICElementDelta[] affectedChildren= delta.getAffectedChildren(); for (int i= 0; i < affectedChildren.length; i++) { processDelta(affectedChildren[i]); } } - /* - * Process resource deltas + /** + * Process resource deltas. + * + * @return true if the parent got refreshed */ - private void processResourceDelta(IResourceDelta delta, Object parent) { + private boolean processResourceDeltas(IResourceDelta[] deltas, Object parent) { + if (deltas == null) + return false; + + if (deltas.length > 1) { + // more than one child changed, refresh from here downwards + postRefresh(parent); + return true; + } + + for (int i= 0; i < deltas.length; i++) { + if (processResourceDelta(deltas[i], parent)) + return true; + } + + return false; + } + + /** + * Process a resource delta. + * + * @return true if the parent got refreshed + */ + private boolean processResourceDelta(IResourceDelta delta, Object parent) { int status= delta.getKind(); IResource resource= delta.getResource(); // filter out changes affecting the output folder if (resource == null) { - return; + return false; } // this could be optimized by handling all the added children in the parent @@ -241,17 +263,16 @@ public class CElementContentProvider extends BaseCElementContentProvider impleme if ((status & IResourceDelta.ADDED) != 0) { postAdd(parent, resource); } - IResourceDelta[] affectedChildren= delta.getAffectedChildren(); - if (affectedChildren.length > 1) { - // more than one child changed, refresh from here downwards - postRefresh(resource); - return; + int flags= delta.getFlags(); + // open/close state change of a project + if ((flags & IResourceDelta.OPEN) != 0) { + postRefresh(parent); + return true; } - for (int i= 0; i < affectedChildren.length; i++) { - processResourceDelta(affectedChildren[i], resource); - } + processResourceDeltas(delta.getAffectedChildren(), resource); + return false; } private boolean updateContainer(ICElement cfile) throws CModelException { @@ -339,27 +360,54 @@ public class CElementContentProvider extends BaseCElementContentProvider impleme return element.hashCode()*7 + 490487; } } - - private void postContainerRefresh(final IParent container, final ICProject cproject) { + + final class RefreshProjectState implements IRefreshable { + private Object element; + public RefreshProjectState(Object element) { + this.element = element; + } + public void refresh() { + fViewer.refresh(element, true); + // trigger a syntetic selection change so that action refresh their + // enable state. + fViewer.setSelection(fViewer.getSelection()); + } + public boolean equals(Object o) { + if (o instanceof RefreshElement) { + RefreshElement c = (RefreshElement)o; + return c.element.equals(element); + } + return false; + } + public int hashCode() { + return element.hashCode()*11 + 490487; + } + } + + protected void postContainerRefresh(final IParent container, final ICProject cproject) { //System.out.println("UI Container:" + cproject + " " + container); postRefreshable(new RefreshContainer(container, cproject)); } - private void postRefresh(final Object element) { + protected void postRefresh(final Object element) { //System.out.println("UI refresh:" + root); postRefreshable(new RefreshElement(element)); } - private void postAdd(final Object parent, final Object element) { + protected void postAdd(final Object parent, final Object element) { //System.out.println("UI add:" + parent + " " + element); postRefreshable(new RefreshElement(parent)); } - private void postRemove(final Object element) { + protected void postRemove(final Object element) { //System.out.println("UI remove:" + element); postRefreshable(new RefreshElement(internalGetParent(element))); } + protected void postProjectStateChanged(final Object root) { + postRefreshable(new RefreshProjectState(root)); + } + private void postRefreshable(final IRefreshable r) { Control ctrl= fViewer.getControl(); if (ctrl != null && !ctrl.isDisposed()) {