001/* 002 GRANITE DATA SERVICES 003 Copyright (C) 2011 GRANITE DATA SERVICES S.A.S. 004 005 This file is part of Granite Data Services. 006 007 Granite Data Services is free software; you can redistribute it and/or modify 008 it under the terms of the GNU Library General Public License as published by 009 the Free Software Foundation; either version 2 of the License, or (at your 010 option) any later version. 011 012 Granite Data Services is distributed in the hope that it will be useful, but 013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License 015 for more details. 016 017 You should have received a copy of the GNU Library General Public License 018 along with this library; if not, see <http://www.gnu.org/licenses/>. 019*/ 020 021package org.granite.builder.ui; 022 023import java.util.Arrays; 024import java.util.TreeSet; 025 026import org.eclipse.core.resources.IProject; 027import org.eclipse.core.runtime.CoreException; 028import org.eclipse.core.runtime.IPath; 029import org.eclipse.core.runtime.Path; 030import org.eclipse.swt.SWT; 031import org.eclipse.swt.events.SelectionAdapter; 032import org.eclipse.swt.events.SelectionEvent; 033import org.eclipse.swt.graphics.Rectangle; 034import org.eclipse.swt.layout.FillLayout; 035import org.eclipse.swt.layout.GridData; 036import org.eclipse.swt.layout.GridLayout; 037import org.eclipse.swt.widgets.Button; 038import org.eclipse.swt.widgets.Composite; 039import org.eclipse.swt.widgets.Label; 040import org.eclipse.swt.widgets.Tree; 041import org.eclipse.swt.widgets.TreeItem; 042import org.granite.builder.GraniteBuilderContext; 043import org.granite.builder.properties.Gas3Project; 044import org.granite.builder.properties.GraniteProperties; 045import org.granite.builder.util.ProjectUtil; 046import org.granite.builder.util.SWTUtil; 047 048/** 049 * @author Franck WOLFF 050 */ 051public class ProjectsPanel extends Composite { 052 053 private final GraniteBuilderContext context; 054 private final GraniteProperties properties; 055 056 private Tree projectsTree = null; 057 private boolean initialized = false; 058 059 public ProjectsPanel(Composite parent, GraniteBuilderContext context) throws CoreException { 060 super(parent, SWT.NONE); 061 if (parent == null || context == null) 062 throw new NullPointerException("parent and context cannot be null"); 063 this.context = context; 064 this.properties = context.getProperties(); 065 initializeComponents(); 066 } 067 068 public TreeSet<Gas3Project> getProjects() { 069 if (!initialized) 070 return properties.getGas3().getProjects(); 071 072 TreeSet<Gas3Project> projects = new TreeSet<Gas3Project>(); 073 for (TreeItem root : projectsTree.getItems()) 074 projects.add((Gas3Project)root.getData()); 075 return projects; 076 } 077 078 @Override 079 public Rectangle getClientArea() { 080 initializeContent(); 081 return super.getClientArea(); 082 } 083 084 private void initializeContent() { 085 if (!initialized) { 086 for (Gas3Project project : properties.getGas3().getProjects()) 087 addProjectFolderTreeItem(project); 088 initialized = true; 089 } 090 } 091 092 private void initializeComponents() { 093 setLayout(new GridLayout(2, false)); 094 095 Label text = new Label(this, SWT.NONE); 096 text.setText("Other granite projects used for generation:"); 097 text.setLayoutData(SWTUtil.newGridData(SWT.NONE, 2)); 098 099 projectsTree = new Tree(this, SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); 100 projectsTree.setLayoutData(new GridData( 101 GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | 102 GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL 103 )); 104 105 Composite buttons = new Composite(this, SWT.NONE); 106 buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); 107 buttons.setLayout(new FillLayout(SWT.VERTICAL)); 108 109 final Button addButton = SWTUtil.newButton(buttons, "Add Project...", true, new SelectionAdapter() { 110 @Override 111 public void widgetSelected(SelectionEvent e) { 112 addProjectsHandler(e); 113 } 114 }); 115 116 final Button removeButton = SWTUtil.newButton(buttons, "Remove", false, new SelectionAdapter() { 117 @Override 118 public void widgetSelected(SelectionEvent e) { 119 // Remove selected root items. 120 for (TreeItem item : projectsTree.getSelection()) { 121 if (item.getParentItem() == null) 122 item.dispose(); 123 } 124 // Disable remove button if there is no more root nodes. 125 if (projectsTree.getItemCount() == 0) 126 ((Button)e.getSource()).setEnabled(false); 127 } 128 }); 129 130 projectsTree.addSelectionListener(new SelectionAdapter() { 131 @Override 132 public void widgetSelected(SelectionEvent e) { 133 // Enable/Disable buttons based on selected tree item. 134 boolean isRoot = (((TreeItem)e.item).getParentItem() == null); 135 removeButton.setEnabled(isRoot); 136 addButton.setEnabled(isRoot); 137 } 138 }); 139 } 140 141 private TreeItem addProjectFolderTreeItem(Gas3Project project) { 142 try { 143 IProject dependentProject = ProjectUtil.getProject(context.getJavaProject().getProject(), project.getPath()); 144 145 String displayedPath = dependentProject.getFullPath().makeRelative().toString(); 146 String icon = SWTUtil.IMG_GPROJECT_ERROR; 147 if (!dependentProject.exists()) 148 displayedPath += " (does not exist)"; 149 else if (!dependentProject.isOpen()) 150 displayedPath += " (not opened)"; 151 else if (!ProjectUtil.isGraniteProject(dependentProject)) 152 displayedPath += " (not a granite project)"; 153 else 154 icon = SWTUtil.IMG_GPROJECT; 155 156 TreeItem root = SWTUtil.addTreeItem(projectsTree, icon, displayedPath, null, null); 157 root.setData(project); 158 159 return root; 160 } catch (CoreException e) { 161 throw new RuntimeException(e); 162 } 163 } 164 165 private void addProjectsHandler(SelectionEvent event) { 166 // Get currently configured projects. 167 TreeItem[] roots = projectsTree.getItems(); 168 IPath[] usedEntries = new IPath[roots.length]; 169 for (int i = 0; i < usedEntries.length; i++) 170 usedEntries[i] = new Path(roots[i].getText()); 171 172 // Run add projects dialog. 173 IPath[] selectedPaths = Dialogs.chooseProjectEntries( 174 context.getJavaProject(), 175 getDisplay().getActiveShell(), 176 null, 177 usedEntries 178 ); 179 180 // Rebuild sorted projects list. 181 if (selectedPaths != null && selectedPaths.length > 0) { 182 selectedPaths = ProjectUtil.makeRelative(selectedPaths); 183 184 IPath[] entries = new IPath[usedEntries.length + selectedPaths.length]; 185 System.arraycopy(usedEntries, 0, entries, 0, usedEntries.length); 186 System.arraycopy(selectedPaths, 0, entries, usedEntries.length, selectedPaths.length); 187 Arrays.sort(entries, ProjectUtil.IPATH_COMPARATOR); 188 189 for (TreeItem root : projectsTree.getItems()) 190 root.dispose(); 191 192 for (IPath path : entries) 193 addProjectFolderTreeItem(new Gas3Project(path.toString())); 194 } 195 } 196}