blob: a350efe84e525e341a2deadb4c3b489fb248a7be [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 Christian Pontesegger 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:
* Christian Pontesegger - initial API and implementation
* IBM Corporation - ongoing enhancements
*******************************************************************************/
package org.eclipse.pde.internal.ui.views.imagebrowser;
import java.util.*;
import java.util.List;
import org.eclipse.jface.viewers.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.internal.ui.*;
import org.eclipse.pde.internal.ui.views.imagebrowser.filter.*;
import org.eclipse.pde.internal.ui.views.imagebrowser.filter.IFilter;
import org.eclipse.pde.internal.ui.views.imagebrowser.repositories.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.ISourceProvider;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.services.ISourceProviderService;
/**
* Provides the PDE Image browser view which displays all icons and images from plug-ins. The plug-ins
* can be loaded from the target platform, the workspace or the current install.
*/
public class ImageBrowserView extends ViewPart implements IImageTarget {
private final UpdateUI mUIJob = new UpdateUI();
private final List<IFilter<ImageElement>> mFilters = new ArrayList<IFilter<ImageElement>>();
private final IFilter<ImageElement> disabledIcons;
private final IFilter<ImageElement> enabledIcons;
private final IFilter<ImageElement> wizard;
private ScrolledComposite scrolledComposite;
private Composite imageComposite;
private ComboViewer sourceCombo;
int mImageCounter = 0;
private Label lblPlugin;
private Label lblPath;
private Label lblWidth;
private Label lblHeight;
private Text txtReference;
private Button nextButton;
private Spinner spinMaxImages;
private List<Image> displayedImages = new ArrayList<Image>();
@SuppressWarnings("unchecked")
public ImageBrowserView() {
// create default filters
final IFilter<ImageElement> iconSize = new SizeFilter(16, SizeFilter.TYPE_EXACT, 16, SizeFilter.TYPE_EXACT);
final IFilter<ImageElement> disabled1 = new PatternFilter(".*/obj16/\\w+dis(_obj)?\\W.+"); //$NON-NLS-1$
final IFilter<ImageElement> disabled2 = new PatternFilter(".*/d(?!ialogs)(?!ecorations)(?!nd)(?!evguide)\\w+/.+"); //$NON-NLS-1$
final IFilter<ImageElement> disabled = new OrFilter<ImageElement>(new IFilter[] {disabled1, disabled2});
disabledIcons = new AndFilter<ImageElement>(new IFilter[] {iconSize, disabled});
final IFilter<ImageElement> enabled = new NotFilter<ImageElement>(disabled);
enabledIcons = new AndFilter<ImageElement>(new IFilter[] {iconSize, enabled});
final IFilter<ImageElement> wizardSize = new SizeFilter(75, SizeFilter.TYPE_EXACT, 66, SizeFilter.TYPE_EXACT);
final IFilter<ImageElement> wizard1 = new PatternFilter(".*/wizban/.+"); //$NON-NLS-1$
final IFilter<ImageElement> wizard2 = new PatternFilter(".+_wiz\\.\\w+"); //$NON-NLS-1$
final IFilter<ImageElement> wizardName = new OrFilter<ImageElement>(new IFilter[] {wizard1, wizard2});
wizard = new AndFilter<ImageElement>(new IFilter[] {wizardSize, wizardName});
mFilters.add(enabledIcons);
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
public void createPartControl(final Composite parent) {
final Composite composite = SWTFactory.createComposite(parent, 1, 1, GridData.FILL_BOTH, 0, 0);
PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IHelpContextIds.IMAGE_BROWSER_VIEW);
Composite topComp = new Composite(composite, SWT.NONE);
RowLayout layout = new RowLayout();
topComp.setLayout(layout);
topComp.setFont(parent.getFont());
topComp.setBackground(composite.getBackground());
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
topComp.setLayoutData(gd);
Composite sourceComp = SWTFactory.createComposite(topComp, 7, 1, SWT.NONE, 0, 0);
sourceComp.setLayoutData(new RowData());
SWTFactory.createLabel(sourceComp, PDEUIMessages.ImageBrowserView_Source, 1);
sourceCombo = new ComboViewer(SWTFactory.createCombo(sourceComp, SWT.READ_ONLY, 1, null));
sourceCombo.setContentProvider(new ArrayContentProvider());
sourceCombo.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
scanImages();
}
});
ArrayList<Object> sourceComboInput = new ArrayList<Object>();
sourceComboInput.add(new TargetPlatformRepository(this, true));
sourceComboInput.add(new TargetPlatformRepository(this, false));
sourceComboInput.add(new WorkspaceRepository(this));
sourceCombo.setInput(sourceComboInput);
SWTFactory.createHorizontalSpacer(sourceComp, 3);
SWTFactory.createLabel(sourceComp, PDEUIMessages.ImageBrowserView_Show, 1);
Combo typeCombo = SWTFactory.createCombo(sourceComp, SWT.READ_ONLY, 1, new String[] {PDEUIMessages.ImageBrowserView_FilterIcons, PDEUIMessages.ImageBrowserView_FilterDisabled, PDEUIMessages.ImageBrowserView_FilterWizards, PDEUIMessages.ImageBrowserView_FilterAllImages});
typeCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mFilters.clear();
Combo source = (Combo) e.getSource();
switch (source.getSelectionIndex()) {
case 0 :
mFilters.add(enabledIcons);
break;
case 1 :
mFilters.add(disabledIcons);
break;
case 2 :
mFilters.add(wizard);
break;
case 3 :
default :
}
scanImages();
}
});
Composite pageComp = SWTFactory.createComposite(topComp, 6, 1, SWT.NONE, 0, 0);
((GridLayout) pageComp.getLayout()).marginLeft = 20;
pageComp.setLayoutData(new RowData());
SWTFactory.createLabel(pageComp, PDEUIMessages.ImageBrowserView_MaxImages, 1);
spinMaxImages = new Spinner(pageComp, SWT.BORDER);
spinMaxImages.setMaximum(999);
spinMaxImages.setMinimum(1);
spinMaxImages.setSelection(250);
SWTFactory.createHorizontalSpacer(pageComp, 3);
nextButton = SWTFactory.createPushButton(pageComp, PDEUIMessages.ImageBrowserView_ShowMore, null);
nextButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(final SelectionEvent e) {
scanImages();
}
});
nextButton.setEnabled(false);
scrolledComposite = new ScrolledComposite(composite, SWT.BORDER | SWT.V_SCROLL);
scrolledComposite.setBackground(scrolledComposite.getParent().getBackground());
scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
scrolledComposite.setExpandHorizontal(true);
scrolledComposite.setExpandVertical(true);
scrolledComposite.addControlListener(new ControlAdapter() {
public void controlResized(final ControlEvent e) {
Rectangle r = scrolledComposite.getClientArea();
scrolledComposite.setMinSize(imageComposite.computeSize(r.width, SWT.DEFAULT));
}
});
imageComposite = SWTFactory.createComposite(scrolledComposite, 1, 1, GridData.FILL_BOTH, 0, 0);
((GridLayout) imageComposite.getLayout()).verticalSpacing = 0;
imageComposite.setBackground(imageComposite.getParent().getBackground());
scrolledComposite.setContent(imageComposite);
scrolledComposite.setMinSize(imageComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
Composite infoGroup = SWTFactory.createComposite(composite, 4, 1, GridData.FILL_HORIZONTAL, 0, 0);
((GridLayout) infoGroup.getLayout()).verticalSpacing = 0;
SWTFactory.createLabel(infoGroup, PDEUIMessages.ImageBrowserView_Path, 1);
lblPath = new Label(infoGroup, SWT.NONE);
lblPath.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
SWTFactory.createLabel(infoGroup, PDEUIMessages.ImageBrowserView_Width, 1);
lblWidth = new Label(infoGroup, SWT.NONE);
final GridData gd_lblWidth = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gd_lblWidth.widthHint = 50;
lblWidth.setLayoutData(gd_lblWidth);
SWTFactory.createLabel(infoGroup, PDEUIMessages.ImageBrowserView_Plugin, 1);
lblPlugin = new Label(infoGroup, SWT.NONE);
lblPlugin.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
SWTFactory.createLabel(infoGroup, PDEUIMessages.ImageBrowserView_Height, 1);
lblHeight = new Label(infoGroup, SWT.NONE);
final GridData gd_lblHeight = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gd_lblHeight.widthHint = 50;
lblHeight.setLayoutData(gd_lblHeight);
SWTFactory.createLabel(infoGroup, PDEUIMessages.ImageBrowserView_Reference, 1);
txtReference = new Text(infoGroup, SWT.BORDER | SWT.READ_ONLY);
txtReference.setBackground(txtReference.getParent().getBackground());
txtReference.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#setFocus()
*/
public void setFocus() {
// Pressing enter when navigating the images calls this method, stealing focus
if (sourceCombo.getSelection().isEmpty()) {
sourceCombo.getCombo().setFocus();
}
}
public void notifyImage(final ImageElement element) {
for (final IFilter<ImageElement> filter : mFilters) {
if (!filter.accept(element))
return;
}
mUIJob.addImage(element);
mImageCounter--;
if (mImageCounter <= 0) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
nextButton.setEnabled(true);
}
});
}
}
public boolean needsMore() {
return mImageCounter > 0;
}
private void scanImages() {
nextButton.setEnabled(false);
// reset UI components
mUIJob.reset();
lblPath.setText(""); //$NON-NLS-1$
lblPlugin.setText(""); //$NON-NLS-1$
lblWidth.setText(""); //$NON-NLS-1$
lblHeight.setText(""); //$NON-NLS-1$
txtReference.setText(""); //$NON-NLS-1$
// first dispose controls
for (final Control control : imageComposite.getChildren()) {
control.dispose();
}
// then dispose images used in controls
disposeImages();
// initialize scan job
if (!sourceCombo.getSelection().isEmpty()) {
// set maximum image counter
mImageCounter = spinMaxImages.getSelection();
final AbstractRepository repository = (AbstractRepository) ((IStructuredSelection) sourceCombo.getSelection()).getFirstElement();
repository.schedule();
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#dispose()
*/
@Override
public void dispose() {
disposeImages();
}
private void disposeImages() {
for (Image image : displayedImages) {
image.dispose();
}
displayedImages.clear();
}
private class UpdateUI extends FocusAdapter implements Runnable {
Collection<ImageElement> mElements = new LinkedList<ImageElement>();
String mLastPlugin = ""; //$NON-NLS-1$
private Composite mPluginImageContainer = null;
private final RowLayout mRowLayout = new RowLayout(SWT.HORIZONTAL);
public UpdateUI() {
mRowLayout.wrap = true;
mRowLayout.marginWidth = 0;
mRowLayout.marginHeight = 0;
}
public synchronized void addImage(final ImageElement element) {
mElements.add(element);
if (mElements.size() == 1)
Display.getDefault().asyncExec(this);
}
public synchronized void run() {
if (!mElements.isEmpty()) {
for (final ImageElement element : mElements) {
if (!mLastPlugin.equals(element.getPlugin())) {
// new plug-in detected
mLastPlugin = element.getPlugin();
Label label = new Label(imageComposite, SWT.NONE);
label.setText(mLastPlugin);
label.setBackground(label.getParent().getBackground());
if (mPluginImageContainer != null)
mPluginImageContainer.layout();
mPluginImageContainer = new Composite(imageComposite, SWT.NONE);
mPluginImageContainer.setLayout(mRowLayout);
mPluginImageContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
mPluginImageContainer.setBackground(mPluginImageContainer.getParent().getBackground());
}
Button button = new Button(mPluginImageContainer, SWT.FLAT);
Image image = new Image(getViewSite().getShell().getDisplay(), element.getImageData());
displayedImages.add(image);
button.setImage(image);
button.setToolTipText(element.getPath());
button.setData(element);
button.addFocusListener(this);
button.addListener(SWT.Activate, new Listener() {
public void handleEvent(Event e) {
}
});
}
mElements.clear();
mPluginImageContainer.layout();
imageComposite.layout();
Rectangle r = scrolledComposite.getClientArea();
scrolledComposite.setMinSize(imageComposite.computeSize(r.width, SWT.DEFAULT));
}
}
public void focusGained(FocusEvent e) {
// Scroll the focused control into view
Control child = (Control) e.widget;
Rectangle bounds = child.getBounds();
// Because we store the buttons in an additional composite, need to adjust bounds
Rectangle pluginBounds = child.getParent().getBounds();
bounds.x += pluginBounds.x;
bounds.y += pluginBounds.y;
Rectangle area = scrolledComposite.getClientArea();
Point origin = scrolledComposite.getOrigin();
if (origin.x > bounds.x)
origin.x = Math.max(0, bounds.x);
if (origin.y > bounds.y)
origin.y = Math.max(0, bounds.y);
if (origin.x + area.width < bounds.x + bounds.width)
origin.x = Math.max(0, bounds.x + bounds.width - area.width);
if (origin.y + area.height < bounds.y + bounds.height)
origin.y = Math.max(0, bounds.y + bounds.height - area.height);
scrolledComposite.setOrigin(origin);
final Object data = e.widget.getData();
if (data instanceof ImageElement) {
// Example of how we could use a popup dialog instead
// org.eclipse.core.runtime.Path path = new org.eclipse.core.runtime.Path(((ImageElement) data).getPath());
//
// new PopupDialog(getSite().getShell(), PopupDialog.HOVER_SHELLSTYLE, true, false, false, false, false, path.lastSegment(), "") {
// protected Control createInfoTextArea(Composite parent) {
//
// Composite infoGroup = SWTFactory.createComposite(parent, 4, 1, GridData.FILL_HORIZONTAL, 0, 0);
//
// SWTFactory.createLabel(infoGroup, PDEUIMessages.ImageBrowserView_Path, 1);
// lblPath = new Label(infoGroup, SWT.NONE);
// lblPath.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
//
// SWTFactory.createLabel(infoGroup, PDEUIMessages.ImageBrowserView_Width, 1);
// lblWidth = new Label(infoGroup, SWT.NONE);
// final GridData gd_lblWidth = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
// gd_lblWidth.widthHint = 50;
// lblWidth.setLayoutData(gd_lblWidth);
//
// SWTFactory.createLabel(infoGroup, PDEUIMessages.ImageBrowserView_Plugin, 1);
// lblPlugin = new Label(infoGroup, SWT.NONE);
// lblPlugin.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
//
// SWTFactory.createLabel(infoGroup, PDEUIMessages.ImageBrowserView_Height, 1);
// lblHeight = new Label(infoGroup, SWT.NONE);
// final GridData gd_lblHeight = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
// gd_lblHeight.widthHint = 50;
// lblHeight.setLayoutData(gd_lblHeight);
//
// SWTFactory.createLabel(infoGroup, PDEUIMessages.ImageBrowserView_Reference, 1);
// txtReference = new Text(infoGroup, SWT.BORDER | SWT.READ_ONLY);
// txtReference.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
//
// lblPath.setText(((ImageElement) data).getPath());
// lblPlugin.setText(((ImageElement) data).getFullPlugin());
// txtReference.setText("platform:/plugin/" + ((ImageElement) data).getPlugin() + "/" + ((ImageElement) data).getPath()); //$NON-NLS-1$ //$NON-NLS-2$
//
// lblWidth.setText(NLS.bind(PDEUIMessages.ImageBrowserView_Pixels, Integer.toString(((ImageElement) data).getImageData().width)));
// lblHeight.setText(NLS.bind(PDEUIMessages.ImageBrowserView_Pixels, Integer.toString(((ImageElement) data).getImageData().height)));
//
// return infoGroup;
// }
// }.open();
//
// StringBuffer text = new StringBuffer();
// text.append(NLS.bind("Image Path: {0}", path.toString())).append('\n');
// text.append(NLS.bind("Plug-in Provider: {0}", ((ImageElement) data).getFullPlugin())).append('\n');
// text.append(NLS.bind("Reference URL: {0}", "platform:/plugin/" + ((ImageElement) data).getPlugin() + "/" + ((ImageElement) data).getPath())).append('\n'); //$NON-NLS-1$ //$NON-NLS-2$
// text.append(NLS.bind("Width: {0} Height: {1}", Integer.toString(((ImageElement) data).getImageData().width), Integer.toString(((ImageElement) data).getImageData().height)));
//
// PopupDialog popup = new PopupDialog(getSite().getShell(), SWT.NONE, false, false, false, false, false, path.lastSegment(), text.toString());
// popup.open();
lblPath.setText(((ImageElement) data).getPath());
lblPlugin.setText(((ImageElement) data).getFullPlugin());
txtReference.setText("platform:/plugin/" + ((ImageElement) data).getPlugin() + "/" + ((ImageElement) data).getPath()); //$NON-NLS-1$ //$NON-NLS-2$
lblWidth.setText(NLS.bind(PDEUIMessages.ImageBrowserView_Pixels, Integer.toString(((ImageElement) data).getImageData().width)));
lblHeight.setText(NLS.bind(PDEUIMessages.ImageBrowserView_Pixels, Integer.toString(((ImageElement) data).getImageData().height)));
// update source provider
ISourceProviderService service = (ISourceProviderService) PlatformUI.getWorkbench().getService(ISourceProviderService.class);
ISourceProvider provider = service.getSourceProvider(ActiveImageSourceProvider.ACTIVE_IMAGE);
if (provider instanceof ActiveImageSourceProvider)
((ActiveImageSourceProvider) provider).setImageData(((ImageElement) data));
}
}
public synchronized void reset() {
mLastPlugin = ""; //$NON-NLS-1$
mElements.clear();
mPluginImageContainer = null;
}
}
}