/** * GRANITE DATA SERVICES * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. * * This file is part of the Granite Data Services Platform. * * Granite Data Services is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * Granite Data Services is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA, or see <http://www.gnu.org/licenses/>. */ package org.granite.builder.ui; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import org.eclipse.core.resources.IFolder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Rectangle; 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.Label; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.granite.builder.GraniteBuilderContext; import org.granite.builder.properties.Gas3Source; import org.granite.builder.properties.GraniteProperties; import org.granite.builder.util.ProjectUtil; import org.granite.builder.util.SWTUtil; /** * @author Franck WOLFF */ public class SourcesPanel extends Composite { private static final String INCLUDED = "Included: "; private static final String EXCLUDED = "Excluded: "; private static final String OUTPUT = "Output: "; private static final String ALL = "(All)"; private static final String NONE = "(None)"; private final GraniteBuilderContext context; private final GraniteProperties properties; private Tree sourcesTree = null; private boolean initialized = false; public SourcesPanel(Composite parent, GraniteBuilderContext context) throws CoreException { super(parent, SWT.NONE); if (parent == null || context == null) throw new NullPointerException("parent and context cannot be null"); this.context = context; this.properties = context.getProperties(); initializeComponents(); } public TreeSet<Gas3Source> getSources() { if (!initialized) return properties.getGas3().getSources(); TreeSet<Gas3Source> sources = new TreeSet<Gas3Source>(); for (TreeItem root : sourcesTree.getItems()) sources.add((Gas3Source)root.getData()); return sources; } @Override public Rectangle getClientArea() { initializeContent(); return super.getClientArea(); } private void initializeContent() { if (!initialized) { for (Gas3Source source : properties.getGas3().getSources()) addSourceFolderTreeItem(source); initialized = true; } } private void initializeComponents() { setLayout(new GridLayout(2, false)); Label text = new Label(this, SWT.NONE); text.setText("Source folders used for generation:"); text.setLayoutData(SWTUtil.newGridData(SWT.NONE, 2)); sourcesTree = new Tree(this, SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); sourcesTree.setLayoutData(new GridData( GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL )); Composite buttons = new Composite(this, SWT.NONE); buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); buttons.setLayout(new FillLayout(SWT.VERTICAL)); final Button addButton = SWTUtil.newButton(buttons, "Add Folder...", true, new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { addFoldersHandler(e); } }); final Button editButton = SWTUtil.newButton(buttons, "Edit...", false, new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { editFolderAttributesHandler(e); } }); final Button removeButton = SWTUtil.newButton(buttons, "Remove", false, new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // Remove selected root items. for (TreeItem item : sourcesTree.getSelection()) { if (item.getParentItem() == null) item.dispose(); } // Disable remove button if there is no more root nodes. if (sourcesTree.getItemCount() == 0) ((Button)e.getSource()).setEnabled(false); } }); sourcesTree.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // Enable/Disable buttons based on selected tree item. boolean isRoot = (((TreeItem)e.item).getParentItem() == null); removeButton.setEnabled(isRoot); addButton.setEnabled(isRoot); editButton.setEnabled(!isRoot); } }); } private TreeItem addSourceFolderTreeItem(Gas3Source source) { IFolder folder = context.getJavaProject().getProject().getFolder(source.getPath()); String displayedPath = folder.getFullPath().makeRelative().toString(); String icon = folder.exists() ? SWTUtil.IMG_PKG_FOLDER : SWTUtil.IMG_PKG_FOLDER_ERROR; TreeItem root = SWTUtil.addTreeItem(sourcesTree, icon, displayedPath, null, null); SWTUtil.addTreeItem(root, SWTUtil.IMG_INCLUDES, source.getIncludes(), INCLUDED, ALL); SWTUtil.addTreeItem(root, SWTUtil.IMG_EXCLUDES, source.getExcludes(), EXCLUDED, NONE); SWTUtil.addTreeItem(root, SWTUtil.IMG_OUT_FOLDER, source.getOutput(), OUTPUT, null); root.setData(source); return root; } private void addFoldersHandler(SelectionEvent event) { // Get currently configured source folders. TreeItem[] roots = sourcesTree.getItems(); IPath[] usedEntries = new IPath[roots.length]; for (int i = 0; i < usedEntries.length; i++) usedEntries[i] = new Path(roots[i].getText()); // Run add folders dialog. IPath[] selectedPaths = Dialogs.chooseSourceFolderEntries( context.getJavaProject(), getDisplay().getActiveShell(), null, usedEntries ); // Rebuild sorted source folders list. if (selectedPaths != null && selectedPaths.length > 0) { selectedPaths = ProjectUtil.makeRelative(selectedPaths); IPath projectPath = context.getJavaProject().getPath().makeRelative(); Set<IPath> newSourceFolders = new TreeSet<IPath>(ProjectUtil.IPATH_COMPARATOR); newSourceFolders.addAll(Arrays.asList(usedEntries)); List<IPath> jSourceFolders = ProjectUtil.makeRelative(getSourceFolders()); for (IPath selectedPath : selectedPaths) { if (selectedPath.equals(projectPath)) { newSourceFolders.addAll(jSourceFolders); break; } for (IPath jSourceFolder : jSourceFolders) { if (jSourceFolder.matchingFirstSegments(selectedPath) >= 2) newSourceFolders.add(jSourceFolder); } } Map<IPath, TreeItem> rootMap = new HashMap<IPath, TreeItem>(roots.length); for (TreeItem root : roots) rootMap.put(new Path(root.getText()), root); String defaultOutput = "as3"; for (IPath newSourceFolder : newSourceFolders) { TreeItem root = rootMap.get(newSourceFolder); if (root != null) addSourceFolderTreeItem((Gas3Source)root.getData()); else { String path = newSourceFolder.removeFirstSegments(1).makeRelative().toString(); TreeItem item = addSourceFolderTreeItem(new Gas3Source(path, null, null, defaultOutput)); item.setExpanded(true); } } for (TreeItem root : roots) root.dispose(); } } private void editFolderAttributesHandler(SelectionEvent event) { TreeItem[] selection = sourcesTree.getSelection(); if (selection.length == 1 && selection[0].getParentItem() != null && selection[0].getParentItem().getParentItem() == null) { Gas3Source source = (Gas3Source)selection[0].getParentItem().getData(); source = Dialogs.editSourceFolderAttributes(context.getJavaProject(), getDisplay().getActiveShell(), source); SWTUtil.setTreeItemText(selection[0].getParentItem().getItem(0), source.getIncludes()); SWTUtil.setTreeItemText(selection[0].getParentItem().getItem(1), source.getExcludes()); SWTUtil.setTreeItemText(selection[0].getParentItem().getItem(2), source.getOutput()); selection[0].getParentItem().setData(source); } } private List<IPath> getSourceFolders() { try { return ProjectUtil.getSourceFolders(context.getJavaProject()); } catch (CoreException e) { return Collections.emptyList(); } } }