/******************************************************************************* * Copyright (c) 2004, 2010 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 - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.ui.dialogs.cpaths; import java.util.ArrayList; import java.util.Arrays; import java.util.List; 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.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.layout.PixelConverter; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.jface.window.Window; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; import org.eclipse.ui.model.WorkbenchLabelProvider; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModelUtil; import org.eclipse.cdt.core.model.ICContainer; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.IContainerEntry; import org.eclipse.cdt.core.model.IIncludeEntry; import org.eclipse.cdt.core.model.IMacroEntry; import org.eclipse.cdt.core.model.IPathEntry; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.ui.CDTSharedImages; import org.eclipse.cdt.ui.CElementContentProvider; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.internal.ui.ICHelpContextIds; import org.eclipse.cdt.internal.ui.dialogs.IStatusChangeListener; import org.eclipse.cdt.internal.ui.dialogs.TypedElementSelectionValidator; import org.eclipse.cdt.internal.ui.dialogs.TypedViewerFilter; import org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField; import org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener; import org.eclipse.cdt.internal.ui.wizards.dialogfields.ITreeListAdapter; import org.eclipse.cdt.internal.ui.wizards.dialogfields.LayoutUtil; import org.eclipse.cdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField; import org.eclipse.cdt.internal.ui.wizards.dialogfields.TreeListDialogField; /** * DialogPage for C/C++ Project Paths page for 3.X projects. * * @deprecated as of CDT 4.0. This page was used for property pages * for 3.X style projects. */ @Deprecated public class CPathIncludeSymbolEntryPerFilePage extends CPathIncludeSymbolEntryBasePage { private TreeListDialogField<CPElementGroup> fIncludeSymPathsList; private SelectionButtonDialogField fShowInheritedPaths; private ICElement fCurrCElement; private ICProject fCurrCProject; private CPElementFilter fFilter; private IStatusChangeListener fContext; private int fTreeExpansionLevel = 2; private final int IDX_ADD_FOLDER_FILE = 0; private final int IDX_ADD_SYMBOL = 2; private final int IDX_ADD_EXT_INCLUDE = 4; private final int IDX_ADD_WS_INCLUDE = 5; private final int IDX_ADD_CONTRIBUTED = 7; private final int IDX_EDIT = 9; private final int IDX_REMOVE = 10; private final int IDX_EXPORT = 12; private final int IDX_UP = 14; private final int IDX_DOWN = 15; private static final String[] buttonLabel = new String[]{ CPathEntryMessages.IncludeSymbolEntryPage_addFolderFile, null, CPathEntryMessages.IncludeSymbolEntryPage_addUserSymbol, null, CPathEntryMessages.IncludeSymbolEntryPage_addExternalInclude, CPathEntryMessages.IncludeSymbolEntryPage_addFromWorkspace, null, CPathEntryMessages.IncludeSymbolEntryPage_addContributed, null, CPathEntryMessages.IncludeSymbolEntryPage_edit, CPathEntryMessages.IncludeSymbolEntryPage_remove, null, CPathEntryMessages.IncludeSymbolEntryPage_export, null, CPathEntryMessages.IncludeSymbolEntryPage_up, CPathEntryMessages.IncludeSymbolEntryPage_down}; private CPElementGroup fTopGroup; /** * Per file specific CPElementFilter * * @author vhirsl */ private class CPElementPerFileFilter extends CPElementFilter { public CPElementPerFileFilter(int[] kind, boolean exportedOnly, boolean showInherited) { super(kind, exportedOnly, showInherited); } /* (non-Javadoc) * @see org.eclipse.cdt.internal.ui.dialogs.cpaths.CPElementFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) */ @Override public boolean select(Viewer viewer, Object parent, Object element) { IResource res = null; if (element instanceof CPElement) { CPElement cpElem = (CPElement) element; res = cpElem.getResource(); } else if (element instanceof CPElementGroup) { CPElementGroup cpElemGroup = (CPElementGroup) element; res = cpElemGroup.getResource(); } if (res != null && !res.equals(fCurrCElement.getResource())) { IPath currResPath = fCurrCElement.getResource().getFullPath(); IPath resPath = res.getFullPath(); boolean found = false; for (int i = currResPath.segmentCount() - 1; i >= 0; --i) { if (resPath.equals(currResPath.uptoSegment(i))) { found = true; break; } } if (found == false) return false; } return super.select(viewer, parent, element); } } private class IncludeSymbolAdapter implements IDialogFieldListener, ITreeListAdapter<CPElementGroup> { private final Object[] EMPTY_ARR = new Object[0]; // -------- IListAdapter -------- public void customButtonPressed(TreeListDialogField<CPElementGroup> field, int index) { listCustomButtonPressed(field, index); } public void selectionChanged(TreeListDialogField<CPElementGroup> field) { listPageSelectionChanged(field); } public void doubleClicked(TreeListDialogField<CPElementGroup> field) { listPageDoubleClicked(field); } public void keyPressed(TreeListDialogField<CPElementGroup> field, KeyEvent event) { listPageKeyPressed(field, event); } public Object[] getChildren(TreeListDialogField<CPElementGroup> field, Object element) { if (element instanceof CPElement) { return ((CPElement)element).getChildren(); } else if (element instanceof CPElementGroup) { return ((CPElementGroup)element).getChildren(); } return EMPTY_ARR; } public Object getParent(TreeListDialogField<CPElementGroup> field, Object element) { if (element instanceof CPElementGroup) { return ((CPElementGroup)element).getParent(); } else if (element instanceof CPElement) { return ((CPElement)element).getParent(); } return null; } public boolean hasChildren(TreeListDialogField<CPElementGroup> field, Object element) { if (element instanceof CPElementGroup) { return true; } if (element instanceof CPElement) { return ((CPElement)element).getChildren().length > 0; } return false; } // ---------- IDialogFieldListener -------- public void dialogFieldChanged(DialogField field) { listPageDialogFieldChanged(field); } } public CPathIncludeSymbolEntryPerFilePage(IStatusChangeListener context) { super(CPathEntryMessages.IncludeSymbolEntryPage_title); fContext = context; IncludeSymbolAdapter adapter = new IncludeSymbolAdapter(); fIncludeSymPathsList = new TreeListDialogField<CPElementGroup>(adapter, buttonLabel, new CPElementLabelProvider(true, false)) { @Override protected int getTreeStyle() { return super.getTreeStyle() & ~SWT.MULTI; } }; fIncludeSymPathsList.setLabelText(CPathEntryMessages.IncludeSymbolEntryPage_label); fIncludeSymPathsList.enableButton(IDX_ADD_FOLDER_FILE, false); fIncludeSymPathsList.enableButton(IDX_REMOVE, false); fIncludeSymPathsList.enableButton(IDX_EDIT, false); fIncludeSymPathsList.enableButton(IDX_ADD_CONTRIBUTED, true); fIncludeSymPathsList.enableButton(IDX_ADD_EXT_INCLUDE, true); fIncludeSymPathsList.enableButton(IDX_ADD_WS_INCLUDE, true); fIncludeSymPathsList.enableButton(IDX_ADD_SYMBOL, true); fIncludeSymPathsList.enableButton(IDX_EXPORT, false); fIncludeSymPathsList.enableButton(IDX_UP, false); fIncludeSymPathsList.enableButton(IDX_DOWN, false); fIncludeSymPathsList.setTreeExpansionLevel(fTreeExpansionLevel); fShowInheritedPaths = new SelectionButtonDialogField(SWT.CHECK); fShowInheritedPaths.setSelection(true); fShowInheritedPaths.setLabelText(CPathEntryMessages.IncludeSymbolsEntryPage_show_inherited_check); fShowInheritedPaths.setDialogFieldListener(adapter); fFilter = new CPElementPerFileFilter(new int[]{-1, IPathEntry.CDT_INCLUDE, IPathEntry.CDT_INCLUDE_FILE, IPathEntry.CDT_MACRO, IPathEntry.CDT_MACRO_FILE, IPathEntry.CDT_CONTAINER}, false, true); } @Override public void createControl(Composite parent) { PixelConverter converter = new PixelConverter(parent); Composite composite = new Composite(parent, SWT.NONE); composite.setLayoutData(new GridData(GridData.FILL_BOTH)); LayoutUtil.doDefaultLayout(composite, new DialogField[]{fIncludeSymPathsList, fShowInheritedPaths}, true); LayoutUtil.setHorizontalGrabbing(fIncludeSymPathsList.getTreeControl(null), true); int buttonBarWidth = converter.convertWidthInCharsToPixels(24); fIncludeSymPathsList.setButtonsMinWidth(buttonBarWidth); setControl(composite); fIncludeSymPathsList.getTreeViewer().addFilter(fFilter); CUIPlugin.getDefault().getWorkbench().getHelpSystem().setHelp(composite, ICHelpContextIds.PROJECT_INCLUDE_PATHS_SYMBOLS); } @Override public Image getImage() { return CDTSharedImages.getImage(CDTSharedImages.IMG_OBJS_INCLUDES_CONTAINER); } @Override public void init(ICElement cElement, List<CPElement> cPaths) { fCurrCElement = cElement; fCurrCProject = cElement.getCProject(); List<CPElementGroup> elements = createGroups(cElement, cPaths); fIncludeSymPathsList.setElements(elements); updateStatus(); } private void updateStatus() { CPElement entryError = null; int nErrorEntries = 0; IStatus status = Status.OK_STATUS; List<CPElement> elements = getCPaths(); for (int i = elements.size() - 1; i >= 0; i--) { CPElement currElement = elements.get(i); if (currElement.getStatus().getSeverity() != IStatus.OK) { nErrorEntries++; if (entryError == null) { entryError = currElement; } } } if (nErrorEntries > 0) { if (nErrorEntries == 1 && entryError != null) { status = entryError.getStatus(); } else { status = new Status(IStatus.WARNING, CUIPlugin.PLUGIN_ID, -1, NLS.bind( CPathEntryMessages.CPElement_status_multiplePathErrors, String.valueOf(nErrorEntries)), null); } } fContext.statusChanged(status); } private void updateStatus(List<?> selected) { if (selected.size() != 1) { updateStatus(); return; } CPElement element = null; if (selected.get(0) instanceof CPElement) { element = (CPElement)selected.get(0); } else if (selected.get(0) instanceof CPElementAttribute) { element = ((CPElementAttribute)selected.get(0)).getParent(); } if (element != null && element.getStatus().getSeverity() != IStatus.OK) { fContext.statusChanged(element.getStatus()); } else { updateStatus(); return; } } private List<CPElementGroup> createGroups(ICElement element, List<CPElement> cPaths) { // create resource groups List<CPElementGroup> resourceGroups = new ArrayList<CPElementGroup>(5); fTopGroup = new CPElementGroup(element.getResource()); resourceGroups.add(fTopGroup); // add containers first so that they appear at top of list for (int i = 0; i < cPaths.size(); i++) { CPElement cpelement = cPaths.get(i); switch (cpelement.getEntryKind()) { case IPathEntry.CDT_CONTAINER : fTopGroup.addChild(cpelement); break; } } for (int i = 0; i < cPaths.size(); i++) { CPElement cpelement = cPaths.get(i); switch (cpelement.getEntryKind()) { case IPathEntry.CDT_INCLUDE : case IPathEntry.CDT_INCLUDE_FILE : case IPathEntry.CDT_MACRO : case IPathEntry.CDT_MACRO_FILE : CPElementGroup resGroup = new CPElementGroup(cpelement.getResource()); int ndx = resourceGroups.indexOf(resGroup); if (ndx == -1) { resourceGroups.add(resGroup); } else { resGroup = resourceGroups.get(ndx); } resGroup.addChild(cpelement); } } // place each path in its appropriate inherited group (or not if // excluded) for (int i = 0; i < cPaths.size(); i++) { CPElement cpelement = cPaths.get(i); switch (cpelement.getEntryKind()) { case IPathEntry.CDT_INCLUDE : case IPathEntry.CDT_INCLUDE_FILE : case IPathEntry.CDT_MACRO : case IPathEntry.CDT_MACRO_FILE : addPathToResourceGroups(cpelement, null, resourceGroups); } } return resourceGroups; } private void addPathToResourceGroup(CPElement element, CPElementGroup parent, CPElementGroup group) { IPath resPath = element.getPath(); IPath[] exclusions = (IPath[])element.getAttribute(CPElement.EXCLUSION); if ( (group != parent || !group.getResource().equals(element.getResource())) && resPath.isPrefixOf(group.getPath()) && (resPath.equals(group.getPath()) || !CoreModelUtil.isExcludedPath( group.getResource().getFullPath().removeFirstSegments(resPath.segmentCount()), exclusions))) { if (parent != null) { // try to insert at proper place in group... int insertHere = -1; int ndx = parent.indexof(element); if (ndx != -1) { CPElement[] children = parent.getChildren(element.getEntryKind()); for (int i = ndx; i < children.length; i++) { insertHere = group.indexof(new CPElement(children[i], group.getPath(), group.getResource())); if (insertHere != -1) { group.addChild(new CPElement(element, group.getPath(), group.getResource()), insertHere); break; } } } if (insertHere == -1) { group.addChild(new CPElement(element, group.getPath(), group.getResource())); } } else { group.addChild(new CPElement(element, group.getPath(), group.getResource())); } } } private void addPathToResourceGroups(CPElement element, CPElementGroup parent, List<CPElementGroup> groups) { if (parent != null) { parent.addChild(element); } for (int i = 0; i < groups.size(); i++) { CPElementGroup group = groups.get(i); addPathToResourceGroup(element, parent, group); } } private void updatePathOnResourceGroups(CPElement element, List<CPElementGroup> groups) { CPElementGroup parent = element.getParent(); IPath resPath = element.getPath(); IPath[] exclusions = (IPath[])element.getAttribute(CPElement.EXCLUSION); for (int i = 0; i < groups.size(); i++) { CPElementGroup group = groups.get(i); if (group != parent) { boolean found = false; CPElement[] elements = group.getChildren(element.getEntryKind()); for (CPElement element2 : elements) { if (element2.getInherited() == element) { found = true; if (!CoreModelUtil.isExcludedPath(group.getResource().getFullPath().removeFirstSegments( resPath.segmentCount()), exclusions)) { group.replaceChild(element2, new CPElement(element, group.getPath(), group.getResource())); } else { group.removeChild(element2); } break; } } if (!found) { addPathToResourceGroup(element, parent, group); } } } } private CPElement removePathFromResourceGroups(CPElement element, List<CPElementGroup> groups) { CPElement Inherited = element.getInherited(); CPElementGroup resGroup = element.getParent(); resGroup.removeChild(element); if (Inherited != null) { // applied exclusion to orig. IPath exclude = element.getPath().removeFirstSegments(Inherited.getPath().segmentCount()); IPath[] exclusions = (IPath[])Inherited.getAttribute(CPElement.EXCLUSION); IPath[] newExlusions = new IPath[exclusions.length + 1]; System.arraycopy(exclusions, 0, newExlusions, 0, exclusions.length); newExlusions[exclusions.length] = exclude; Inherited.setAttribute(CPElement.EXCLUSION, newExlusions); return null; } // remove all inherited for (int i = 0; i < groups.size(); i++) { CPElementGroup group = groups.get(i); CPElement elements[] = group.getChildren(element.getEntryKind()); for (CPElement element2 : elements) { if (element2.getInherited() == element) { group.removeChild(element2); break; } } } return element; } private boolean canAddPath(List<?> selected) { CPElementGroup group = getSelectedGroup(); if (group != null) { return group.getEntryKind() == -1; // resource group } return false; } private boolean canRemove(List<?> selected) { if (selected.size() != 1) { return false; } Object elem = selected.get(0); if (elem instanceof CPElement) { CPElement element = (CPElement)elem; if (element.getParentContainer() == null) { return element.getEntryKind() == IPathEntry.CDT_INCLUDE || element.getEntryKind() == IPathEntry.CDT_MACRO; } } else if (elem instanceof CPElementAttribute) { CPElementAttribute attrib = (CPElementAttribute)elem; if (attrib.getKey().equals(CPElement.EXCLUSION)) { if ( ((IPath[])attrib.getValue()).length > 0) { return true; } } } return false; } private void removeEntry() { List<?> selected = getSelection(); Object elem = selected.get(0); if (elem instanceof CPElement) { CPElement element = (CPElement)elem; CPElementGroup parent = element.getParent(); if (removePathFromResourceGroups(element, fIncludeSymPathsList.getElements()) == null) { updatePathOnResourceGroups( element.getInherited(), fIncludeSymPathsList.getElements()); } fIncludeSymPathsList.refresh(); fIncludeSymPathsList.selectElements(new StructuredSelection(parent)); } else if (elem instanceof CPElementAttribute) { CPElementAttribute attrib = (CPElementAttribute)elem; String key = attrib.getKey(); Object value = key.equals(CPElement.EXCLUSION) ? new Path[0] : null; attrib.getParent().setAttribute(key, value); updatePathOnResourceGroups(attrib.getParent(), fIncludeSymPathsList.getElements()); fIncludeSymPathsList.refresh(); } updateStatus(); } private boolean canEdit(List<?> selected) { if (selected.size() != 1) { return false; } Object elem = selected.get(0); if (elem instanceof CPElement) { CPElement element = (CPElement)selected.get(0); if (element.getParentContainer() == null && element.getInherited() == null) { IPath path = (IPath)element.getAttribute(CPElement.BASE_REF); if (path != null && !path.equals(Path.EMPTY)) { return false; } return element.getEntryKind() == IPathEntry.CDT_INCLUDE || element.getEntryKind() == IPathEntry.CDT_MACRO || element.getEntryKind() == IPathEntry.CDT_CONTAINER; } } if (elem instanceof CPElementAttribute) { return true; } return false; } private void editEntry() { List<?> selElements = fIncludeSymPathsList.getSelectedElements(); if (selElements.size() != 1) { return; } Object element = selElements.get(0); if (element instanceof CPElement) { editElementEntry((CPElement)element); } else if (element instanceof CPElementAttribute) { editAttributeEntry((CPElementAttribute)element); } } private void editElementEntry(CPElement element) { IPath path = (IPath)element.getAttribute(CPElement.BASE_REF); if (path != null && !path.equals(Path.EMPTY)) { return; } else if (element.getEntryKind() == IPathEntry.CDT_MACRO) { addSymbol(element); } else if (element.getEntryKind() == IPathEntry.CDT_INCLUDE) { path = (IPath)element.getAttribute(CPElement.BASE); if (path != null && !path.equals(Path.EMPTY)) { CPElement[] includes = openWorkspacePathEntryDialog(null); if (includes != null && includes.length > 0) { includes[0].setExported(element.isExported()); } } else { addInclude(element); } } else if (element.getEntryKind() == IPathEntry.CDT_CONTAINER) { CPElement[] res = null; res = openContainerSelectionDialog(element); if (res != null && res.length > 0) { CPElement curr = res[0]; curr.setExported(element.isExported()); fTopGroup.replaceChild(element, curr); fIncludeSymPathsList.refresh(); } } } private void editAttributeEntry(CPElementAttribute elem) { String key = elem.getKey(); if (key.equals(CPElement.EXCLUSION)) { CPElement selElement = elem.getParent(); ExclusionPatternDialog dialog = new ExclusionPatternDialog(getShell(), selElement); if (dialog.open() == Window.OK) { selElement.setAttribute(CPElement.EXCLUSION, dialog.getExclusionPattern()); updatePathOnResourceGroups(selElement, fIncludeSymPathsList.getElements()); fIncludeSymPathsList.refresh(); updateStatus(); } } } private void exportEntry() { CPElement element = (CPElement)getSelection().get(0); element.setExported(!element.isExported()); // toggle fIncludeSymPathsList.refresh(element); } private boolean canExport(List<?> selected) { if (selected.size() != 1) { return false; } Object elem = selected.get(0); if (elem instanceof CPElement) { CPElement element = (CPElement)selected.get(0); if (element.getParentContainer() == null && element.getInherited() == null) { IPath base_ref = (IPath)element.getAttribute(CPElement.BASE_REF); if (base_ref != null && !base_ref.equals(Path.EMPTY)) return false; return element.getEntryKind() == IPathEntry.CDT_INCLUDE || element.getEntryKind() == IPathEntry.CDT_MACRO; } } return false; } private boolean canMove(List<?> selected) { if (selected.size() == 0) { return false; } for (int i = 0; i < selected.size(); i++) { Object element = selected.get(i); if (! (element instanceof CPElement)) return false; CPElement elem = (CPElement)element; if (elem.getEntryKind() != IPathEntry.CDT_INCLUDE && elem.getEntryKind() != IPathEntry.CDT_MACRO) { return false; } if (elem.getParentContainer() != null || elem.getInherited() != null) { return false; } } return true; } private boolean canMoveUp(List<?> selected) { if (!canMove(selected)) { return false; } CPElement first = (CPElement)selected.get(0); CPElementGroup parent = first.getParent(); CPElement children[] = parent.getChildren(first.getEntryKind()); int indx = Arrays.asList(children).indexOf(first); if (indx <= 0) { return false; } return true; } private boolean canMoveDown(List<?> selected) { if (!canMove(selected)) { return false; } CPElement last = (CPElement)selected.get(selected.size() - 1); CPElementGroup parent = last.getParent(); CPElement children[] = parent.getChildren(last.getEntryKind()); int indx = Arrays.asList(children).indexOf(last); if (indx >= children.length - 1 || children[indx + 1].getInherited() != null) { return false; } return true; } private boolean moveUp(CPElement element) { boolean rc = false; int kind = element.getEntryKind(); for (CPElementGroup group : fIncludeSymPathsList.getElements()) { CPElement[] children = group.getChildren(kind); for (int k = 0; k < children.length; ++k) { CPElement child = children[k]; if (element.equals(child) || (child.getInherited() != null && child.getInherited().equals(element))) { if (child.getInherited() != null && k > 0 && children[k - 1].getInherited() == null) { break; } int prevIndex = k - 1; if (prevIndex >= 0) { // swap the two children[k] = children[prevIndex]; children[prevIndex] = child; rc = true; break; } } } group.setChildren(children); } fIncludeSymPathsList.refresh(); fIncludeSymPathsList.selectElements(new StructuredSelection(element)); fIncludeSymPathsList.setFocus(); return rc; } /** * */ private boolean moveDown(CPElement element) { boolean rc = false; int kind = element.getEntryKind(); for (CPElementGroup group : fIncludeSymPathsList.getElements()) { CPElement[] children = group.getChildren(kind); for (int k = children.length - 1; k >= 0; --k) { CPElement child = children[k]; if (element.equals(child) || (child.getInherited() != null && child.getInherited().equals(element))) { int prevIndex = k + 1; if (prevIndex < children.length) { // swap the two children[k] = children[prevIndex]; children[prevIndex] = child; rc = true; break; } } } group.setChildren(children); } fIncludeSymPathsList.refresh(); fIncludeSymPathsList.selectElements(new StructuredSelection(element)); fIncludeSymPathsList.setFocus(); return rc; } private CPElementGroup getSelectedGroup() { List<?> selected = fIncludeSymPathsList.getSelectedElements(); if (!selected.isEmpty()) { Object item = selected.get(0); if (item instanceof CPElement) { item = ((CPElement)item).getParent(); } if (item instanceof CPElementGroup) { return (CPElementGroup)item; } } return fTopGroup; } protected void listPageDialogFieldChanged(DialogField field) { boolean showInherited = fShowInheritedPaths.isSelected(); if (field == fShowInheritedPaths) { if (fFilter != null) { fIncludeSymPathsList.getTreeViewer().removeFilter(fFilter); } fFilter = new CPElementPerFileFilter(new int[]{-1, IPathEntry.CDT_INCLUDE, IPathEntry.CDT_INCLUDE_FILE, IPathEntry.CDT_MACRO, IPathEntry.CDT_MACRO_FILE, IPathEntry.CDT_CONTAINER}, false, showInherited); fIncludeSymPathsList.getTreeViewer().addFilter(fFilter); fIncludeSymPathsList.setTreeExpansionLevel(fTreeExpansionLevel); fIncludeSymPathsList.refresh(); } updateStatus(); } protected void listPageSelectionChanged(TreeListDialogField<CPElementGroup> field) { List<?> selected = field.getSelectedElements(); field.enableButton(IDX_REMOVE, canRemove(selected)); field.enableButton(IDX_EDIT, canEdit(selected)); field.enableButton(IDX_ADD_CONTRIBUTED, canAddPath(selected)); field.enableButton(IDX_ADD_EXT_INCLUDE, canAddPath(selected)); field.enableButton(IDX_ADD_WS_INCLUDE, canAddPath(selected)); field.enableButton(IDX_ADD_SYMBOL, canAddPath(selected)); field.enableButton(IDX_EXPORT, canExport(selected)); field.enableButton(IDX_DOWN, canMoveDown(selected)); field.enableButton(IDX_UP, canMoveUp(selected)); updateStatus(selected); } protected void listCustomButtonPressed(TreeListDialogField<CPElementGroup> field, int index) { switch (index) { case IDX_ADD_FOLDER_FILE : addNewPathResource(); break; case IDX_ADD_SYMBOL : addSymbol(null); break; case IDX_ADD_EXT_INCLUDE : addInclude(null); break; case IDX_ADD_WS_INCLUDE : addFromWorkspace(); break; case IDX_ADD_CONTRIBUTED : addContributed(); break; case IDX_EDIT : if (canEdit(field.getSelectedElements())) { editEntry(); } break; case IDX_REMOVE : if (canRemove(field.getSelectedElements())) { removeEntry(); } break; case IDX_DOWN : if (canMoveDown(field.getSelectedElements())) { moveDown((CPElement)field.getSelectedElements().get(0)); } break; case IDX_UP : if (canMoveUp(field.getSelectedElements())) { moveUp((CPElement)field.getSelectedElements().get(0)); } break; case IDX_EXPORT : if (canExport(field.getSelectedElements())) { exportEntry(); } } } protected void listPageDoubleClicked(TreeListDialogField<CPElementGroup> field) { if (canEdit(fIncludeSymPathsList.getSelectedElements())) { editEntry(); } } protected void listPageKeyPressed(TreeListDialogField<CPElementGroup> field, KeyEvent event) { if (field == fIncludeSymPathsList) { if (event.character == SWT.DEL && event.stateMask == 0) { List<?> selection = field.getSelectedElements(); if (canEdit(selection)) { removeEntry(); } } } } protected IPathEntry[] getRawPathEntries() { List<CPElement> paths = getCPaths(); IPathEntry[] currEntries = new IPathEntry[paths.size()]; for (int i = 0; i < currEntries.length; i++) { CPElement curr = paths.get(i); currEntries[i] = curr.getPathEntry(); } return currEntries; } protected void addNewPathResource() { Class<?>[] acceptedClasses = new Class[]{ICProject.class, ICContainer.class, ITranslationUnit.class}; TypedElementSelectionValidator validator = new TypedElementSelectionValidator(acceptedClasses, false); ViewerFilter filter = new TypedViewerFilter(acceptedClasses); String title = CPathEntryMessages.IncludeSymbolEntryPage_newResource_title; String message = CPathEntryMessages.IncludeSymbolEntryPage_newResource_description; ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), new WorkbenchLabelProvider(), new CElementContentProvider()); dialog.setValidator(validator); dialog.setTitle(title); dialog.setMessage(message); dialog.addFilter(filter); dialog.setInput(fCurrCProject); dialog.setInitialSelection(fCurrCProject); if (dialog.open() == Window.OK) { Object[] elements = dialog.getResult(); IResource resource; if (elements[0] instanceof IResource) { resource = (IResource)elements[0]; } else { resource = ((ICElement)elements[0]).getResource(); } CPElementGroup newGroup = new CPElementGroup(resource); if (!fIncludeSymPathsList.getElements().contains(newGroup)) { List<CPElementGroup> groups = fIncludeSymPathsList.getElements(); for (int i = 0; i < groups.size(); i++) { CPElementGroup group = groups.get(i); if (group.getPath().isPrefixOf(newGroup.getPath())) { CPElement[] cpelements = group.getChildren(); for (CPElement cpelement : cpelements) { if (cpelement.getInherited() == null) { switch (cpelement.getEntryKind()) { case IPathEntry.CDT_INCLUDE : case IPathEntry.CDT_INCLUDE_FILE : case IPathEntry.CDT_MACRO : case IPathEntry.CDT_MACRO_FILE : addPathToResourceGroup(cpelement, null, newGroup); } } } } } fIncludeSymPathsList.addElement(newGroup); } fIncludeSymPathsList.selectElements(new StructuredSelection(newGroup)); fIncludeSymPathsList.expandElement(newGroup, 1); } } protected void addSymbol(CPElement existing) { // Popup an entry dialog InputDialog dialog; if (existing == null) { dialog = new InputDialog(getShell(), CPathEntryMessages.IncludeSymbolEntryPage_addSymbol_title, CPathEntryMessages.IncludeSymbolEntryPage_addSymbol_message, "", //$NON-NLS-1$ null); } else { StringBuffer initialValue = new StringBuffer(); initialValue.append((String)existing.getAttribute(CPElement.MACRO_NAME)); initialValue.append('='); initialValue.append((String)existing.getAttribute(CPElement.MACRO_VALUE)); dialog = new InputDialog(getShell(), CPathEntryMessages.IncludeSymbolEntryPage_editSymbol_title, CPathEntryMessages.IncludeSymbolEntryPage_editSymbol_message, initialValue.toString(), null); } String symbol = null; if (dialog.open() == Window.OK) { symbol = dialog.getValue(); if (symbol != null && symbol.length() > 0) { CPElementGroup group = getSelectedGroup(); CPElement newPath = new CPElement(fCurrCProject, IPathEntry.CDT_MACRO, group.getResource().getFullPath(), group.getResource()); String name, value = ""; //$NON-NLS-1$ int index = symbol.indexOf("="); //$NON-NLS-1$ if (index != -1) { name = symbol.substring(0, index).trim(); value = symbol.substring(index + 1).trim(); } else { name = symbol.trim(); } if (existing != null) { existing.setAttribute(CPElement.MACRO_NAME, name); existing.setAttribute(CPElement.MACRO_VALUE, value); updatePathOnResourceGroups(existing, fIncludeSymPathsList.getElements()); fIncludeSymPathsList.refresh(); } else { newPath.setAttribute(CPElement.MACRO_NAME, name); newPath.setAttribute(CPElement.MACRO_VALUE, value); if (!group.contains(newPath)) { addPathToResourceGroups(newPath, group, fIncludeSymPathsList.getElements()); fIncludeSymPathsList.refresh(); fIncludeSymPathsList.selectElements(new StructuredSelection(newPath)); } updateStatus(); } } } } protected void addInclude(CPElement existing) { InputDialog dialog; if (existing == null) { dialog = new SelectPathInputDialog(getShell(), CPathEntryMessages.IncludeSymbolEntryPage_addExternal_title, CPathEntryMessages.IncludeSymbolEntryPage_addExternal_message, null, null); } else { dialog = new SelectPathInputDialog( getShell(), CPathEntryMessages.IncludeSymbolEntryPage_editExternal_title, CPathEntryMessages.IncludeSymbolEntryPage_editExternal_message, ((IPath)existing.getAttribute(CPElement.INCLUDE)).toOSString(), null); } String newItem = null; if (dialog.open() == Window.OK) { newItem = dialog.getValue(); if (newItem != null && !newItem.equals("")) { //$NON-NLS-1$ if (existing == null) { CPElementGroup group = getSelectedGroup(); CPElement newPath = new CPElement(fCurrCProject, IPathEntry.CDT_INCLUDE, group.getResource().getFullPath(), group.getResource()); newPath.setAttribute(CPElement.INCLUDE, new Path(newItem)); if (!group.contains(newPath)) { addPathToResourceGroups(newPath, group, fIncludeSymPathsList.getElements()); fIncludeSymPathsList.refresh(); fIncludeSymPathsList.selectElements(new StructuredSelection(newPath)); } } else { existing.setAttribute(CPElement.INCLUDE, new Path(newItem)); updatePathOnResourceGroups(existing, fIncludeSymPathsList.getElements()); fIncludeSymPathsList.refresh(); } updateStatus(); } } } protected void addFromWorkspace() { CPElement[] includes = openWorkspacePathEntryDialog(null); if (includes != null && includes.length > 0) { int nElementsChosen = includes.length; CPElementGroup group = getSelectedGroup(); for (int i = 0; i < nElementsChosen; i++) { CPElement curr = includes[i]; if (!group.contains(curr)) { addPathToResourceGroups(curr, group, fIncludeSymPathsList.getElements()); fIncludeSymPathsList.refresh(); fIncludeSymPathsList.selectElements(new StructuredSelection(curr)); updateStatus(); } } } } protected void addContributed() { CPElement[] includes = openContainerSelectionDialog(null); if (includes != null && includes.length > 0) { int nElementsChosen = includes.length; // remove duplicates CPElementGroup group = getSelectedGroup(); for (int i = 0; i < nElementsChosen; i++) { CPElement curr = includes[i]; if (!group.contains(curr)) { addPathToResourceGroups(curr, getSelectedGroup(), fIncludeSymPathsList.getElements()); fIncludeSymPathsList.refresh(); fIncludeSymPathsList.selectElements(new StructuredSelection(curr)); updateStatus(); } } } } protected CPElement[] openWorkspacePathEntryDialog(CPElement existing) { Class<?>[] acceptedClasses = new Class[]{ICProject.class, IProject.class, IContainer.class, ICContainer.class}; TypedElementSelectionValidator validator = new TypedElementSelectionValidator(acceptedClasses, existing == null); ViewerFilter filter = new TypedViewerFilter(acceptedClasses); String title = (existing == null) ? CPathEntryMessages.IncludeSymbolEntryPage_fromWorkspaceDialog_new_title : CPathEntryMessages.IncludeSymbolEntryPage_fromWorkspaceDialog_edit_title; String message = (existing == null) ? CPathEntryMessages.IncludeSymbolEntryPage_fromWorkspaceDialog_new_description : CPathEntryMessages.IncludeSymbolEntryPage_fromWorkspaceDialog_edit_description; ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), new WorkbenchLabelProvider(), new CElementContentProvider()); dialog.setValidator(validator); dialog.setTitle(title); dialog.setMessage(message); dialog.addFilter(filter); dialog.setInput(CoreModel.getDefault().getCModel()); if (existing == null) { dialog.setInitialSelection(fCurrCProject); } else { dialog.setInitialSelection(existing.getCProject()); } if (dialog.open() == Window.OK) { Object[] elements = dialog.getResult(); CPElement[] res = new CPElement[elements.length]; for (int i = 0; i < res.length; i++) { IProject project; IPath includePath; if (elements[i] instanceof IResource) { project = ((IResource)elements[i]).getProject(); includePath = ((IResource)elements[i]).getProjectRelativePath(); } else { project = ((ICElement)elements[i]).getCProject().getProject(); includePath = ((ICElement)elements[i]).getResource().getProjectRelativePath(); } CPElementGroup group = getSelectedGroup(); res[i] = new CPElement(fCurrCProject, IPathEntry.CDT_INCLUDE, group.getResource().getFullPath(), group.getResource()); res[i].setAttribute(CPElement.BASE, project.getFullPath().makeRelative()); res[i].setAttribute(CPElement.INCLUDE, includePath); } return res; } return null; } protected CPElement[] openContainerSelectionDialog(CPElement existing) { IContainerEntry elem = null; String title; if (existing == null) { title = CPathEntryMessages.IncludeSymbolEntryPage_ContainerDialog_new_title; } else { title = CPathEntryMessages.IncludeSymbolEntryPage_ContainerDialog_edit_title; elem = (IContainerEntry)existing.getPathEntry(); } CPathContainerWizard wizard = new CPathContainerWizard(elem, null, fCurrCProject, getRawPathEntries(), new int[]{ IPathEntry.CDT_INCLUDE, IPathEntry.CDT_MACRO}); wizard.setWindowTitle(title); if (CPathContainerWizard.openWizard(getShell(), wizard) == Window.OK) { IPathEntry parent = wizard.getEntriesParent(); IPathEntry[] elements = wizard.getEntries(); if (elements != null) { CPElement[] res = new CPElement[elements.length]; CPElementGroup group = getSelectedGroup(); for (int i = 0; i < res.length; i++) { if (elements[i].getEntryKind() == IPathEntry.CDT_INCLUDE) { res[i] = new CPElement(fCurrCProject, IPathEntry.CDT_INCLUDE, group.getResource().getFullPath(), group.getResource()); res[i].setAttribute(CPElement.INCLUDE, ((IIncludeEntry)elements[i]).getIncludePath()); res[i].setAttribute(CPElement.BASE_REF, parent.getPath()); } else if (elements[i].getEntryKind() == IPathEntry.CDT_MACRO) { res[i] = new CPElement(fCurrCProject, IPathEntry.CDT_MACRO, group.getResource().getFullPath(), group.getResource()); res[i].setAttribute(CPElement.MACRO_NAME, ((IMacroEntry)elements[i]).getMacroName()); res[i].setAttribute(CPElement.BASE_REF, parent.getPath()); } } return res; } return new CPElement[]{CPElement.createFromExisting(parent, fCurrCProject)}; } return null; } private class SelectPathInputDialog extends InputDialog { public SelectPathInputDialog(Shell parentShell, String dialogTitle, String dialogMessage, String initialValue, IInputValidator validator) { super(parentShell, dialogTitle, dialogMessage, initialValue, validator); } @Override protected void createButtonsForButtonBar(Composite parent) { super.createButtonsForButtonBar(parent); Button browse = createButton(parent, 3, CPathEntryMessages.IncludeSymbolEntryPage_addExternal_button_browse, false); browse.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent ev) { DirectoryDialog dialog = new DirectoryDialog(getShell(), SWT.OPEN); dialog.setText(CPathEntryMessages.IncludeSymbolEntryPage_browseForFolder); String currentName = getText().getText(); if (currentName != null && currentName.trim().length() != 0) { dialog.setFilterPath(currentName); } String dirname = dialog.open(); if (dirname != null) { getText().setText(dirname); } } }); } } /* * (non-Javadoc) * * @see org.eclipse.cdt.internal.ui.dialogs.cpaths.CPathBasePage#getSelection() */ @Override public List<?> getSelection() { return fIncludeSymPathsList.getSelectedElements(); } /* * (non-Javadoc) * * @see org.eclipse.cdt.internal.ui.dialogs.cpaths.CPathBasePage#setSelection(java.util.List) */ @Override public void setSelection(List<?> selElements) { fIncludeSymPathsList.selectElements(new StructuredSelection(selElements)); } @Override public boolean isEntryKind(int kind) { return kind == IPathEntry.CDT_INCLUDE || kind == IPathEntry.CDT_MACRO; } @Override public void performApply(IProgressMonitor monitor) throws CoreException { } @Override public void performDefaults() { } @Override public List<CPElement> getCPaths() { List<CPElement> cPaths = new ArrayList<CPElement>(); List<CPElementGroup> groups = fIncludeSymPathsList.getElements(); for (int i = 0; i < groups.size(); i++) { CPElementGroup group = groups.get(i); CPElement[] elements = group.getChildren(); for (CPElement element : elements) { if (element.getInherited() == null) { cPaths.add(element); } } } return cPaths; } }