com.aptana.editor.php.internal.ui.preferences.BuildPathEditingComposite.java Source code

Java tutorial

Introduction

Here is the source code for com.aptana.editor.php.internal.ui.preferences.BuildPathEditingComposite.java

Source

/**
 * Aptana Studio
 * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions).
 * Please see the license.html included with this distribution for details.
 * Any modifications to this file must keep this entire header intact.
 */
package com.aptana.editor.php.internal.ui.preferences;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.DialogPage;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
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.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PropertyPage;
import org.eclipse.ui.progress.UIJob;

import com.aptana.editor.php.internal.builder.IPHPLibrary;
import com.aptana.editor.php.internal.builder.LibraryManager;
import com.aptana.editor.php.internal.builder.preferences.ProjectDependencies;

/**
 * Composite for editing PHP project build path.
 * 
 * @author Pavel Petrochenko
 * @author Denis Denisenko
 */
public class BuildPathEditingComposite extends Composite {
    private TableViewer workspaceViewer;
    private TableViewer directoryViewer;
    private CheckboxTableViewer libraryViewer;

    private boolean usesCustomLibs;

    private Set<String> notusedLibraries = new HashSet<String>();
    private Button customLibsButton;
    private Button select;
    private Button deselect;
    private IProject project;
    private final PropertyPage propertyPage;

    /**
     * Constructs a new BuildPathEditingComposite
     * 
     * @param propertyPage
     *            The {@link PropertyPage} that contains this composite.
     * @param parent
     * @param style
     */
    public BuildPathEditingComposite(PropertyPage propertyPage, Composite parent, int style) {
        super(parent, style);
        Assert.isNotNull(propertyPage, "PropertyPage was null"); //$NON-NLS-1$
        this.propertyPage = propertyPage;
        this.project = (IProject) propertyPage.getElement().getAdapter(IProject.class);
        this.setLayout(new FillLayout());
        TabFolder fld = new TabFolder(this, SWT.LEFT);
        TabItem item = new TabItem(fld, SWT.NONE);
        item.setText(Messages.BuildPathEditingComposite_ProjectsTabTitle);
        createWorkspacePart(item);
        TabItem item1 = new TabItem(fld, SWT.NONE);
        item1.setText(Messages.BuildPathEditingComposite_DirectoriesTabTitle);
        TabItem item2 = new TabItem(fld, SWT.NONE);
        item2.setText(Messages.BuildPathEditingComposite_libraries);
        createDirectoryPart(item1);
        createLibraryPart(item2);
    }

    private void createLibraryPart(TabItem item) {
        TabFolder parent2 = item.getParent();
        Composite projectPart = new Composite(parent2, SWT.NONE);
        projectPart.setLayout(new GridLayout(2, false));
        customLibsButton = new Button(projectPart, SWT.CHECK);
        GridData layoutData = new GridData(GridData.FILL_HORIZONTAL);
        layoutData.horizontalSpan = 2;
        customLibsButton.setLayoutData(layoutData);
        customLibsButton.setText(Messages.BuildPathEditingComposite_projectSpecific);
        libraryViewer = CheckboxTableViewer.newCheckList(projectPart, SWT.BORDER);
        libraryViewer.setContentProvider(new ArrayContentProvider());
        IPHPLibrary[] allLibraries = LibraryManager.getInstance().getAllLibraries();
        libraryViewer.setInput(allLibraries);
        libraryViewer.setComparator(new ViewerComparator());
        final Map<URL, Image> images = new HashMap<URL, Image>();
        libraryViewer.setLabelProvider(new LibraryLabelProvider(images));
        final Composite buttons = new Composite(projectPart, SWT.NONE);
        projectPart.addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
                for (Image m : images.values()) {
                    m.dispose();
                }
            }
        });
        libraryViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
        GridLayout layout = new GridLayout(1, false);
        layout.marginHeight = 0;
        buttons.setLayout(layout);
        select = new Button(buttons, SWT.NONE);
        select.setText(Messages.LibrariesPage_selectAll);
        select.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        deselect = new Button(buttons, SWT.NONE);
        deselect.setText(Messages.LibrariesPage_deselectAll);
        deselect.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        buttons.setLayoutData(new GridData(GridData.FILL_VERTICAL));
        customLibsButton.addSelectionListener(new SelectionListener() {
            public void widgetDefaultSelected(SelectionEvent e) {
            }

            public void widgetSelected(SelectionEvent e) {
                boolean selection = customLibsButton.getSelection();
                libraryViewer.getControl().setEnabled(selection);
                select.setEnabled(selection);
                deselect.setEnabled(selection);
            }
        });
        select.addSelectionListener(new SelectAction(true));
        deselect.addSelectionListener(new SelectAction(false));
        item.setControl(projectPart);

    }

    private void createDirectoryPart(TabItem item) {
        TabFolder parent2 = item.getParent();
        Composite projectPart = new Composite(parent2, SWT.NONE);
        projectPart.setLayout(new GridLayout(2, false));
        directoryViewer = new TableViewer(projectPart, SWT.BORDER | SWT.MULTI);
        directoryViewer.setLabelProvider(new LabelProvider() {

            @Override
            public Image getImage(Object element) {
                return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
            }

            @Override
            public String getText(Object element) {
                File fl = (File) element;
                return fl.getAbsolutePath();
            }

        });
        directoryViewer.setContentProvider(new ArrayContentProvider());
        directoryViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
        Composite buttonsComp = new Composite(projectPart, SWT.NONE);
        buttonsComp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
        buttonsComp.setLayout(new GridLayout(1, false));
        Button add = new Button(buttonsComp, SWT.NONE);
        add.setText(Messages.BuildPathEditingComposite_AddDirectory);
        add.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                DirectoryDialog dialog = new DirectoryDialog(Display.getCurrent().getActiveShell(), SWT.NONE);
                dialog.setText(Messages.BuildPathEditingComposite_AddDirectoryDescription);
                String open = dialog.open();
                if (open != null) {
                    addWithValidation(directoryViewer, new File(open));
                }
            }
        });
        add.setLayoutData(GridDataFactory.fillDefaults().hint(100, -1).create());
        final Button remove = new Button(buttonsComp, SWT.NONE);
        remove.setText(Messages.BuildPathEditingComposite_RemoveDirectory);
        remove.setLayoutData(GridDataFactory.fillDefaults().hint(100, -1).create());
        directoryViewer.addSelectionChangedListener(new ISelectionChangedListener() {

            public void selectionChanged(SelectionChangedEvent event) {
                remove.setEnabled(!event.getSelection().isEmpty());
            }

        });
        remove.setEnabled(false);
        remove.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                IStructuredSelection sel = (IStructuredSelection) directoryViewer.getSelection();
                Object[] selections = sel.toArray();
                for (Object selected : selections) {
                    directoryViewer.remove(selected);
                }
            }
        });
        directoryViewer.setSorter(new ViewerSorter());
        item.setControl(projectPart);
    }

    private void createWorkspacePart(TabItem item) {
        TabFolder parent2 = item.getParent();
        Composite projectPart = new Composite(parent2, SWT.NONE);
        item.setControl(projectPart);
        projectPart.setLayout(new GridLayout(2, false));
        workspaceViewer = new TableViewer(projectPart, SWT.BORDER | SWT.MULTI);
        final FullPathWorkbenchLabelProvider workbenchLabelProvider = new FullPathWorkbenchLabelProvider(project);
        workspaceViewer.setLabelProvider(workbenchLabelProvider);
        workspaceViewer.getControl().addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
                workbenchLabelProvider.doDispose();
            }
        });
        workspaceViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
        workspaceViewer.setContentProvider(new ArrayContentProvider());
        Composite buttonsComp = new Composite(projectPart, SWT.NONE);
        buttonsComp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
        buttonsComp.setLayout(new GridLayout(1, false));
        Button add = new Button(buttonsComp, SWT.NONE);
        add.setText(Messages.BuildPathEditingComposite_AddProjectTitle);
        add.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                WorkspaceFolderSelectionDialog dialog = new WorkspaceFolderSelectionDialog(
                        Display.getCurrent().getActiveShell());
                dialog.setTitle(Messages.BuildPathEditingComposite_ProjectsSelectionTitle);
                dialog.setMessage(Messages.BuildPathEditingComposite_AddProjectDesription);
                IWorkspace workspace = ResourcesPlugin.getWorkspace();
                dialog.setInput(workspace);

                // filtering out current project and its contents
                dialog.addFilter(new ViewerFilter() {

                    @Override
                    public boolean select(Viewer viewer, Object parentElement, Object element) {
                        if (element instanceof IResource) {
                            if (project.equals(((IResource) element).getProject())) {
                                return false;
                            }
                        }

                        return true;
                    }

                });
                if (dialog.open() == Dialog.OK) {
                    addWithValidation(workspaceViewer, dialog.getResult());
                }
            }
        });
        add.setLayoutData(GridDataFactory.fillDefaults().hint(100, -1).create());
        final Button remove = new Button(buttonsComp, SWT.NONE);
        remove.setText(Messages.BuildPathEditingComposite_RemoveProjectTitle);
        remove.setEnabled(false);
        workspaceViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                if (project != null) {
                    // Do not allow removal in case the default project is selected
                    remove.setEnabled(!event.getSelection().isEmpty()
                            && !((IStructuredSelection) event.getSelection()).toList().contains(project));
                } else {
                    remove.setEnabled(!event.getSelection().isEmpty());
                }
            }
        });
        remove.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                IStructuredSelection sel = (IStructuredSelection) workspaceViewer.getSelection();
                Object[] selections = sel.toArray();
                for (Object selected : selections) {
                    workspaceViewer.remove(selected);
                }
            }
        });
        remove.setLayoutData(GridDataFactory.fillDefaults().hint(100, -1).create());
        workspaceViewer.setSorter(new ViewerSorter());
    }

    /**
     * Initializes composite.
     * 
     * @param workspaceResources
     *            - workspace resources.
     * @param directories
     *            - external directories.
     */
    public void init(List<IResource> workspaceResources, List<File> directories) {
        if (project != null && !workspaceResources.contains(project)) {
            workspaceResources.add(0, project);
        }
        workspaceViewer.setInput(workspaceResources.toArray());
        directoryViewer.setInput(directories.toArray());
    }

    /**
     * Add an item to the table viewer after verifying that the path of that item does not exist or is not containing
     * the path for this item.
     * 
     * @param tableViewer
     * @param item
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    private void addWithValidation(TableViewer tableViewer, Object item) {
        propertyPage.setMessage(null);
        TableItem[] tableItems = tableViewer.getTable().getItems();
        if (tableItems == null || tableItems.length == 0) {
            // Just add
            if (item instanceof Object[]) {
                Object[] items = (Object[]) item;
                for (Object obj : items) {
                    tableViewer.add(obj);
                    return;
                }
            } else {
                if (item != null) {
                    tableViewer.add(item);
                    return;
                }
            }
        }
        List toAdd = new ArrayList();
        boolean hasAlreadyIncludedPaths = false;
        if (item instanceof File) {
            File directoryAdded = (File) item;
            // Check for files that are already in the table.
            boolean shouldAdd = true;
            for (TableItem tableItem : tableItems) {
                Object data = tableItem.getData();
                if (data instanceof File) {
                    File existinsDirectory = (File) data;
                    if (existinsDirectory.equals(directoryAdded)
                            || directoryAdded.getAbsolutePath().startsWith(existinsDirectory.getAbsolutePath())) {
                        hasAlreadyIncludedPaths = true;
                        shouldAdd = false;
                        break;
                    }
                }
            }
            if (shouldAdd) {
                toAdd.add(directoryAdded);
            }
        } else if (item instanceof Object[]) {
            Object[] elements = (Object[]) item;

            for (Object element : elements) {
                boolean shouldAdd = true;
                for (TableItem tableItem : tableItems) {
                    if (element instanceof IResource && tableItem.getData() instanceof IResource) {
                        IResource resource = (IResource) element;
                        IResource resourceInTable = (IResource) tableItem.getData();
                        if ((resourceInTable).getFullPath().isPrefixOf(resource.getFullPath())) {
                            hasAlreadyIncludedPaths = true;
                            shouldAdd = false;
                            break;
                        }
                    }
                }
                if (shouldAdd) {
                    toAdd.add(element);
                }
            }
        }
        tableViewer.add(toAdd.toArray());
        if (hasAlreadyIncludedPaths) {
            propertyPage.setMessage(Messages.BuildPathEditingComposite_selectionIncludedNotice,
                    DialogPage.INFORMATION);
            Job job = new UIJob("Build-Path::Remove message") //$NON-NLS-1$
            {
                public IStatus runInUIThread(IProgressMonitor monitor) {
                    if (propertyPage != null && !propertyPage.getControl().isDisposed()) {
                        propertyPage.setMessage(null);
                    }
                    return Status.OK_STATUS;
                }
            };
            job.schedule(4000); // wait 4 seconds before removing the message
        }
    }

    /**
     * Fills composite result.
     * 
     * @param workspaceResources
     *            - workspace resource to fill.
     * @param fileList
     *            - external folders to fill.
     */
    public void fillResult(List<IResource> workspaceResources, List<File> fileList) {
        TableItem[] items = workspaceViewer.getTable().getItems();
        for (TableItem i : items) {
            IResource resource = (IResource) i.getData();
            if (resource != project) {
                workspaceResources.add(resource);
            }
        }
        items = directoryViewer.getTable().getItems();
        for (TableItem i : items) {
            fileList.add((File) i.getData());
        }
    }

    public void init(ProjectDependencies buildPath) {
        init(buildPath.getWorkspaceResources(), buildPath.getDirectories());
        usesCustomLibs = buildPath.isUsesCustomLibs();
        List<String> notUsedLibrariesIds = buildPath.getNotUsedLibrariesIds();
        notusedLibraries = new HashSet<String>(notUsedLibrariesIds);
        customLibsButton.setSelection(usesCustomLibs);
        for (IPHPLibrary l : LibraryManager.getInstance().getAllLibraries()) {
            if (!notusedLibraries.contains(l.getId())) {
                libraryViewer.setChecked(l, true);
            }
        }
        libraryViewer.getControl().setEnabled(usesCustomLibs);
        select.setEnabled(usesCustomLibs);
        deselect.setEnabled(usesCustomLibs);
    }

    public void fillResult(ProjectDependencies bp) {
        List<IResource> ps = new ArrayList<IResource>();
        List<File> fs = new ArrayList<File>();
        fillResult(ps, fs);
        bp.set(ps, fs);
        bp.setUsesCustomLibs(customLibsButton.getSelection());
        List<String> notUsed = new ArrayList<String>();
        for (IPHPLibrary l : LibraryManager.getInstance().getAllLibraries()) {
            if (!libraryViewer.getChecked(l)) {
                notUsed.add(l.getId());
            }
        }
        bp.setNotUsedLibrariesIds(notUsed);
    }

    private final class SelectAction implements SelectionListener {

        boolean select;

        private SelectAction(boolean doSelect) {
            this.select = doSelect;
        }

        public void widgetDefaultSelected(SelectionEvent e) {

        }

        public void widgetSelected(SelectionEvent e) {
            libraryViewer.setAllChecked(select);
        }
    }

}