Java tutorial
/** * Copyright (c) 2009, 2010 Anyware Technologies 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: * Anyware Technologies - initial API and implementation * Sebastien Moran <SMoran@sierrawireless.com> - bug 308802, 322393 * Jacques Lescot <JLescot@sierrawireless.com> - bug 314677 * * $Id: EmfMasterDetailBlock.java,v 1.25 2010/06/16 17:28:11 bcabe Exp $ */ package org.eclipse.pde.emfforms.editor; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.property.value.IValueProperty; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.edit.ui.dnd.*; import org.eclipse.emf.edit.ui.provider.*; import org.eclipse.jface.action.*; import org.eclipse.jface.databinding.swt.SWTObservables; import org.eclipse.jface.databinding.util.JFaceProperties; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.viewers.*; import org.eclipse.pde.emfforms.editor.actions.RemoveAction; import org.eclipse.pde.emfforms.internal.Activator; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.*; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.*; import org.eclipse.ui.IEditorActionBarContributor; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.FilteredTree; import org.eclipse.ui.dialogs.PatternFilter; import org.eclipse.ui.forms.*; import org.eclipse.ui.forms.widgets.*; public abstract class EmfMasterDetailBlock extends MasterDetailsBlock implements IDetailsPageProvider, IMenuListener { public static final int DEFAULT_SECTION_OPTIONS = Section.DESCRIPTION | ExpandableComposite.TITLE_BAR; public static final int DEFAULT_VIEWER_OPTIONS = SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL; protected EmfFormEditor<?> parentEditor; /** * Style constant to indicate that no generic buttons (neither toolbar nor push) should be displayed */ public static final int NO_BUTTONS = 0; /** * Style constant to indicate whether generic toolbar buttons should be displayed or not */ public static final int USE_GENERIC_TOOLBAR_BUTTONS = 1 << 0; /** * Style constant to indicate whether generic push buttons should be displayed on the * right-hand side of the tree viewer or not */ public static final int USE_GENERIC_PUSH_BUTTONS = 1 << 1; /** * Style constant to indicate whether custom push buttons should be displayed on the * right-hand side of the tree viewer or not. * If the flag is set, the {@link EmfMasterDetailBlock#createCustomButtons(Composite)} will be called. */ public static final int USE_CUSTOM_PUSH_BUTTONS = 1 << 2; /** * Style constant to indicate whether generic "Collapse All" and "Expand All" buttons should be displayed * in the toolbar or not. Note that this style is only relevant when the USE_GENERIC_TOOLBAR_BUTTONS style * is applied too, otherwise it has no effect. A separator is also added before adding those buttons. */ public static final int USE_EXPAND_COLLAPSE_BUTTONS = 1 << 3; protected int buttonOption = USE_GENERIC_TOOLBAR_BUTTONS; private String title; private TreeViewer treeViewer; private Button addButton; private Button removeButton; protected ToolBarManager toolBarManager; private IAction removeAction; private Section section; public EmfMasterDetailBlock(EmfFormEditor<?> editor, String title) { this.title = title; this.parentEditor = editor; } public EmfMasterDetailBlock(EmfFormEditor<?> editor, String title, int buttonOption) { this(editor, title); this.buttonOption = buttonOption; } @Override protected void createMasterPart(final IManagedForm managedForm, Composite parent) { FormToolkit toolkit = parentEditor.getToolkit(); section = toolkit.createSection(parent, getSectionOptions()); section.setText(title); section.setDescription("Edit " + title); //$NON-NLS-1$ section.marginWidth = 5; section.setLayout(new FillLayout()); section.marginHeight = 5; Composite client = toolkit.createComposite(section, SWT.WRAP); GridLayoutFactory.fillDefaults().numColumns(showPushButtons() ? 2 : 1).applyTo(client); // deliberate use of the 3.4 API // TODO try to use the new look using a 3.5 fragment FilteredTree ft = new FilteredTree(client, getViewerOptions(), new PatternFilter()); treeViewer = ft.getViewer(); // Prevent scrollbars to be managed by the editor's root composite GridDataFactory.fillDefaults().grab(true, true).hint(50, 50).applyTo(treeViewer.getTree()); //Buttons if (showPushButtons()) { Composite buttonComposite = new Composite(client, SWT.NONE); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(buttonComposite); if (showGenericPushButtons()) addButton = createButton(buttonComposite, "Add"); //$NON-NLS-1$ if (showCustomPushButtons()) createCustomButtons(buttonComposite); if (showGenericPushButtons()) removeButton = createButton(buttonComposite, "Remove"); //$NON-NLS-1$ GridDataFactory.fillDefaults().grab(false, false).applyTo(buttonComposite); } //SectionToolBar removeAction = createCustomToolbarRemoveAction(); if (showToolbarButtons()) { toolBarManager = PDEFormToolkit.createSectionToolBarManager(section); Action addAction = createCustomToolbarAddAction(); if (addAction != null) { toolBarManager.add(addAction); } if (removeAction != null) { toolBarManager.add(removeAction); } if (showExpandCollapseButtons()) { toolBarManager.add(new Separator()); toolBarManager .add(new Action("Expand All", Activator.getImageDescriptor("icons/obj16/expand.gif")) { //$NON-NLS-1$ //$NON-NLS-2$ @Override public void run() { treeViewer.getTree().setRedraw(false); treeViewer.expandAll(); treeViewer.getTree().setRedraw(true); } }); toolBarManager .add(new Action("Collapse All", Activator.getImageDescriptor("icons/obj16/collapse.gif")) { //$NON-NLS-1$ //$NON-NLS-2$ @Override public void run() { treeViewer.getTree().setRedraw(false); treeViewer.collapseAll(); treeViewer.getTree().setRedraw(true); } }); } toolBarManager.update(true); section.setTextClient(toolBarManager.getControl()); } treeViewer.setContentProvider(new AdapterFactoryContentProvider(parentEditor.getAdapterFactory())); treeViewer.setLabelProvider( new DecoratingLabelProvider(new AdapterFactoryLabelProvider(parentEditor.getAdapterFactory()), PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator())); treeViewer.addFilter(getTreeFilter()); int dndOperations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; Transfer[] transfers = new Transfer[] { LocalTransfer.getInstance() }; treeViewer.addDragSupport(dndOperations, transfers, new ViewerDragAdapter(treeViewer)); treeViewer.addDropSupport(dndOperations, transfers, new EditingDomainViewerDropAdapter(parentEditor.getEditingDomain(), treeViewer)); final SectionPart spart = new SectionPart(section); managedForm.addPart(spart); treeViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { managedForm.fireSelectionChanged(spart, event.getSelection()); } }); treeViewer.addOpenListener(new IOpenListener() { public void open(OpenEvent event) { detailsPart.setFocus(); } }); // Add listeners to manage activation/deactivation of the treeViewer's // ActionBarContributor's global handlers configureActionBarManagement(); if (getRemoveButton() != null) { DataBindingContext bindingContext = new DataBindingContext(); IValueProperty p = JFaceProperties.value(IAction.class, IAction.ENABLED, IAction.ENABLED); bindingContext.bindValue(SWTObservables.observeEnabled(getRemoveButton()), p.observe(removeAction)); //Generic action for remove button getRemoveButton().addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { if (removeAction != null) removeAction.run(); } }); } createContextMenuFor(treeViewer); //update Editor selection getEditor().addViewerToListenTo(getTreeViewer()); section.setClient(client); } protected int getSectionOptions() { return DEFAULT_SECTION_OPTIONS; } /** * Default styles : SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL * * @return int, style used to create the TreeViewer */ protected int getViewerOptions() { return DEFAULT_VIEWER_OPTIONS; } /** * Add listeners to manage activation/deactivation of the treeViewer's * ActionBarContributor's global handlers */ protected void configureActionBarManagement() { final IEditorActionBarContributor actionBarContributor = getEditor().getEditorSite() .getActionBarContributor(); if (actionBarContributor != null && actionBarContributor instanceof EmfActionBarContributor) { treeViewer.getControl().addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { ((EmfActionBarContributor) actionBarContributor).enableGlobalHandlers(); } @Override public void focusLost(FocusEvent e) { ((EmfActionBarContributor) actionBarContributor).disableGlobalHandlers(); } }); } } private boolean showPushButtons() { return showCustomPushButtons() || showGenericPushButtons(); } private boolean showCustomPushButtons() { return ((buttonOption & USE_CUSTOM_PUSH_BUTTONS) > 0); } private boolean showGenericPushButtons() { return ((buttonOption & USE_GENERIC_PUSH_BUTTONS) > 0); } private boolean showToolbarButtons() { return (buttonOption & USE_GENERIC_TOOLBAR_BUTTONS) > 0; } private boolean showExpandCollapseButtons() { return showToolbarButtons() && (buttonOption & USE_EXPAND_COLLAPSE_BUTTONS) > 0; } protected Action createCustomToolbarAddAction() { // Subclass may override this method return null; } /** * Create the Action to be performed when a deletion should be performed. * Default implementation create a {@link RemoveAction} that delegates the job to the DELETE action * registered through the {@link EmfActionBarContributor} of the current {@link EmfFormEditor} * Subclasses may override this method in order to provide their own Action * @return Action the delete action to perform */ protected Action createCustomToolbarRemoveAction() { return new RemoveAction(this); } protected Button createButton(Composite parent, String btnText) { Button btn = new Button(parent, SWT.FLAT | SWT.PUSH); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.BEGINNING).grab(true, false).applyTo(btn); btn.setText(btnText); return btn; } /** * Return a ViewerFilter to apply on the treeViewer * * @return a ViewerFilter to apply on the treeViewer */ protected ViewerFilter getTreeFilter() { return new ViewerFilter() { @Override public boolean select(Viewer viewer, Object parentElement, Object element) { return true; } }; } @Override protected void createToolBarActions(IManagedForm managedForm) { // TODO Auto-generated method stub } @Override protected void registerPages(DetailsPart detailsPart) { detailsPart.setPageProvider(this); } public Object getPageKey(Object object) { return AdapterFactoryEditingDomain.unwrap(object).getClass(); } public TreeViewer getTreeViewer() { return treeViewer; } /** * @return The "Add..." button that can be used to hook an element creation wizard, or <code>null</code> if the {@link EmfMasterDetailBlock#useGenericButton} flag is set to <code>false</code> */ public Button getGenericAddButton() { return addButton; } protected void createCustomButtons(Composite parent) { // Should be overriden by clients wanting to contribute their own "add" button(s) } public Button getRemoveButton() { return removeButton; } public void setAddButton(Button addButton) { this.addButton = addButton; } public void setRemoveButton(Button removeButton) { this.removeButton = removeButton; } protected void createContextMenuFor(StructuredViewer viewer) { MenuManager contextMenu = new MenuManager("#PopUp"); //$NON-NLS-1$ contextMenu.add(new Separator("additions")); //$NON-NLS-1$ contextMenu.setRemoveAllWhenShown(true); contextMenu.addMenuListener(this); Menu menu = contextMenu.createContextMenu(viewer.getControl()); viewer.getControl().setMenu(menu); IEditorActionBarContributor actionBarContributor = parentEditor.getEditorSite().getActionBarContributor(); if (actionBarContributor != null && actionBarContributor instanceof EmfActionBarContributor) { ((EmfActionBarContributor) actionBarContributor) .setCreateChildMenuFilter(getCreateChildContextMenuFilter()); ((EmfActionBarContributor) actionBarContributor) .setCreateSiblingMenuFilter(getCreateSiblingContextMenuFilter()); } parentEditor.getSite().registerContextMenu(contextMenu, new UnwrappingSelectionProvider(viewer)); } /** * TODO doc */ protected IFilter getCreateChildContextMenuFilter() { return AcceptAllFilter.getInstance(); } /** * TODO doc */ protected IFilter getCreateSiblingContextMenuFilter() { return AcceptAllFilter.getInstance(); } public void menuAboutToShow(IMenuManager manager) { if (parentEditor.getEditorSite().getActionBarContributor() != null) ((IMenuListener) parentEditor.getEditorSite().getActionBarContributor()).menuAboutToShow(manager); } public EmfFormEditor<?> getEditor() { return parentEditor; } public void setButtonOption(int buttonOption) { this.buttonOption = buttonOption; } }