| /*=============================================================================# |
| # Copyright (c) 2005, 2019 Stephan Wahlbrink and others. |
| # |
| # This program and the accompanying materials are made available under the |
| # terms of the Eclipse Public License 2.0 which is available at |
| # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
| # which is available at https://www.apache.org/licenses/LICENSE-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
| # |
| # Contributors: |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.internal.r.ui; |
| |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.jface.action.ToolBarManager; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.ui.model.WorkbenchLabelProvider; |
| import org.eclipse.ui.views.navigator.ResourceComparator; |
| |
| import org.eclipse.statet.ecommons.ui.SharedMessages; |
| import org.eclipse.statet.ecommons.ui.SharedUIResources; |
| import org.eclipse.statet.ecommons.ui.components.WidgetToolBarComposite; |
| import org.eclipse.statet.ecommons.ui.util.LayoutUtils; |
| import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils; |
| import org.eclipse.statet.ecommons.ui.workbench.workspace.ResourceContentProvider; |
| |
| |
| /** |
| * Workbench-level composite for choosing a container. |
| */ |
| public class RProjectContainerComposite extends Composite { |
| |
| |
| private class CollapseAllAction extends Action { |
| |
| CollapseAllAction() { |
| super(); |
| setText(SharedMessages.CollapseAllAction_label); |
| setDescription(SharedMessages.CollapseAllAction_description); |
| setToolTipText(SharedMessages.CollapseAllAction_tooltip); |
| setImageDescriptor(SharedUIResources.getImages().getDescriptor(SharedUIResources.LOCTOOL_COLLAPSEALL_IMAGE_ID)); |
| } |
| |
| @Override |
| public void run() { |
| RProjectContainerComposite.this.treeViewer.collapseAll(); |
| } |
| |
| } |
| |
| private class ExpandAllAction extends Action { |
| |
| ExpandAllAction() { |
| super(); |
| setText(SharedMessages.ExpandAllAction_label); |
| setDescription(SharedMessages.ExpandAllAction_description); |
| setToolTipText(SharedMessages.ExpandAllAction_tooltip); |
| setImageDescriptor(SharedUIResources.getImages().getDescriptor(SharedUIResources.LOCTOOL_EXPANDALL_IMAGE_ID)); |
| } |
| |
| @Override |
| public void run() { |
| RProjectContainerComposite.this.treeViewer.expandAll(); |
| } |
| |
| } |
| |
| private class RLabelProvider extends LabelProvider { |
| |
| |
| private final WorkbenchLabelProvider baseProvider; |
| |
| |
| public RLabelProvider() { |
| this.baseProvider= new WorkbenchLabelProvider(); |
| } |
| |
| |
| @Override |
| public Image getImage(final Object element) { |
| return this.baseProvider.getImage(element); |
| } |
| |
| @Override |
| public String getText(final Object element) { |
| final String text= this.baseProvider.getText(element); |
| int flags= 0; |
| if (RProjectContainerComposite.this.pkgBaseContainer != null && RProjectContainerComposite.this.pkgBaseContainer.equals(element)) { |
| flags|= 1; |
| } |
| |
| if (flags != 0) { |
| final StringBuilder sb= new StringBuilder(text); |
| sb.append("\u2002("); //$NON-NLS-1$ |
| if ((flags & 1) != 0) { |
| sb.append("R Package Root"); //$NON-NLS-1$ |
| sb.append(", "); //$NON-NLS-1$ |
| } |
| sb.replace(sb.length() - 2, sb.length(), ")"); //$NON-NLS-1$ |
| return sb.toString(); |
| } |
| return text; |
| } |
| |
| } |
| |
| // sizing constants |
| private static final int SIZING_SELECTION_PANE_WIDTH= 320; |
| private static final int SIZING_SELECTION_PANE_HEIGHT= 300; |
| |
| |
| private final IProject project; |
| |
| private IContainer pkgBaseContainer; |
| |
| private TreeViewer treeViewer; |
| private ToolBarManager rightToolBarMgr; |
| |
| |
| /** |
| * Creates a new instance of the widget. |
| * |
| * @param parent The parent widget of the group. |
| * @param listener A listener to forward events to. Can be null if |
| * no listener is required. |
| * @param allowNewContainerName Enable the user to type in a new container |
| * name instead of just selecting from the existing ones. |
| * @param message The text to present to the user. |
| * @param showClosedProjects Whether or not to show closed projects. |
| * @param heightHint height hint for the drill down composite |
| */ |
| public RProjectContainerComposite(final Composite parent, |
| final IProject project) { |
| super(parent, SWT.NONE); |
| this.project= project; |
| |
| createContents(); |
| } |
| |
| protected void createContents() { |
| setLayout(LayoutUtils.newCompositeGrid(1)); |
| setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| |
| createTreeViewer(); |
| Dialog.applyDialogFont(this); |
| |
| this.treeViewer.setInput(new IContainer[] { this.project }); |
| this.treeViewer.expandToLevel(2); |
| if (this.pkgBaseContainer != null) { |
| this.treeViewer.expandToLevel(this.pkgBaseContainer, 1); |
| } |
| } |
| |
| /** |
| * Returns a new drill down viewer for this dialog. |
| * |
| * @param heightHint height hint for the drill down composite |
| * @return a new drill down viewer |
| */ |
| protected void createTreeViewer() { |
| final WidgetToolBarComposite treeGroup= new WidgetToolBarComposite(this, SWT.BORDER); |
| { final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, true); |
| gd.widthHint= SIZING_SELECTION_PANE_WIDTH; |
| gd.heightHint= SIZING_SELECTION_PANE_HEIGHT; |
| treeGroup.setLayoutData(gd); |
| } |
| |
| this.rightToolBarMgr= new ToolBarManager(treeGroup.getRightToolBar()); |
| |
| this.treeViewer= new TreeViewer(treeGroup, SWT.NONE); |
| this.treeViewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); |
| |
| this.rightToolBarMgr.add(new CollapseAllAction()); |
| this.rightToolBarMgr.add(new ExpandAllAction()); |
| |
| this.rightToolBarMgr.update(true); |
| |
| // layout group |
| treeGroup.layout(); |
| |
| this.treeViewer.setContentProvider( |
| new ResourceContentProvider(IResource.PROJECT | IResource.FOLDER) ); |
| this.treeViewer.setLabelProvider(new RLabelProvider()); |
| this.treeViewer.setComparator(new ResourceComparator(ResourceComparator.NAME)); |
| // this.treeViewer.addSelectionChangedListener(new ISelectionChangedListener() { |
| // public void selectionChanged(final SelectionChangedEvent event) { |
| // final IStructuredSelection selection= (IStructuredSelection) event.getSelection(); |
| // containerSelectionChanged((IContainer) selection.getFirstElement()); // allow null |
| // } |
| // }); |
| ViewerUtils.addDoubleClickExpansion(this.treeViewer); |
| } |
| |
| |
| /** |
| * Gives focus to one of the widgets in the group, as determined by the group. |
| */ |
| public void setInitialFocus() { |
| this.treeViewer.getTree().setFocus(); |
| } |
| |
| |
| public void setPkgBaseContainer(final IPath path) { |
| if (path == null) { |
| this.pkgBaseContainer= null; |
| } |
| else if (path.segmentCount() == 0) { |
| this.pkgBaseContainer= this.project; |
| } |
| else { |
| this.pkgBaseContainer= this.project.getFolder(path); |
| } |
| this.treeViewer.refresh(true); |
| } |
| |
| public void togglePkgBaseContainer() { |
| final Object element= ((IStructuredSelection) this.treeViewer.getSelection()).getFirstElement(); |
| if (element instanceof IContainer) { |
| if (element != null && !element.equals(this.pkgBaseContainer)) { |
| this.pkgBaseContainer= (IContainer) element; |
| } |
| else { |
| this.pkgBaseContainer= null; |
| } |
| } |
| else { |
| this.pkgBaseContainer= null; |
| } |
| this.treeViewer.refresh(true); |
| } |
| |
| public IPath getPkgBaseContainer() { |
| if (this.pkgBaseContainer == null) { |
| return null; |
| } |
| return this.pkgBaseContainer.getProjectRelativePath(); |
| } |
| |
| |
| // public static IStatus validate(IPath path) { |
| // // validate Container |
| // if (path == null || path.isEmpty()) { |
| // return new StatusInfo(IStatus.ERROR, Messages.ContainerSelectionControl_error_FolderEmpty); |
| // } |
| // final IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot(); |
| // final String projectName= path.segment(0); |
| // if (projectName == null || !root.getProject(projectName).exists()) |
| // return new StatusInfo(IStatus.ERROR, Messages.ContainerSelectionControl_error_ProjectNotExists); |
| // // path is invalid if any prefix is occupied by a file |
| // while (path.segmentCount() > 1) { |
| // if (root.getFile(path).exists()) { |
| // return new StatusInfo(IStatus.ERROR, NLS.bind( |
| // Messages.ContainerSelectionControl_error_PathOccupied, |
| // path.makeRelative() )); |
| // } |
| // path= path.removeLastSegments(1); |
| // } |
| // return new StatusInfo(); |
| // } |
| |
| } |