blob: f059a8c8ba235acaef36f90c46c35ab0bb4297a9 [file] [log] [blame]
/**
* Copyright (c) 2008 IBM Corporation 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:
* IBM - Initial API and implementation
*/
package org.eclipse.emf.codegen.ecore.genmodel.handler;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.action.StatusLineManager;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.dialogs.FilteredResourcesSelectionDialog;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.emf.codegen.ecore.generator.Generator;
import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
import org.eclipse.emf.codegen.ecore.genmodel.generator.GenBaseGeneratorAdapter;
import org.eclipse.emf.codegen.ecore.genmodel.presentation.GeneratorUIUtil;
import org.eclipse.emf.codegen.ecore.genmodel.provider.GenModelEditPlugin;
import org.eclipse.emf.codegen.ecore.genmodel.util.GenModelUtil;
import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
/**
* PROVISIONAL
* This API is subject to arbitrary change, including renaming or removal.
*
* @since 2.5
*/
public class GenerateHandler extends AbstractHandler
{
protected static List<URI> getGenModelURIs(IProgressMonitor progressMonitor, Object[] objects)
{
if (objects.length > 0)
{
progressMonitor.beginTask(GenModelEditPlugin.INSTANCE.getString("_UI_AnalyzingObjects_message"), objects.length);
List<URI> uris = new ArrayList<URI>(objects.length);
for (Object object : objects)
{
IFile file = null;
if (object instanceof IFile)
{
file = (IFile)object;
}
else if (object instanceof IAdaptable)
{
file = (IFile)((IAdaptable)object).getAdapter(IFile.class);
}
if (file != null && "genmodel".equals(file.getFileExtension()))
{
progressMonitor.subTask(file.getName());
URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true);
uris.add(uri);
}
progressMonitor.worked(1);
}
return uris;
}
return new ArrayList<URI>();
}
protected static class GenModelSelectionDialog extends FilteredResourcesSelectionDialog
{
protected class GenModelResourceFilter extends FilteredResourcesSelectionDialog.ResourceFilter
{
public GenModelResourceFilter(IContainer container)
{
super(container, false, IResource.FILE);
}
@Override
public boolean matchItem(Object item)
{
return
item instanceof IFile &&
"genmodel".equals(((IFile)item).getFileExtension()) &&
super.matchItem(item);
}
}
protected IContainer container;
protected IStatus status;
protected StatusLineManager statusLineManager;
protected List<GenModel> genModels;
protected Point size;
protected Point location;
public GenModelSelectionDialog(Shell shell, boolean multi, IContainer container, int typesMask)
{
super(shell, multi, container, typesMask);
this.container = container;
}
public void initialize(Point size, Point location)
{
this.size = size;
this.location = location;
}
public List<GenModel> getGenModels()
{
if (genModels == null)
{
genModels = new ArrayList<GenModel>();
}
return genModels;
}
public Point getSize()
{
return size;
}
public Point getLocation()
{
return location;
}
@Override
protected void configureShell(Shell newShell)
{
super.configureShell(newShell);
if (size != null)
{
newShell.setSize(size);
}
if (location != null)
{
newShell.setLocation(location);
}
}
@Override
public void create()
{
super.create();
if (size != null)
{
Point shellSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
getShell().setSize(Math.max(shellSize.x, size.x), size.y);
}
if (location != null)
{
getShell().setLocation(location);
}
}
@Override
protected Control createDialogArea(Composite parent)
{
Composite composite = (Composite)super.createDialogArea(parent);
statusLineManager = new StatusLineManager();
statusLineManager.createControl(composite);
statusLineManager.setCancelEnabled(true);
GridData gridData = new GridData();
gridData.horizontalAlignment = GridData.FILL;
gridData.grabExcessHorizontalSpace = true;
gridData.heightHint = convertVerticalDLUsToPixels(9);
statusLineManager.getControl().setLayoutData(gridData);
return composite;
}
@Override
protected void createButtonsForButtonBar(Composite parent)
{
super.createButtonsForButtonBar(parent);
Button okButton = getOkButton();
okButton.setText(IDialogConstants.NEXT_LABEL);
Button button = createButton(parent, IDialogConstants.BACK_ID, IDialogConstants.BACK_LABEL, false);
button.moveAbove(okButton);
button.setEnabled(false);
button = createButton(parent, IDialogConstants.FINISH_ID, IDialogConstants.FINISH_LABEL, false);
button.moveBelow(okButton);
button.setEnabled(false);
}
@Override
protected ItemsFilter createFilter()
{
return new GenModelResourceFilter(container);
}
@Override
protected void updateStatus(IStatus status)
{
this.status = status;
super.updateStatus(status);
}
@Override
protected void cancelPressed()
{
super.cancelPressed();
}
@Override
public boolean close()
{
location = getShell().getLocation();
size = getShell().getSize();
return super.close();
}
@Override
protected void okPressed()
{
if (status != null && (status.isOK() || status.getCode() == IStatus.INFO))
{
computeResult();
IProgressMonitor progressMonitor = statusLineManager.getProgressMonitor();
progressMonitor.beginTask("", 10);
List<URI> uris = getGenModelURIs(BasicMonitor.subProgress(progressMonitor, 3), getResult());
List<GenModel> genModels = GeneratorUIUtil.loadGenModels(BasicMonitor.subProgress(progressMonitor, 7), uris, getShell());
progressMonitor.done();
if (!genModels.isEmpty())
{
getGenModels().addAll(genModels);
close();
}
}
}
}
protected static class GenModelGenerationDialog extends TrayDialog
{
protected enum ProjectType
{
MODEL
{
@Override
public String getID()
{
return GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE;
}
@Override
public String getLabel()
{
return GenModelEditPlugin.INSTANCE.getString("_UI_Model_title");
}
@Override
public boolean canGenerate(GenModel genModel)
{
return genModel.canGenerate();
}
},
EDIT
{
@Override
public String getID()
{
return GenBaseGeneratorAdapter.EDIT_PROJECT_TYPE;
}
@Override
public String getLabel()
{
return GenModelEditPlugin.INSTANCE.getString("_UI_Edit_title");
}
@Override
public boolean canGenerate(GenModel genModel)
{
return genModel.canGenerateEdit();
}
},
EDITOR
{
@Override
public String getID()
{
return GenBaseGeneratorAdapter.EDITOR_PROJECT_TYPE;
}
@Override
public String getLabel()
{
return GenModelEditPlugin.INSTANCE.getString("_UI_Editor_title");
}
@Override
public boolean canGenerate(GenModel genModel)
{
return genModel.canGenerateEditor();
}
},
TESTS
{
@Override
public String getID()
{
return GenBaseGeneratorAdapter.TESTS_PROJECT_TYPE;
}
@Override
public String getLabel()
{
return GenModelEditPlugin.INSTANCE.getString("_UI_Tests_title");
}
@Override
public boolean canGenerate(GenModel genModel)
{
return genModel.canGenerateTests();
}
};
public abstract boolean canGenerate(GenModel genModel);
public abstract String getID();
public abstract String getLabel();
}
protected List<GenModel> genModels;
protected List<Object[]> generatorAndArgumentsList;
protected boolean startWithProjectSelected = true;
protected Point size;
protected Point location;
protected Table genModelTable;
protected CLabel genModelLabel;
protected boolean showBackButton = false;
public GenModelGenerationDialog(Shell shell, List<GenModel> genModels)
{
super(shell);
this.genModels = genModels;
setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX);
}
public boolean isShowBackButton()
{
return showBackButton;
}
public void setShowBackButton(boolean showBackButton)
{
this.showBackButton = showBackButton;
}
public List<Object[]> getGeneratorAndArgumentsList()
{
if (generatorAndArgumentsList == null)
{
generatorAndArgumentsList = new ArrayList<Object[]>();
}
return generatorAndArgumentsList;
}
public void initialize(Point size, Point location)
{
this.size = size;
this.location = location;
}
public Point getSize()
{
return size;
}
public Point getLocation()
{
return location;
}
@Override
protected void configureShell(Shell newShell)
{
super.configureShell(newShell);
newShell.setText(GenModelEditPlugin.INSTANCE.getString("_UI_GenModelGenerationDialog_title"));
}
@Override
public void create()
{
super.create();
if (size != null)
{
Point shellSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
getShell().setSize(Math.max(shellSize.x, size.x), size.y);
}
if (location != null)
{
getShell().setLocation(location);
}
if (genModelTable.getSelectionCount() == 0)
{
genModelTable.select(0);
selectionChanged((GenModel)genModelTable.getItem(0).getData());
}
}
@Override
protected Control createDialogArea(Composite parent)
{
Composite composite = (Composite)super.createDialogArea(parent);
createControls(composite);
refresh();
return composite;
}
protected void createControls(Composite parent)
{
createTable(parent);
createGenModelDetailControl(parent);
}
@Override
protected void createButtonsForButtonBar(Composite parent)
{
if (isShowBackButton())
{
Button backButton = createButton(parent, IDialogConstants.BACK_ID, IDialogConstants.BACK_LABEL, false);
Listener backButtonListener = new Listener()
{
public void handleEvent(Event event)
{
setReturnCode(IDialogConstants.BACK_ID);
close();
}
};
backButton.addListener(SWT.Selection, backButtonListener);
Button button = createButton(parent, IDialogConstants.NEXT_ID, IDialogConstants.NEXT_LABEL, false);
button.setEnabled(false);
}
super.createButtonsForButtonBar(parent);
if (isShowBackButton())
{
getButton(IDialogConstants.OK_ID).setText(IDialogConstants.FINISH_LABEL);
}
updateButtons(false);
}
protected void createTable(Composite parent)
{
CLabel label = new CLabel(parent, SWT.NONE);
label.setText(GenModelEditPlugin.INSTANCE.getString("_UI_GenModelGenerationDialog_message"));
genModelTable = new Table(parent, SWT.BORDER);
genModelTable.setLinesVisible(true);
genModelTable.setHeaderVisible(true);
GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
genModelTable.setLayoutData(gridData);
Listener tableListener = new Listener()
{
public void handleEvent(Event event)
{
if (genModelTable.getSelectionCount() == 1)
{
if (event.type == SWT.MouseDoubleClick)
{
Boolean select = null;
TableColumn[] tableColumns = genModelTable.getColumns();
for (int i=1; i < tableColumns.length; i++)
{
select = checkBoxColumnHeaderSelected(tableColumns[i], genModelTable.getSelectionIndex(), select);
}
updateButtons(select);
}
TableItem tableItem = genModelTable.getSelection()[0];
selectionChanged((GenModel)tableItem.getData());
}
}
};
genModelTable.addListener(SWT.Selection, tableListener);
genModelTable.addListener(SWT.MouseDoubleClick, tableListener);
TableColumn genModelColumn = new TableColumn(genModelTable, SWT.NONE);
genModelColumn.setText(GenModelEditPlugin.INSTANCE.getString("_UI_GenModelFile_title"));
Listener genModelColumnListener = new Listener()
{
public void handleEvent(Event event)
{
Boolean select = null;
TableColumn[] tableColumns = genModelTable.getColumns();
for (int i=1; i < tableColumns.length; i++)
{
select = checkBoxColumnHeaderSelected(tableColumns[i], -1, select);
}
updateButtons(select);
}
};
genModelColumn.addListener(SWT.Selection, genModelColumnListener);
Listener checkBoxColumnListener = new Listener()
{
public void handleEvent(Event event)
{
TableColumn tableColumn = (TableColumn)event.widget;
Boolean select = checkBoxColumnHeaderSelected(tableColumn, -1, null);
updateButtons(select);
}
};
int maxWidth = 0;
for (ProjectType projectType : ProjectType.values())
{
maxWidth = Math.max(maxWidth, createCheckBoxColumn(projectType, checkBoxColumnListener));
}
TableColumn[] tableColumns = genModelTable.getColumns();
for (int i=1; i < tableColumns.length; i++)
{
tableColumns[i].setWidth(maxWidth);
}
}
protected int createCheckBoxColumn(ProjectType projectType, Listener listener)
{
TableColumn tableColumn = new TableColumn(genModelTable, SWT.NONE);
tableColumn.setText(" " + projectType.getLabel() + " ");
tableColumn.setData("type", projectType);
tableColumn.setResizable(false);
tableColumn.pack();
tableColumn.addListener(SWT.Selection, listener);
return tableColumn.getWidth();
}
protected Boolean checkBoxColumnHeaderSelected(TableColumn tableColumn, int itemIndex, Boolean select)
{
@SuppressWarnings("unchecked")
List<Button> buttons = (List<Button>)tableColumn.getData("buttons");
if (buttons != null && !buttons.isEmpty())
{
if (itemIndex > -1)
{
buttons = buttons.subList(itemIndex, itemIndex+1);
}
for (Button button : buttons)
{
if (button.isEnabled())
{
if (select == null)
{
select = !button.getSelection();
}
button.setSelection(select);
}
}
}
return select;
}
protected void selectionChanged(GenModel genModel)
{
StringBuilder text = new StringBuilder();
for (GenPackage genPackage : genModel.getGenPackages())
{
text.append(", ").append(genPackage.getEcorePackage().getNsURI());
}
Image image = ExtendedImageRegistry.INSTANCE.getImage(URI.createPlatformPluginURI("/org.eclipse.emf.ecore.edit/icons/full/obj16/EPackage.gif", false));
genModelLabel.setImage(image);
genModelLabel.setText(text.substring(", ".length()));
}
protected void refresh()
{
genModelLabel.setText("");
genModelTable.clearAll();
TableColumn[] tableColumns = genModelTable.getColumns();
for (int i=1; i < tableColumns.length; i++)
{
@SuppressWarnings("unchecked")
List<Button> buttons = (List<Button>)tableColumns[i].getData("buttons");
if (buttons != null)
{
for (Button button : buttons)
{
button.dispose();
}
buttons.clear();
}
else
{
tableColumns[i].setData("buttons", new ArrayList<Button>());
}
}
for (GenModel genModel : genModels)
{
TableItem tableItem = new TableItem(genModelTable, SWT.NONE);
tableItem.setText(0, genModel.eResource().getURI().toPlatformString(true) + " ");
tableItem.setImage(ExtendedImageRegistry.INSTANCE.getImage(URI.createPlatformPluginURI("/org.eclipse.emf.codegen.ecore.ui/icons/full/obj16/GenModel.gif", false)));
tableItem.setData(genModel);
for (int i=1; i < tableColumns.length; i++)
{
TableColumn tableColumn = tableColumns[i];
ProjectType projectType = (ProjectType)tableColumn.getData("type");
Button button = new Button(genModelTable, SWT.CHECK);
if (projectType.canGenerate(genModel))
{
button.setSelection(startWithProjectSelected);
}
else
{
button.setEnabled(false);
}
button.pack();
Listener buttonListener = new Listener()
{
public void handleEvent(Event event)
{
updateButtons(((Button)event.widget).getSelection());
}
};
button.addListener(SWT.Selection, buttonListener);
@SuppressWarnings("unchecked")
List<Button> buttons = (List<Button>)tableColumn.getData("buttons");
buttons.add(button);
TableEditor editor = new TableEditor(genModelTable);
editor.minimumWidth = button.getSize().x;
editor.horizontalAlignment = SWT.CENTER;
editor.setEditor(button, tableItem, i);
}
}
tableColumns[0].pack();
updateButtons(false);
}
protected void createGenModelDetailControl(Composite parent)
{
ViewForm viewForm = new ViewForm(parent, SWT.BORDER | SWT.FLAT);
viewForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
genModelLabel = new CLabel(viewForm, SWT.FLAT);
genModelLabel.setFont(parent.getFont());
genModelLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
genModelLabel.setToolTipText(GenModelEditPlugin.INSTANCE.getString("_UI_GenModelGenerationDetail_message"));
genModelLabel.pack();
viewForm.setContent(genModelLabel);
}
@Override
protected void okPressed()
{
getGeneratorAndArgumentsList().addAll(prepareGenerators());
super.okPressed();
}
protected void updateButtons(Boolean hasSelection)
{
Button okButton = getButton(IDialogConstants.OK_ID);
if (okButton != null)
{
if (hasSelection == null)
{
hasSelection = false;
}
else if (!hasSelection)
{
TableColumn[] tableColumns = genModelTable.getColumns();
LOOP:
for (int column=1; column < tableColumns.length; column++)
{
@SuppressWarnings("unchecked")
List<Button> buttons = (List<Button>)tableColumns[column].getData("buttons");
for (Button button : buttons)
{
hasSelection |= button.isEnabled() && button.getSelection();
if (hasSelection)
{
break LOOP;
}
}
}
}
okButton.setEnabled(hasSelection);
}
}
@Override
public boolean close()
{
location = getShell().getLocation();
size = getShell().getSize();
return super.close();
}
protected List<Object[]> prepareGenerators()
{
TableColumn[] tableColumns = genModelTable.getColumns();
TableItem[] tableItems = genModelTable.getItems();
List<Object[]> generatorAndArgumentsList = new ArrayList<Object[]>(tableItems.length*(tableColumns.length-1));
for (int line=0; line < tableItems.length; line++)
{
GenModel genModel = (GenModel)tableItems[line].getData();
for (int column=1; column < tableColumns.length; column++)
{
@SuppressWarnings("unchecked")
Button button = ((List<Button>)tableColumns[column].getData("buttons")).get(line);
if (button.isEnabled() && button.getSelection())
{
ProjectType projectType = (ProjectType)tableColumns[column].getData("type");
Generator generator = GenModelUtil.createGenerator(genModel);
Object[] generatorAndArguments = new Object[4];
generatorAndArguments[0] = generator;
generatorAndArguments[1] = genModel;
generatorAndArguments[2] = projectType.getID();
generatorAndArguments[3] = projectType.getLabel();
generatorAndArgumentsList.add(generatorAndArguments);
}
}
}
return generatorAndArgumentsList;
}
}
protected Point dialogSize = null;
protected Point dialogLocation = null;
/* (non-Javadoc)
* @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
*/
public Object execute(ExecutionEvent event) throws ExecutionException
{
Shell shell = HandlerUtil.getActiveShell(event);
List<GenModel> genModels = null;
boolean usingSelection = false;
ISelection selection = HandlerUtil.getCurrentSelection(event);
if (selection instanceof IStructuredSelection)
{
Object[] selectedObjects = ((IStructuredSelection)selection).toArray();
if (selectedObjects.length >= 1)
{
IProgressMonitor progressMonitor = new NullProgressMonitor();
List<URI> uris = getGenModelURIs(progressMonitor, selectedObjects);
if (!uris.isEmpty())
{
genModels = GeneratorUIUtil.loadGenModels(progressMonitor, uris, shell);
if (genModels.isEmpty())
return null;
usingSelection = true;
}
}
}
if (!usingSelection)
{
GenModelSelectionDialog selectionDialog =
new GenModelSelectionDialog(shell, true, ResourcesPlugin.getWorkspace().getRoot(), IResource.FILE);
selectionDialog.initialize(dialogSize, dialogLocation);
selectionDialog.setTitle(GenModelEditPlugin.INSTANCE.getString("_UI_GenModelSelectionDialog_title"));
selectionDialog.setInitialPattern("*.genmodel");
if (selectionDialog.open() == Window.OK)
{
dialogSize = selectionDialog.getSize();
dialogLocation = selectionDialog.getLocation();
genModels = selectionDialog.getGenModels();
}
}
if (genModels != null && !genModels.isEmpty())
{
GenModelGenerationDialog generationDialog = new GenModelGenerationDialog(shell, genModels);
generationDialog.setShowBackButton(!usingSelection);
generationDialog.initialize(dialogSize, dialogLocation);
int ret = generationDialog.open();
if (ret == Window.OK)
{
try
{
new ProgressMonitorDialog(shell).run(true, true, new GeneratorUIUtil.GeneratorOperation(shell, generationDialog.getGeneratorAndArgumentsList()));
}
catch (Exception exception)
{
GenModelEditPlugin.INSTANCE.log(exception);
}
}
else if (ret == IDialogConstants.BACK_ID)
{
dialogSize = generationDialog.getSize();
dialogLocation = generationDialog.getLocation();
execute(event);
}
}
return null;
}
}