/******************************************************************************* * Copyright (c) 2012, 2016, 2017 PDT Extension Group 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: * PDT Extension Group - initial API and implementation * Kaloyan Raev - [501269] externalize strings *******************************************************************************/ package org.eclipse.php.composer.ui.editor.composer; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IResource; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.*; import org.eclipse.osgi.util.NLS; import org.eclipse.php.composer.api.collection.Psr; import org.eclipse.php.composer.api.objects.Namespace; import org.eclipse.php.composer.ui.controller.PsrController; import org.eclipse.php.composer.ui.dialogs.PsrDialog; import org.eclipse.php.composer.ui.editor.ComposerFormPage; import org.eclipse.php.composer.ui.editor.FormLayoutFactory; import org.eclipse.php.composer.ui.editor.TreeSection; import org.eclipse.php.composer.ui.parts.TreePart; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.dnd.TransferData; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Section; import org.eclipse.ui.part.ResourceTransfer; public abstract class PsrSection extends TreeSection implements PropertyChangeListener { protected TreeViewer psrViewer; private IAction addAction; private IAction editAction; private IAction removeAction; private static final int ADD_INDEX = 0; private static final int EDIT_INDEX = 1; private static final int REMOVE_INDEX = 2; protected Psr psr = null; public PsrSection(ComposerFormPage page, Composite parent) { super(page, parent, Section.DESCRIPTION, new String[] { Messages.PsrSection_AddButton, Messages.PsrSection_EditButton, Messages.PsrSection_RemoveButton }); psr = getPsr(); createClient(getSection(), page.getManagedForm().getToolkit()); } abstract protected Psr getPsr(); abstract protected String getPsrName(); @Override protected void createClient(Section section, FormToolkit toolkit) { String name = getPsrName(); section.setText(name); section.setDescription(NLS.bind(Messages.PsrSection_Description, name)); section.setLayout(FormLayoutFactory.createClearGridLayout(false, 1)); GridData gd = new GridData(GridData.FILL_BOTH); gd.grabExcessVerticalSpace = true; section.setLayoutData(gd); Composite container = createClientContainer(section, 2, toolkit); createViewerPartControl(container, SWT.SINGLE, 2, toolkit); TreePart treePart = getTreePart(); PsrController controller = new PsrController(treePart.getTreeViewer()); psrViewer = treePart.getTreeViewer(); psrViewer.setContentProvider(controller); psrViewer.setLabelProvider(controller); Transfer[] transferTypes = new Transfer[] { ResourceTransfer.getInstance() }; int types = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK | DND.DROP_DEFAULT; psrViewer.addDropSupport(types, transferTypes, new PathDropAdapter(psrViewer)); toolkit.paintBordersFor(container); section.setClient(container); section.setLayout(FormLayoutFactory.createClearGridLayout(false, 1)); psrViewer.setInput(psr); composerPackage.getAutoload().addPropertyChangeListener(this); updateButtons(); makeActions(); updateMenu(); } private void updateButtons() { ISelection selection = psrViewer.getSelection(); TreePart treePart = getTreePart(); treePart.setButtonEnabled(ADD_INDEX, enabled); treePart.setButtonEnabled(EDIT_INDEX, !selection.isEmpty() && enabled); treePart.setButtonEnabled(REMOVE_INDEX, !selection.isEmpty() && enabled); } private void updateMenu() { IStructuredSelection selection = (IStructuredSelection) psrViewer.getSelection(); editAction.setEnabled(selection.size() > 0); removeAction.setEnabled(selection.size() > 0); } @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); updateButtons(); refresh(); psrViewer.getTree().setEnabled(enabled); } public void refresh() { psrViewer.refresh(); } @Override public void propertyChange(PropertyChangeEvent e) { if (e.getPropertyName().startsWith(getPsrName())) { refresh(); } } protected void selectionChanged(IStructuredSelection sel) { updateButtons(); updateMenu(); } private void makeActions() { addAction = new Action(Messages.PsrSection_AddActionTitle) { @Override public void run() { handleAdd(); } }; editAction = new Action(Messages.PsrSection_EditActionTitle) { @Override public void run() { handleEdit(); } }; removeAction = new Action(Messages.PsrSection_RemoveActionTitle) { @Override public void run() { handleRemove(); } }; } @Override protected void fillContextMenu(IMenuManager manager) { manager.add(addAction); manager.add(editAction); manager.add(removeAction); } private void handleAdd() { PsrDialog dialog = new PsrDialog(psrViewer.getTree().getShell(), new Namespace(), getPage().getComposerEditor().getProject()); if (dialog.open() == Dialog.OK) { psr.add(dialog.getNamespace()); } } private void handleEdit() { Namespace namespace = null; Object element = ((StructuredSelection) psrViewer.getSelection()).getFirstElement(); // get parent if element is string if (element instanceof String) { element = ((PsrController) psrViewer.getContentProvider()).getParent(element); } if (element instanceof Namespace) { namespace = (Namespace) element; } if (namespace != null) { PsrDialog diag = new PsrDialog(psrViewer.getTree().getShell(), namespace.clone(), getPage().getComposerEditor().getProject()); if (diag.open() == Dialog.OK) { Namespace nmspc = psr.get(namespace.getNamespace()); if (nmspc.equals(diag.getNamespace())) { // nothing changed return; } if (!nmspc.getNamespace().equals(diag.getNamespace().getNamespace())) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=507543 // We cannot simply do // "nmspc.setNamespace(diag.getNamespace().getNamespace());" // since namespace name nmspc.getNamespace() is used as key // in map psr.properties // We do remove&add to properly update psr.properties keys psr.remove(nmspc); psr.add(diag.getNamespace()); } else { nmspc.clear(); nmspc.addPaths(diag.getNamespace().getPaths()); } } } } private void handleRemove() { Object element = ((StructuredSelection) psrViewer.getSelection()).getFirstElement(); if (element instanceof Namespace) { psr.remove((Namespace) element); } else if (element instanceof String) { Namespace namespace = (Namespace) ((PsrController) psrViewer.getContentProvider()).getParent(element); if (namespace != null) { namespace.remove((String) element); } } } @Override protected void buttonSelected(int index) { switch (index) { case ADD_INDEX: handleAdd(); break; case EDIT_INDEX: handleEdit(); break; case REMOVE_INDEX: handleRemove(); break; } } private class PathDropAdapter extends ViewerDropAdapter { private Namespace target; public PathDropAdapter(Viewer viewer) { super(viewer); } @Override public boolean performDrop(Object data) { if (data instanceof IResource[]) { IResource[] resources = (IResource[]) data; List<IFolder> folders = new ArrayList<IFolder>(); for (IResource resource : resources) { if (resource instanceof IFolder) { folders.add((IFolder) resource); } } for (IFolder folder : folders) { target.add(folder.getProjectRelativePath().toString()); } return false; } return false; } @Override public boolean validateDrop(Object target, int operation, TransferData transferType) { if (target instanceof Namespace) { this.target = (Namespace) target; return true; } return false; } } }