blob: 1bca1c97c1daec156c1422b210097826258df500 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2016 Red Hat Inc. 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:
* Rastislav Wagner (Red Hat)
* Patrick Tasse - Remove dialog parent shell
*******************************************************************************/
package org.eclipse.swtbot.generator.jdt.editor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration;
import org.eclipse.jdt.ui.text.JavaTextTools;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.VerticalRuler;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swtbot.generator.SWTBotGeneratorPlugin;
import org.eclipse.swtbot.generator.framework.GenerationRule;
import org.eclipse.swtbot.generator.framework.Generator;
import org.eclipse.swtbot.generator.framework.IRecorderDialog;
import org.eclipse.swtbot.generator.jdt.editor.document.ClassDocument;
import org.eclipse.swtbot.generator.jdt.editor.listener.AnnotationSelectionListener;
import org.eclipse.swtbot.generator.jdt.editor.listener.ClassAnnotationSelectionListener;
import org.eclipse.swtbot.generator.jdt.editor.listener.MethodSelectionListener;
import org.eclipse.swtbot.generator.ui.BotGeneratorEventDispatcher;
import org.eclipse.swtbot.generator.ui.BotGeneratorEventDispatcher.CodeGenerationListener;
import org.eclipse.ui.plugin.AbstractUIPlugin;
public class JDTRecorderDialog extends TitleAreaDialog implements IRecorderDialog{
private BotGeneratorEventDispatcher recorder;
private List<Generator> availableGenerators;
private Map<CTabItem, SourceViewer> tabViewer;
private Map<CTabItem, ToolBar> tabToolBar;
private CTabFolder classTabFolder;
private Button recordPauseButton;
private MethodSelectionListener methodListener;
private List<Shell> ignoredShells;
public static final String ID = "org.eclipse.swtbot.generator.dialog.jdt"; //$NON-NLS-1$
private Image wizban;
private Image icon;
/**
* Create the dialog.
*
*/
public JDTRecorderDialog() {
super(null);
ignoredShells = new ArrayList<Shell>();
this.tabViewer = new HashMap<CTabItem, SourceViewer>();
setShellStyle(SWT.CLOSE | SWT.MODELESS | SWT.BORDER | SWT.TITLE | SWT.RESIZE | SWT.MAX);
setBlockOnOpen(false);
this.tabToolBar = new HashMap<CTabItem, ToolBar>();
}
@Override
public void create() {
this.wizban = AbstractUIPlugin.imageDescriptorFromPlugin(SWTBotGeneratorPlugin.PLUGIN_ID, "icons/swtbot_rec64.png").createImage(); //$NON-NLS-1$
this.icon = AbstractUIPlugin.imageDescriptorFromPlugin(SWTBotGeneratorPlugin.PLUGIN_ID, "icons/swtbot_rec16.png").createImage(); //$NON-NLS-1$
super.create();
getShell().setImage(this.icon);
getShell().setText("SWTBot Test Recorder");
setMessage("This dialog will track the generated code while you're recording your UI scenario.");
setTitle("SWTBot Test Recorder");
setTitleImage(this.wizban);
ignoredShells.add(getShell());
}
/**
* Create contents of the dialog.
*
* @param parent
*/
@Override
protected Control createDialogArea(Composite parent) {
Composite container = (Composite) super.createDialogArea(parent);
container.setLayout(new GridLayout(1, false));
container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Composite generatorSelectionContainer = new Composite(container,SWT.NONE);
generatorSelectionContainer.setLayout(new GridLayout(2, false));
Label selectorLabel = new Label(generatorSelectionContainer, SWT.NONE);
selectorLabel.setText("Target Bot API:");
selectorLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false,false));
ComboViewer generatorSelectionCombo = new ComboViewer(generatorSelectionContainer);
generatorSelectionCombo.setContentProvider(new ArrayContentProvider());
generatorSelectionCombo.setLabelProvider(new LabelProvider() {
@Override
public String getText(Object o) {
return ((Generator) o).getLabel();
}
});
generatorSelectionCombo.setInput(this.availableGenerators);
generatorSelectionCombo.setSelection(new StructuredSelection(this.recorder.getCurrentGenerator()));
generatorSelectionCombo.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
Generator newGenerator = (Generator) ((IStructuredSelection) event.getSelection()).getFirstElement();
recorder.setGenerator(newGenerator);
updateAnnotationToolBar();
Image image = newGenerator.getImage();
if(image != null){
image = new Image(Display.getDefault(), image.getImageData().scaledTo(80,80));
setTitleImage(image);
} else {
setTitleImage(null);
}
}
});
classTabFolder = new CTabFolder(container, SWT.CLOSE |SWT.BORDER);
classTabFolder.setUnselectedCloseVisible(false);
classTabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,true));
ToolBar addClassToolbar = new ToolBar(classTabFolder, SWT.HORIZONTAL);
classTabFolder.setTopRight(addClassToolbar);
ToolItem addClassItem = new ToolItem(addClassToolbar, SWT.NONE);
addClassItem.setText("+");
addClassItem.setToolTipText("Add class");
addClassItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
openClassShell();
}
});
createTabItem(classTabFolder, "RecordedTestCase");
classTabFolder.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(org.eclipse.swt.events.SelectionEvent event) {
SourceViewer viewer = tabViewer.get(classTabFolder.getSelection());
ClassDocument doc = (ClassDocument) viewer.getDocument();
if (doc.getActiveMethod() == null) {
recorder.setRecording(false);
recordPauseButton.setText("Start Recording");
}
updateAnnotationToolBar();
}
});
Composite actionsComposite = new Composite(container, SWT.NONE);
actionsComposite.setLayout(new RowLayout(SWT.HORIZONTAL));
recordPauseButton = new Button(actionsComposite, SWT.PUSH);
recordPauseButton.setText("Start Recording");
final Button copyButton = new Button(actionsComposite, SWT.PUSH);
copyButton.setText("Copy");
recordPauseButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (recorder.isRecording()) {
recorder.setRecording(false);
recordPauseButton.setText("Start Recording");
} else {
SourceViewer viewer = tabViewer.get(classTabFolder.getSelection());
ClassDocument doc = (ClassDocument) viewer.getDocument();
if(doc.getActiveMethod() == null){
openMethodShell(true);
} else {
recorder.setRecording(true);
recordPauseButton.setText("Pause");
}
}
}
});
this.recorder.addListener(new CodeGenerationListener() {
public void handleCodeGenerated(GenerationRule code) {
SourceViewer viewer = tabViewer.get(classTabFolder.getSelection());
ClassDocument doc = (ClassDocument) viewer.getDocument();
doc.addGenerationRule(code);
viewer.setTopIndex(((ClassDocument) viewer.getDocument()).getLastOffset()-4);
}
});
copyButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
final Clipboard cb = new Clipboard(Display.getDefault());
TextTransfer textTransfer = TextTransfer.getInstance();
SourceViewer viewer = tabViewer.get(classTabFolder.getSelection());
cb.setContents(new Object[] { viewer.getDocument().get() }, new Transfer[] { textTransfer });
cb.dispose();
}
});
return container;
}
private void createTabItem(final CTabFolder tabFolder, String text) {
CTabItem tabItem = new CTabItem(tabFolder, SWT.NONE);
tabItem.setText(text);
Composite composite = new Composite(tabFolder, SWT.NONE);
GridLayout gridLayout = new GridLayout();
composite.setLayout(gridLayout);
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
ToolBar toolBar = new ToolBar(composite, SWT.HORIZONTAL);
tabToolBar.put(tabItem, toolBar);
RowLayout rLayout = new RowLayout();
rLayout.fill = true;
rLayout.justify = true;
toolBar.setLayout(rLayout);
ToolItem tItem = new ToolItem(toolBar, SWT.PUSH);
tItem.setText("Add method");
ToolItem methodItemDropDown = new ToolItem(toolBar, SWT.DROP_DOWN);
methodItemDropDown.setText("No active method");
ToolItem annotationsToolItem = new ToolItem(toolBar, SWT.DROP_DOWN);
annotationsToolItem.setText("Method annotation");
ToolItem annotationsClassToolItem = new ToolItem(toolBar, SWT.DROP_DOWN);
annotationsClassToolItem.setText("Class annotation");
methodListener = new MethodSelectionListener(methodItemDropDown, recorder,tabViewer,classTabFolder,annotationsToolItem);
methodItemDropDown.addSelectionListener(methodListener);
tItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent arg0) {
openMethodShell(false);
}
});
// create editor with syntax coloring
final ClassDocument doc = new ClassDocument(
text,
this.recorder.getCurrentGenerator().getLabel().toUpperCase().contains("SWTBOT") ? "org.eclipse.swtbot.eclipse.finder.SWTBotEclipseTestCase" : null);
final SourceViewer generatedCode = new SourceViewer(composite, new VerticalRuler(0), SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
JavaSourceViewerConfiguration javaConf = new JavaSourceViewerConfiguration(JavaUI.getColorManager(), PreferenceConstants.getPreferenceStore(), null, null);
generatedCode.configure(javaConf);
JavaTextTools tools = new JavaTextTools(PreferenceConstants.getPreferenceStore());
tools.setupJavaDocumentPartitioner(doc);
generatedCode.setDocument(doc);
generatedCode.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
generatedCode.setEditable(false);
tabItem.setControl(composite);
tabFolder.setSelection(tabItem);
tabViewer.put(tabItem, generatedCode);
doc.setViewer(generatedCode);
final AnnotationSelectionListener listenerAnnot = new AnnotationSelectionListener(annotationsToolItem, recorder,tabViewer,classTabFolder);
annotationsToolItem.addSelectionListener(listenerAnnot);
annotationsToolItem.setData(listenerAnnot);
final ClassAnnotationSelectionListener listenerClassAnnot = new ClassAnnotationSelectionListener(annotationsClassToolItem, recorder,tabViewer,classTabFolder);
annotationsClassToolItem.addSelectionListener(listenerClassAnnot);
annotationsClassToolItem.setData(listenerClassAnnot);
listenerAnnot.update();
}
private void openClassShell(){
final AddClassDialog d = new AddClassDialog(getShell());
this.getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
if(Window.OK == d.open()){
String classText = d.getClassName();
createTabItem(classTabFolder, classText);
recorder.setRecording(false);
recordPauseButton.setText("Start Recording");
}
}
});
}
private void openMethodShell(final boolean fromStartButton){
SourceViewer viewer = tabViewer.get(classTabFolder.getSelection());
final ClassDocument doc = (ClassDocument) viewer.getDocument();
final AddMethodDialog d = new AddMethodDialog(getShell(), doc.getMethods());
this.getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
if(Window.OK == d.open()){
String methodText = d.getMethodName();
doc.addMethod(methodText);
methodListener.add(methodText);
if(fromStartButton){
recorder.setRecording(true);
recordPauseButton.setText("Pause");
}
updateAnnotationToolBar();
}
}
});
}
@Override
protected Point getInitialSize() {
return new Point(585, 650);
}
@Override
public void createButtonsForButtonBar(Composite parent) {
// Override to remove default buttons
}
public BotGeneratorEventDispatcher getRecorder() {
return recorder;
}
public void setRecorder(BotGeneratorEventDispatcher recorder) {
this.recorder = recorder;
}
public List<Generator> getAvailableGenerators() {
return availableGenerators;
}
public void setAvailableGenerators(List<Generator> availableGenerators) {
this.availableGenerators = availableGenerators;
}
public List<Shell> getIgnoredShells() {
return ignoredShells;
}
public String getName() {
return "JDT Dialog";
}
public String getId() {
return ID;
}
public void setRecording(boolean record){
recorder.setRecording(record);
if(record){
recordPauseButton.setText("Pause");
} else {
recordPauseButton.setText("Start Recording");
}
}
public String getGeneratedCodeText(){
SourceViewer viewer = tabViewer.get(classTabFolder.getSelection());
ClassDocument doc = (ClassDocument) viewer.getDocument();
return doc.get();
}
private void updateAnnotationToolBar(){
ToolBar activeToolBar = tabToolBar.get(classTabFolder.getSelection());
for(ToolItem item: activeToolBar.getItems()){
if(item.getData() instanceof AnnotationSelectionListener){
((AnnotationSelectionListener)item.getData()).addItems(recorder.getCurrentGenerator().createAnnotationRules());
((AnnotationSelectionListener)item.getData()).update();
} else if(item.getData() instanceof ClassAnnotationSelectionListener){
((ClassAnnotationSelectionListener)item.getData()).addItems(recorder.getCurrentGenerator().createAnnotationRules());
((ClassAnnotationSelectionListener)item.getData()).update();
}
}
}
@Override
public boolean close() {
this.wizban.dispose();
this.icon.dispose();
return super.close();
}
}