blob: 0e58a5bf1c886c825c83c36c920233892897ab2c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2002, 2012 QNX Software Systems and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.cview;
import java.util.ArrayList;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.IArchive;
import org.eclipse.cdt.core.model.IArchiveContainer;
import org.eclipse.cdt.core.model.IBinary;
import org.eclipse.cdt.core.model.IBinaryContainer;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IIncludeReference;
import org.eclipse.cdt.core.model.ILibraryReference;
import org.eclipse.cdt.internal.ui.util.RemoteTreeContentManager;
import org.eclipse.cdt.internal.ui.util.RemoteTreeViewer;
import org.eclipse.cdt.ui.CElementContentProvider;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.ui.IWorkbenchPartSite;
/**
* CViewContentProvider
*/
public class CViewContentProvider extends CElementContentProvider {
private RemoteTreeContentManager fManager;
public CViewContentProvider() {
super();
}
/**
*
*/
public CViewContentProvider(TreeViewer viewer, IWorkbenchPartSite site) {
super();
fManager = createContentManager(viewer, site);
}
/**
* @param provideMembers
* @param provideWorkingCopy
*/
public CViewContentProvider(TreeViewer viewer, IWorkbenchPartSite site, boolean provideMembers,
boolean provideWorkingCopy) {
super(provideMembers, provideWorkingCopy);
fManager = createContentManager(viewer, site);
}
protected RemoteTreeContentManager createContentManager(TreeViewer viewer, IWorkbenchPartSite site) {
if (site == null) {
return new RemoteTreeContentManager(this, (RemoteTreeViewer) viewer, null);
}
return new RemoteTreeContentManager(this, (RemoteTreeViewer) viewer, site);
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
*/
@Override
public Object[] getChildren(Object element) {
Object[] objs = null;
if (fManager != null) {
// use the the deferred manager for some cases
if (element instanceof IBinary) {
// It takes sometimes to parse binaries deferred it
objs = fManager.getChildren(element);
} else if (element instanceof IArchive) {
// It takes sometimes to parse archives deferred it
objs = fManager.getChildren(element);
}
}
if (objs == null) {
objs = super.getChildren(element);
}
Object[] extras = null;
try {
if (element instanceof ICProject) {
extras = getProjectChildren((ICProject) element);
} else if (element instanceof IBinaryContainer) {
extras = getExecutables((IBinaryContainer) element);
} else if (element instanceof IArchiveContainer) {
extras = getArchives((IArchiveContainer) element);
} else if (element instanceof IIncludeReference) {
extras = getIncludeReferenceChildren((IIncludeReference) element);
}
/*
* Do not to this for now, since ILibraryReference is an Archive.
else if (element instanceof ILibraryReference) {
extras = ((ILibraryReference)element).getChildren();
}*/
} catch (CModelException e) {
}
if (extras != null && extras.length > 0) {
objs = concatenate(objs, extras);
}
return objs;
}
public Object[] getIncludeReferenceChildren(IIncludeReference ref) throws CModelException {
// We do not want to show children for Include paths that are inside the workspace.
// no need to that since they can access elsewhere and that simplifies the
// CView code.
IPath location = ref.getPath();
IContainer[] containers = ref.getCModel().getWorkspace().getRoot().findContainersForLocation(location);
for (int i = 0; i < containers.length; ++i) {
if (containers[i].isAccessible()) {
return NO_CHILDREN;
}
}
return ref.getChildren();
}
private Object[] getProjectChildren(ICProject cproject) throws CModelException {
Object[] extras = null;
IArchiveContainer archive = cproject.getArchiveContainer();
if (getArchives(archive).length > 0) {
extras = new Object[] { archive };
}
IBinaryContainer bin = cproject.getBinaryContainer();
if (getExecutables(bin).length > 0) {
Object[] o = new Object[] { bin };
if (extras != null && extras.length > 0) {
extras = concatenate(extras, o);
} else {
extras = o;
}
}
LibraryRefContainer libRefCont = new LibraryRefContainer(cproject);
Object[] libRefs = libRefCont.getChildren(cproject);
if (libRefs != null && libRefs.length > 0) {
Object[] o = new Object[] { libRefCont };
if (extras != null && extras.length > 0) {
extras = concatenate(extras, o);
} else {
extras = o;
}
}
IncludeRefContainer incRefCont = new IncludeRefContainer(cproject);
Object[] incRefs = incRefCont.getChildren(cproject);
if (incRefs != null && incRefs.length > 0) {
Object[] o = new Object[] { incRefCont };
if (extras != null && extras.length > 0) {
extras = concatenate(extras, o);
} else {
extras = o;
}
}
return extras;
}
protected IBinary[] getExecutables(IBinaryContainer container) throws CModelException {
ICElement[] celements = container.getChildren();
ArrayList<IBinary> list = new ArrayList<>(celements.length);
for (int i = 0; i < celements.length; i++) {
if (celements[i] instanceof IBinary) {
IBinary bin = (IBinary) celements[i];
if (bin.showInBinaryContainer()) {
list.add(bin);
}
}
}
IBinary[] bins = new IBinary[list.size()];
list.toArray(bins);
return bins;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.ui.BaseCElementContentProvider#internalGetParent(java.lang.Object)
*/
@Override
public Object internalGetParent(Object element) {
// since we insert logical containers we have to fix
// up the parent for {IInclude,ILibrary}Reference so that they refer
// to the container and containers refere to the project
Object parent = super.internalGetParent(element);
if (element instanceof IncludeReferenceProxy) {
parent = ((IncludeReferenceProxy) element).getIncludeRefContainer();
} else if (element instanceof IncludeRefContainer) {
parent = ((IncludeRefContainer) element).getCProject();
} else if (element instanceof ILibraryReference) {
if (parent instanceof ICProject) {
parent = new LibraryRefContainer((ICProject) parent);
}
} else if (element instanceof LibraryRefContainer) {
parent = ((LibraryRefContainer) element).getCProject();
}
return parent;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
*/
@Override
public boolean hasChildren(Object element) {
if (fManager != null) {
if (element instanceof IBinary) {
return fManager.mayHaveChildren(element);
} else if (element instanceof IArchive) {
return fManager.mayHaveChildren(element);
}
}
if (element instanceof IBinaryContainer) {
try {
IBinaryContainer cont = (IBinaryContainer) element;
IBinary[] bins = getBinaries(cont);
return (bins != null) && bins.length > 0;
} catch (CModelException e) {
return false;
}
} else if (element instanceof IArchiveContainer) {
try {
IArchiveContainer cont = (IArchiveContainer) element;
IArchive[] ars = getArchives(cont);
return (ars != null) && ars.length > 0;
} catch (CModelException e) {
return false;
}
} else if (element instanceof IncludeReferenceProxy) {
IIncludeReference reference = ((IncludeReferenceProxy) element).getReference();
IContainer container = ResourcesPlugin.getWorkspace().getRoot()
.getContainerForLocation(reference.getPath());
if (container != null) {
// do not allow to navigate to workspace containers inside "Includes" node
return false;
}
return reference.hasChildren();
}
return super.hasChildren(element);
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
*/
@Override
public void dispose() {
if (fManager != null) {
fManager.cancel();
}
super.dispose();
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
*/
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
if (fManager != null) {
fManager.cancel();
}
super.inputChanged(viewer, oldInput, newInput);
}
}