blob: 5a0f9cd0ffe1fecd5e27a9977c7f5329de926d86 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2016 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 Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.swt.tools.internal;
import java.io.*;
import java.lang.reflect.*;
import org.eclipse.swt.*;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class JNIGeneratorAppUI {
Display display;
Shell shell;
Composite actionsPanel;
Combo mainClassCb, outputDirCb;
Table classesLt, membersLt, paramsLt;
ProgressBar progressBar;
Label progressLabel;
FileDialog fileDialog;
TableEditor paramTextEditor, memberTextEditor, classTextEditor;
FlagsEditor paramListEditor, memberListEditor, classListEditor;
Text paramEditorTx, memberEditorTx, classEditorTx;
List paramEditorLt, memberEditorLt, classEditorLt;
static class FlagsEditor {
Table parent;
int column = -1;
TableItem item;
public FlagsEditor(Table parent) {
this.parent = parent;
}
public int getColumn() {
return column;
}
public TableItem getItem() {
return item;
}
public void setColumn(int column) {
this.column = column;
}
public void setItem(TableItem item) {
this.item = item;
}
}
JNIGeneratorApp app;
static final int CLASS_NAME_COLUMN = 0;
static final int CLASS_FLAGS_COLUMN = 1;
static final int CLASS_EXCLUDE_COLUMN = 2;
static final int FIELD_NAME_COLUMN = 0;
static final int FIELD_FLAGS_COLUMN = 1;
static final int FIELD_CAST_COLUMN = 2;
static final int FIELD_ACCESSOR_COLUMN = 3;
static final int FIELD_EXCLUDE_COLUMN = 4;
static final int METHOD_NAME_COLUMN = 0;
static final int METHOD_FLAGS_COLUMN = 1;
static final int METHOD_ACCESSOR_COLUMN = 2;
static final int METHOD_EXCLUDE_COLUMN = 3;
static final int PARAM_INDEX_COLUMN = 0;
static final int PARAM_TYPE_COLUMN = 1;
static final int PARAM_FLAGS_COLUMN = 2;
static final int PARAM_CAST_COLUMN = 3;
public JNIGeneratorAppUI() {
this (new JNIGeneratorApp());
}
public JNIGeneratorAppUI(JNIGeneratorApp app) {
this.app = app;
}
void cleanup() {
display.dispose();
}
void generateStructsHeader () {
StructsGenerator gen = new StructsGenerator(true);
gen.setMainClass(app.getMainClass());
gen.setMetaData(app.getMetaData());
gen.setClasses(getSelectedClasses());
gen.generate();
}
void generateStructs () {
StructsGenerator gen = new StructsGenerator(false);
gen.setMainClass(app.getMainClass());
gen.setMetaData(app.getMetaData());
gen.setClasses(getSelectedClasses());
gen.generate();
}
void generateSizeof () {
SizeofGenerator gen = new SizeofGenerator();
gen.setMainClass(app.getMainClass());
gen.setMetaData(app.getMetaData());
gen.setClasses(getSelectedClasses());
gen.generate();
}
void generateMetaData () {
MetaDataGenerator gen = new MetaDataGenerator();
gen.setMainClass(app.getMainClass());
gen.setMetaData(app.getMetaData());
JNIMethod[] methods = getSelectedMethods();
if (methods.length != 0) {
gen.generate(methods);
} else {
gen.setClasses(getSelectedClasses());
gen.generate();
}
}
void generateNatives () {
NativesGenerator gen = new NativesGenerator();
gen.setMainClass(app.getMainClass());
gen.setMetaData(app.getMetaData());
JNIMethod[] methods = getSelectedMethods();
if (methods.length != 0) {
gen.generate(methods);
} else {
gen.setClasses(getSelectedClasses());
gen.generate();
}
}
void generateAll() {
if (!updateOutputDir()) return;
Cursor cursor = display.getSystemCursor(SWT.CURSOR_WAIT);
shell.setCursor(cursor);
shell.setEnabled(false);
Control[] children = actionsPanel.getChildren();
for (int i = 0; i < children.length; i++) {
Control child = children[i];
if (child instanceof Button) child.setEnabled(false);
}
boolean showProgress = true;
final boolean finalShowProgress = showProgress; /* avoid dead code warning below */
if (showProgress) {
progressLabel.setText("");
progressBar.setSelection(0);
progressLabel.setVisible(true);
progressBar.setVisible(true);
}
final boolean[] done = new boolean[1];
new Thread() {
@Override
public void run() {
try {
app.generate(!finalShowProgress ? null : new ProgressMonitor() {
int total, step, maximum = 100;
@Override
public void setTotal(final int total) {
this.total = total;
display.syncExec(() -> progressBar.setMaximum(maximum));
}
@Override
public void step() {
int oldValue = step * maximum / total;
step++;
final int newValue = step * maximum / total;
if (oldValue == newValue) return;
display.syncExec(() -> progressBar.setSelection(newValue));
}
@Override
public void setMessage(final String message) {
display.syncExec(() -> {
progressLabel.setText(message);
progressLabel.update();
});
}
});
} finally {
done[0] = true;
display.wake();
}
}
}.start();
while (!done[0]) {
if (!display.readAndDispatch()) display.sleep();
}
for (int i = 0; i < children.length; i++) {
Control child = children[i];
if (child instanceof Button) child.setEnabled(true);
}
if (showProgress) {
progressBar.setVisible(false);
progressLabel.setVisible(false);
}
shell.setEnabled(true);
shell.setCursor(null);
}
void generateConstants () {
ConstantsGenerator gen = new ConstantsGenerator();
gen.setMainClass(app.getMainClass());
gen.setMetaData(app.getMetaData());
JNIField[] fields = getSelectedFields();
if (fields.length != 0) {
gen.generate(fields);
} else {
gen.setClasses(getSelectedClasses());
gen.generate();
}
}
JNIClass[] getSelectedClasses() {
TableItem[] items = classesLt.getSelection();
JNIClass[] classes = new JNIClass[items.length];
for (int i = 0; i < items.length; i++) {
TableItem item = items[i];
classes[i] = (JNIClass)item.getData();
}
return classes;
}
JNIMethod[] getSelectedMethods() {
TableItem[] selection = membersLt.getSelection();
JNIMethod[] methods = new JNIMethod[selection.length];
int count = 0;
for (int i = 0; i < selection.length; i++) {
TableItem item = selection [i];
Object data = item.getData();
if (data instanceof JNIMethod) {
methods[count++] = (JNIMethod)data;
}
}
if (count != methods.length) {
JNIMethod[] result = new JNIMethod[count];
System.arraycopy(methods, 0, result, 0, count);
methods = result;
}
return methods;
}
JNIField[] getSelectedFields() {
TableItem[] selection = membersLt.getSelection();
JNIField[] fields = new JNIField[selection.length];
int count = 0;
for (int i = 0; i < selection.length; i++) {
TableItem item = selection [i];
Object data = item.getData();
if (data instanceof JNIField) {
fields[count++] = (JNIField)data;
}
}
if (count != fields.length) {
JNIField[] result = new JNIField[count];
System.arraycopy(fields, 0, result, 0, count);
fields = result;
}
return fields;
}
public void open () {
display = new Display();
shell = new Shell(display);
shell.setText("JNI Generator");
GridData data;
GridLayout shellLayout = new GridLayout();
shellLayout.numColumns = 2;
shell.setLayout(shellLayout);
Composite panel = new Composite(shell, SWT.NONE);
data = new GridData(GridData.FILL_BOTH);
panel.setLayoutData(data);
GridLayout panelLayout = new GridLayout();
panelLayout.numColumns = 1;
panel.setLayout(panelLayout);
Listener updateMainClassListener = e -> {
updateMainClass();
if (!updateOutputDir()) return;
updateClasses();
updateMembers();
updateParameters();
};
createMainClassPanel(panel, updateMainClassListener);
createClassesPanel(panel);
createMembersPanel(panel);
createParametersPanel(panel);
createActionButtons(shell);
Point preferredSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
shell.setSize(shell.getSize().x, preferredSize.y);
updateMainClass();
updateClasses();
updateMembers();
updateParameters();
}
void createMainClassPanel(Composite panel, Listener updateListener) {
Label mainClassLb = new Label(panel, SWT.NONE);
mainClassLb.setText("&Main Class:");
GridData data;
mainClassCb = new Combo(panel, SWT.DROP_DOWN);
String mainClass = app.getMainClassName();
mainClassCb.setText(mainClass == null ? "" : mainClass);
data = new GridData(GridData.FILL_HORIZONTAL);
mainClassCb.setLayoutData(data);
mainClassCb.addListener(SWT.Selection, updateListener);
mainClassCb.addListener(SWT.DefaultSelection, updateListener);
Label outputDirLb = new Label(panel, SWT.NONE);
outputDirLb.setText("&Output Dir:");
outputDirCb = new Combo(panel, SWT.DROP_DOWN);
String outputDir = app.getOutputDir();
outputDirCb.setText(outputDir == null ? "" : outputDir);
data = new GridData(GridData.FILL_HORIZONTAL);
outputDirCb.setLayoutData(data);
outputDirCb.addListener(SWT.Selection, updateListener);
outputDirCb.addListener(SWT.DefaultSelection, updateListener);
String mainClasses = app.getMetaData().getMetaData("swt_main_classes", null);
if (mainClasses != null) {
String[] list = JNIGenerator.split(mainClasses, ",");
for (int i = 0; i < list.length; i += 2) {
String className = list[i].trim();
try {
Class.forName(className, false, getClass().getClassLoader());
mainClassCb.add(className);
outputDirCb.add(list[i + 1].trim());
} catch (Exception e) {}
}
}
}
void createClassesPanel(Composite panel) {
Label classesLb = new Label(panel, SWT.NONE);
classesLb.setText("&Classes:");
GridData data;
classesLt = new Table(panel, SWT.CHECK | SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
data = new GridData(GridData.FILL_BOTH);
data.heightHint = classesLt.getItemHeight() * 6;
classesLt.setLayoutData(data);
classesLt.setHeaderVisible(true);
classesLt.addListener(SWT.Selection, e -> {
if (e.detail == SWT.CHECK) {
updateGenerate((TableItem)e.item);
} else {
updateMembers();
updateParameters();
}
});
TableColumn column;
column = new TableColumn(classesLt, SWT.NONE, CLASS_NAME_COLUMN);
column.setText("Class");
column = new TableColumn(classesLt, SWT.NONE, CLASS_FLAGS_COLUMN);
column.setText("Flags");
/*
column = new TableColumn(classesLt, SWT.NONE, CLASS_EXCLUDE_COLUMN);
column.setText("Exclude");
*/
classTextEditor = new TableEditor(classesLt);
classTextEditor.grabHorizontal = true;
classEditorTx = new Text(classesLt, SWT.SINGLE);
classTextEditor.setEditor(classEditorTx);
Listener classTextListener = e -> {
if (e.type == SWT.Traverse) {
switch (e.detail) {
case SWT.TRAVERSE_ESCAPE:
classTextEditor.setItem(null);
break;
default:
return;
}
}
classEditorTx.setVisible(false);
TableItem item = classTextEditor.getItem();
if (item == null) return;
int column1 = classTextEditor.getColumn();
JNIClass clazz = (JNIClass)item.getData();
if (column1 == CLASS_EXCLUDE_COLUMN) {
String text = classEditorTx.getText();
clazz.setExclude(text);
item.setText(column1, clazz.getExclude());
classesLt.getColumn(column1).pack();
}
};
classEditorTx.addListener(SWT.DefaultSelection, classTextListener);
classEditorTx.addListener(SWT.FocusOut, classTextListener);
classEditorTx.addListener(SWT.Traverse, classTextListener);
final Shell floater = new Shell(shell, SWT.NO_TRIM);
floater.setLayout(new FillLayout());
classListEditor = new FlagsEditor(classesLt);
classEditorLt = new List(floater, SWT.MULTI | SWT.BORDER);
classEditorLt.setItems(JNIClass.FLAGS);
floater.pack();
floater.addListener(SWT.Close, e -> {
classListEditor.setItem(null);
e.doit = false;
floater.setVisible(false);
});
Listener classesListListener = e -> {
if (e.type == SWT.Traverse) {
switch (e.detail) {
case SWT.TRAVERSE_RETURN:
break;
default:
return;
}
}
floater.setVisible(false);
TableItem item = classListEditor.getItem();
if (item == null) return;
int column1 = classListEditor.getColumn();
JNIClass clazz = (JNIClass)item.getData();
if (column1 == CLASS_FLAGS_COLUMN) {
String[] flags = classEditorLt.getSelection();
clazz.setFlags(flags);
item.setText(column1, getFlagsString(clazz.getFlags()));
item.setChecked(clazz.getGenerate());
classesLt.getColumn(column1).pack();
}
};
classEditorLt.addListener(SWT.DefaultSelection, classesListListener);
classEditorLt.addListener(SWT.FocusOut, classesListListener);
classEditorLt.addListener(SWT.Traverse, classesListListener);
classesLt.addListener(SWT.MouseDown, e -> e.display.asyncExec (() -> {
if (classesLt.isDisposed ()) return;
if (e.button != 1) return;
Point pt = new Point(e.x, e.y);
TableItem item = classesLt.getItem(pt);
if (item == null) return;
int column1 = -1;
for (int i = 0; i < classesLt.getColumnCount(); i++) {
if (item.getBounds(i).contains(pt)) {
column1 = i;
break;
}
}
if (column1 == -1) return;
JNIClass data1 = (JNIClass)item.getData();
if (column1 == CLASS_EXCLUDE_COLUMN) {
classTextEditor.setColumn(column1);
classTextEditor.setItem(item);
classEditorTx.setText(data1.getExclude());
classEditorTx.selectAll();
classEditorTx.setVisible(true);
classEditorTx.setFocus();
} else if (column1 == CLASS_FLAGS_COLUMN) {
classListEditor.setColumn(column1);
classListEditor.setItem(item);
classEditorLt.setSelection(data1.getFlags());
floater.setLocation(classesLt.toDisplay(e.x, e.y));
floater.setVisible(true);
classEditorLt.setFocus();
}
}));
}
void createMembersPanel(Composite panel) {
GridData data;
Composite comp = new Composite(panel, SWT.NONE);
data = new GridData(GridData.FILL_HORIZONTAL);
comp.setLayoutData(data);
GridLayout layout = new GridLayout(2, false);
layout.marginWidth = layout.marginHeight = 0;
comp.setLayout(layout);
Label membersLb = new Label(comp, SWT.NONE);
membersLb.setText("Mem&bers [regex]:");
final Text searchText = new Text(comp, SWT.SINGLE | SWT.SEARCH);
searchText.setText(".*");
data = new GridData(GridData.FILL_HORIZONTAL);
searchText.setLayoutData(data);
searchText.addListener(SWT.DefaultSelection, new Listener() {
boolean match (int index, String pattern) {
TableItem item = membersLt.getItem(index);
String text = item.getText();
try {
if (text.matches(pattern)) {
membersLt.setSelection(index);
return true;
}
} catch (Exception ex) {}
return false;
}
@Override
public void handleEvent(Event e) {
String pattern = searchText.getText();
int selection = membersLt.getSelectionIndex();
int count = membersLt.getItemCount();
selection++;
for (int i = selection; i < count; i++) {
if (match (i, pattern)) return;
}
for (int i = 0; i < selection; i++) {
if (match (i, pattern)) return;
}
}
});
membersLt = new Table(panel, SWT.CHECK | SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
data = new GridData(GridData.FILL_BOTH);
data.heightHint = membersLt.getItemHeight() * 6;
membersLt.setLayoutData(data);
membersLt.addListener(SWT.Selection, e -> {
if (e.detail == SWT.CHECK) {
updateGenerate((TableItem)e.item);
} else {
updateParameters();
}
});
memberTextEditor = new TableEditor(membersLt);
memberTextEditor.grabHorizontal = true;
memberEditorTx = new Text(membersLt, SWT.SINGLE);
memberTextEditor.setEditor(memberEditorTx);
Listener memberTextListener = e -> {
if (e.type == SWT.Traverse) {
switch (e.detail) {
case SWT.TRAVERSE_ESCAPE:
memberTextEditor.setItem(null);
break;
default:
return;
}
}
memberEditorTx.setVisible(false);
TableItem item = memberTextEditor.getItem();
if (item == null) return;
int column = memberTextEditor.getColumn();
JNIItem memberData = (JNIItem)item.getData();
String text = memberEditorTx.getText();
if (memberData instanceof JNIField) {
JNIField field = (JNIField)memberData;
switch (column) {
case FIELD_CAST_COLUMN: {
field.setCast(text);
item.setText(column, field.getCast());
break;
}
case FIELD_ACCESSOR_COLUMN: {
field.setAccessor(text.equals(field.getName()) ? "" : text);
item.setText(column, field.getAccessor());
break;
}
case FIELD_EXCLUDE_COLUMN: {
field.setExclude(text);
item.setText(column, field.getExclude());
break;
}
}
membersLt.getColumn(column).pack();
} else if (memberData instanceof JNIMethod) {
JNIMethod method = (JNIMethod)memberData;
switch (column) {
case METHOD_ACCESSOR_COLUMN: {
method.setAccessor(text.equals(method.getName()) ? "" : text);
item.setText(column, method.getAccessor());
break;
}
case METHOD_EXCLUDE_COLUMN: {
method.setExclude(text);
item.setText(column, method.getExclude());
break;
}
}
membersLt.getColumn(column).pack();
}
};
memberEditorTx.addListener(SWT.DefaultSelection, memberTextListener);
memberEditorTx.addListener(SWT.FocusOut, memberTextListener);
memberEditorTx.addListener(SWT.Traverse, memberTextListener);
final Shell floater = new Shell(shell, SWT.NO_TRIM);
floater.setLayout(new FillLayout());
memberListEditor = new FlagsEditor(membersLt);
memberEditorLt = new List(floater, SWT.MULTI | SWT.BORDER);
floater.addListener(SWT.Close, e -> {
memberListEditor.setItem(null);
e.doit = false;
floater.setVisible(false);
});
Listener memberListListener = e -> {
if (e.type == SWT.Traverse) {
switch (e.detail) {
case SWT.TRAVERSE_RETURN:
break;
default:
return;
}
}
floater.setVisible(false);
TableItem item = memberListEditor.getItem();
if (item == null) return;
int column = memberListEditor.getColumn();
JNIItem data1 = (JNIItem)item.getData();
String[] flags = memberEditorLt.getSelection();
data1.setFlags(flags);
item.setText(column, getFlagsString(data1.getFlags()));
item.setChecked(data1.getGenerate());
membersLt.getColumn(column).pack();
};
memberEditorLt.addListener(SWT.DefaultSelection, memberListListener);
memberEditorLt.addListener(SWT.FocusOut, memberListListener);
memberEditorLt.addListener(SWT.Traverse, memberListListener);
membersLt.addListener(SWT.MouseDown, e -> e.display.asyncExec (() -> {
if (membersLt.isDisposed ()) return;
if (e.button != 1) return;
Point pt = new Point(e.x, e.y);
TableItem item = membersLt.getItem(pt);
if (item == null) return;
int column = -1;
for (int i = 0; i < membersLt.getColumnCount(); i++) {
if (item.getBounds(i).contains(pt)) {
column = i;
break;
}
}
if (column == -1) return;
Object itemData = item.getData();
if (itemData instanceof JNIField) {
JNIField field = (JNIField)itemData;
if (column == FIELD_CAST_COLUMN || column == FIELD_ACCESSOR_COLUMN || column == FIELD_EXCLUDE_COLUMN) {
memberTextEditor.setColumn(column);
memberTextEditor.setItem(item);
String text1 = "";
switch (column) {
case FIELD_CAST_COLUMN: text1 = field.getCast(); break;
case FIELD_ACCESSOR_COLUMN: {
text1 = field.getAccessor();
if (text1.length() == 0) {
text1 = field.getName();
int index = text1.lastIndexOf('_');
if (index != -1) {
char[] chars = text1.toCharArray();
chars[index] = '.';
text1 = new String(chars);
}
}
break;
}
case FIELD_EXCLUDE_COLUMN: text1 = field.getExclude(); break;
}
memberEditorTx.setText(text1);
memberEditorTx.selectAll();
memberEditorTx.setVisible(true);
memberEditorTx.setFocus();
} else if (column == FIELD_FLAGS_COLUMN) {
memberListEditor.setColumn(column);
memberListEditor.setItem(item);
memberEditorLt.setItems(JNIField.FLAGS);
memberEditorLt.setSelection(field.getFlags());
floater.setLocation(membersLt.toDisplay(e.x, e.y));
floater.pack();
floater.setVisible(true);
memberEditorLt.setFocus();
}
} else if (itemData instanceof JNIMethod) {
JNIMethod method = (JNIMethod)itemData;
if (column == METHOD_EXCLUDE_COLUMN || column == METHOD_ACCESSOR_COLUMN) {
memberTextEditor.setColumn(column);
memberTextEditor.setItem(item);
String text2 = "";
switch (column) {
case METHOD_ACCESSOR_COLUMN: {
text2 = method.getAccessor();
if (text2.length() == 0) text2 = method.getName();
break;
}
case METHOD_EXCLUDE_COLUMN: text2 = method.getExclude(); break;
}
memberEditorTx.setText(text2);
memberEditorTx.selectAll();
memberEditorTx.setVisible(true);
memberEditorTx.setFocus();
} else if (column == METHOD_FLAGS_COLUMN) {
memberListEditor.setColumn(column);
memberListEditor.setItem(item);
memberEditorLt.setItems(JNIMethod.FLAGS);
memberEditorLt.setSelection(method.getFlags());
floater.setLocation(membersLt.toDisplay(e.x, e.y));
floater.pack();
floater.setVisible(true);
memberEditorLt.setFocus();
}
}
}));
}
void createParametersPanel(Composite panel) {
Label paramsLb = new Label(panel, SWT.NONE);
paramsLb.setText("&Parameters:");
GridData data;
paramsLt = new Table(panel, SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
data = new GridData(GridData.FILL_BOTH);
int itemHeight = paramsLt.getItemHeight();
data.heightHint = itemHeight * 6;
paramsLt.setLayoutData(data);
paramsLt.addListener(SWT.Selection, e -> {
if (e.detail == SWT.CHECK) {
updateGenerate((TableItem)e.item);
}
});
TableColumn column;
column = new TableColumn(paramsLt, SWT.NONE, PARAM_INDEX_COLUMN);
column = new TableColumn(paramsLt, SWT.NONE, PARAM_TYPE_COLUMN);
column.setText("Type");
column = new TableColumn(paramsLt, SWT.NONE, PARAM_FLAGS_COLUMN);
column.setText("Flags");
column = new TableColumn(paramsLt, SWT.NONE, PARAM_CAST_COLUMN);
column.setText("Cast");
paramTextEditor = new TableEditor(paramsLt);
paramTextEditor.grabHorizontal = true;
paramEditorTx = new Text(paramsLt, SWT.SINGLE);
paramTextEditor.setEditor(paramEditorTx);
Listener paramTextListener = e -> {
if (e.type == SWT.Traverse) {
switch (e.detail) {
case SWT.TRAVERSE_ESCAPE:
paramTextEditor.setItem(null);
break;
default:
return;
}
}
paramEditorTx.setVisible(false);
TableItem item = paramTextEditor.getItem();
if (item == null) return;
int column1 = paramTextEditor.getColumn();
JNIParameter param = (JNIParameter)item.getData();
if (column1 == PARAM_CAST_COLUMN) {
String text = paramEditorTx.getText();
param.setCast(text);
item.setText(column1, param.getCast());
paramsLt.getColumn(column1).pack();
}
};
paramEditorTx.addListener(SWT.DefaultSelection, paramTextListener);
paramEditorTx.addListener(SWT.FocusOut, paramTextListener);
paramEditorTx.addListener(SWT.Traverse, paramTextListener);
final Shell floater = new Shell(shell, SWT.NO_TRIM);
floater.setLayout(new FillLayout());
paramListEditor = new FlagsEditor(paramsLt);
paramEditorLt = new List(floater, SWT.MULTI | SWT.BORDER);
paramEditorLt.setItems(JNIParameter.FLAGS);
floater.pack();
floater.addListener(SWT.Close, e -> {
paramListEditor.setItem(null);
e.doit = false;
floater.setVisible(false);
});
Listener paramListListener = e -> {
if (e.type == SWT.Traverse) {
switch (e.detail) {
case SWT.TRAVERSE_RETURN:
break;
default:
return;
}
}
floater.setVisible(false);
TableItem item = paramListEditor.getItem();
if (item == null) return;
int column1 = paramListEditor.getColumn();
JNIParameter param = (JNIParameter)item.getData();
if (column1 == PARAM_FLAGS_COLUMN) {
String[] flags = paramEditorLt.getSelection();
param.setFlags(flags);
item.setText(column1, getFlagsString(param.getFlags()));
paramsLt.getColumn(column1).pack();
}
};
paramEditorLt.addListener(SWT.DefaultSelection, paramListListener);
paramEditorLt.addListener(SWT.FocusOut, paramListListener);
paramEditorLt.addListener(SWT.Traverse, paramListListener);
paramsLt.addListener(SWT.MouseDown, e -> e.display.asyncExec (() -> {
if (paramsLt.isDisposed ()) return;
if (e.button != 1) return;
Point pt = new Point(e.x, e.y);
TableItem item = paramsLt.getItem(pt);
if (item == null) return;
int column1 = -1;
for (int i = 0; i < paramsLt.getColumnCount(); i++) {
if (item.getBounds(i).contains(pt)) {
column1 = i;
break;
}
}
if (column1 == -1) return;
JNIParameter param = (JNIParameter)item.getData();
if (column1 == PARAM_CAST_COLUMN) {
paramTextEditor.setColumn(column1);
paramTextEditor.setItem(item);
paramEditorTx.setText(param.getCast());
paramEditorTx.selectAll();
paramEditorTx.setVisible(true);
paramEditorTx.setFocus();
} else if (column1 == PARAM_FLAGS_COLUMN) {
paramListEditor.setColumn(column1);
paramListEditor.setItem(item);
paramEditorLt.setSelection(param.getFlags());
floater.setLocation(paramsLt.toDisplay(e.x, e.y));
floater.setVisible(true);
paramEditorLt.setFocus();
}
}));
}
Button createActionButton(Composite parent, String text, Listener listener) {
Button action = new Button(parent, SWT.PUSH);
action.setText(text);
GridData data = new GridData(GridData.FILL_HORIZONTAL);
action.setLayoutData(data);
action.addListener(SWT.Selection, listener);
return action;
}
void createActionButtons(Composite parent) {
actionsPanel = new Composite(parent, SWT.NONE);
GridData data = new GridData(GridData.FILL_VERTICAL);
actionsPanel.setLayoutData(data);
GridLayout actionsLayout = new GridLayout();
actionsLayout.numColumns = 1;
actionsPanel.setLayout(actionsLayout);
createActionButton(actionsPanel, "Generate &All", e -> generateAll());
Label separator = new Label(actionsPanel, SWT.SEPARATOR | SWT.HORIZONTAL);
data = new GridData(GridData.FILL_HORIZONTAL);
separator.setLayoutData(data);
separator = new Label(actionsPanel, SWT.SEPARATOR | SWT.HORIZONTAL);
data = new GridData(GridData.FILL_HORIZONTAL);
separator.setLayoutData(data);
createActionButton(actionsPanel, "Generate Structs &Header", e -> generateStructsHeader());
createActionButton(actionsPanel, "Generate &Structs", e -> generateStructs());
createActionButton(actionsPanel, "Generate &Natives", e -> generateNatives());
createActionButton(actionsPanel, "Generate Meta &Data", e -> generateMetaData());
createActionButton(actionsPanel, "Generate Cons&tants", e -> generateConstants());
createActionButton(actionsPanel, "Generate Si&zeof", e -> generateSizeof());
Composite filler = new Composite(actionsPanel, SWT.NONE);
filler.setLayoutData(new GridData(GridData.FILL_BOTH));
progressLabel = new Label(actionsPanel, SWT.NONE);
data = new GridData(GridData.FILL_HORIZONTAL);
progressLabel.setLayoutData(data);
progressLabel.setVisible(false);
progressBar = new ProgressBar(actionsPanel, SWT.NONE);
data = new GridData(GridData.FILL_HORIZONTAL);
progressBar.setLayoutData(data);
progressBar.setVisible(false);
}
public void run() {
shell.open();
MessageBox box = new MessageBox(shell, SWT.YES | SWT.NO);
box.setText("Warning");
box.setMessage("This tool is obsolete as of Eclipse 3.5 M2.\nThe meta data has been embedded in java source files.\nThere is a new plugin tool that replaces this tool.\nSee http://www.eclipse.org/swt/jnigen.php.\n\n Continue?");
int result = box.open();
if (result == SWT.NO) {
shell.dispose();
}
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep ();
}
cleanup();
}
String getPackageString(String className) {
int dot = app.getMainClassName().lastIndexOf('.');
if (dot == -1) return "";
return app.getMainClassName().substring(0, dot);
}
String getClassString(JNIType type) {
String name = type.getTypeSignature3(false);
int index = name.lastIndexOf('.');
if (index == -1) return name;
return name.substring(index + 1, name.length());
}
String getFlagsString(String[] flags) {
if (flags.length == 0) return "";
StringBuffer buffer = new StringBuffer();
for (int j = 0; j < flags.length; j++) {
String flag = flags[j];
if (buffer.length() != 0) buffer.append(", ");
buffer.append(flag);
}
return buffer.toString();
}
String getMethodString(JNIMethod method) {
String pkgName = getPackageString(method.getDeclaringClass().getName());
StringBuffer buffer = new StringBuffer();
buffer.append(method.getName());
buffer.append("(");
JNIParameter[] params = method.getParameters();
for (int i = 0; i < params.length; i++) {
JNIParameter param = params[i];
if (i != 0) buffer.append(",");
String string = param.getType().getTypeSignature3(false);
if (string.startsWith(pkgName)) string = string.substring(pkgName.length() + 1);
buffer.append(string);
}
buffer.append(")");
return buffer.toString();
}
String getFieldString(JNIField field) {
return field.getName();
}
void updateClasses() {
classesLt.removeAll();
JNIClass[] classes = app.getClasses();
int mainIndex = 0;
for (int i = 0; i < classes.length; i++) {
JNIClass clazz = classes[i];
if (clazz.equals(app.getMainClass())) mainIndex = i;
TableItem item = new TableItem(classesLt, SWT.NONE);
item.setData(clazz);
item.setText(CLASS_NAME_COLUMN, clazz.getSimpleName());
item.setText(CLASS_FLAGS_COLUMN, getFlagsString(clazz.getFlags()));
item.setChecked(clazz.getGenerate());
}
TableColumn[] columns = classesLt.getColumns();
for (int i = 0; i < columns.length; i++) {
TableColumn column = columns[i];
column.pack();
}
classesLt.setSelection(mainIndex);
}
void updateMembers() {
membersLt.removeAll();
membersLt.setHeaderVisible(false);
TableColumn[] columns = membersLt.getColumns();
for (int i = 0; i < columns.length; i++) {
TableColumn column = columns[i];
column.dispose();
}
int[] indices = classesLt.getSelectionIndices();
if (indices.length != 1) return;
TableItem classItem = classesLt.getItem(indices[0]);
JNIClass clazz = (JNIClass)classItem.getData();
boolean hasNatives = false;
JNIMethod[] methods = clazz.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
JNIMethod method = methods[i];
int mods = method.getModifiers();
if (hasNatives =((mods & Modifier.NATIVE) != 0)) break;
}
membersLt.setRedraw(false);
if (hasNatives) {
TableColumn column;
column = new TableColumn(membersLt, SWT.NONE, METHOD_NAME_COLUMN);
column.setText("Method");
column = new TableColumn(membersLt, SWT.NONE, METHOD_FLAGS_COLUMN);
column.setText("Flags");
column = new TableColumn(membersLt, SWT.NONE, METHOD_ACCESSOR_COLUMN);
column.setText("Accessor");
/*
column = new TableColumn(membersLt, SWT.NONE, METHOD_EXCLUDE_COLUMN);
column.setText("Exclude");
*/
JNIGenerator.sort(methods);
for (int i = 0; i < methods.length; i++) {
JNIMethod method = methods[i];
if ((method.getModifiers() & Modifier.NATIVE) == 0) continue;
TableItem item = new TableItem(membersLt, SWT.NONE);
item.setData(method);
item.setText(METHOD_NAME_COLUMN, getMethodString(method));
item.setChecked(method.getGenerate());
item.setText(METHOD_FLAGS_COLUMN, getFlagsString(method.getFlags()));
item.setText(METHOD_ACCESSOR_COLUMN, method.getAccessor());
/*
item.setText(METHOD_EXCLUDE_COLUMN, methodData.getExclude());
*/
}
} else {
TableColumn column;
column = new TableColumn(membersLt, SWT.NONE, FIELD_NAME_COLUMN);
column.setText("Field");
column = new TableColumn(membersLt, SWT.NONE, FIELD_FLAGS_COLUMN);
column.setText("Flags");
column = new TableColumn(membersLt, SWT.NONE, FIELD_CAST_COLUMN);
column.setText("Cast");
column = new TableColumn(membersLt, SWT.NONE, FIELD_ACCESSOR_COLUMN);
column.setText("Accessor");
/*
column = new TableColumn(membersLt, SWT.NONE, FIELD_EXCLUDE_COLUMN);
column.setText("Exclude");
*/
JNIField[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
JNIField field = fields[i];
int mods = field.getModifiers();
if (((mods & Modifier.PUBLIC) == 0) ||
((mods & Modifier.FINAL) != 0) ||
((mods & Modifier.STATIC) != 0)) continue;
TableItem item = new TableItem(membersLt, SWT.NONE);
item.setData(field);
item.setText(FIELD_NAME_COLUMN, getFieldString(field));
item.setChecked(field.getGenerate());
item.setText(FIELD_CAST_COLUMN, field.getCast());
item.setText(FIELD_FLAGS_COLUMN, getFlagsString(field.getFlags()));
item.setText(FIELD_ACCESSOR_COLUMN, field.getAccessor());
/*
item.setText(FIELD_EXCLUDE_COLUMN, fieldData.getExclude());
*/
}
}
columns = membersLt.getColumns();
for (int i = 0; i < columns.length; i++) {
TableColumn column = columns[i];
column.pack();
}
membersLt.setHeaderVisible(true);
membersLt.setRedraw(true);
}
void updateParameters() {
paramsLt.removeAll();
int[] indices = membersLt.getSelectionIndices();
if (indices.length != 1) {
paramsLt.setHeaderVisible(false);
return;
}
TableItem memberItem = membersLt.getItem(indices[0]);
Object data = memberItem.getData();
if (!(data instanceof JNIMethod)) return;
paramsLt.setRedraw(false);
JNIMethod method = (JNIMethod)data;
JNIParameter[] params = method.getParameters();
for (int i = 0; i < params.length; i++) {
JNIParameter param = params[i];
TableItem item = new TableItem(paramsLt, SWT.NONE);
item.setData(param);
item.setText(PARAM_INDEX_COLUMN, String.valueOf(i));
item.setText(PARAM_TYPE_COLUMN, getClassString(param.getType()));
item.setText(PARAM_CAST_COLUMN, param.getCast());
item.setText(PARAM_FLAGS_COLUMN, getFlagsString(param.getFlags()));
}
TableColumn[] columns = paramsLt.getColumns();
for (int i = 0; i < columns.length; i++) {
TableColumn column = columns[i];
column.pack();
}
paramsLt.setRedraw(true);
paramsLt.setHeaderVisible(true);
}
void updateGenerate(TableItem item) {
JNIItem itemData = (JNIItem)item.getData();
itemData.setGenerate(item.getChecked());
// MetaData metaData = app.getMetaData();
// if (itemData instanceof JNIClass) {
// ClassData data = (ClassData)itemData;
// metaData.setMetaData(data.getClazz(), data);
// } else if (itemData instanceof FieldData) {
// FieldData data = (FieldData)itemData;
// item.setText(FIELD_FLAGS_COLUMN, getFlagsString(data.getFlags()));
// metaData.setMetaData(data.getField(), data);
// } else if (itemData instanceof MethodData) {
// MethodData data = (MethodData)itemData;
// item.setText(METHOD_FLAGS_COLUMN, getFlagsString(data.getFlags()));
// metaData.setMetaData(data.getMethod(), data);
// } else if (itemData instanceof ParameterData) {
// ParameterData data = (ParameterData)itemData;
// item.setText(PARAM_FLAGS_COLUMN, getFlagsString(data.getFlags()));
// metaData.setMetaData(data.getMethod(), data.getParameter(), data);
// }
}
boolean updateOutputDir() {
String outputDirStr = outputDirCb.getText();
File file = new File(outputDirStr);
if (!file.exists()) {
MessageBox dialog = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
dialog.setMessage("Output directory does not exist.");
dialog.open();
return false;
}
if (!file.isDirectory()) {
MessageBox dialog = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
dialog.setMessage("Output directory is not a directory.");
dialog.open();
return false;
}
if (outputDirStr.length() > 0) {
if (!outputDirStr.equals(app.getOutputDir())) {
app.setOutputDir(outputDirStr);
}
if (outputDirCb.indexOf(outputDirStr) == -1) {
outputDirCb.add(outputDirStr);
}
}
return true;
}
void updateMainClass() {
String mainClassStr = mainClassCb.getText();
if (mainClassStr.length() > 0) {
if (!mainClassStr.equals(app.getMainClassName())) {
app.setMainClassName(mainClassStr);
}
if (mainClassCb.indexOf(mainClassStr) == -1) {
mainClassCb.add(mainClassStr);
}
if (app.getOutputDir() != null) {
int index = outputDirCb.indexOf(app.getOutputDir());
if (index != -1) outputDirCb.select(index);
}
}
}
public static void main(String[] args) {
JNIGeneratorApp gen = new JNIGeneratorApp ();
if (args.length > 0) {
gen.setMainClassName(args[0]);
if (args.length > 1) gen.setOutputDir(args[1]);
} else {
gen.setMainClassName(JNIGeneratorApp.getDefaultMainClass());
}
JNIGeneratorAppUI ui = new JNIGeneratorAppUI(gen);
ui.open();
ui.run();
}
}