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    
021    package org.granite.builder.ui;
022    
023    import java.util.Arrays;
024    import java.util.TreeSet;
025    
026    import org.eclipse.core.resources.IProject;
027    import org.eclipse.core.runtime.CoreException;
028    import org.eclipse.core.runtime.IPath;
029    import org.eclipse.core.runtime.Path;
030    import org.eclipse.swt.SWT;
031    import org.eclipse.swt.events.SelectionAdapter;
032    import org.eclipse.swt.events.SelectionEvent;
033    import org.eclipse.swt.graphics.Rectangle;
034    import org.eclipse.swt.layout.FillLayout;
035    import org.eclipse.swt.layout.GridData;
036    import org.eclipse.swt.layout.GridLayout;
037    import org.eclipse.swt.widgets.Button;
038    import org.eclipse.swt.widgets.Composite;
039    import org.eclipse.swt.widgets.Label;
040    import org.eclipse.swt.widgets.Tree;
041    import org.eclipse.swt.widgets.TreeItem;
042    import org.granite.builder.GraniteBuilderContext;
043    import org.granite.builder.properties.Gas3Project;
044    import org.granite.builder.properties.GraniteProperties;
045    import org.granite.builder.util.ProjectUtil;
046    import org.granite.builder.util.SWTUtil;
047    
048    /**
049     * @author Franck WOLFF
050     */
051    public 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    }