blob: bbaa03271b32c714de21061c74cdcd33957e032a [file] [log] [blame]
/*=============================================================================#
# 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();
// }
}