-
Notifications
You must be signed in to change notification settings - Fork 207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add UI for specifying CMake tools and generators' locations #1067
base: main
Are you sure you want to change the base?
Changes from 6 commits
9e60988
9b56300
7aa6da6
1952eed
ba20266
18ad0ef
b3f626a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -10,6 +10,10 @@ | |||||||||||||||||||||||||||||||||||||||||||||
*******************************************************************************/ | ||||||||||||||||||||||||||||||||||||||||||||||
package org.eclipse.cdt.cmake.ui.internal; | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
import java.io.BufferedReader; | ||||||||||||||||||||||||||||||||||||||||||||||
import java.io.File; | ||||||||||||||||||||||||||||||||||||||||||||||
import java.io.IOException; | ||||||||||||||||||||||||||||||||||||||||||||||
import java.io.InputStreamReader; | ||||||||||||||||||||||||||||||||||||||||||||||
import java.nio.file.Path; | ||||||||||||||||||||||||||||||||||||||||||||||
import java.util.ArrayList; | ||||||||||||||||||||||||||||||||||||||||||||||
import java.util.Collections; | ||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -20,44 +24,78 @@ | |||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.cdt.cmake.core.ICMakeToolChainFile; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.cdt.cmake.core.ICMakeToolChainManager; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.cdt.cmake.core.internal.CMakeToolChainManager; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.cdt.core.CCorePlugin; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.cdt.core.build.IToolChain; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.cdt.core.cdtvariables.CdtVariableException; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.cdt.core.cdtvariables.ICdtVariable; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.cdt.ui.newui.BuildVarListDialog; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.cdt.utils.ui.controls.FileListControl; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.core.runtime.CoreException; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.core.runtime.preferences.InstanceScope; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.jface.dialogs.Dialog; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.jface.dialogs.MessageDialog; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.jface.layout.TableColumnLayout; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.jface.preference.PreferencePage; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.jface.viewers.ColumnWeightData; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.jface.window.Window; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.jface.wizard.WizardDialog; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.swt.SWT; | ||||||||||||||||||||||||||||||||||||||||||||||
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.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.DirectoryDialog; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.swt.widgets.Group; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.swt.widgets.Label; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.swt.widgets.Shell; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.swt.widgets.Table; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.swt.widgets.TableColumn; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.swt.widgets.TableItem; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.swt.widgets.Text; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.ui.IWorkbench; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.eclipse.ui.IWorkbenchPreferencePage; | ||||||||||||||||||||||||||||||||||||||||||||||
import org.osgi.service.prefs.Preferences; | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||
* GUI page to configure workbench preferences for cmake. | ||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||
public class CMakePreferencePage extends PreferencePage implements IWorkbenchPreferencePage { | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
private static final String NODENAME = "cmake_environment"; //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||
private static final String ENABLE_USE_CMAKE_LOCATION = "enable_use_cmake_location"; //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||
private static final String CMAKE_LOCATION = "cmake_location"; //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||
private static final String CMAKE_GENERATOR_LOCATION = "cmake_generator_locations"; //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||
private static final String VALUE_DELIMITER = " || "; //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
private ICMakeToolChainManager manager; | ||||||||||||||||||||||||||||||||||||||||||||||
private Table filesTable; | ||||||||||||||||||||||||||||||||||||||||||||||
private Button removeButton; | ||||||||||||||||||||||||||||||||||||||||||||||
private Button variablesButton; | ||||||||||||||||||||||||||||||||||||||||||||||
private Button testButton; | ||||||||||||||||||||||||||||||||||||||||||||||
private Button browseButton; | ||||||||||||||||||||||||||||||||||||||||||||||
private Button editButton; | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
private Text cmakeLocationTextBox; | ||||||||||||||||||||||||||||||||||||||||||||||
private Text generatorLocationTextBox; | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
private String[] generatorLocations; | ||||||||||||||||||||||||||||||||||||||||||||||
private String cmakeLocation; | ||||||||||||||||||||||||||||||||||||||||||||||
private boolean useCmakeToolLocation; | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
private Map<Path, ICMakeToolChainFile> filesToAdd = new HashMap<>(); | ||||||||||||||||||||||||||||||||||||||||||||||
private Map<Path, ICMakeToolChainFile> filesToRemove = new HashMap<>(); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||||||||||||||||||
public void init(IWorkbench workbench) { | ||||||||||||||||||||||||||||||||||||||||||||||
manager = Activator.getService(ICMakeToolChainManager.class); | ||||||||||||||||||||||||||||||||||||||||||||||
updateCmakeToolGroupData(); | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -141,11 +179,141 @@ public void widgetSelected(SelectionEvent e) { | |||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
// CMake tools section | ||||||||||||||||||||||||||||||||||||||||||||||
Group cmakeToolsGroup = new Group(control, SWT.NONE); | ||||||||||||||||||||||||||||||||||||||||||||||
cmakeToolsGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); | ||||||||||||||||||||||||||||||||||||||||||||||
cmakeToolsGroup.setText(Messages.CMakePreferencePage_CMakeTools); | ||||||||||||||||||||||||||||||||||||||||||||||
cmakeToolsGroup.setLayout(new GridLayout(1, false)); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Composite checkBoxComp = new Composite(cmakeToolsGroup, SWT.NONE); | ||||||||||||||||||||||||||||||||||||||||||||||
checkBoxComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); | ||||||||||||||||||||||||||||||||||||||||||||||
checkBoxComp.setLayout(new GridLayout()); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Button useCMakeToolLocCheckBox = new Button(checkBoxComp, SWT.CHECK); | ||||||||||||||||||||||||||||||||||||||||||||||
useCMakeToolLocCheckBox.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1)); | ||||||||||||||||||||||||||||||||||||||||||||||
useCMakeToolLocCheckBox.setText(Messages.CMakePreferencePage_UseCMakeToolLocationsInCMakeBuilds); | ||||||||||||||||||||||||||||||||||||||||||||||
useCMakeToolLocCheckBox.setToolTipText(Messages.CMakePreferencePage_UseCMakeToolLocationsInCMakeBuildsTooltip); | ||||||||||||||||||||||||||||||||||||||||||||||
useCMakeToolLocCheckBox.setSelection(useCmakeToolLocation); | ||||||||||||||||||||||||||||||||||||||||||||||
useCMakeToolLocCheckBox.addListener(SWT.Selection, e -> { | ||||||||||||||||||||||||||||||||||||||||||||||
useCmakeToolLocation = useCMakeToolLocCheckBox.getSelection(); | ||||||||||||||||||||||||||||||||||||||||||||||
updateCMakeGroup(useCmakeToolLocation); | ||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Composite locationComp = new Composite(cmakeToolsGroup, SWT.NONE); | ||||||||||||||||||||||||||||||||||||||||||||||
locationComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); | ||||||||||||||||||||||||||||||||||||||||||||||
locationComp.setLayout(new GridLayout(3, false)); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Label cmakeLocationLabel = new Label(locationComp, SWT.NONE); | ||||||||||||||||||||||||||||||||||||||||||||||
cmakeLocationLabel.setText(Messages.CMakePreferencePage_CMakeLocation); | ||||||||||||||||||||||||||||||||||||||||||||||
cmakeLocationLabel.setToolTipText(Messages.CMakePreferencePage_CMakeLocationTooltip); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
cmakeLocationTextBox = new Text(locationComp, SWT.BORDER); | ||||||||||||||||||||||||||||||||||||||||||||||
cmakeLocationTextBox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); | ||||||||||||||||||||||||||||||||||||||||||||||
cmakeLocationTextBox.setText(cmakeLocation); | ||||||||||||||||||||||||||||||||||||||||||||||
cmakeLocationTextBox.addModifyListener(new ModifyListener() { | ||||||||||||||||||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||||||||||||||||||
public void modifyText(ModifyEvent evt) { | ||||||||||||||||||||||||||||||||||||||||||||||
cmakeLocation = resolveVariableValue(cmakeLocationTextBox.getText()); | ||||||||||||||||||||||||||||||||||||||||||||||
testButton.setEnabled(useCmakeToolLocation && cmakeLocationTextBox.getText().trim().length() > 0); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Composite cmakeLocationButtonComp = new Composite(locationComp, SWT.NONE); | ||||||||||||||||||||||||||||||||||||||||||||||
cmakeLocationButtonComp.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); | ||||||||||||||||||||||||||||||||||||||||||||||
cmakeLocationButtonComp.setLayout(new GridLayout(3, true)); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
variablesButton = new Button(cmakeLocationButtonComp, SWT.PUSH); | ||||||||||||||||||||||||||||||||||||||||||||||
variablesButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); | ||||||||||||||||||||||||||||||||||||||||||||||
variablesButton.setText(Messages.CMakePreferencePage_Variables); | ||||||||||||||||||||||||||||||||||||||||||||||
variablesButton.setData(cmakeLocationTextBox); | ||||||||||||||||||||||||||||||||||||||||||||||
variablesButton.addListener(SWT.Selection, e -> { | ||||||||||||||||||||||||||||||||||||||||||||||
String x = null; | ||||||||||||||||||||||||||||||||||||||||||||||
if (variablesButton.getData() instanceof Text t) { | ||||||||||||||||||||||||||||||||||||||||||||||
x = getVariableDialog(getShell(), null); | ||||||||||||||||||||||||||||||||||||||||||||||
if (x != null) { | ||||||||||||||||||||||||||||||||||||||||||||||
t.insert(x); | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+226
to
+238
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only getData on this button is in the listener - by doing it this way we need instanceof checks and we lose the natural connection. e.g. doing find references on cmakeLocationTextBox won't show the t on line 232. Also, if you have one access to the field (variablesButton) you may as well directly access the field you really wanted. Here is a suggestion for this block of code, it does this following:
Suggested change
You can apply a similar change to the The use of set/get data is suitable when there is some reuse of code. For example, if you used the same listener for a bunch of different Variables... buttons and wanted each one to work on its associated text you could do something like this: /**
* Opens the variable dialog and applies the result to the text box associated with the
* widget that issued the selection event.
*/
Listener applyVariableToTextbox = e -> {
if (e.widget.getData() instanceof Text t) {
String variable = getVariableDialog(getShell(), null);
if (variable != null) {
t.insert(variable);
}
}
};
cmakeVariablesButton = new Button(composite, SWT.PUSH);
cmakeVariablesButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
cmakeVariablesButton.setText("Variables...");
cmakeVariablesButton.setData(cmakeLocationTextBox);
cmakeVariablesButton.addListener(SWT.Selection, applyVariableToTextbox);
anotherVariablesButton = new Button(composite, SWT.PUSH);
anotherVariablesButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
anotherVariablesButton.setText("Variables...");
anotherVariablesButton.setData(anotherTextBox);
anotherVariablesButton.addListener(SWT.Selection, applyVariableToTextbox); |
||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
testButton = new Button(cmakeLocationButtonComp, SWT.PUSH); | ||||||||||||||||||||||||||||||||||||||||||||||
testButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); | ||||||||||||||||||||||||||||||||||||||||||||||
testButton.setText(Messages.CMakePreferencePage_Test); | ||||||||||||||||||||||||||||||||||||||||||||||
testButton.setToolTipText(Messages.CMakePreferencePage_TestTooltip); | ||||||||||||||||||||||||||||||||||||||||||||||
testButton.setData(cmakeLocationTextBox); | ||||||||||||||||||||||||||||||||||||||||||||||
testButton.addListener(SWT.Selection, e -> { | ||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||
Process p = Runtime.getRuntime() | ||||||||||||||||||||||||||||||||||||||||||||||
.exec(new String[] { cmakeLocation + File.separatorChar + "cmake", "--version" }); //$NON-NLS-1$ //$NON-NLS-2$ | ||||||||||||||||||||||||||||||||||||||||||||||
List<String> buf = new ArrayList<>(); | ||||||||||||||||||||||||||||||||||||||||||||||
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); | ||||||||||||||||||||||||||||||||||||||||||||||
String line; | ||||||||||||||||||||||||||||||||||||||||||||||
while ((line = br.readLine()) != null) { | ||||||||||||||||||||||||||||||||||||||||||||||
buf.add(line); | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
MessageDialog.openInformation(getShell(), Messages.CMakePreferencePage_TestCmakeLocation_Title, | ||||||||||||||||||||||||||||||||||||||||||||||
Messages.CMakePreferencePage_TestCmakeLocation_Body + String.join(System.lineSeparator(), buf)); | ||||||||||||||||||||||||||||||||||||||||||||||
} catch (IOException e1) { | ||||||||||||||||||||||||||||||||||||||||||||||
MessageDialog.openError(getShell(), Messages.CMakePreferencePage_FailToTestCmakeLocation_Title, | ||||||||||||||||||||||||||||||||||||||||||||||
Messages.CMakePreferencePage_FailToTestCmakeLocation_Body + e1.getMessage()); | ||||||||||||||||||||||||||||||||||||||||||||||
Activator.log(e1); | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
browseButton = new Button(cmakeLocationButtonComp, SWT.PUSH); | ||||||||||||||||||||||||||||||||||||||||||||||
browseButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); | ||||||||||||||||||||||||||||||||||||||||||||||
browseButton.setText(Messages.CMakePreferencePage_Browse); | ||||||||||||||||||||||||||||||||||||||||||||||
browseButton.setData(cmakeLocationTextBox); | ||||||||||||||||||||||||||||||||||||||||||||||
browseButton.addListener(SWT.Selection, e -> { | ||||||||||||||||||||||||||||||||||||||||||||||
DirectoryDialog dirDialog = new DirectoryDialog(getShell()); | ||||||||||||||||||||||||||||||||||||||||||||||
String browsedDirectory = dirDialog.open(); | ||||||||||||||||||||||||||||||||||||||||||||||
if (browsedDirectory != null && browseButton.getData() instanceof Text t) { | ||||||||||||||||||||||||||||||||||||||||||||||
t.setText(browsedDirectory); | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Label generatorLocationsLabel = new Label(locationComp, SWT.NONE); | ||||||||||||||||||||||||||||||||||||||||||||||
generatorLocationsLabel.setText(Messages.CMakePreferencePage_GeneratorLocation); | ||||||||||||||||||||||||||||||||||||||||||||||
generatorLocationsLabel.setToolTipText(Messages.CMakePreferencePage_GeneratorLocationTooltip); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
generatorLocationTextBox = new Text(locationComp, SWT.BORDER); | ||||||||||||||||||||||||||||||||||||||||||||||
generatorLocationTextBox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); | ||||||||||||||||||||||||||||||||||||||||||||||
generatorLocationTextBox.setEditable(false); | ||||||||||||||||||||||||||||||||||||||||||||||
generatorLocationTextBox.setText(String.join(VALUE_DELIMITER, generatorLocations)); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Composite generatorLocationButtonComp = new Composite(locationComp, SWT.NONE); | ||||||||||||||||||||||||||||||||||||||||||||||
generatorLocationButtonComp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); | ||||||||||||||||||||||||||||||||||||||||||||||
generatorLocationButtonComp.setLayout(new GridLayout(3, true)); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
editButton = new Button(generatorLocationButtonComp, SWT.PUSH); | ||||||||||||||||||||||||||||||||||||||||||||||
editButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); | ||||||||||||||||||||||||||||||||||||||||||||||
editButton.setText(Messages.CMakePreferencePage_Edit); | ||||||||||||||||||||||||||||||||||||||||||||||
editButton.setData(generatorLocationTextBox); | ||||||||||||||||||||||||||||||||||||||||||||||
editButton.addListener(SWT.Selection, e -> { | ||||||||||||||||||||||||||||||||||||||||||||||
EditGeneratorLocationDialog dialog = new EditGeneratorLocationDialog(getShell(), | ||||||||||||||||||||||||||||||||||||||||||||||
Messages.CMakePreferencePage_EditGeneratorLocations_Title, generatorLocations); | ||||||||||||||||||||||||||||||||||||||||||||||
if (dialog.open() == Window.OK && editButton.getData() instanceof Text t) { | ||||||||||||||||||||||||||||||||||||||||||||||
generatorLocations = dialog.getValues(); | ||||||||||||||||||||||||||||||||||||||||||||||
t.setText(String.join(VALUE_DELIMITER, generatorLocations)); | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
updateTable(); | ||||||||||||||||||||||||||||||||||||||||||||||
updateCMakeGroup(useCmakeToolLocation); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
return control; | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
protected void updateCMakeGroup(boolean enable) { | ||||||||||||||||||||||||||||||||||||||||||||||
cmakeLocationTextBox.setEnabled(enable); | ||||||||||||||||||||||||||||||||||||||||||||||
generatorLocationTextBox.setEnabled(enable); | ||||||||||||||||||||||||||||||||||||||||||||||
variablesButton.setEnabled(enable); | ||||||||||||||||||||||||||||||||||||||||||||||
testButton.setEnabled(enable && cmakeLocationTextBox.getText().trim().length() > 0); | ||||||||||||||||||||||||||||||||||||||||||||||
browseButton.setEnabled(enable); | ||||||||||||||||||||||||||||||||||||||||||||||
editButton.setEnabled(enable); | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
private void updateTable() { | ||||||||||||||||||||||||||||||||||||||||||||||
List<ICMakeToolChainFile> sorted = new ArrayList<>(getFiles().values()); | ||||||||||||||||||||||||||||||||||||||||||||||
Collections.sort(sorted, (o1, o2) -> o1.getPath().toString().compareToIgnoreCase(o2.getPath().toString())); | ||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -205,7 +373,89 @@ public boolean performOk() { | |||||||||||||||||||||||||||||||||||||||||||||
filesToAdd.clear(); | ||||||||||||||||||||||||||||||||||||||||||||||
filesToRemove.clear(); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
// Update Preferences for cmakeSupplier | ||||||||||||||||||||||||||||||||||||||||||||||
getPreferences().putBoolean(ENABLE_USE_CMAKE_LOCATION, useCmakeToolLocation); | ||||||||||||||||||||||||||||||||||||||||||||||
getPreferences().put(CMAKE_LOCATION, cmakeLocation); | ||||||||||||||||||||||||||||||||||||||||||||||
getPreferences().put(CMAKE_GENERATOR_LOCATION, String.join(VALUE_DELIMITER, generatorLocations)); | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please serialize the list using XML or propose another serialization format that has no ambiguity. For example, to reuse the CDT infrastructure to do this see org.eclipse.cdt.internal.core.cdtvariables.UserDefinedVariableSupplier.storeMacrosToStream(StorableCdtVariables) Note that the CDT Variables GUI + backend is pretty complicated and it can be hard to see how the variable serialize connects to the preference tab. Here is a call hierarchy that shows how they are connected:
|
||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
private void updateCmakeToolGroupData() { | ||||||||||||||||||||||||||||||||||||||||||||||
useCmakeToolLocation = getPreferences().getBoolean(ENABLE_USE_CMAKE_LOCATION, false); | ||||||||||||||||||||||||||||||||||||||||||||||
cmakeLocation = getPreferences().get(CMAKE_LOCATION, ""); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||
String genLocations = getPreferences().get(CMAKE_GENERATOR_LOCATION, ""); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||
generatorLocations = genLocations.length() > 0 ? genLocations.split(" \\|\\| ") : new String[0]; //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
private String resolveVariableValue(String value) { | ||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||
ICdtVariableManager vm = CCorePlugin.getDefault().getCdtVariableManager(); | ||||||||||||||||||||||||||||||||||||||||||||||
return vm.resolveValue(value, null, "", null); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||
} catch (CdtVariableException e) { | ||||||||||||||||||||||||||||||||||||||||||||||
Activator.log(e); | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
return null; | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
private String getVariableDialog(Shell shell, ICConfigurationDescription cfgd) { | ||||||||||||||||||||||||||||||||||||||||||||||
ICdtVariableManager vm = CCorePlugin.getDefault().getCdtVariableManager(); | ||||||||||||||||||||||||||||||||||||||||||||||
BuildVarListDialog dialog = new BuildVarListDialog(shell, vm.getVariables(cfgd)); | ||||||||||||||||||||||||||||||||||||||||||||||
dialog.setTitle(Messages.VariablesDialog_Title); | ||||||||||||||||||||||||||||||||||||||||||||||
if (dialog.open() == Window.OK) { | ||||||||||||||||||||||||||||||||||||||||||||||
Object[] selected = dialog.getResult(); | ||||||||||||||||||||||||||||||||||||||||||||||
if (selected.length > 0) { | ||||||||||||||||||||||||||||||||||||||||||||||
String s = ((ICdtVariable) selected[0]).getName(); | ||||||||||||||||||||||||||||||||||||||||||||||
return "${" + s.trim() + "}"; //$NON-NLS-1$//$NON-NLS-2$ | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
return null; | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
private class EditGeneratorLocationDialog extends Dialog { | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
private String fTitle; | ||||||||||||||||||||||||||||||||||||||||||||||
private FileListControl fListEditor; | ||||||||||||||||||||||||||||||||||||||||||||||
private String[] fGeneratorLocations; | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
public EditGeneratorLocationDialog(Shell parentShell, String title, String[] generatorLocations) { | ||||||||||||||||||||||||||||||||||||||||||||||
super(parentShell); | ||||||||||||||||||||||||||||||||||||||||||||||
this.fGeneratorLocations = generatorLocations; | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||||||||||||||||||
protected void configureShell(Shell shell) { | ||||||||||||||||||||||||||||||||||||||||||||||
super.configureShell(shell); | ||||||||||||||||||||||||||||||||||||||||||||||
if (fTitle != null) { | ||||||||||||||||||||||||||||||||||||||||||||||
shell.setText(fTitle); | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||||||||||||||||||
protected Control createDialogArea(Composite parent) { | ||||||||||||||||||||||||||||||||||||||||||||||
Composite comp = new Composite(parent, SWT.NULL); | ||||||||||||||||||||||||||||||||||||||||||||||
comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); | ||||||||||||||||||||||||||||||||||||||||||||||
comp.setLayout(new GridLayout()); | ||||||||||||||||||||||||||||||||||||||||||||||
fListEditor = new FileListControl(comp, | ||||||||||||||||||||||||||||||||||||||||||||||
Messages.CMakePreferencePage_EditGeneratorLocations_GeneratorLocation, 0); | ||||||||||||||||||||||||||||||||||||||||||||||
if (fGeneratorLocations != null) { | ||||||||||||||||||||||||||||||||||||||||||||||
fListEditor.setList(fGeneratorLocations); | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
return comp; | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||||||||||||||||||
protected void okPressed() { | ||||||||||||||||||||||||||||||||||||||||||||||
fGeneratorLocations = fListEditor.getItems(); | ||||||||||||||||||||||||||||||||||||||||||||||
super.okPressed(); | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
public String[] getValues() { | ||||||||||||||||||||||||||||||||||||||||||||||
return fGeneratorLocations; | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
private Preferences getPreferences() { | ||||||||||||||||||||||||||||||||||||||||||||||
return InstanceScope.INSTANCE.getNode(CCorePlugin.PLUGIN_ID).node(NODENAME); | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is some commentary on the design to explain why I have requested changes about serializing and deserializing.
||
was chosen as a value delimiter based on its prior art in CPropertyVarsTab, specifically fromcdt/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/CPropertyVarsTab.java
Line 90 in c252113
However in CPropertyVarsTab this was used strictly as a display convenience when displaying values in the GUI, it is not prior art for what you are doing here because you are using the
||
to serialize the values.For example, the above setting in the screenshot is stored in
.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.core.prefs
as string escaped XML file:macros/workspace=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\n<macros>\n <stringListMacro name\="jonah" type\="VALUE_TEXT_LIST">\n <value name\="val1"/>\n <value name\="val2"/>\n </stringListMacro>\n</macros>\n
The code that converts the list/array to the serialized form is
cdt/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/cdtvariables/StorableCdtVariable.java
Lines 149 to 153 in caf2292
That ties quite tightly with CDT as it is part of the org.eclipse.cdt.core.settings.model.