blob: 780bf53b478f9081b5d4f9a0fe7d0262225a6d39 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ant.internal.ui.views.actions;
import com.ibm.icu.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.ant.internal.ui.AntUtil;
import org.eclipse.ant.internal.ui.IAntUIConstants;
import org.eclipse.ant.internal.ui.model.AntElementNode;
import org.eclipse.core.resources.IFile;
import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
/**
*
* Code mostly a copy of the OpenWithMenu which cannot be effectively subclassed
*/
public class AntOpenWithMenu extends ContributionItem {
private IWorkbenchPage fPage;
private IEditorRegistry fRegistry = PlatformUI.getWorkbench().getEditorRegistry();
private static final String SYSTEM_EDITOR_ID= PlatformUI.PLUGIN_ID + ".SystemEditor"; //$NON-NLS-1$
private static Map imageCache = new Hashtable(11);
private AntElementNode fNode;
/**
* The id of this action.
*/
public static final String ID = IAntUIConstants.PLUGIN_ID + ".AntOpenWithMenu"; //$NON-NLS-1$
public AntOpenWithMenu(IWorkbenchPage page) {
super(ID);
this.fPage= page;
}
/* (non-Javadoc)
* @see org.eclipse.jface.action.IContributionItem#dispose()
*/
public void dispose() {
super.dispose();
Iterator iter= imageCache.values().iterator();
while (iter.hasNext()) {
Image image = (Image) iter.next();
image.dispose();
}
imageCache.clear();
}
/**
* Returns an image to show for the corresponding editor descriptor.
*
* @param editorDesc the editor descriptor, or <code>null</code> for the system editor
* @return the image or <code>null</code>
*/
private Image getImage(IEditorDescriptor editorDesc) {
ImageDescriptor imageDesc = getImageDescriptor(editorDesc);
if (imageDesc == null) {
return null;
}
Image image = (Image) imageCache.get(imageDesc);
if (image == null) {
image = imageDesc.createImage();
imageCache.put(imageDesc, image);
}
return image;
}
/**
* Returns the image descriptor for the given editor descriptor,
* or <code>null</code> if it has no image.
*/
private ImageDescriptor getImageDescriptor(IEditorDescriptor editorDesc) {
ImageDescriptor imageDesc = null;
if (editorDesc == null) {
imageDesc = fRegistry.getImageDescriptor(fNode.getIFile().getName());
} else {
imageDesc = editorDesc.getImageDescriptor();
}
if (imageDesc == null && editorDesc != null) {
if (editorDesc.getId().equals(SYSTEM_EDITOR_ID)) {
imageDesc = getSystemEditorImageDescriptor(fNode.getIFile().getFileExtension());
}
}
return imageDesc;
}
/**
* Return the image descriptor of the system editor
* that is registered with the OS to edit files of
* this type. <code>null</code> if none can be found.
*/
private ImageDescriptor getSystemEditorImageDescriptor(String extension) {
Program externalProgram = null;
if (extension != null) {
externalProgram = Program.findProgram(extension);
}
if (externalProgram == null) {
return null;
}
return new EditorImageDescriptor(externalProgram);
}
/**
* Creates the menu item for the editor descriptor.
*
* @param menu the menu to add the item to
* @param descriptor the editor descriptor, or null for the system editor
* @param preferredEditor the descriptor of the preferred editor, or <code>null</code>
*/
private void createMenuItem(Menu menu, final IEditorDescriptor descriptor, final IEditorDescriptor preferredEditor) {
// XXX: Would be better to use bold here, but SWT does not support it.
final MenuItem menuItem = new MenuItem(menu, SWT.RADIO);
boolean isPreferred = preferredEditor != null && descriptor.getId().equals(preferredEditor.getId());
menuItem.setSelection(isPreferred);
menuItem.setText(descriptor.getLabel());
Image image = getImage(descriptor);
if (image != null) {
menuItem.setImage(image);
}
Listener listener = new Listener() {
/* (non-Javadoc)
* @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
*/
public void handleEvent(Event event) {
switch (event.type) {
case SWT.Selection :
if (menuItem.getSelection()) {
openEditor(descriptor);
}
break;
}
}
};
menuItem.addListener(SWT.Selection, listener);
}
/* (non-Javadoc)
* @see org.eclipse.jface.action.IContributionItem#fill(org.eclipse.swt.widgets.Menu, int)
*/
public void fill(Menu menu, int index) {
IFile fileResource = fNode.getIFile();
if (fileResource == null) {
return;
}
IEditorDescriptor defaultEditor = fRegistry.findEditor(IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID); // should not be null
IEditorDescriptor preferredEditor = IDE.getDefaultEditor(fileResource); // may be null
Object[] editors= fRegistry.getEditors(fileResource.getName());
Arrays.sort(editors, new Comparator() {
/* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(Object o1, Object o2) {
String s1 = ((IEditorDescriptor) o1).getLabel();
String s2 = ((IEditorDescriptor) o2).getLabel();
//Return true if elementTwo is 'greater than' elementOne
return s1.compareToIgnoreCase(s2);
}
});
IEditorDescriptor antEditor= fRegistry.findEditor("org.eclipse.ant.internal.ui.editor.AntEditor"); //$NON-NLS-1$
boolean defaultFound = false;
boolean antFound= false;
List alreadyAddedEditors= new ArrayList(editors.length);
for (int i = 0; i < editors.length; i++) {
IEditorDescriptor editor = (IEditorDescriptor) editors[i];
if (alreadyAddedEditors.contains(editor.getId())) {
continue;
}
createMenuItem(menu, editor, preferredEditor);
if (defaultEditor != null && editor.getId().equals(defaultEditor.getId())) {
defaultFound = true;
}
if (antEditor != null && editor.getId().equals(antEditor.getId())) {
antFound= true;
}
alreadyAddedEditors.add(editor.getId());
}
// Only add a separator if there is something to separate
if (editors.length > 0) {
new MenuItem(menu, SWT.SEPARATOR);
}
// Add ant editor.
if (!antFound && antEditor != null) {
createMenuItem(menu, antEditor, preferredEditor);
}
// Add default editor.
if (!defaultFound && defaultEditor != null) {
createMenuItem(menu, defaultEditor, preferredEditor);
}
// Add system editor.
IEditorDescriptor descriptor = fRegistry.findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID);
createMenuItem(menu, descriptor, preferredEditor);
createDefaultMenuItem(menu, fileResource);
}
/* (non-Javadoc)
* @see org.eclipse.jface.action.IContributionItem#isDynamic()
*/
public boolean isDynamic() {
return true;
}
/**
* Opens the given editor on the selected file.
*
* @param editor the editor descriptor, or <code>null</code> for the system editor
*/
private void openEditor(IEditorDescriptor editorDescriptor) {
AntUtil.openInEditor(fPage, editorDescriptor, fNode);
}
/**
* Creates the menu item for the default editor
*
* @param menu the menu to add the item to
* @param file the file being edited
* @param registry the editor registry
*/
private void createDefaultMenuItem(Menu menu, final IFile fileResource) {
final MenuItem menuItem = new MenuItem(menu, SWT.RADIO);
menuItem.setSelection(IDE.getDefaultEditor(fileResource) == null);
menuItem.setText(AntViewActionMessages.AntViewOpenWithMenu_Default_Editor_4);
Listener listener = new Listener() {
/* (non-Javadoc)
* @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
*/
public void handleEvent(Event event) {
switch (event.type) {
case SWT.Selection :
if (menuItem.getSelection()) {
IDE.setDefaultEditor(fileResource, null);
try {
IDE.openEditor(fPage, fileResource, true);
} catch (PartInitException e) {
AntUIPlugin.log(MessageFormat.format(AntViewActionMessages.AntViewOpenWithMenu_Editor_failed, new String[]{fileResource.getLocation().toOSString()}), e);
}
}
break;
}
}
};
menuItem.addListener(SWT.Selection, listener);
}
public void setNode(AntElementNode node) {
fNode= node;
}
}