/******************************************************************************* * Copyright (c) 2009, 2016 Red Hat Inc. * 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: * Red Hat Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.autotools.ui.properties; import java.util.ArrayList; import java.util.List; import org.eclipse.cdt.internal.autotools.core.configure.AutotoolsConfiguration; import org.eclipse.cdt.internal.autotools.core.configure.IAConfiguration; import org.eclipse.cdt.internal.autotools.core.configure.IConfigureOption; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.FieldEditor; import org.eclipse.jface.preference.ListEditor; import org.eclipse.jface.preference.StringFieldEditor; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.graphics.FontMetrics; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; 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; public class AutotoolsCategoryPropertyOptionPage extends AbstractConfigurePropertyOptionsPage { private static final int MARGIN = 3; private String catName = ""; private IAConfiguration cfg; // Label class for a preference page. static class LabelFieldEditor extends FieldEditor { private String fTitle; private Label fTitleLabel; public LabelFieldEditor( Composite parent, String title ) { fTitle = title; this.createControl( parent ); } @Override protected void adjustForNumColumns( int numColumns ) { ((GridData)fTitleLabel.getLayoutData()).horizontalSpan = 2; } @Override protected void doFillIntoGrid( Composite parent, int numColumns ) { fTitleLabel = new Label( parent, SWT.WRAP ); fTitleLabel.setText( fTitle ); GridData gd = new GridData(); gd.verticalAlignment = SWT.TOP; gd.grabExcessHorizontalSpace = false; gd.horizontalSpan = 2; fTitleLabel.setLayoutData( gd ); } @Override public int getNumberOfControls() { return 1; } /** * The label field editor is only used to present a text label on a preference page. */ @Override protected void doLoad() {} @Override protected void doLoadDefault() {} @Override protected void doStore() {} } static class VariableListEditor extends ListEditor { Composite fParent; String fName; String fLabelText; boolean isLoaded; public VariableListEditor(String name, String labelText, Composite parent) { fName = name; fLabelText = labelText; fParent = parent; isLoaded = false; init(fName, fLabelText); createControl(fParent); } @Override protected void selectionChanged() { super.selectionChanged(); super.fireValueChanged(getPreferenceName(), "", ""); //$NON-NLS-1$ //$NON-NLS-2$ } @Override protected String createList(String[] arg0) { StringBuilder sb = new StringBuilder(); for (String item : arg0) { sb.append(item); sb.append("\\s"); //$NON-NLS-1$ } return sb.toString(); } @Override protected void doLoad() { if (!isLoaded) { super.doLoad(); isLoaded = true; } }; public void setToolTipText(String toolTip) { this.getLabelControl().setToolTipText(toolTip); } /** * Dialog user inputs variable's name and value. */ class DialogNewVar extends Dialog { private String name; private Text fTextName; private String value; private Text fTextValue; private Button fOkButton; public DialogNewVar(Shell shell) { super(shell); } @Override protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText(AutotoolsPropertyMessages.getString("NewEnvVarDialog.title")); }; @Override protected Control createDialogArea(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(2, false); layout.marginWidth = 5; layout.numColumns = 2; composite.setLayout(layout); GC gc = new GC(composite); gc.setFont(composite.getFont()); FontMetrics metrics = gc.getFontMetrics(); gc.dispose(); int fieldWidthHint = convertWidthInCharsToPixels(metrics, 50); Label label = new Label(composite, SWT.NONE); label.setText(AutotoolsPropertyMessages.getString("NewEnvVarDialog.name_field")); fTextName = new Text(composite, SWT.SINGLE | SWT.BORDER); GridData gd = new GridData(GridData.FILL_BOTH); gd.grabExcessHorizontalSpace = true; gd.widthHint = fieldWidthHint; fTextName.setLayoutData(gd); // Name field cannot be empty. fTextName.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { if (fOkButton != null) { fOkButton.setEnabled(fTextName.getText().length() > 0); } } }); label = new Label(composite, SWT.NONE); label.setText(AutotoolsPropertyMessages.getString("NewEnvVarDialog.value_field")); fTextValue = new Text(composite, SWT.SINGLE | SWT.BORDER); gd = new GridData(GridData.FILL_BOTH); gd.grabExcessHorizontalSpace = true; gd.widthHint = fieldWidthHint; fTextValue.setLayoutData(gd); return composite; }; // Obtain instance of OK button and set disabled. @Override protected Control createButtonBar(Composite parent) { Control control = super.createButtonBar(parent); fOkButton = getButton(IDialogConstants.OK_ID); fOkButton.setEnabled(false); return control; } @Override protected void okPressed() { name = fTextName.getText().trim(); value = fTextValue.getText(); if (value != null) { value = value.trim(); } else { value = ""; //$NON-NLS-1$ } super.okPressed(); } public String getName() { return name; } public String getValue() { return value; } }; @Override protected String getNewInputObject() { DialogNewVar newDialog = new DialogNewVar(getShell()); newDialog.open(); String name = newDialog.getName(); // Create quoted string like CFLAGS="-q -O3" if (name != null) { String quote = "\""; //$NON-NLS-1$ StringBuilder sb = new StringBuilder(name.trim()); sb.append("="); //$NON-NLS-1$ String value = newDialog.getValue(); if (value != null) { value = value.trim(); if (value.length() == 0) { // Check empty value sb.append(quote); sb.append(quote); } else if (value.charAt(0) == '"' && value.charAt(value.length() - 1) == '"') { // Check user has already quoted it. sb.append(value); } else { sb.append(quote); sb.append(value); sb.append(quote); } } return sb.toString(); } return null; } /* * Expect string with format: VAR1="VALUE1" VAR2="VALUE2". Count quotes * to mark end of a variable. * * @see * org.eclipse.jface.preference.ListEditor#parseString(java.lang.String) */ @Override protected String[] parseString(String str) { if (str == null) { return new String[] {}; } ArrayList<String> variables = new ArrayList<>(); StringBuilder sb = new StringBuilder(); int i = 0; int quote = 0; // 0 = begin variable, // 1 = looking for end of variable. while (i < str.length()) { char c = str.charAt(i); sb.append(c); if (c == '"') { quote++; } if (quote == 2) { // Found end of variable. quote = 0; variables.add(sb.toString()); sb.delete(0, sb.length()); i++; // Skip whitespace char separating variables. } i++; } return variables.toArray(new String[0]); } /** * Get the list of environment variables in a single line. * * @return environment variables */ public String getVariablesValue() { org.eclipse.swt.widgets.List list = super.getList(); StringBuilder sb = new StringBuilder(); for (String var : list.getItems()) { sb.append(var); sb.append(" "); //$NON-NLS-1$ } return sb.toString().trim(); } }; private List<FieldEditor> fieldEditors; public AutotoolsCategoryPropertyOptionPage(ToolListElement element, IAConfiguration cfg) { super(element.getName()); this.catName = element.getName(); this.cfg = cfg; fieldEditors = new ArrayList<>(); } @Override protected void createFieldEditors() { super.createFieldEditors(); Composite parent = getFieldEditorParent(); // Add margin parent.setLayout(new GridLayout(1, false)); Composite area = new Composite(parent, SWT.NONE); GridLayout gl = new GridLayout(1, false); gl.marginTop = MARGIN; gl.marginLeft = MARGIN; gl.marginRight = MARGIN; area.setLayout(gl); area.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); // FontMetrics fm = AbstractCPropertyTab.getFontMetrics(parent); AutotoolsConfiguration.Option[] options = AutotoolsConfiguration.getChildOptions(catName); for (int i = 0; i < options.length; ++i) { AutotoolsConfiguration.Option option = options[i]; switch (option.getType()) { case IConfigureOption.STRING: case IConfigureOption.INTERNAL: case IConfigureOption.MULTIARG: StringFieldEditor f = new StringFieldEditor(option.getName(), option.getDescription(), area); f.getLabelControl(area).setToolTipText(option.getToolTip()); addField(f); fieldEditors.add(f); break; case IConfigureOption.BIN: case IConfigureOption.FLAGVALUE: BooleanFieldEditor b = new BooleanFieldEditor(option.getName(), option.getDescription(), area); b.getDescriptionControl(area).setToolTipText(option.getToolTip()); addField(b); fieldEditors.add(b); break; case IConfigureOption.FLAG: FieldEditor l = new LabelFieldEditor(area, option.getDescription()); addField(l); fieldEditors.add(l); break; case IConfigureOption.ENVVAR: VariableListEditor listEditor = new VariableListEditor(option.getName(), option.getDescription(), area); listEditor.setToolTipText(option.getToolTip()); addField(listEditor); fieldEditors.add(listEditor); break; } } } /** * Update the field editor that displays all the build options */ @Override public void updateFields() { setValues(); } @Override public void setValues() { for (int i = 0; i < fieldEditors.size(); ++i) { fieldEditors.get(i).load(); } } @Override public void propertyChange(PropertyChangeEvent event) { // allow superclass to handle as well super.propertyChange(event); if (event.getSource() instanceof StringFieldEditor) { StringFieldEditor f = (StringFieldEditor)event.getSource(); cfg.setOption(f.getPreferenceName(), f.getStringValue()); } else if (event.getSource() instanceof BooleanFieldEditor) { BooleanFieldEditor b = (BooleanFieldEditor)event.getSource(); cfg.setOption(b.getPreferenceName(), Boolean.toString(b.getBooleanValue())); } else if (event.getSource() instanceof VariableListEditor) { VariableListEditor v = (VariableListEditor) event.getSource(); cfg.setOption(v.getPreferenceName(), v.getVariablesValue()); } } }