+package org.simantics.scl.ui.modulebrowser;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.osgi.framework.Bundle;
+import org.simantics.scl.osgi.SCLOsgi;
+import org.simantics.scl.ui.editor2.OpenSCLModule;
+import org.simantics.scl.ui.modulebrowser.PluginSelectionDialog.Entry;
+
+import gnu.trove.map.hash.THashMap;
+
+public class CreateModuleDialog extends Dialog {
+
+ SCLModuleBrowser parentBrowser;
+
+ String initialPackageName = "";
+ String initialPluginName = "";
+
+ Text packageName;
+ Text moduleName;
+ Text pluginName;
+ private THashMap<String,Bundle> bundles;
+
+ private Color normalBackground;
+ private Color errorBackground;
+
+ protected CreateModuleDialog(Shell parentShell, SCLModuleBrowser parentBrowser) {
+ super(parentShell);
+ this.parentBrowser = parentBrowser;
+ setShellStyle(SWT.RESIZE | SWT.TITLE | SWT.BORDER);
+ bundles = CreateModuleAction.findGoodBundles();
+
+ normalBackground = parentShell.getDisplay().getSystemColor(SWT.COLOR_WHITE);
+ errorBackground = new Color(parentShell.getDisplay(), 255, 128, 128);
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ getShell().setText("Create New Module");
+ getShell().addDisposeListener(new DisposeListener() {
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ errorBackground.dispose();
+ }
+ });
+
+ final Composite composite = (Composite) super.createDialogArea(parent);
+ GridLayoutFactory.fillDefaults().margins(10,10).numColumns(2).applyTo(composite);
+ GridDataFactory.fillDefaults().grab(true,true).applyTo(composite);
+
+ // Package name
+ Label packageNameLabel = new Label(composite, SWT.NONE);
+ packageNameLabel.setText("Package");
+ GridDataFactory.fillDefaults().applyTo(packageNameLabel);
+
+ packageName = new Text(composite, SWT.BORDER);
+ GridDataFactory.fillDefaults().grab(true, false).minSize(500, SWT.DEFAULT).applyTo(packageName);
+ packageName.setText(initialPackageName);
+ packageName.addModifyListener(modifyListener);
+
+ // Module name
+ Label moduleNameLabel = new Label(composite, SWT.NONE);
+ moduleNameLabel.setText("Module name");
+ GridDataFactory.fillDefaults().applyTo(moduleNameLabel);
+
+ moduleName = new Text(composite, SWT.BORDER);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(moduleName);
+ moduleName.addModifyListener(modifyListener);
+
+ // Plugin
+ Label pluginNameLabel = new Label(composite, SWT.NONE);
+ pluginNameLabel.setText("Plugin");
+ GridDataFactory.fillDefaults().applyTo(pluginNameLabel);
+
+ Composite pluginNameComposite = new Composite(composite, SWT.NONE);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(pluginNameComposite);
+ GridLayoutFactory.fillDefaults().numColumns(2).applyTo(pluginNameComposite);
+
+ pluginName = new Text(pluginNameComposite, SWT.BORDER);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(pluginName);
+ pluginName.setText(initialPluginName);
+ pluginName.addModifyListener(modifyListener);
+
+ Button browsePlugins = new Button(pluginNameComposite, SWT.PUSH);
+ browsePlugins.setText("Browse...");
+ GridDataFactory.fillDefaults().applyTo(browsePlugins);
+ browsePlugins.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ browsePlugins();
+ }
+ });
+
+ // Focus
+ moduleName.setFocus();
+ parent.getDisplay().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ validate();
+ }
+ });
+
+ return composite;
+ }
+
+ private void browsePlugins() {
+ ArrayList<Entry> entries = new ArrayList<Entry>(bundles.size());
+ String currentPackageName = packageName.getText();
+ for(Bundle bundle : bundles.values())
+ entries.add(new Entry(bundle, CreateModuleAction.packageMatchLength(bundle, currentPackageName)));
+ PluginSelectionDialog dialog = new PluginSelectionDialog(getShell(), entries);
+ if(dialog.open() == Dialog.OK) {
+ Entry result = (Entry)dialog.getFirstResult();
+ if(result != null) {
+ pluginName.setText(result.bundle.getSymbolicName());
+ validate();
+ }
+ }
+ }
+
+ private void validate() {
+ boolean validPackageName = CreateModuleValidator.isValidPackageName(packageName.getText());
+ packageName.setBackground(validPackageName ? normalBackground : errorBackground);
+
+ boolean validModuleName = CreateModuleValidator.isValidModuleName(moduleName.getText());
+ if(validModuleName && validPackageName) {
+ String fullModuleName = packageName.getText() + "/" + moduleName.getText();
+ validModuleName = SCLOsgi.SOURCE_REPOSITORY.getModuleSource(fullModuleName, null) == null;
+ }
+ moduleName.setBackground(validModuleName ? normalBackground : errorBackground);
+
+ boolean validPluginName = bundles.containsKey(pluginName.getText());
+ pluginName.setBackground(validPluginName ? normalBackground : errorBackground);
+
+ getButton(IDialogConstants.OK_ID).setEnabled(validPackageName && validModuleName && validPackageName);
+ }
+
+ private ModifyListener modifyListener = new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ validate();
+ }
+ };
+
+ public void setPackage(String initialPackageName) {
+ this.initialPackageName = initialPackageName;
+ this.initialPluginName = CreateModuleAction.findBestPlugin(bundles, initialPackageName);
+ }
+
+ @Override
+ protected void okPressed() {
+ try {
+ Bundle bundle = bundles.get(pluginName.getText());
+ if(bundle != null) {
+ CreateModuleAction.createModule(bundle, packageName.getText(), moduleName.getText());
+ parentBrowser.refresh();
+ OpenSCLModule.openModule(packageName.getText() + "/" + moduleName.getText());
+ }
+ } catch (IOException e) {
+ ErrorDialog.openError(getParentShell(), "Module creation failed", e.getMessage(),
+ new Status(Status.ERROR, "org.simantics.scl.ui", e.getMessage()));
+ }
+ super.okPressed();
+ }
+}