| /******************************************************************************* |
| * Copyright (c) 2004, 2007 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.debug.internal.ui.actions.breakpointGroups; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.debug.internal.ui.IDebugHelpContextIds; |
| import org.eclipse.debug.internal.ui.SWTFactory; |
| import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointOrganizerManager; |
| import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsView; |
| import org.eclipse.debug.internal.ui.views.breakpoints.IBreakpointOrganizer; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.TrayDialog; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.viewers.DoubleClickEvent; |
| import org.eclipse.jface.viewers.IDoubleClickListener; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.IStructuredContentProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.ITreeContentProvider; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.TableViewer; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.swt.SWT; |
| 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.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Table; |
| import org.eclipse.swt.widgets.Tree; |
| import org.eclipse.ui.PlatformUI; |
| |
| /** |
| * Dialog which presents available breakpoint groupings to |
| * the user and allows them to specify which they'd like |
| * to use and in what order they should be applied. |
| */ |
| public class GroupBreakpointsByDialog extends TrayDialog { |
| |
| private BreakpointsView fView; |
| |
| // Table viewer that presents available containers |
| private TableViewer fAvailableViewer; |
| private AvailableOrganizersProvider fAvailableOrganizersProvider= new AvailableOrganizersProvider(); |
| |
| // Tree viewer that presents selected containers |
| private TreeViewer fSelectedViewer; |
| private SelectedOrganizerProvider fSelectedOrganizersProvider= new SelectedOrganizerProvider(); |
| |
| private List fResult= new ArrayList(); |
| |
| private Button fAddButton; |
| private Button fRemoveButton; |
| private Button fMoveUpButton; |
| private Button fMoveDownButton; |
| |
| /** |
| * Selection listener that listens to selection from all buttons in this |
| * dialog. |
| */ |
| private SelectionAdapter fSelectionListener= new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| Object source= e.getSource(); |
| if (source == fAddButton) { |
| handleAddPressed(); |
| } else if (source == fRemoveButton) { |
| handleRemovePressed(); |
| } else if (source == fMoveUpButton) { |
| handleMoveUpPressed(); |
| } else if (source == fMoveDownButton) { |
| handleMoveDownPressed(); |
| } |
| } |
| }; |
| |
| protected GroupBreakpointsByDialog(BreakpointsView view) { |
| super(view.getSite().getShell()); |
| fView= view; |
| setShellStyle(getShellStyle() | SWT.RESIZE); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) |
| */ |
| protected Control createDialogArea(Composite parent) { |
| ILabelProvider labelProvider= new BreakpointOrganzierLabelProvider(); |
| |
| Composite parentComposite= (Composite) super.createDialogArea(parent); |
| parentComposite.setFont(parent.getFont()); |
| Composite composite= new Composite(parentComposite, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 3; |
| composite.setLayout(layout); |
| GridData data= new GridData(GridData.FILL_BOTH); |
| data.heightHint= 400; |
| composite.setLayoutData(data); |
| composite.setFont(parent.getFont()); |
| |
| Label label= new Label(composite, SWT.WRAP); |
| label.setText(BreakpointGroupMessages.GroupBreakpointsByDialog_0); |
| GridData gridData = new GridData(GridData.FILL_HORIZONTAL); |
| gridData.horizontalSpan = 3; |
| label.setLayoutData(gridData); |
| |
| createAvailableViewer(composite, labelProvider); |
| createButtons(composite); |
| createSelectedViewer(composite, labelProvider); |
| |
| initializeContent(); |
| updateViewers(); |
| Dialog.applyDialogFont(parentComposite); |
| return parentComposite; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.dialogs.Dialog#createContents(org.eclipse.swt.widgets.Composite) |
| */ |
| protected Control createContents(Composite parent) { |
| Control contents = super.createContents(parent); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(getDialogArea(), IDebugHelpContextIds.GROUP_BREAKPOINTS_DIALOG); |
| return contents; |
| } |
| |
| /** |
| * Divides the available breakpoint container factories into the |
| * appropriate viewers ("available" or "selected"). |
| */ |
| private void initializeContent() { |
| IBreakpointOrganizer[] organizers= BreakpointOrganizerManager.getDefault().getOrganizers(); |
| for (int i = 0; i < organizers.length; i++) { |
| fAvailableOrganizersProvider.addAvailable(organizers[i]); |
| } |
| organizers = fView.getBreakpointOrganizers(); |
| if (organizers != null) { |
| for (int i = 0; i < organizers.length; i++) { |
| fSelectedOrganizersProvider.addSelected(organizers[i]); |
| } |
| } |
| } |
| |
| /** |
| * Creates and configured the viewer that shows the available (not currently selected) |
| * breakpoint container factories. |
| */ |
| private void createAvailableViewer(Composite parent, ILabelProvider labelProvider) { |
| Composite availableComposite= new Composite(parent, SWT.NONE); |
| availableComposite.setFont(parent.getFont()); |
| GridLayout layout = new GridLayout(); |
| layout.marginHeight=0; |
| layout.marginWidth=0; |
| availableComposite.setLayout(layout); |
| GridData gridData= new GridData(GridData.FILL_BOTH); |
| gridData.widthHint= 225; |
| availableComposite.setLayoutData(gridData); |
| |
| Label label= new Label(availableComposite, SWT.WRAP); |
| label.setText(BreakpointGroupMessages.GroupBreakpointsByDialog_1); |
| gridData = new GridData(GridData.FILL_HORIZONTAL); |
| label.setLayoutData(gridData); |
| |
| fAvailableViewer= new TableViewer(availableComposite); |
| fAvailableViewer.setContentProvider(fAvailableOrganizersProvider); |
| fAvailableViewer.setLabelProvider(labelProvider); |
| fAvailableViewer.setInput(new Object()); |
| Table table = fAvailableViewer.getTable(); |
| table.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| table.setFont(parent.getFont()); |
| fAvailableViewer.addDoubleClickListener(new IDoubleClickListener() { |
| public void doubleClick(DoubleClickEvent event) { |
| handleAddPressed(); |
| } |
| }); |
| fAvailableViewer.addSelectionChangedListener(new ISelectionChangedListener() { |
| public void selectionChanged(SelectionChangedEvent event) { |
| updateAddButton(); |
| } |
| }); |
| } |
| |
| /** |
| * Creates and configures the viewer that shows the currently selected |
| * breakpoint container factories. |
| */ |
| private void createSelectedViewer(Composite parent, ILabelProvider labelProvider) { |
| Composite selectedComposite= new Composite(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.marginHeight=0; |
| layout.marginWidth=0; |
| layout.numColumns= 2; |
| selectedComposite.setLayout(layout); |
| GridData gridData= new GridData(GridData.FILL_BOTH); |
| gridData.widthHint= 225; |
| selectedComposite.setLayoutData(gridData); |
| selectedComposite.setFont(parent.getFont()); |
| |
| Label label= new Label(selectedComposite, SWT.WRAP); |
| label.setText(BreakpointGroupMessages.GroupBreakpointsByDialog_3); |
| gridData = new GridData(); |
| gridData.horizontalSpan = 2; |
| label.setLayoutData(gridData); |
| |
| fSelectedViewer= new TreeViewer(selectedComposite); |
| fSelectedViewer.setContentProvider(fSelectedOrganizersProvider); |
| fSelectedViewer.setLabelProvider(labelProvider); |
| fSelectedViewer.setInput(new Object()); |
| Tree tree = fSelectedViewer.getTree(); |
| tree.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| tree.setFont(parent.getFont()); |
| fSelectedViewer.addDoubleClickListener(new IDoubleClickListener() { |
| public void doubleClick(DoubleClickEvent event) { |
| handleRemovePressed(); |
| } |
| }); |
| fSelectedViewer.addSelectionChangedListener(new ISelectionChangedListener() { |
| public void selectionChanged(SelectionChangedEvent event) { |
| updateSelectedButtons(); |
| } |
| }); |
| } |
| |
| public void createButtons(Composite parent) { |
| Composite buttonComposite= new Composite(parent, SWT.NONE); |
| buttonComposite.setLayout(new GridLayout()); |
| buttonComposite.setLayoutData(new GridData()); |
| buttonComposite.setFont(parent.getFont()); |
| |
| fAddButton= SWTFactory.createPushButton(buttonComposite, BreakpointGroupMessages.GroupBreakpointsByDialog_2, null); |
| fAddButton.addSelectionListener(fSelectionListener); |
| |
| fRemoveButton= SWTFactory.createPushButton(buttonComposite, BreakpointGroupMessages.GroupBreakpointsByDialog_4, null); |
| fRemoveButton.addSelectionListener(fSelectionListener); |
| |
| fMoveUpButton= SWTFactory.createPushButton(buttonComposite, BreakpointGroupMessages.GroupBreakpointsByDialog_5, null); |
| fMoveUpButton.addSelectionListener(fSelectionListener); |
| |
| fMoveDownButton= SWTFactory.createPushButton(buttonComposite, BreakpointGroupMessages.GroupBreakpointsByDialog_6, null); |
| fMoveDownButton.addSelectionListener(fSelectionListener); |
| |
| } |
| |
| /** |
| * Returns the organizers chosen by the user. The order |
| * of the list is the order that the organizers should be displayed |
| * in the breakpoints view. |
| * @return the breakpoint organizers chosen by the user |
| */ |
| public IBreakpointOrganizer[] getOrganizers() { |
| return (IBreakpointOrganizer[]) fResult.toArray(new IBreakpointOrganizer[fResult.size()]); |
| } |
| |
| /** |
| * When the user presses OK, convert the tree selection into a list. |
| */ |
| protected void okPressed() { |
| Object[] factories= fSelectedOrganizersProvider.getElements(null); |
| while (factories.length > 0) { |
| Object factory= factories[0]; |
| fResult.add(factory); |
| factories= fSelectedOrganizersProvider.getChildren(factory); |
| } |
| super.okPressed(); |
| } |
| |
| /** |
| * Moves the selected item from the list of "available" factories |
| * to the tree of "selected" factories. |
| */ |
| public void handleAddPressed() { |
| IStructuredSelection selection= (IStructuredSelection) fAvailableViewer.getSelection(); |
| if (selection.size() < 1) { |
| return; |
| } |
| Iterator iter= selection.iterator(); |
| while (iter.hasNext()) { |
| fSelectedOrganizersProvider.addSelected((IBreakpointOrganizer) iter.next()); |
| } |
| updateViewers(); |
| } |
| |
| /** |
| * Moves the selected item from the tree of "selected" factories |
| * to the list of "available" factories. |
| */ |
| public void handleRemovePressed() { |
| IStructuredSelection selection= (IStructuredSelection) fSelectedViewer.getSelection(); |
| if (selection.size() < 1) { |
| return; |
| } |
| Iterator iter= selection.iterator(); |
| while (iter.hasNext()) { |
| fAvailableOrganizersProvider.addAvailable((IBreakpointOrganizer) iter.next()); |
| } |
| updateViewers(); |
| } |
| |
| /** |
| * Moves each selected item up in the tree of selected containers |
| */ |
| public void handleMoveUpPressed() { |
| IStructuredSelection selection = (IStructuredSelection) fSelectedViewer.getSelection(); |
| Iterator iter = selection.iterator(); |
| while (iter.hasNext()) { |
| fSelectedOrganizersProvider.moveUp(iter.next()); |
| } |
| updateViewers(); |
| } |
| |
| /** |
| * Moves each selected item down in the tree of selected containers |
| */ |
| public void handleMoveDownPressed() { |
| IStructuredSelection selection = (IStructuredSelection) fSelectedViewer.getSelection(); |
| Object[] elements= selection.toArray(); |
| for (int i= elements.length - 1; i >= 0; i--) { |
| fSelectedOrganizersProvider.moveDown(elements[i]); |
| } |
| updateViewers(); |
| } |
| |
| /** |
| * Fully refreshes and updates all viewers and buttons. |
| */ |
| public void updateViewers() { |
| fAvailableViewer.refresh(); |
| fSelectedViewer.refresh(); |
| fSelectedViewer.expandAll(); |
| updateAddButton(); |
| updateSelectedButtons(); |
| } |
| |
| /** |
| * Updates all buttons associated with the tree of selected containers. |
| */ |
| public void updateSelectedButtons() { |
| updateRemoveButton(); |
| updateMoveUpButton(); |
| updateMoveDownButton(); |
| } |
| |
| public void updateAddButton() { |
| IStructuredSelection selection = (IStructuredSelection) fAvailableViewer.getSelection(); |
| fAddButton.setEnabled(selection.size() > 0); |
| } |
| |
| public void updateRemoveButton() { |
| IStructuredSelection selection = (IStructuredSelection) fSelectedViewer.getSelection(); |
| fRemoveButton.setEnabled(selection.size() > 0); |
| } |
| |
| public void updateMoveUpButton() { |
| boolean enabled= true; |
| IStructuredSelection selection = (IStructuredSelection) fSelectedViewer.getSelection(); |
| if (selection.size() == 0) { |
| enabled= false; |
| } else { |
| Object firstSelected= selection.getFirstElement(); |
| Object parent= fSelectedOrganizersProvider.getParent(firstSelected); |
| if (!(parent instanceof IBreakpointOrganizer)) { |
| enabled= false; |
| } |
| } |
| fMoveUpButton.setEnabled(enabled); |
| } |
| |
| public void updateMoveDownButton() { |
| boolean enabled= true; |
| IStructuredSelection selection = (IStructuredSelection) fSelectedViewer.getSelection(); |
| if (selection.size() == 0) { |
| enabled= false; |
| } else { |
| Object lastSelected= selection.toList().get(selection.size() - 1); |
| Object[] children= fSelectedOrganizersProvider.getChildren(lastSelected); |
| if (children.length < 1) { |
| enabled= false; |
| } |
| } |
| fMoveDownButton.setEnabled(enabled); |
| } |
| |
| /** |
| * Content provider that provides the list of breakpoint organaisers |
| * that are available but not currently selected. |
| */ |
| private class AvailableOrganizersProvider implements IStructuredContentProvider { |
| protected List availableOrganziers= new ArrayList(); |
| |
| public void addAvailable(IBreakpointOrganizer organizer) { |
| availableOrganziers.add(organizer); |
| fSelectedOrganizersProvider.selectedOrganizers.remove(organizer); |
| } |
| |
| public Object[] getElements(Object inputElement) { |
| return availableOrganziers.toArray(); |
| } |
| |
| public void dispose() { |
| } |
| public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { |
| } |
| } |
| |
| /** |
| * Content provider that returns the selected breakpoint organizers |
| * as a tree. This tree shows the list of organzizers as they will |
| * appear in the breakpoints view. |
| */ |
| private class SelectedOrganizerProvider implements ITreeContentProvider { |
| protected List selectedOrganizers= new ArrayList(); |
| |
| public void addSelected(IBreakpointOrganizer organizer) { |
| selectedOrganizers.add(organizer); |
| fAvailableOrganizersProvider.availableOrganziers.remove(organizer); |
| } |
| |
| public void moveUp(Object object) { |
| int index = selectedOrganizers.indexOf(object); |
| if (index > 0) { |
| selectedOrganizers.remove(object); |
| selectedOrganizers.add(index - 1, object); |
| } |
| } |
| |
| public void moveDown(Object object) { |
| int index = selectedOrganizers.indexOf(object); |
| if (index < selectedOrganizers.size() - 1) { |
| selectedOrganizers.remove(object); |
| selectedOrganizers.add(index + 1, object); |
| } |
| } |
| |
| public Object[] getChildren(Object parentElement) { |
| // A factory's "child" is the next factory in the list |
| int index = selectedOrganizers.indexOf(parentElement); |
| if (index < selectedOrganizers.size() - 1) { |
| return new Object[] { selectedOrganizers.get(index + 1) }; |
| } |
| return new Object[0]; |
| } |
| |
| public Object getParent(Object element) { |
| // A factory's "parent" is the factory before it |
| int index = selectedOrganizers.indexOf(element); |
| if (index <= 0 || selectedOrganizers.size() <= 1) { |
| return null; |
| } |
| return selectedOrganizers.get(index - 1); |
| } |
| |
| public boolean hasChildren(Object element) { |
| // A factory has "children" if there are more |
| // factories after it. |
| int index = selectedOrganizers.indexOf(element); |
| return index != -1 && index < selectedOrganizers.size() - 1; |
| } |
| |
| public Object[] getElements(Object inputElement) { |
| if (selectedOrganizers.size() > 0) { |
| return new Object[] { selectedOrganizers.get(0) }; |
| } |
| return new Object[0]; |
| } |
| public void dispose() { |
| } |
| public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { |
| } |
| } |
| |
| /** |
| * Label provider which provides text and images for breakpoint container factories |
| */ |
| private class BreakpointOrganzierLabelProvider extends LabelProvider { |
| private HashMap fImageCache= new HashMap(); |
| |
| public String getText(Object element) { |
| if (element instanceof IBreakpointOrganizer) { |
| return ((IBreakpointOrganizer) element).getLabel(); |
| } |
| return super.getText(element); |
| } |
| public Image getImage(Object element) { |
| if (element instanceof IBreakpointOrganizer) { |
| ImageDescriptor imageDescriptor = ((IBreakpointOrganizer) element).getImageDescriptor(); |
| if (imageDescriptor != null) { |
| Image image = (Image) fImageCache.get(imageDescriptor); |
| if (image == null) { |
| image= imageDescriptor.createImage(); |
| if (image != null) { |
| fImageCache.put(imageDescriptor, image); |
| } |
| } |
| return image; |
| } |
| } |
| return super.getImage(element); |
| } |
| public void dispose() { |
| Iterator imageIter = fImageCache.values().iterator(); |
| while (imageIter.hasNext()) { |
| ((Image) imageIter.next()).dispose(); |
| } |
| super.dispose(); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) |
| */ |
| protected void configureShell(Shell shell) { |
| super.configureShell(shell); |
| shell.setText(BreakpointGroupMessages.GroupBreakpointsByDialog_7); |
| } |
| } |