blob: a5f0fe68e4b074f858fe012db630291e6ec537ef [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2017 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
*
*******************************************************************************/
package org.eclipse.dltk.internal.ui.wizards.buildpath.newsourcepage;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptFolder;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.internal.corext.buildpath.AddSelectedSourceFolderOperation;
import org.eclipse.dltk.internal.corext.buildpath.BuildpathModifier;
import org.eclipse.dltk.internal.corext.buildpath.BuildpathModifier.IBuildpathModifierListener;
import org.eclipse.dltk.internal.corext.buildpath.BuildpathModifierOperation;
import org.eclipse.dltk.internal.corext.buildpath.CreateFolderOperation;
import org.eclipse.dltk.internal.corext.buildpath.EditFiltersOperation;
import org.eclipse.dltk.internal.corext.buildpath.ExcludeOperation;
import org.eclipse.dltk.internal.corext.buildpath.IBuildpathInformationProvider;
import org.eclipse.dltk.internal.corext.buildpath.IPackageExplorerActionListener;
import org.eclipse.dltk.internal.corext.buildpath.LinkedSourceFolderOperation;
import org.eclipse.dltk.internal.corext.buildpath.PackageExplorerActionEvent;
import org.eclipse.dltk.internal.corext.buildpath.RemoveFromBuildpathOperation;
import org.eclipse.dltk.internal.corext.buildpath.ResetAllOperation;
import org.eclipse.dltk.internal.corext.buildpath.UnexcludeOperation;
import org.eclipse.dltk.internal.ui.actions.CompositeActionGroup;
import org.eclipse.dltk.internal.ui.scriptview.BuildPathContainer;
import org.eclipse.dltk.internal.ui.util.ViewerPane;
import org.eclipse.dltk.internal.ui.wizards.NewWizardMessages;
import org.eclipse.dltk.ui.DLTKPluginImages;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.actions.ActionContext;
/**
* Action group for the package explorer. Creates and manages a set of
* <code>BuildpathModifierOperation</code>s and creates a
* <code>ToolBarManager</code> on request. Based on this operations,
* <code>BuildpathModifierAction</code>s are generated. The available operations
* are:
*
* @see org.eclipse.dltk.internal.corext.buildpath.AddSelectedSourceFolderOperation
* @see org.eclipse.dltk.internal.corext.buildpath.RemoveFromBuildpathOperation
* @see org.eclipse.dltk.internal.corext.buildpath.IncludeOperation
* @see org.eclipse.dltk.internal.corext.buildpath.UnincludeOperation
* @see org.eclipse.dltk.internal.corext.buildpath.ExcludeOperation
* @see org.eclipse.dltk.internal.corext.buildpath.UnexcludeOperation
* @see org.eclipse.dltk.internal.corext.buildpath.EditFiltersOperation
* @see org.eclipse.dltk.internal.corext.buildpath.ResetOperation
*/
public class DialogPackageExplorerActionGroup extends CompositeActionGroup {
public static class DialogExplorerActionContext extends ActionContext {
private IScriptProject fScriptProject;
private List fSelectedElements;
/**
* Constructor to create an action context for the dialog package
* explorer.
*
* For reasons of completeness, the selection of the super class
* <code>ActionContext</code> is also set, but is not intendet to be
* used.
*
* @param selection
* the current selection
* @param jProject
* the element's script project
*/
public DialogExplorerActionContext(ISelection selection,
IScriptProject jProject) {
super(null);
fScriptProject = jProject;
fSelectedElements = ((IStructuredSelection) selection).toList();
IStructuredSelection structuredSelection = new StructuredSelection(
new Object[] { fSelectedElements, jProject });
super.setSelection(structuredSelection);
}
/**
* Constructor to create an action context for the dialog package
* explorer.
*
* For reasons of completeness, the selection of the super class
* <code>ActionContext</code> is also set, but is not intendet to be
* used.
*
* @param selectedElements
* a list of currently selected elements
* @param jProject
* the element's script project
*/
public DialogExplorerActionContext(List selectedElements,
IScriptProject jProject) {
super(null);
fScriptProject = jProject;
fSelectedElements = selectedElements;
IStructuredSelection structuredSelection = new StructuredSelection(
new Object[] { fSelectedElements, jProject });
super.setSelection(structuredSelection);
}
public IScriptProject getScriptProject() {
return fScriptProject;
}
public List getSelectedElements() {
return fSelectedElements;
}
}
/** script project */
public static final int SCRIPT_PROJECT = 0x01;
/** Package fragment root */
public static final int PACKAGE_FRAGMENT_ROOT = 0x02;
/** Package fragment */
public static final int PACKAGE_FRAGMENT = 0x03;
/** Compilation unit */
public static final int SOURCE_MODULE = 0x04;
/** File */
public static final int FILE = 0x05;
/** Normal folder */
public static final int FOLDER = 0x06;
/** Excluded folder */
public static final int EXCLUDED_FOLDER = 0x07;
/** Excluded file */
public static final int EXCLUDED_FILE = 0x08;
/** Included file */
public static final int INCLUDED_FILE = 0xA;
/** Included folder */
public static final int INCLUDED_FOLDER = 0xB;
/** An archive element */
public static final int ARCHIVE = 0xD;
/** A IProjectFragment with include/exclude filters set */
public static final int MODIFIED_FRAGMENT_ROOT = 0xE;
/** Default package fragment */
public static final int DEFAULT_FRAGMENT = 0xF;
/** Undefined type */
public static final int UNDEFINED = 0x10;
/** Multi selection */
public static final int MULTI = 0x11;
/** No elements selected */
public static final int NULL_SELECTION = 0x12;
/** Elements that are contained in an archive */
public static final int ARCHIVE_RESOURCE = 0x13;
public static final int EXTERNAL_RESOURCE = 0x15;
/** Elements that represent Buildpath container (= libraries) */
public static final int CONTAINER = 0x14;
private BuildpathModifierAction[] fActions;
private int fLastType;
private List fListeners;
private static final int fContextSensitiveActions = 5;
/**
* Constructor which creates the operations and based on this operations the
* actions.
*
* @param provider
* a information provider to pass necessary information to the
* operations
* @param listener
* a listener for the changes on Buildpath entries, that is the
* listener will be notified whenever a Buildpath entry changed.
* @see IBuildpathModifierListener
*/
public DialogPackageExplorerActionGroup(
IBuildpathInformationProvider provider,
IBuildpathModifierListener listener) {
super();
fLastType = UNDEFINED;
fListeners = new ArrayList();
fActions = new BuildpathModifierAction[8];
BuildpathModifierOperation op;
op = new AddSelectedSourceFolderOperation(listener, provider);
// TODO User disabled image when available
addAction(new BuildpathModifierAction(op,
DLTKPluginImages.DESC_ELCL_ADD_AS_SOURCE_FOLDER, null,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_AddSelSFToCP_label,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_AddSelSFToCP_tooltip,
IAction.AS_PUSH_BUTTON), 0);
op = new RemoveFromBuildpathOperation(listener, provider);
addAction(new BuildpathModifierAction(op,
DLTKPluginImages.DESC_ELCL_REMOVE_AS_SOURCE_FOLDER,
DLTKPluginImages.DESC_DLCL_REMOVE_AS_SOURCE_FOLDER,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_RemoveFromCP_label,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_RemoveFromCP_tooltip,
IAction.AS_PUSH_BUTTON), 1);
op = new ExcludeOperation(listener, provider);
addAction(new BuildpathModifierAction(op,
DLTKPluginImages.DESC_ELCL_EXCLUDE_FROM_BUILDPATH,
DLTKPluginImages.DESC_DLCL_EXCLUDE_FROM_BUILDPATH,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Exclude_label,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Exclude_tooltip,
IAction.AS_PUSH_BUTTON), 2);
op = new UnexcludeOperation(listener, provider);
addAction(new BuildpathModifierAction(op,
DLTKPluginImages.DESC_ELCL_INCLUDE_ON_BUILDPATH,
DLTKPluginImages.DESC_DLCL_INCLUDE_ON_BUILDPATH,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Unexclude_label,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Unexclude_tooltip,
IAction.AS_PUSH_BUTTON), 3);
op = new EditFiltersOperation(listener, provider);
BuildpathModifierAction action = new BuildpathModifierAction(op,
DLTKPluginImages.DESC_ELCL_CONFIGURE_BUILDPATH_FILTERS,
DLTKPluginImages.DESC_DLCL_CONFIGURE_BUILDPATH_FILTERS,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Edit_label,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Edit_tooltip,
IAction.AS_PUSH_BUTTON);
BuildpathModifierDropDownAction dropDown = new BuildpathModifierDropDownAction(
action,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Configure_label,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Configure_tooltip);
addAction(dropDown, 4);
/*
* addAction(new BuildpathModifierAction(op,
* DLTKPluginImages.DESC_OBJS_TEXT_EDIT,
* DLTKPluginImages.DESC_DLCL_TEXT_EDIT, NewWizardMessages.getString(
* "NewSourceContainerWorkbookPage.ToolBar.Edit.label"), //$NON-NLS-1$
* NewWizardMessages.getString(
* "NewSourceContainerWorkbookPage.ToolBar.Edit.tooltip"),
* IAction.AS_PUSH_BUTTON), //$NON-NLS-1$
* IBuildpathInformationProvider.EDIT);
*/
op = new LinkedSourceFolderOperation(listener, provider);
addAction(new BuildpathModifierAction(op,
DLTKPluginImages.DESC_ELCL_ADD_LINKED_SOURCE_TO_BUILDPATH,
DLTKPluginImages.DESC_DLCL_ADD_LINKED_SOURCE_TO_BUILDPATH,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Link_label,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_Link_tooltip,
IAction.AS_PUSH_BUTTON), 5);
op = new CreateFolderOperation(listener, provider);
addAction(new BuildpathModifierAction(op,
DLTKPluginImages.DESC_OBJS_PACKFRAG_ROOT, null,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_CreateSrcFolder_label,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_CreateSrcFolder_tooltip,
IAction.AS_PUSH_BUTTON), 6);
op = new ResetAllOperation(listener, provider);
addAction(new BuildpathModifierAction(op,
DLTKPluginImages.DESC_ELCL_CLEAR,
DLTKPluginImages.DESC_DLCL_CLEAR,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_ClearAll_label,
NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_ClearAll_tooltip,
IAction.AS_PUSH_BUTTON), 7);
}
private void addAction(BuildpathModifierAction action, int index) {
fActions[index] = action;
}
/**
* Get an action of the specified type
*
* @param type
* the type of the desired action, must be a constante of
* <code>IBuildpathInformationProvider</code>
* @return the requested action
*
* @see IBuildpathInformationProvider
*/
public BuildpathModifierAction getAction(int type) {
for (int i = 0; i < fActions.length; i++) {
if (fActions[i].getOperation().getTypeId() == type)
return fActions[i];
}
throw new ArrayIndexOutOfBoundsException();
}
public BuildpathModifierAction[] getActions() {
List<BuildpathModifierAction> result = new ArrayList<BuildpathModifierAction>();
for (int i = 0; i < fActions.length; i++) {
BuildpathModifierAction action = fActions[i];
if (action instanceof BuildpathModifierDropDownAction) {
BuildpathModifierDropDownAction dropDownAction = (BuildpathModifierDropDownAction) action;
BuildpathModifierAction[] actions = dropDownAction.getActions();
for (int j = 0; j < actions.length; j++) {
result.add(actions[j]);
}
} else {
result.add(action);
}
}
return result.toArray(new BuildpathModifierAction[result.size()]);
}
/**
* Create a toolbar manager for a given <code>ViewerPane</code>
*
* @param pane
* the pane to create the <code>
* ToolBarManager</code> for.
* @return the created <code>ToolBarManager</code>
*/
public ToolBarManager createLeftToolBarManager(ViewerPane pane) {
ToolBarManager tbm = pane.getToolBarManager();
for (int i = 0; i < fContextSensitiveActions; i++) {
tbm.add(fActions[i]);
if (i == 1 || i == 3)
tbm.add(new Separator());
}
tbm.update(true);
return tbm;
}
/**
* Create a toolbar manager for a given <code>ViewerPane</code>
*
* @param pane
* the pane to create the help toolbar for
* @return the created <code>ToolBarManager</code>
*/
public ToolBarManager createLeftToolBar(ViewerPane pane) {
ToolBar tb = new ToolBar(pane, SWT.FLAT);
pane.setTopRight(tb);
ToolBarManager tbm = new ToolBarManager(tb);
for (int i = fContextSensitiveActions; i < fActions.length; i++) {
tbm.add(fActions[i]);
}
if (DLTKCore.DEBUG) {
System.err.println("Add help support here..."); //$NON-NLS-1$
}
// tbm.add(new HelpAction());
tbm.update(true);
return tbm;
}
/**
* Forces the action group to recompute the available actions and fire an
* event to all listeners
*
* @throws ModelException
*
* @see #setContext(DialogExplorerActionContext)
* @see #informListeners(String[], BuildpathModifierAction[])
*/
public void refresh(DialogExplorerActionContext context)
throws ModelException {
super.setContext(context);
if (context == null) // can happen when disposing
return;
List selectedElements = context.getSelectedElements();
IScriptProject project = context.getScriptProject();
int type = MULTI;
if (selectedElements.size() == 0) {
type = NULL_SELECTION;
if (type == fLastType)
return;
} else if (selectedElements.size() == 1
|| identicalTypes(selectedElements, project)) {
type = getType(selectedElements.get(0), project);
}
internalSetContext(selectedElements, project, type);
}
/**
* Set the context for the action group. This also includes updating the
* actions (that is, enable or disable them). The decision which actions
* should be enabled or disabled is based on the content of the
* <code>DialogExplorerActionContext</code>
*
* If the type of the selection changes, then listeners will be notified
* about the new set of available actions.
*
* Note: notification is only done if the TYPE changes (not the selected
* object as such). This means that if elements of the same type are
* selected (for example two times a folder), NO notification will take
* place. There might be situations where the type of two objects is the
* same but the set of available actions is not. However, if clients decide
* that upon some action a recomputation of the available actions has to be
* forced, then
* <code>PackageExplorerActionGroup.refresh(DialogExplorerActionContext)</code>
* can be called.
*
* @param context
* the action context
*
* @see IPackageExplorerActionListener
* @see PackageExplorerActionEvent
* @see DialogExplorerActionContext
* @see #addListener(IPackageExplorerActionListener)
* @see #refresh(DialogExplorerActionContext)
*
* @throws ModelException
* if there is a failure while computing the available actions.
*/
public void setContext(DialogExplorerActionContext context)
throws ModelException {
super.setContext(context);
if (context == null) // can happen when disposing
return;
List selectedElements = context.getSelectedElements();
IScriptProject project = context.getScriptProject();
int type = MULTI;
if (selectedElements.size() == 0) {
type = NULL_SELECTION;
if (type == fLastType)
return;
} else if (selectedElements.size() == 1
|| identicalTypes(selectedElements, project)) {
type = getType(selectedElements.get(0), project);
if (selectedElements.size() > 1)
type = type | MULTI;
if (type == fLastType)
return;
}
internalSetContext(selectedElements, project, type);
}
/**
* Get a description for the last selection explaining why no operation is
* possible.
* <p>
* This can be usefull if a context sensitive widget does not want to
* display all operations although some of them are valid.
*
* @return a description for the last selection that explains why no
* operation is available.
*/
public String getNoActionDescription() {
String[] description = noAction(fLastType);
return description[0];
}
/**
* Internal method to set the context of the action group.
*
* @param selectedElements
* a list of selected elements, can be empty
* @param project
* the script project
* @param type
* the type of the selected element(s)
* @throws ModelException
*/
private void internalSetContext(List selectedElements,
IScriptProject project, int type) throws ModelException {
fLastType = type;
List availableActions = getAvailableActions(selectedElements, project);
BuildpathModifierAction[] actions = new BuildpathModifierAction[availableActions
.size()];
String[] descriptions = new String[availableActions.size()];
if (availableActions.size() > 0) {
for (int i = 0; i < availableActions.size(); i++) {
BuildpathModifierAction action = (BuildpathModifierAction) availableActions
.get(i);
actions[i] = action;
descriptions[i] = action.getDescription(type);
}
} else
descriptions = noAction(type);
informListeners(descriptions, actions);
}
/**
* Finds out wheter the list of elements consists only of elements having
* the same type (for example all are of type
* DialogPackageExplorerActionGroup.COMPILATION_UNIT). This allows to use a
* description for the available actions which is more specific and
* therefore provides more information.
*
* @param elements
* a list of elements to be compared to each other
* @param project
* the script project
* @return <code>true</code> if all elements are of the same type,
* <code>false</code> otherwise.
* @throws ModelException
*/
private boolean identicalTypes(List elements, IScriptProject project)
throws ModelException {
if (elements.size() == 0) {
return false;
}
Object firstElement = elements.get(0);
int firstType = getType(firstElement, project);
for (int i = 1; i < elements.size(); i++) {
if (firstType != getType(elements.get(i), project))
return false;
}
return true;
}
/**
* Inform all listeners about new actions.
*
* @param descriptions
* an array of descriptions for each actions, where the
* description at position 'i' belongs to the action at position
* 'i'
* @param actions
* an array of available actions
*/
private void informListeners(String[] descriptions,
BuildpathModifierAction[] actions) {
Iterator iterator = fListeners.iterator();
PackageExplorerActionEvent event = new PackageExplorerActionEvent(
descriptions, actions);
while (iterator.hasNext()) {
IPackageExplorerActionListener listener = (IPackageExplorerActionListener) iterator
.next();
listener.handlePackageExplorerActionEvent(event);
}
}
/**
* Returns string array with only one element which contains a short reason
* to indicate why there are no actions available.
*
* @return a description to explain why there are no actions available
*/
private String[] noAction(int type) {
String reason;
switch (type) {
case FILE:
reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_File;
break;
case FILE | MULTI:
reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_File;
break;
case DEFAULT_FRAGMENT:
reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_DefaultPackage;
break;
case DEFAULT_FRAGMENT | MULTI:
reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_DefaultPackage;
break;
case NULL_SELECTION:
reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_NullSelection;
break;
case MULTI:
reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_MultiSelection;
break;
case ARCHIVE_RESOURCE:
reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_ArchiveResource;
break;
default:
reason = NewWizardMessages.PackageExplorerActionGroup_NoAction_NoReason;
}
return new String[] { reason };
}
/**
* Computes the type based on the current selection. The type can be usefull
* to set the content of the hint text group properly.
*
* @param obj
* the object to get the type from
* @return the type of the current selection or UNDEFINED if no appropriate
* type could be found. Possible types are:<br>
* PackageExplorerActionGroup.FOLDER<br>
* PackageExplorerActionGroup.EXCLUDED_FOLDER;<br>
* PackageExplorerActionGroup.EXCLUDED_FILE<br>
* PackageExplorerActionGroup.DEFAULT_OUTPUT<br>
* PackageExplorerActionGroup.INCLUDED_FILE<br>
* PackageExplorerActionGroup.INCLUDED_FOLDER<br>
* PackageExplorerActionGroup.OUTPUT<br>
* PackageExplorerActionGroup.MODIFIED_FRAGMENT_ROOT<br>
* PackageExplorerActionGroup.DEFAULT_FRAGMENT<br>
* PackageExplorerActionGroup.JAVA_PROJECT<br>
* PackageExplorerActionGroup.PACKAGE_FRAGMENT_ROOT<br>
* PackageExplorerActionGroup.PACKAGE_FRAGMENT<br>
* PackageExplorerActionGroup.COMPILATION_UNIT<br>
* PackageExplorerActionGroup.FILE<br>
* @throws ModelException
*/
public static int getType(Object obj, IScriptProject project)
throws ModelException {
if (obj instanceof IScriptProject)
return SCRIPT_PROJECT;
if (obj instanceof BuildPathContainer)
return CONTAINER;
if (obj instanceof IProjectFragment)
return BuildpathModifier.filtersSet((IProjectFragment) obj)
? MODIFIED_FRAGMENT_ROOT
: PACKAGE_FRAGMENT_ROOT;
if (obj instanceof IScriptFolder) {
if (BuildpathModifier.isDefaultFragment((IScriptFolder) obj)) {
if (((IProjectFragment) ((IModelElement) obj)
.getAncestor(IModelElement.PROJECT_FRAGMENT))
.isArchive())
return ARCHIVE_RESOURCE;
return DEFAULT_FRAGMENT;
}
if (BuildpathModifier.isIncluded((IModelElement) obj, project,
null))
return INCLUDED_FOLDER;
if (((IProjectFragment) ((IModelElement) obj)
.getAncestor(IModelElement.PROJECT_FRAGMENT)).isArchive())
return ARCHIVE_RESOURCE;
if (((IProjectFragment) ((IModelElement) obj)
.getAncestor(IModelElement.PROJECT_FRAGMENT)).isExternal())
return EXTERNAL_RESOURCE;
return PACKAGE_FRAGMENT;
}
if (obj instanceof ISourceModule) {
if (((IProjectFragment) ((IModelElement) obj)
.getAncestor(IModelElement.PROJECT_FRAGMENT)).isArchive()) {
return ARCHIVE_RESOURCE;
}
if (((IProjectFragment) ((IModelElement) obj)
.getAncestor(IModelElement.PROJECT_FRAGMENT))
.isExternal()) {
return EXTERNAL_RESOURCE;
}
return BuildpathModifier.isIncluded((IModelElement) obj, project,
null) ? INCLUDED_FILE : SOURCE_MODULE;
}
if (obj instanceof IFolder) {
return getFolderType((IFolder) obj, project);
}
if (obj instanceof IFile)
return getFileType((IFile) obj, project);
return UNDEFINED;
}
/**
* Get the type of the folder
*
* @param folder
* folder to get the type from
* @return the type code for the folder. Possible types are:<br>
* PackageExplorerActionGroup.FOLDER<br>
* PackageExplorerActionGroup.EXCLUDED_FOLDER;<br>
* @throws ModelException
*/
private static int getFolderType(IFolder folder, IScriptProject project)
throws ModelException {
IContainer folderParent = folder.getParent();
if (folderParent.getFullPath().equals(project.getPath()))
return FOLDER;
if (BuildpathModifier.getFragment(folderParent) != null)
return EXCLUDED_FOLDER;
IProjectFragment fragmentRoot = BuildpathModifier
.getFragmentRoot(folder, project, null);
if (fragmentRoot == null)
return FOLDER;
if (fragmentRoot.equals(DLTKCore.create(folderParent)))
return EXCLUDED_FOLDER;
return FOLDER;
}
/**
* Get the type of the file
*
* @param file
* file to get the type from
* @return the type code for the file. Possible types are:<br>
* PackageExplorerActionGroup.EXCLUDED_FILE<br>
* PackageExplorerActionGroup.FILE
* @throws ModelException
*/
private static int getFileType(IFile file, IScriptProject project)
throws ModelException {
if (BuildpathModifier.isArchive(file, project))
return ARCHIVE;
if (DLTKCore.DEBUG) {
System.err.println(
"DialogPackageExplorerActionGroup:: Add some filters here"); //$NON-NLS-1$
}
// if (!DLTKCore.isScriptLikeFileName(file.getName()))
// return FILE;
IContainer fileParent = file.getParent();
if (fileParent.getFullPath().equals(project.getPath())) {
if (project.isOnBuildpath(project))
return EXCLUDED_FILE;
return FILE;
}
IProjectFragment fragmentRoot = BuildpathModifier.getFragmentRoot(file,
project, null);
if (fragmentRoot == null)
return FILE;
if (fragmentRoot.isArchive())
return ARCHIVE_RESOURCE;
if (fragmentRoot.equals(DLTKCore.create(fileParent)))
return EXCLUDED_FILE;
if (BuildpathModifier.getFragment(fileParent) == null) {
if (BuildpathModifier.parentExcluded(fileParent, project))
return FILE;
return EXCLUDED_FILE;
}
return EXCLUDED_FILE;
}
/**
* Based on the given list of elements, get the list of available actions
* that can be applied on this elements
*
* @param selectedElements
* the list of elements to get the actions for
* @param project
* the script project
* @return a list of <code>BuildpathModifierAction</code>s
* @throws ModelException
*/
private List getAvailableActions(List selectedElements,
IScriptProject project) throws ModelException {
if (project == null || !project.exists()) {
return new ArrayList();
}
List actions = new ArrayList();
int[] types = new int[selectedElements.size()];
for (int i = 0; i < types.length; i++) {
types[i] = getType(selectedElements.get(i), project);
}
for (int i = 0; i < fActions.length; i++) {
if (fActions[i] instanceof BuildpathModifierDropDownAction) {
if (changeEnableState(fActions[i], selectedElements, types)) {
BuildpathModifierAction[] dropDownActions = ((BuildpathModifierDropDownAction) fActions[i])
.getActions();
for (int j = 0; j < dropDownActions.length; j++) {
if (changeEnableState(dropDownActions[j],
selectedElements, types))
actions.add(dropDownActions[j]);
}
}
} else if (changeEnableState(fActions[i], selectedElements,
types)) {
actions.add(fActions[i]);
}
}
return actions;
}
/**
* Changes the enabled state of an action if necessary.
*
* @param action
* the action to change it's state for
* @param selectedElements
* a list of selected elements
* @param types
* an array of types corresponding to the types of the selected
* elements
* @return <code>true</code> if the action is valid (= enabled),
* <code>false</code> otherwise
* @throws ModelException
*/
private boolean changeEnableState(BuildpathModifierAction action,
List selectedElements, int[] types) throws ModelException {
if (action.isValid(selectedElements, types)) {
if (!action.isEnabled())
action.setEnabled(true);
return true;
} else {
if (action.isEnabled())
action.setEnabled(false);
return false;
}
}
/**
* Fill the context menu with the available actions
*
* @param menu
* the menu to be filled up with actions
*/
@Override
public void fillContextMenu(IMenuManager menu) {
for (int i = 0; i < fContextSensitiveActions; i++) {
IAction action = getAction(i);
if (action instanceof BuildpathModifierDropDownAction) {
if (action.isEnabled()) {
IAction[] actions = ((BuildpathModifierDropDownAction) action)
.getActions();
for (int j = 0; j < actions.length; j++) {
if (actions[j].isEnabled())
menu.add(actions[j]);
}
}
} else if (action.isEnabled())
menu.add(action);
}
super.fillContextMenu(menu);
}
/**
* Add listeners for the <code>PackageExplorerActionEvent</code>.
*
* @param listener
* the listener to be added
*
* @see PackageExplorerActionEvent
* @see IPackageExplorerActionListener
*/
public void addListener(IPackageExplorerActionListener listener) {
fListeners.add(listener);
}
/**
* Remove the listener from the list of registered listeners.
*
* @param listener
* the listener to be removed
*/
public void removeListener(IPackageExplorerActionListener listener) {
fListeners.remove(listener);
}
@Override
public void dispose() {
fListeners.clear();
super.dispose();
}
}