1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-19 15:05:36 +02:00

Fix working set support for use with Common Navigator

This commit is contained in:
Anton Leherbauer 2006-10-09 15:25:55 +00:00
parent 4fd4c4adce
commit ead46b18a7
12 changed files with 784 additions and 541 deletions

View file

@ -34,6 +34,7 @@
</adapter>
<adapter type="org.eclipse.ui.progress.IDeferredWorkbenchAdapter"/>
<adapter type="org.eclipse.ui.IActionFilter"/>
<adapter type="org.eclipse.ui.IPersistableElement"/>
</factory>
<factory
adaptableType="org.eclipse.cdt.internal.ui.editor.CEditor"
@ -42,6 +43,13 @@
</factory>
</extension>
<extension
point="org.eclipse.ui.elementFactories">
<factory
class="org.eclipse.cdt.internal.ui.PersistableCElementFactory"
id="org.eclipse.cdt.ui.PersistableCElementFactory"/>
</extension>
<!-- Implement our filters. -->
<extension
point="org.eclipse.cdt.ui.CElementFilters">
@ -1229,10 +1237,11 @@
<extension
point="org.eclipse.ui.workingSets">
<workingSet
icon="icons/view16/cview.gif"
id="org.eclipse.cdt.ui.CElementWorkingSetPage"
name="%CElementWorkingSetPage.name"
pageClass="org.eclipse.cdt.internal.ui.workingsets.CElementWorkingSetPage"
icon="icons/view16/cview.gif"
id="org.eclipse.cdt.ui.CElementWorkingSetPage">
updaterClass="org.eclipse.cdt.internal.ui.workingsets.CElementWorkingSetUpdater">
</workingSet>
</extension>
<extension
@ -1484,10 +1493,6 @@
<instanceof value="org.eclipse.cdt.core.model.ICElement"/>
</enablement>
</actionProvider>
<actionProvider
class="org.eclipse.cdt.internal.ui.navigator.CNavigatorWorkingSetActionProvider"
id="org.eclipse.cdt.ui.navigator.actions.workingSet">
</actionProvider>
<actionProvider
class="org.eclipse.cdt.internal.ui.navigator.CNavigatorSearchActionProvider"
id="org.eclipse.cdt.ui.navigator.actions.search">

View file

@ -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);
}

View file

@ -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)) {

View file

@ -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());
}
}
}

View file

@ -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:
* <ul>
* <li><code>part instanceof CEditor</code>: returns a structured selection
* using code resolve to convert the editor's text selection.</li>
* <li><code>part instanceof IWorkbenchPart</code>: returns the part's selection
* if it is a structured selection.</li>
* <li><code>default</code>: returns an empty structured selection.</li>
* </ul>
*/
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) {

View file

@ -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));
}
}

View file

@ -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 <code>WorkingSetFilterActionGroup</code> 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.
* <p>
* Note: This method does not refresh the viewer.
* </p>
* @param memento
*/
public void restoreState(IMemento memento) {
String workingSetName= memento.getString(TAG_WORKING_SET_NAME);
IWorkingSet workingSet= PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSet(workingSetName);
setWorkingSet(workingSet);
}
}

View file

@ -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();
}
}

View file

@ -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.
* <p>
* Working set elements are presented as a simple resource tree.
* Working set elements are presented as a C element tree.
* </p>
*
*/
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]);
}
}
}

View file

@ -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();

View file

@ -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()]));
}
}
}

View file

@ -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()) {