| /******************************************************************************* |
| * Copyright (c) 2010 SAP AG. |
| * 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: |
| * Emil Simeonov - initial API and implementation. |
| * Dimitar Donchev - initial API and implementation. |
| * Dimitar Tenev - initial API and implementation. |
| * Nevena Manova - initial API and implementation. |
| * Georgi Konstantinov - initial API and implementation. |
| *******************************************************************************/ |
| package org.eclipse.wst.sse.sieditor.ui.v2; |
| |
| import org.eclipse.jface.resource.ImageRegistry; |
| import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; |
| import org.eclipse.jface.viewers.DoubleClickEvent; |
| import org.eclipse.jface.viewers.IDoubleClickListener; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.dnd.DND; |
| import org.eclipse.swt.dnd.Transfer; |
| import org.eclipse.swt.events.KeyAdapter; |
| import org.eclipse.swt.events.KeyEvent; |
| 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.ToolBar; |
| import org.eclipse.ui.dialogs.FilteredTree; |
| import org.eclipse.ui.dialogs.PatternFilter; |
| import org.eclipse.ui.forms.DetailsPart; |
| import org.eclipse.ui.forms.IDetailsPage; |
| import org.eclipse.ui.forms.IDetailsPageProvider; |
| import org.eclipse.ui.forms.IManagedForm; |
| import org.eclipse.ui.forms.MasterDetailsBlock; |
| import org.eclipse.ui.forms.SectionPart; |
| import org.eclipse.ui.forms.widgets.FormToolkit; |
| import org.eclipse.ui.forms.widgets.Section; |
| import org.eclipse.wst.sse.sieditor.model.api.IChangeListener; |
| import org.eclipse.wst.sse.sieditor.model.api.IModelChangeEvent; |
| import org.eclipse.wst.sse.sieditor.ui.Activator; |
| import org.eclipse.wst.sse.sieditor.ui.v2.dt.dnd.SiEditorTransfer; |
| import org.eclipse.wst.sse.sieditor.ui.v2.dt.dnd.TreeViewerDragAdapter; |
| import org.eclipse.wst.sse.sieditor.ui.v2.dt.dnd.TreeViewerDropAdapter; |
| |
| public abstract class AbstractMasterDetailsBlock extends MasterDetailsBlock implements IChangeListener { |
| |
| private ImageRegistry imageRegistry; |
| |
| protected static final int BUTTONS_WIDTH = 100; |
| |
| protected Section masterSection; |
| |
| protected SectionPart masterSectionPart; |
| |
| protected TreeViewer treeViewer; |
| |
| protected AbstractFormPageController controller; |
| |
| protected ToolBar titleToolbar; |
| |
| @Override |
| public void createContent(final IManagedForm managedForm) { |
| super.createContent(managedForm); |
| detailsPart.setPageProvider(createDetailsPageProvider()); |
| } |
| |
| @Override |
| protected void createMasterPart(final IManagedForm managedForm, final Composite parent) { |
| final FormToolkit toolkit = managedForm.getToolkit(); |
| |
| masterSectionPart = new SectionPart(parent, toolkit, Section.TITLE_BAR | Section.EXPANDED); |
| managedForm.addPart(masterSectionPart); |
| masterSection = masterSectionPart.getSection(); |
| |
| masterSection.setExpanded(true); |
| masterSection.marginWidth = 5; |
| masterSection.marginHeight = 5; |
| |
| masterSection.setTextClient(titleToolbar); |
| |
| // content of the section |
| final Composite masterClientComposite = toolkit.createComposite(masterSection); |
| masterSection.setLayout(new GridLayout(1, false)); |
| masterSection.setClient(masterClientComposite); |
| |
| createMasterSectionControlls(toolkit, masterClientComposite); |
| |
| toolkit.paintBordersFor(masterClientComposite); |
| |
| ColumnViewerToolTipSupport.enableFor(treeViewer); |
| treeViewer.addSelectionChangedListener(new TreeViewerSelectionListener(masterSectionPart, managedForm)); |
| treeViewer.addDoubleClickListener(new IDoubleClickListener() { |
| @Override |
| public void doubleClick(DoubleClickEvent event) { |
| final IStructuredSelection selection = (IStructuredSelection) event.getSelection(); |
| handleDoubleClickEvent(selection); |
| updateButtonsState(selection); |
| } |
| |
| }); |
| } |
| |
| @Override |
| public void componentChanged(IModelChangeEvent event) { |
| refreshTreeViewer(); |
| if (detailsPart != null) { |
| detailsPart.refresh(); |
| } |
| updateButtonsState((IStructuredSelection) treeViewer.getSelection()); |
| |
| } |
| |
| protected ImageRegistry getImageRegistry() { |
| if (imageRegistry == null) { |
| imageRegistry = Activator.getDefault().getImageRegistry(); |
| } |
| return imageRegistry; |
| } |
| |
| private void createMasterSectionControlls(final FormToolkit toolkit, final Composite masterClientComposite) { |
| |
| final FilteredTree filteredTree = new FilteredTree(masterClientComposite, SWT.BORDER | SWT.MULTI, new PatternFilter(), |
| true); |
| treeViewer = filteredTree.getViewer(); |
| addDragAdapterToTreeViewer(); |
| addDropAdapterToTreeViewer(); |
| final Composite buttonsComposite = toolkit.createComposite(masterClientComposite); |
| createButtons(toolkit, buttonsComposite); |
| |
| final GridLayout gridLayout = new GridLayout(); |
| gridLayout.makeColumnsEqualWidth = false; |
| |
| masterClientComposite.setLayout(gridLayout); |
| if (buttonsComposite.getChildren().length == 0) { |
| gridLayout.numColumns = 1; |
| } else { |
| gridLayout.numColumns = 2; |
| final GridData gridData = new GridData(); |
| final int width = buttonsComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; |
| gridData.minimumWidth = width; |
| gridData.grabExcessHorizontalSpace = false; |
| gridData.widthHint = width; |
| final int horisontalSpacingFilter = ((GridLayout) filteredTree.getLayout()).horizontalSpacing; |
| final int horisontalSpacingParent = ((GridLayout) masterClientComposite.getLayout()).horizontalSpacing; |
| final int textFieldHeight = ((Composite) filteredTree.getChildren()[0]).getChildren()[0].computeSize(SWT.DEFAULT, |
| SWT.DEFAULT).y + horisontalSpacingFilter + horisontalSpacingParent; |
| gridData.verticalIndent = textFieldHeight; |
| gridData.verticalAlignment = SWT.TOP; |
| buttonsComposite.setLayoutData(gridData); |
| } |
| final GridData gridData = new GridData(); |
| gridData.grabExcessHorizontalSpace = true; |
| gridData.grabExcessVerticalSpace = true; |
| gridData.horizontalAlignment = SWT.FILL; |
| gridData.verticalAlignment = SWT.FILL; |
| |
| // constraint tree |
| gridData.widthHint = 100; |
| gridData.heightHint = 20; |
| |
| filteredTree.setLayoutData(gridData); |
| } |
| |
| private void addDragAdapterToTreeViewer() { |
| int ops = DND.DROP_COPY | DND.DROP_MOVE; |
| Transfer[] transfers = new Transfer[] { SiEditorTransfer.getInstance() }; |
| treeViewer.addDragSupport(ops, transfers, new TreeViewerDragAdapter(treeViewer)); |
| } |
| |
| private void addDropAdapterToTreeViewer() { |
| int ops = DND.DROP_COPY | DND.DROP_MOVE; |
| Transfer[] transfers = new Transfer[] { SiEditorTransfer.getInstance() }; |
| treeViewer.addDropSupport(ops, transfers, new TreeViewerDropAdapter(treeViewer, controller)); |
| } |
| |
| protected abstract void createButtons(FormToolkit toolkit, Composite buttonsComposite); |
| |
| protected abstract IDetailsPageProvider createDetailsPageProvider(); |
| |
| protected abstract void updateButtonsState(final IStructuredSelection structSelection); |
| |
| @Override |
| protected void createToolBarActions(final IManagedForm managedForm) { |
| // this method adds buttons to the bar containing the editor form's |
| // title. thus it is not to be used - no such |
| // buttons exist in the design |
| } |
| |
| public void setController(final AbstractFormPageController controller) { |
| this.controller = controller; |
| } |
| |
| public AbstractFormPageController getController() { |
| return controller; |
| } |
| |
| @Override |
| protected void registerPages(final DetailsPart detailsPart) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| /** |
| * used to set the tree input by the editorPart |
| * |
| * @return the tree viewer of the tree representing the service interface |
| */ |
| public TreeViewer getTreeViewer() { |
| return treeViewer; |
| } |
| |
| /** |
| * Used to handle doubleClick events in SIE and DTE |
| * |
| * @param selection |
| * is the current selected item in the treeViewer |
| */ |
| private void handleDoubleClickEvent(IStructuredSelection selection) { |
| if (!selection.isEmpty()) { |
| Object firstElement = selection.getFirstElement(); |
| if (treeViewer.getExpandedState(firstElement)) { |
| treeViewer.collapseToLevel(firstElement, 1); |
| } else { |
| treeViewer.expandToLevel(firstElement, 1); |
| } |
| |
| } |
| } |
| |
| /** |
| * used to refresh the treeViewer |
| */ |
| public void refreshTreeViewer() { |
| Object[] expandedTreeItems = treeViewer.getExpandedElements(); |
| treeViewer.refresh(); |
| treeViewer.setExpandedElements(expandedTreeItems); |
| } |
| |
| /** |
| * Sets the focus to the current detail page. It's up to the page to decide |
| * if and how (on which section and widget) to set it. |
| */ |
| public void setDetailsPartFocus() { |
| IDetailsPage currentPage = detailsPart.getCurrentPage(); |
| if (currentPage != null) { |
| currentPage.setFocus(); |
| } |
| } |
| |
| /** |
| * utility method. returns new {@link KeyAdapter} implementation for the |
| * SIE/DTE tree |
| * |
| * @return the created key adapter |
| */ |
| protected KeyAdapter createKeyListener() { |
| return new KeyAdapter() { |
| @Override |
| public void keyPressed(final KeyEvent e) { |
| if (shouldProcessRemoveAction(e)) { |
| removePressed(); |
| } |
| } |
| }; |
| } |
| |
| /** |
| * utility method. checks if the remove action should be executed |
| * |
| * @param e |
| * - the key event that triggered the action |
| * @return <code>true</code> if the remove action is to be executed. |
| * <code>false</code> otherwise |
| */ |
| protected boolean shouldProcessRemoveAction(final KeyEvent e) { |
| return e.keyCode == SWT.DEL && getRemoveButton().isEnabled(); |
| } |
| |
| protected abstract void removePressed(); |
| |
| protected abstract Button getRemoveButton(); |
| |
| public static class TreeViewerSelectionListener implements ISelectionChangedListener { |
| |
| private final SectionPart masterSectionPart; |
| private final IManagedForm managedForm; |
| |
| public TreeViewerSelectionListener(SectionPart masterSectionPart, IManagedForm managedForm) { |
| this.masterSectionPart = masterSectionPart; |
| this.managedForm = managedForm; |
| } |
| |
| @Override |
| public void selectionChanged(final SelectionChangedEvent event) { |
| // This way informs the details part for the node change |
| ISelection selection = event.getSelection(); |
| if (((IStructuredSelection) selection).size() > 1) { |
| // don't show any details in case of multiple selection |
| selection = null; |
| } |
| managedForm.fireSelectionChanged(masterSectionPart, selection); |
| } |
| } |
| } |