blob: 4d91e3b60db1a6fb290aa1b28b899eabdd52d197 [file] [log] [blame]
/*
* Copyright (c) 2021 Eike Stepper (Loehne, Germany) and others.
* 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:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.emf.cdo.explorer.ui.checkouts.wizards;
import org.eclipse.emf.cdo.eresource.CDOResourceFolder;
import org.eclipse.emf.cdo.eresource.CDOResourceNode;
import org.eclipse.emf.cdo.explorer.CDOExplorerUtil;
import org.eclipse.emf.cdo.explorer.checkouts.CDOCheckout;
import org.eclipse.emf.cdo.explorer.ui.checkouts.CDOCheckoutContentProvider;
import org.eclipse.net4j.util.collection.Pair;
import org.eclipse.net4j.util.ui.UIUtil;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jface.viewers.IStructuredContentProvider;
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.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author Eike Stepper
*/
public abstract class CheckoutNodeWizardPage extends WizardPage
{
protected final String title;
private TreeViewer nodeViewer;
private boolean nodeRevealed;
/**
* Either a {@link CDOCheckout}, a {@link CDOResourceNode}, or <code>null</code>.
*/
private Object node;
public CheckoutNodeWizardPage(String pageName, String title, IStructuredSelection selection)
{
super(pageName);
this.title = title;
node = getNode(selection);
}
/**
* Returns either a {@link CDOCheckout}, a {@link CDOResourceNode}, or <code>null</code>.
*/
public final Object getNode()
{
return node;
}
public final TreeViewer getNodeViewer()
{
return nodeViewer;
}
@Override
public void createControl(Composite parent)
{
setTitle(title);
Composite container = new Composite(parent, SWT.NULL);
GridLayout containerGridLayout = new GridLayout();
containerGridLayout.numColumns = 2;
container.setLayout(containerGridLayout);
setControl(container);
doCreateControl(container);
Shell shell = getShell();
UIUtil.asyncExec(shell.getDisplay(), () -> {
try
{
shell.setText(title);
}
catch (Exception ex)
{
//$FALL-THROUGH$
}
revealNode();
validate();
deferredInit();
});
}
protected void doCreateControl(Composite parent)
{
Label nodeLabel = new Label(parent, SWT.NONE);
nodeLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
nodeLabel.setText(getNodeMessage() + ":");
nodeViewer = createNodeViewer(parent);
nodeViewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
nodeViewer.addSelectionChangedListener(event -> nodeSelectionChanged(event));
}
protected abstract String getNodeMessage();
protected TreeViewer createNodeViewer(Composite container)
{
return CDOCheckoutContentProvider.createTreeViewer(container);
}
protected void deferredInit()
{
}
protected final Pair<CDOCheckout, CDOResourceNode> getNodeInfo()
{
if (node instanceof CDOCheckout)
{
CDOCheckout checkout = (CDOCheckout)node;
EObject parentNode = checkout.getRootObject();
if (parentNode instanceof CDOResourceNode)
{
return Pair.create(checkout, (CDOResourceNode)parentNode);
}
}
else if (node instanceof CDOResourceNode)
{
CDOResourceNode parentNode = (CDOResourceNode)node;
CDOCheckout checkout = CDOExplorerUtil.getCheckout(parentNode);
if (checkout != null)
{
return Pair.create(checkout, parentNode);
}
}
return null;
}
protected final EList<EObject> getNodeChildren()
{
if (node instanceof CDOCheckout)
{
CDOCheckout checkout = (CDOCheckout)node;
return checkout.getRootObject().eContents();
}
if (node instanceof CDOResourceFolder)
{
CDOResourceFolder folder = (CDOResourceFolder)node;
return folder.eContents();
}
return ECollections.emptyEList();
}
protected final void validate()
{
try
{
doValidate();
setErrorMessage(null);
setPageComplete(true);
}
catch (Exception ex)
{
setErrorMessage(ex.getMessage());
setPageComplete(false);
}
}
protected void doValidate() throws Exception
{
if (node == null)
{
throw new Exception(getNodeMessage() + ".");
}
}
private void nodeSelectionChanged(SelectionChangedEvent event)
{
Object oldNode = node;
if (nodeRevealed)
{
IStructuredSelection selection = (IStructuredSelection)event.getSelection();
node = getNode(selection);
}
if (!Objects.equals(node, oldNode))
{
nodeSelectionChanged(oldNode, node);
}
validate();
}
protected void nodeSelectionChanged(Object oldNode, Object newNode)
{
}
private void revealNode()
{
if (node != null)
{
List<Object> segments = new ArrayList<>();
fillSegments(segments, node);
for (int i = 0; i < segments.size() - 1; i++)
{
Object segment = segments.get(i);
nodeViewer.setExpandedState(segment, true);
}
}
else
{
IStructuredContentProvider contentProvider = (IStructuredContentProvider)nodeViewer.getContentProvider();
Object[] elements = contentProvider.getElements(nodeViewer.getInput());
if (elements != null && elements.length != 0)
{
if (elements[0] instanceof CDOCheckout || elements[0] instanceof CDOResourceNode)
{
node = elements[0];
}
}
}
if (node != null)
{
nodeViewer.setSelection(new StructuredSelection(node), true);
}
nodeRevealed = true;
}
private void fillSegments(List<Object> segments, Object node)
{
if (node instanceof CDOResourceFolder)
{
CDOResourceFolder folder = (CDOResourceFolder)node;
Adapter adapter = EcoreUtil.getAdapter(folder.eAdapters(), CDOCheckout.class);
if (adapter != null)
{
fillSegments(segments, adapter);
}
else
{
Object parent = folder.getFolder();
if (parent == null)
{
parent = EcoreUtil.getAdapter(folder.cdoView().getRootResource().eAdapters(), CDOCheckout.class);
}
fillSegments(segments, parent);
}
}
segments.add(node);
}
private static Object getNode(IStructuredSelection selection)
{
if (selection != null)
{
Object element = selection.getFirstElement();
if (element instanceof CDOCheckout || element instanceof CDOResourceNode)
{
return element;
}
}
return null;
}
protected static boolean isContainer(Object node)
{
return node instanceof CDOCheckout || node instanceof CDOResourceFolder;
}
}