/******************************************************************************* * Copyright (c) 2005, 2016 Intel 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: * Intel Corporation - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.managedbuilder.ui.properties; import java.util.Arrays; import java.util.Comparator; import org.eclipse.cdt.core.cdtvariables.CdtVariableException; import org.eclipse.cdt.core.cdtvariables.ICdtVariable; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICMultiItemsHolder; import org.eclipse.cdt.managedbuilder.core.IOption; import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacro; import org.eclipse.cdt.managedbuilder.internal.ui.Messages; import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; import org.eclipse.cdt.utils.cdtvariables.CdtVariableResolver; import org.eclipse.cdt.utils.ui.controls.FileListControl; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; 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.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import com.ibm.icu.text.Collator; /** * the dialog used to create or edit the build macro * * @noextend This class is not intended to be subclassed by clients. * @noinstantiate This class is not intended to be instantiated by clients. */ public class NewVarDialog extends Dialog { private static final String EMPTY_STRING = ""; //$NON-NLS-1$ // The title of the dialog. private String fTitle; // hold the macro being edited(in the case of the "edit" mode) private ICdtVariable fEditedMacro; //the resulting macro. Can be accessed only when the dialog is closed private ICdtVariable fResultingMacro; private boolean fTotalSizeCalculated; private String fTypedName; private int fTypedType = -1; public boolean isForAllCfgs = false; // Widgets private Composite fContainer; private CCombo fMacroNameEdit; private Label fMacroValueLabel; private Text fMacroValueEdit; private Button fBrowseButton; private Combo fTypeSelector; private Composite fListEditorContainier; private FileListControl fListEditor; private ICConfigurationDescription cfgd; private ICdtVariable[] vars; public NewVarDialog(Shell parentShell, ICdtVariable editedMacro, ICConfigurationDescription _cfgd, ICdtVariable[] _vars) { super(parentShell); cfgd = _cfgd; if(editedMacro != null) fTitle = Messages.NewBuildMacroDialog_label_title_edit; else fTitle = Messages.NewBuildMacroDialog_label_title_new; fEditedMacro = editedMacro; vars = _vars; } /* (non-Javadoc) * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) */ @Override protected void configureShell(Shell shell) { super.configureShell(shell); if (fTitle != null) shell.setText(fTitle); } /* (non-Javadoc) * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) */ @Override protected Control createDialogArea(Composite parent) { Composite comp = new Composite(parent, SWT.NULL); comp.setFont(parent.getFont()); comp.setLayout(new GridLayout(3, false)); GridData gd = new GridData(GridData.FILL_BOTH); comp.setLayoutData(gd); fContainer = comp; Label nameLabel = new Label(comp, SWT.LEFT); nameLabel.setFont(comp.getFont()); nameLabel.setText(Messages.NewVarDialog_0); nameLabel.setLayoutData(new GridData()); fMacroNameEdit = new CCombo(comp, SWT.BORDER); fMacroNameEdit.setItems(getMacroNames()); fMacroNameEdit.setFont(comp.getFont()); gd = new GridData(); // don't use GridData.FILL_HORIZONTAL; see bugzilla 229793 gd.horizontalSpan = 2; gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH + 50; fMacroNameEdit.setLayoutData(gd); fMacroNameEdit.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { handleMacroNameModified(); } }); fMacroNameEdit.addSelectionListener(new SelectionAdapter(){ @Override public void widgetSelected(SelectionEvent e){ handleMacroNameSelection(); } }); if (fEditedMacro == null && cfgd != null && !(cfgd instanceof ICMultiItemsHolder)) { Button c_all = new Button(comp, SWT.CHECK); c_all.setText(Messages.NewVarDialog_1); gd = new GridData(GridData.BEGINNING); gd.horizontalSpan = 3; c_all.setLayoutData(gd); c_all.addSelectionListener(new SelectionAdapter(){ @Override public void widgetSelected(SelectionEvent e){ isForAllCfgs = ((Button)e.widget).getSelection(); } }); } Label typeLabel = new Label(comp, SWT.LEFT); typeLabel.setFont(comp.getFont()); typeLabel.setText(Messages.NewBuildMacroDialog_label_type); gd = new GridData(); typeLabel.setLayoutData(gd); fTypeSelector = new Combo(comp, SWT.READ_ONLY | SWT.DROP_DOWN | SWT.BORDER); gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); gd.horizontalSpan = 2; // gd.widthHint = 100; fTypeSelector.setLayoutData(gd); fTypeSelector.setItems(new String[]{ Messages.NewBuildMacroDialog_label_type_text, Messages.NewBuildMacroDialog_label_type_text_list, Messages.NewBuildMacroDialog_label_type_path_file, Messages.NewBuildMacroDialog_label_type_path_file_list, Messages.NewBuildMacroDialog_label_type_path_dir, Messages.NewBuildMacroDialog_label_type_path_dir_list, Messages.NewBuildMacroDialog_label_type_path_any, Messages.NewBuildMacroDialog_label_type_path_any_list }); setSelectedType(IBuildMacro.VALUE_TEXT); fTypeSelector.addListener(SWT.Selection, new Listener () { @Override public void handleEvent(Event e) { handleTypeModified(); } }); fMacroValueLabel = new Label(comp, SWT.LEFT); fMacroValueLabel.setFont(comp.getFont()); fMacroValueLabel.setText(Messages.NewBuildMacroDialog_label_value); gd = new GridData(); gd.horizontalSpan = 1; fMacroValueLabel.setLayoutData(gd); fMacroValueEdit = new Text(comp, SWT.SINGLE | SWT.BORDER); fMacroValueEdit.setFont(comp.getFont()); gd = new GridData(GridData.FILL_HORIZONTAL); gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH + 100; gd.horizontalSpan = 1; fMacroValueEdit.setLayoutData(gd); fMacroValueEdit.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { handleMacroValueModified(); } }); fBrowseButton = new Button(comp,SWT.PUSH); fBrowseButton.setFont(comp.getFont()); fBrowseButton.setText(Messages.NewBuildMacroDialog_label_browse); fBrowseButton.addSelectionListener(new SelectionAdapter(){ @Override public void widgetSelected(SelectionEvent e){ handleBrowseButtonPressed(); } }); gd = new GridData(); gd.widthHint = IDialogConstants.BUTTON_WIDTH; gd.horizontalSpan = 1; fBrowseButton.setLayoutData(gd); fListEditorContainier = new Composite(comp,0); gd = new GridData(GridData.FILL_BOTH); gd.horizontalSpan = 3; fListEditorContainier.setLayoutData(gd); fListEditorContainier.setLayout(new GridLayout()); fListEditor = new FileListControl(fListEditorContainier, Messages.NewBuildMacroDialog_label_list_title, IOption.BROWSE_NONE); /* Enable workspace support for list editor */ fListEditor.setWorkspaceSupport(true); // TODO: getContextInfo // fListEditor.setContext(fMacrosBlock.getContextInfo()); if(fEditedMacro != null){ loadVar(fEditedMacro); fMacroNameEdit.setEnabled(false); } return comp; } /* * get the names to be displayed in the var Name combo. */ private String[] getMacroNames(){ String names[] = null; if(vars == null || vars.length == 0) names = new String[0]; else{ names = new String[vars.length]; for(int i = 0; i < vars.length; i++) names[i] = vars[i].getName(); final Collator collator = Collator.getInstance(); Arrays.sort(names, new Comparator<String>() { @Override public int compare(final String a, final String b) { final String strA = a.toUpperCase(); final String strB = b.toUpperCase(); return collator.compare(strA,strB); } }); } return names; } private void handleBrowseButtonPressed(){ switch(getBrowseType(getSelectedType())){ case IOption.BROWSE_FILE: FileDialog fileDlg = new FileDialog(fBrowseButton.getShell()); String file = fileDlg.open(); if(file != null) fMacroValueEdit.setText(file); break; case IOption.BROWSE_DIR: DirectoryDialog dirDlg = new DirectoryDialog(fBrowseButton.getShell()); String dir = dirDlg.open(); if(dir != null) fMacroValueEdit.setText(dir); break; } } private int getBrowseType(int type){ int browseType = IOption.BROWSE_NONE; switch(type){ case IBuildMacro.VALUE_PATH_FILE: case IBuildMacro.VALUE_PATH_FILE_LIST: browseType = IOption.BROWSE_FILE; break; case IBuildMacro.VALUE_PATH_DIR: case IBuildMacro.VALUE_PATH_DIR_LIST: browseType = IOption.BROWSE_DIR; break; case IBuildMacro.VALUE_PATH_ANY: case IBuildMacro.VALUE_PATH_ANY_LIST: break; case IBuildMacro.VALUE_TEXT: case IBuildMacro.VALUE_TEXT_LIST: default: } return browseType; } /* * called when the variable name is selected, loads all the dialog fields with the variable settings */ private void handleMacroNameSelection(){ int index = fMacroNameEdit.getSelectionIndex(); if (index != -1) loadVarSettings(fMacroNameEdit.getItem(index)); } private void loadVarSettings(String name) { ICdtVariable v = null; for (int i=0; i<vars.length; i++) { if (vars[i].getName().equals(name)) { v = vars[i]; break; } } if(v != null) loadVar(v); else loadVar(name,IBuildMacro.VALUE_TEXT,EMPTY_STRING); } private void loadVar(String name, int type, String value[]){ setSelectedType(type); setSelectedMacroName(notNull(name)); fListEditor.setList(value); updateWidgetState(); } private void loadVar(String name, int type, String value){ setSelectedType(type); setSelectedMacroName(notNull(name)); fMacroValueEdit.setText(notNull(value)); updateWidgetState(); } /* * loads all the dialog fields with the variable settings */ private void loadVar(ICdtVariable var){ try{ if(CdtVariableResolver.isStringListVariable(var.getValueType())) loadVar(var.getName(),var.getValueType(),var.getStringListValue()); else loadVar(var.getName(),var.getValueType(),var.getStringValue()); }catch(CdtVariableException e){} } /* * returns an empty string in the case the string passed is null. * otherwise returns the string passed */ private String notNull(String str){ return str == null ? EMPTY_STRING : str; } /* * returns the name typed in the dialog var name edit triming spaces */ private String getSelectedVarName(){ return fMacroNameEdit.getText().trim(); } /* * sets the variable name to the dialog "variable name" edit control */ private void setSelectedMacroName(String name){ if(!macroNamesEqual(fMacroNameEdit.getText(),name)){ fTypedName = name; fMacroNameEdit.setText(notNull(name).trim()); } } private boolean macroNamesEqual(String name1, String name2){ name1 = name1.trim(); name2 = name2.trim(); return name1.equalsIgnoreCase(name2); } /* * returns the selected type */ private int getSelectedType(){ switch(fTypeSelector.getSelectionIndex()){ case 1: return IBuildMacro.VALUE_TEXT_LIST; case 2: return IBuildMacro.VALUE_PATH_FILE; case 3: return IBuildMacro.VALUE_PATH_FILE_LIST; case 4: return IBuildMacro.VALUE_PATH_DIR; case 5: return IBuildMacro.VALUE_PATH_DIR_LIST; case 6: return IBuildMacro.VALUE_PATH_ANY; case 7: return IBuildMacro.VALUE_PATH_ANY_LIST; case 0: default: return IBuildMacro.VALUE_TEXT; } } /* * sets the selected type */ private void setSelectedType(int type){ switch(type){ case IBuildMacro.VALUE_TEXT_LIST: fTypeSelector.select(1); break; case IBuildMacro.VALUE_PATH_FILE: fTypeSelector.select(2); break; case IBuildMacro.VALUE_PATH_FILE_LIST: fTypeSelector.select(3); break; case IBuildMacro.VALUE_PATH_DIR: fTypeSelector.select(4); break; case IBuildMacro.VALUE_PATH_DIR_LIST: fTypeSelector.select(5); break; case IBuildMacro.VALUE_PATH_ANY: fTypeSelector.select(6); break; case IBuildMacro.VALUE_PATH_ANY_LIST: fTypeSelector.select(7); break; case IBuildMacro.VALUE_TEXT: default: fTypeSelector.select(0); break; } } /* (non-Javadoc) * @see org.eclipse.jface.dialogs.Dialog#okPressed() */ @Override protected void okPressed(){ String name = getSelectedVarName(); if(name != null || !EMPTY_STRING.equals(name)){ int type = getSelectedType(); if(CdtVariableResolver.isStringListVariable(type)) fResultingMacro = new BuildMacro(name,type,getSelectedStringListValue()); else fResultingMacro = new BuildMacro(name,type,getSelectedStringValue()); } super.okPressed(); } /* (non-Javadoc) * @see org.eclipse.jface.window.Window#open() */ @Override public int open(){ fResultingMacro = null; return super.open(); } /* * returns the macro value that should be stored in the resulting variable */ private String getSelectedStringValue(){ return fMacroValueEdit.getText(); } private String[] getSelectedStringListValue(){ return fListEditor.getItems(); } /* * this method should be called after the dialog is closed * to obtain the created variable. * if the variable was not created, e.g. because a user has pressed * the cancel button this method returns null */ public ICdtVariable getDefinedMacro(){ return fResultingMacro; } /* * called when the variable name is modified */ private void handleMacroNameModified(){ String name = getSelectedVarName(); if(fTypedName == null || !fTypedName.equals(name)){ loadVarSettings(name); } } private void handleMacroValueModified(){} /* * called when the operation is modified */ private void handleTypeModified(){ int type = getSelectedType(); if(fTypedType != -1 && fTypedType == type) return; fTypedType = type; adjustLayout(type); } private void adjustLayout(int type){ GridData listGd = (GridData)fListEditorContainier.getLayoutData(); GridData labelGd = (GridData)fMacroValueLabel.getLayoutData(); GridData editGd = (GridData)fMacroValueEdit.getLayoutData(); GridData browseGd = (GridData)fBrowseButton.getLayoutData(); if(CdtVariableResolver.isStringListVariable(type)){ listGd.exclude = false; labelGd.exclude = true; editGd.exclude = true; browseGd.exclude = true; fListEditorContainier.setVisible(true); fListEditor.setType(getBrowseType(type)); fMacroValueLabel.setVisible(false); fMacroValueEdit.setVisible(false); fBrowseButton.setVisible(false); } else { listGd.exclude = true; labelGd.exclude = false; editGd.exclude = false; int editSpan; fListEditorContainier.setVisible(false); fMacroValueLabel.setVisible(true); fMacroValueEdit.setVisible(true); if(getBrowseType(type) != IOption.BROWSE_NONE){ browseGd.exclude = false; editSpan = 1; fBrowseButton.setVisible(true); } else { browseGd.exclude = true; editSpan = 2; fBrowseButton.setVisible(false); } editGd.horizontalSpan = editSpan; } fContainer.layout(true,true); } /* * updates the state of the dialog controls */ private void updateWidgetState(){ if(!fTotalSizeCalculated) return; handleTypeModified(); Button b = getButton(IDialogConstants.OK_ID); if (b != null) { String name = getSelectedVarName(); b.setEnabled(!EMPTY_STRING.equals(name)); } } @Override protected Point getInitialSize() { Point size = super.getInitialSize(); fTotalSizeCalculated = true; updateWidgetState(); return size; } }