| /***************************************************************************** |
| * Copyright (c) 2014 CEA LIST. |
| * |
| * 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: |
| * Quentin Le Menez (CEA LIST) quentin.lemenez@cea.fr - Initial API and implementation |
| * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - bug 496176 |
| *****************************************************************************/ |
| package org.eclipse.papyrus.interoperability.common.wizard.pages; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.LinkedHashMap; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.ViewerFilter; |
| import org.eclipse.papyrus.infra.core.services.ServiceException; |
| import org.eclipse.papyrus.infra.services.labelprovider.service.LabelProviderService; |
| import org.eclipse.papyrus.infra.services.labelprovider.service.impl.LabelProviderServiceImpl; |
| import org.eclipse.papyrus.infra.widgets.providers.IGraphicalContentProvider; |
| import org.eclipse.papyrus.infra.widgets.providers.PatternViewerFilter; |
| import org.eclipse.papyrus.infra.widgets.providers.WorkspaceContentProvider; |
| import org.eclipse.papyrus.interoperability.common.Activator; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.layout.FillLayout; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.dialogs.PatternFilter; |
| |
| |
| /** |
| * |
| * Generic and reusable composite used to display the workspace and select the wanted elements |
| * |
| * @author Quentin Le Menez |
| * |
| */ |
| public abstract class ImportTreeComposite extends Composite { |
| |
| protected TreeViewer treeViewer; |
| |
| protected LabelProviderService labelProviderService; |
| |
| protected ILabelProvider treeViewerlabelProvider; |
| |
| protected WorkspaceContentProvider treeViewercontentProvider; |
| |
| protected ISelectionChangedListener treeViewerListener; |
| |
| protected final List<String> filterNames; |
| |
| protected final List<String> filterExtensions; |
| |
| protected Collection<Object> selectedFiles; |
| |
| protected Collection<String> systemPaths; |
| |
| protected FillLayout layout; |
| |
| protected Composite treeViewerComposite; |
| |
| protected Composite selectionButtonsComposite; |
| |
| protected Collection<Object> foundProjects; |
| |
| /** |
| * |
| * Constructor. |
| * |
| * @param parent |
| * The parent composite |
| * @param style |
| * The swt style used for this ConfigurationComposite |
| * @param extensions |
| * The default extensions used to filter the displayed results |
| * @param extensionsNames |
| * The displayed names of those filters |
| */ |
| public ImportTreeComposite(Composite parent, int style, String[] extensions, String[] extensionsNames) { |
| super(parent, style); |
| this.setLayout(new GridLayout(2, false)); |
| this.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| |
| selectedFiles = new LinkedList<Object>(); |
| filterNames = new LinkedList<String>(); |
| filterExtensions = new LinkedList<String>(); |
| systemPaths = new LinkedList<String>(); |
| foundProjects = new LinkedList<Object>(); |
| |
| createTreeViewerComposite(this, extensions, extensionsNames); |
| |
| createSelectionButtons(this); |
| } |
| |
| |
| /** |
| * |
| * Creates the visual representation of the workspace |
| * |
| * @param parent |
| * The parent Composite |
| * @param extensions |
| * The default extensions used to filter the displayed results |
| * @param extensionsNames |
| * The displayed names of those filters |
| */ |
| private void createTreeViewerComposite(Composite parent, String[] extensions, String[] extensionsNames) { |
| treeViewerComposite = new Composite(parent, SWT.NONE); |
| treeViewerComposite.setLayout(new GridLayout(1, true)); |
| treeViewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| Composite beforeTreeComposite = new Composite(treeViewerComposite, SWT.NONE); |
| |
| Composite treeComposite = new Composite(treeViewerComposite, SWT.NONE); |
| treeComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| layout = new FillLayout(); |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| treeComposite.setLayout(layout); |
| |
| treeViewer = new TreeViewer(treeComposite, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); |
| treeViewer.setFilters(new ViewerFilter[] { new PatternFilter() }); |
| |
| labelProviderService = new LabelProviderServiceImpl(); |
| try { |
| labelProviderService.startService(); |
| } catch (ServiceException ex) { |
| Activator.log.error(ex); |
| } |
| |
| treeViewerlabelProvider = labelProviderService.getLabelProvider(); |
| treeViewercontentProvider = new WorkspaceContentProvider(); |
| setFilters(extensions, extensionsNames); |
| |
| treeViewercontentProvider.setExtensionFilters(new LinkedHashMap<String, String>()); |
| for (int i = 0; i < Math.min(filterNames.size(), filterExtensions.size()); i++) { |
| treeViewercontentProvider.addExtensionFilter(filterExtensions.get(i), filterNames.get(i)); |
| } |
| |
| treeViewer.setContentProvider(treeViewercontentProvider); |
| treeViewer.setLabelProvider(treeViewerlabelProvider); |
| |
| defaultViewerInput(); |
| |
| treeViewerListener = new ISelectionChangedListener() { |
| |
| @Override |
| public void selectionChanged(SelectionChangedEvent event) { |
| fireTreeSelectionEvent(event); |
| } |
| }; |
| |
| treeViewer.addSelectionChangedListener(treeViewerListener); |
| |
| // This is used to display both of the filters (before and after the treeViewer) |
| if (treeViewercontentProvider instanceof IGraphicalContentProvider) { |
| IGraphicalContentProvider graphicalContentProvider = treeViewercontentProvider; |
| |
| beforeTreeComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); |
| layout = new FillLayout(); |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| beforeTreeComposite.setLayout(layout); |
| graphicalContentProvider.createBefore(beforeTreeComposite); |
| beforeTreeComposite.moveAbove(treeViewer.getTree()); |
| |
| Composite afterTreeComposite = new Composite(treeViewerComposite, SWT.NONE); |
| layout = new FillLayout(); |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| afterTreeComposite.setLayout(layout); |
| afterTreeComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); |
| graphicalContentProvider.createAfter(afterTreeComposite); |
| } |
| |
| } |
| |
| /** |
| * |
| * Sets the filters for the treeViewer, matching the names with the extensions |
| * |
| * @param filterExtensions |
| * The extensions |
| * @param filterNames |
| * The associated names |
| */ |
| protected void setFilters(String[] filterExtensions, String[] filterNames) { |
| if (filterExtensions.length != filterNames.length) { |
| // This is a simple warning. Only valid filters will be retained. |
| Activator.log.warn("FilterExtensions and FilterNames do not match"); |
| } |
| |
| setFilterNames(getFilterLabels(filterNames, filterExtensions)); |
| setFilterExtensions(filterExtensions); |
| } |
| |
| /** |
| * |
| * Builds the filter labels to be displayed |
| * |
| * @param filterNames |
| * @param filterExtensions |
| * @return |
| * The array containing the built labels |
| */ |
| protected String[] getFilterLabels(String[] filterNames, String[] filterExtensions) { |
| int size = Math.min(filterNames.length, filterExtensions.length); |
| String[] filters = new String[size]; |
| for (int i = 0; i < size; i++) { |
| filters[i] = filterNames[i] + " (" + filterExtensions[i] + ")"; //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| return filters; |
| } |
| |
| /** |
| * |
| * Fills the local array to be manipulated |
| * |
| * @param filterExtensions |
| * The input extensions |
| */ |
| protected void setFilterExtensions(String[] filterExtensions) { |
| this.filterExtensions.clear(); |
| this.filterExtensions.addAll(Arrays.asList(filterExtensions)); |
| } |
| |
| /** |
| * |
| * Fills the local array to be manipulated |
| * |
| * @param filterNames |
| * The input names |
| */ |
| protected void setFilterNames(String[] filterNames) { |
| this.filterNames.clear(); |
| this.filterNames.addAll(Arrays.asList(filterNames)); |
| } |
| |
| |
| /** |
| * |
| * This method allows to set the default input of the treeViewer |
| * |
| */ |
| protected void defaultViewerInput() { |
| treeViewer.setInput(File.listRoots()); |
| // Gets the selection in the workspace at the time of the launch |
| ISelection workbenchSelection = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection(); |
| // Sets the first selection of the treeviewer from the selection in the workspace |
| revealSelection(workbenchSelection); |
| treeViewer.setSelection(workbenchSelection, true); |
| } |
| |
| |
| /** |
| * |
| * Abstract method to be implemented by the child in order to create the useful buttons to manipulate the tree's elements |
| * |
| * @param parent |
| * The parent composite in which the new buttons will be created |
| */ |
| abstract void createSelectionButtons(Composite parent); |
| |
| /** |
| * |
| * Abstract method to be implemented by the child in order to handle the treeViewer element selection |
| * |
| * @param event |
| * The event linked to the selections inside the treeViewer |
| */ |
| abstract void fireTreeSelectionEvent(SelectionChangedEvent event); |
| |
| |
| /** |
| * |
| * This method reveals the elements selected outside of the workspace or from the workspace selection at launch by expanding the tree |
| * |
| * @param importedFiles |
| * The list of selected files |
| */ |
| protected void revealSelectedFiles(Collection<Object> importedFiles) { |
| // this method calls to expand any folders or projects containg the selected files in order to show the workspace selection |
| Collection<IFile> ifiles = new ArrayList<IFile>(); |
| // Collection<IProject> iprojects = new ArrayList<IProject>(); |
| // Collection<IFolder> ifolders = new ArrayList<IFolder>(); |
| if (importedFiles != null && !importedFiles.isEmpty()) { |
| for (Object object : importedFiles) { |
| treeViewer.refresh(); |
| if (object instanceof File) { |
| File file = (File) object; |
| IFile ifile = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(file.getAbsolutePath())); |
| if (ifile != null) { |
| ifiles.add(ifile); |
| revealTreeElement(ifile); |
| } |
| } |
| if (object instanceof IFile) { |
| IFile ifile = (IFile) object; |
| ifiles.add(ifile); |
| revealTreeElement(ifile); |
| } |
| // if (object instanceof IFolder) { |
| // IFolder ifolder = (IFolder) object; |
| // ifolders.add(ifolder); |
| // revealTreeElement(ifolder); |
| // } |
| // if (object instanceof IProject) { |
| // IProject iproject = (IProject) object; |
| // iprojects.add(iproject); |
| // // As a project is a root element, no need to expand it |
| // } |
| } |
| } |
| |
| treeViewer.setSelection(new StructuredSelection(ifiles.toArray()), true); |
| // treeViewer.setSelection(new StructuredSelection(ifolders.toArray()), true); |
| // treeViewer.setSelection(new StructuredSelection(iprojects.toArray()), true); |
| } |
| |
| /** |
| * |
| * Handles the workspace selection |
| * |
| * @param iselection |
| * The selection |
| */ |
| protected void revealSelection(ISelection iselection) { |
| if (iselection instanceof IStructuredSelection) { |
| IStructuredSelection sselection = (IStructuredSelection) iselection; |
| revealSelectedFiles(Arrays.asList(sselection.toArray())); |
| } |
| } |
| |
| /** |
| * |
| * Reveal each elements from the selected elements list |
| * |
| * @param object |
| * The selected object |
| */ |
| protected void revealTreeElement(Object object) { |
| // verify the possibility of getting the file's parent and that the root directory is not already selected |
| if (object instanceof IFile && !(object instanceof IProject)) { |
| IFile ifile = (IFile) object; |
| treeViewer.setExpandedState(ifile.getParent(), true); |
| if (!(ifile.getParent() instanceof IProject)) { |
| revealTreeElement(ifile.getParent()); |
| } |
| } |
| if (object instanceof IFolder && !(object instanceof IProject)) { |
| IFolder ifolder = (IFolder) object; |
| treeViewer.setExpandedState(ifolder.getParent(), true); |
| if (!(ifolder.getParent() instanceof IProject)) { |
| revealTreeElement(ifolder.getParent()); |
| } |
| } |
| } |
| |
| /** |
| * |
| * This method is used to get the projects containing the selected objects |
| * |
| * @param systemSelection |
| * The selection outside of the workspace |
| * @return |
| * The list of projects found |
| */ |
| protected Collection<Object> getProjects(Collection<Object> systemSelection) { |
| if (systemSelection != null && !systemSelection.isEmpty()) { |
| for (Object object : systemSelection) { |
| if (object instanceof File) { |
| File file = (File) object; |
| getProject(file); |
| } |
| } |
| } |
| return foundProjects; |
| } |
| |
| /** |
| * |
| * This method is used to get the projects containing the file |
| * |
| * @param file |
| * The selected file |
| */ |
| protected void getProject(File file) { |
| File parentFile = file.getParentFile(); |
| if (parentFile == null) { |
| // No containing project has been found |
| return; |
| } |
| |
| Collection<File> parentChildren = Arrays.asList(parentFile.listFiles()); |
| for (File nestedFile : parentChildren) { |
| // String fileExtension = Files.getFileExtension(nestedFile.getAbsolutePath()); |
| String fileExtension = getFileExtensions(nestedFile); |
| if (fileExtension.equals(".project") && !foundProjects.contains(nestedFile)) { // $NON-NLS-1$ |
| // A containing project has been found |
| foundProjects.add(nestedFile); |
| return; |
| } |
| } |
| |
| getProject(parentFile); |
| } |
| |
| /** |
| * |
| * This method gathers the file extensions in order to filter them |
| * |
| * @param file |
| * The file |
| * @return |
| * The file's extension |
| */ |
| protected String getFileExtensions(File file) { |
| String fileName = file.getName(); |
| if (fileName.lastIndexOf(".") != -1 /* && fileName.lastIndexOf(".") != 0 */) { // $NON-NLS-1$ |
| return fileName.substring(fileName.lastIndexOf(".")); // $NON-NLS-1$ |
| } else { |
| return ""; |
| } |
| } |
| |
| /** |
| * |
| * Constructs the list of the treeViewer's selected files |
| * |
| * @param elements |
| */ |
| public void setSelectedFiles(Object[] elements) { |
| // get the viewer selection to obtain the filtered files |
| getNestedFiles(elements); |
| } |
| |
| /** |
| * |
| * getter used to access the selectedFiles list |
| * |
| * @return |
| * the list of selected files |
| */ |
| public Collection<Object> getSelectedFiles() { |
| return selectedFiles; |
| } |
| |
| /** |
| * |
| * Gets all the files from the user's selection in the viewer and updates the local selection list |
| * |
| * @param nestedElements |
| * The array containing the selected elements, be they files or folders |
| */ |
| protected void getNestedFiles(Object[] nestedElements) { |
| Collection<Object> projectList = new LinkedList<Object>(); |
| Collection<Object> folderList = new LinkedList<Object>(); |
| List<PatternViewerFilter> currentFilters = new ArrayList<PatternViewerFilter>(); |
| for (ViewerFilter filter : treeViewer.getFilters()) { |
| if (filter instanceof PatternViewerFilter) { |
| currentFilters.add((PatternViewerFilter) filter); |
| } |
| } |
| |
| for (Object element : nestedElements) { |
| if (element instanceof IProject) { |
| projectList.add(element); |
| } |
| if (element instanceof IFolder) { |
| folderList.add(element); |
| } |
| if (element instanceof IFile) { |
| Boolean isVisible = false; |
| IFile selectedFile = (IFile) element; |
| String fileExtension = "*." + selectedFile.getFileExtension(); //$NON-NLS-1$ |
| if (filterExtensions.contains(fileExtension) && !selectedFiles.contains(selectedFile)) { |
| isVisible = true; |
| } |
| for (int index = 0; index < currentFilters.size() && isVisible; index++) { |
| isVisible = currentFilters.get(index).isVisible(treeViewer, selectedFile.getParent(), selectedFile); |
| } |
| if (isVisible) { |
| selectedFiles.add(selectedFile); |
| } |
| } |
| } |
| |
| if (projectList.size() > 0) { |
| for (Object element : projectList) { |
| IProject selectedProject = (IProject) element; |
| try { |
| getNestedFiles(selectedProject.members()); |
| } catch (CoreException e) { |
| Activator.log.error(e); |
| } |
| } |
| } |
| |
| if (folderList.size() > 0) { |
| for (Object element : folderList) { |
| IFolder selectedFolder = (IFolder) element; |
| try { |
| getNestedFiles(selectedFolder.members()); |
| } catch (CoreException e) { |
| Activator.log.error(e); |
| } |
| } |
| } |
| } |
| |
| @Override |
| public void dispose() { |
| if (treeViewerListener != null) { |
| treeViewer.removeSelectionChangedListener(treeViewerListener); |
| } |
| super.dispose(); |
| } |
| |
| } |