package bndtools.editor.project; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.bndtools.utils.swt.AddRemoveButtonBarPart; import org.bndtools.utils.swt.AddRemoveButtonBarPart.AddRemoveListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Section; import aQute.bnd.osgi.Constants; import bndtools.editor.common.BndEditorPart; import bndtools.editor.common.MapContentProvider; import bndtools.editor.common.MapEntryCellModifier; import bndtools.editor.common.PropertiesTableLabelProvider; import bndtools.editor.utils.ToolTips; import bndtools.utils.ModificationLock; public class RunPropertiesPart extends BndEditorPart { private final ModificationLock lock = new ModificationLock(); private Map<String,String> runProperties; private String programArgs = null; private String vmArgs = null; private final AddRemoveButtonBarPart createRemovePropsPart = new AddRemoveButtonBarPart(); private Table tblRunProperties; private TableViewer viewRunProperties; private MapEntryCellModifier<String,String> runPropertiesModifier; private Text txtProgramArgs; private Text txtVmArgs; private static final String[] SUBCRIBE_PROPS = new String[] { Constants.RUNPROPERTIES, Constants.RUNPROGRAMARGS, Constants.RUNVM }; public RunPropertiesPart(Composite parent, FormToolkit toolkit, int style) { super(parent, toolkit, style); createSection(getSection(), toolkit); } private void createSection(Section section, FormToolkit toolkit) { section.setText("Runtime Properties"); final Composite composite = toolkit.createComposite(section); section.setClient(composite); // Create controls: Run Properties Label lblRunProperties = toolkit.createLabel(composite, "OSGi Framework properties:"); tblRunProperties = toolkit.createTable(composite, SWT.FULL_SELECTION | SWT.MULTI | SWT.BORDER); viewRunProperties = new TableViewer(tblRunProperties); runPropertiesModifier = new MapEntryCellModifier<>(viewRunProperties); tblRunProperties.setHeaderVisible(true); final TableColumn tblRunPropsCol1 = new TableColumn(tblRunProperties, SWT.NONE); tblRunPropsCol1.setText("Name"); tblRunPropsCol1.setWidth(100); final TableColumn tblRunPropsCol2 = new TableColumn(tblRunProperties, SWT.NONE); tblRunPropsCol1.setText("Value"); tblRunPropsCol1.setWidth(100); viewRunProperties.setUseHashlookup(true); viewRunProperties.setColumnProperties(MapEntryCellModifier.getColumnProperties()); runPropertiesModifier.addCellEditorsToViewer(); viewRunProperties.setCellModifier(runPropertiesModifier); viewRunProperties.setContentProvider(new MapContentProvider()); viewRunProperties.setLabelProvider(new PropertiesTableLabelProvider()); Control createRemovePropsToolBar = createRemovePropsPart.createControl(composite, SWT.FLAT | SWT.VERTICAL); // Create controls: program args Label lblProgramArgs = toolkit.createLabel(composite, "Launcher Arguments:"); txtProgramArgs = toolkit.createText(composite, "", SWT.MULTI | SWT.BORDER); ToolTips.setupMessageAndToolTipFromSyntax(txtProgramArgs, Constants.RUNPROGRAMARGS); // Create controls: vm args Label lblVmArgs = toolkit.createLabel(composite, "JVM Arguments:"); txtVmArgs = toolkit.createText(composite, "", SWT.MULTI | SWT.BORDER); ToolTips.setupMessageAndToolTipFromSyntax(txtVmArgs, Constants.RUNVM); // Layout GridLayout gl; GridData gd; gl = new GridLayout(2, false); gl.marginWidth = 0; gl.marginHeight = 0; composite.setLayout(gl); lblRunProperties.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1)); gd = new GridData(SWT.FILL, SWT.FILL, true, false); gd.heightHint = 50; gd.widthHint = 50; tblRunProperties.setLayoutData(gd); gd = new GridData(SWT.FILL, SWT.TOP, false, true); createRemovePropsToolBar.setLayoutData(gd); lblProgramArgs.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1)); gd = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1); gd.heightHint = 40; gd.widthHint = 50; txtProgramArgs.setLayoutData(gd); lblVmArgs.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1)); gd = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1); gd.heightHint = 40; gd.widthHint = 50; txtVmArgs.setLayoutData(gd); // Listeners viewRunProperties.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { createRemovePropsPart.setRemoveEnabled(!viewRunProperties.getSelection().isEmpty()); } }); createRemovePropsPart.addListener(new AddRemoveListener() { @Override public void addSelected() { runProperties.put("name", ""); viewRunProperties.add("name"); markDirty(); viewRunProperties.editElement("name", 0); } @Override public void removeSelected() { @SuppressWarnings("rawtypes") Iterator iter = ((IStructuredSelection) viewRunProperties.getSelection()).iterator(); while (iter.hasNext()) { Object item = iter.next(); runProperties.remove(item); viewRunProperties.remove(item); } markDirty(); } }); runPropertiesModifier.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { markDirty(); } }); txtProgramArgs.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent ev) { lock.ifNotModifying(new Runnable() { @Override public void run() { markDirty(); programArgs = txtProgramArgs.getText(); if (programArgs.length() == 0) programArgs = null; } }); } }); txtVmArgs.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent ev) { lock.ifNotModifying(new Runnable() { @Override public void run() { markDirty(); vmArgs = txtVmArgs.getText(); if (vmArgs.length() == 0) vmArgs = null; } }); } }); composite.addControlListener(new ControlAdapter() { @Override public void controlResized(ControlEvent e) { Rectangle area = composite.getClientArea(); Point preferredSize = tblRunProperties.computeSize(SWT.DEFAULT, SWT.DEFAULT); int width = area.width - 2 * tblRunProperties.getBorderWidth(); if (preferredSize.y > area.height + tblRunProperties.getHeaderHeight()) { // Subtract the scrollbar width from the total column width // if a vertical scrollbar will be required Point vBarSize = tblRunProperties.getVerticalBar().getSize(); width -= vBarSize.x; } Point oldSize = tblRunProperties.getSize(); if (oldSize.x > area.width) { // table is getting smaller so make the columns // smaller first and then resize the table to // match the client area width tblRunPropsCol1.setWidth(width / 3); tblRunPropsCol2.setWidth(width - tblRunPropsCol1.getWidth()); tblRunProperties.setSize(area.width, area.height); } else { // table is getting bigger so make the table // bigger first and then make the columns wider // to match the client area width tblRunProperties.setSize(area.width, area.height); tblRunPropsCol1.setWidth(width / 3); tblRunPropsCol2.setWidth(width - tblRunPropsCol1.getWidth()); } } }); } @Override protected String[] getProperties() { return SUBCRIBE_PROPS; } @Override protected void refreshFromModel() { Map<String,String> tmp = model.getRunProperties(); if (tmp == null) this.runProperties = new HashMap<>(); else this.runProperties = new HashMap<>(tmp); viewRunProperties.setInput(runProperties); lock.modifyOperation(new Runnable() { @Override public void run() { programArgs = model.getRunProgramArgs(); if (programArgs == null) programArgs = ""; //$NON-NLS-1$ txtProgramArgs.setText(programArgs); vmArgs = model.getRunVMArgs(); if (vmArgs == null) vmArgs = ""; txtVmArgs.setText(vmArgs); } }); } @Override protected void commitToModel(boolean onSave) { model.setRunProperties(runProperties); model.setRunProgramArgs(emptyToNull(programArgs)); model.setRunVMArgs(emptyToNull(vmArgs)); } private String emptyToNull(String s) { if (s != null && s.isEmpty()) return null; return s; } }