/*******************************************************************************
* 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
*
*******************************************************************************/
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.IScriptProject;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptFolder;
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.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.corext.buildpath.BuildpathModifier.IBuildpathModifierListener;
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.dltk.ui.DLTKUIPlugin;
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 result= new ArrayList();
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 (BuildpathModifierAction[])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 of the action group. Note that this method is deprecated.
* <ul><li>Clients should use DialogPackageExplorerActionGroup.setContext(DialogExplorerActionContext) instead</li>
* <li>If this method is called, it is expected that the provided context is of type
* <code>DialogExplorerActionContext</code>. If this is not the case, the caller will
* end up with a <code>ClassCastException</code>.
*
* @deprecated use instead DialogPackageExplorerActionGroup.setContext(DialogExplorerActionContext)
*
* @see #setContext(DialogExplorerActionContext)
*/
public void setContext(ActionContext context) {
try {
setContext((DialogExplorerActionContext)context);
} catch (ModelException e) {
DLTKUIPlugin.log(e);
}
}
/**
* 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
*/
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);
}
/* (non-Javadoc)
* @see org.eclipse.dltk.internal.ui.actions.CompositeActionGroup#dispose()
*/
public void dispose() {
fListeners.clear();
super.dispose();
}
}