Skip to content

Commit

Permalink
Merge pull request #575 from jonahgraham/toolchain-preferences
Browse files Browse the repository at this point in the history
Add some visual separation between toolchain settings
  • Loading branch information
ilg-ul committed Jun 27, 2023
2 parents 1949b0d + 44d3cf6 commit fd62f0b
Show file tree
Hide file tree
Showing 11 changed files with 897 additions and 178 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2011, 2013 Marc-Andre Laperle and others.
* Copyright (c) 2011, 2023 Marc-Andre Laperle and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand Down Expand Up @@ -64,10 +64,26 @@ public class Messages extends NLS {
public static String ToolchainPaths_label;
public static String ToolchainName_label;

public static String ProjectToolchainsPathPropertiesPage_GlobalSettings_link;

public static String ProjectToolchainsPathPropertiesPage_ToolchainMessageAllConfigs_label;

public static String ProjectToolchainsPathPropertiesPage_ToolchainMessageSomeConfigs_label;

public static String ProjectToolchainsPathPropertiesPage_WorkspaceSettings_link;

public static String ProjectToolchainsPathsPropertiesPage_description;
public static String WorkspaceToolchainsPathsPreferencesPage_description;
public static String GlobalToolchainsPathsPreferencesPage_description;

public static String GlobalToolchainsPathsPreferencesPage_ToolchainDefaultGroup_label;

public static String GlobalToolchainsPathsPreferencesPage_ToolchainMessageDefault_label;

public static String GlobalToolchainsPathsPreferencesPage_ToolchainMessageWithProjects_label;

public static String GlobalToolchainsPathsPreferencesPage_ToolchainPathGroup_label;

public static String SetCrossCommandWizardPage_text;

// ------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
###############################################################################
# Copyright (c) 2011, 2013 Marc-Andre Laperle
# Copyright (c) 2011, 2023 Marc-Andre Laperle and others.
#
# This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
Expand Down Expand Up @@ -64,29 +64,41 @@ ToolsPaths_ToolchainName_label=Toolchain name:
ToolchainPaths_label=Toolchain folder:
ToolchainName_label=Default toolchain:

ProjectToolchainsPathPropertiesPage_GlobalSettings_link=<a>Configure Global Settings...</a>
ProjectToolchainsPathPropertiesPage_ToolchainMessageAllConfigs_label=Toolchain used in this project by all configurations
ProjectToolchainsPathPropertiesPage_ToolchainMessageSomeConfigs_label=Toolchain used in this project by the following configurations: {0}
ProjectToolchainsPathPropertiesPage_WorkspaceSettings_link=<a>Configure Workspace Settings...</a>\n
ProjectToolchainsPathsPropertiesPage_description=\
Configure the location where various GNU Arm toolchains are installed. \
The values are stored in the workspace (not in the project). \
They are used for all build configurations of this project, \
and override the workspace or global paths. \
A path specified on this page is stored in the project and override the workspace or global paths.\n\
As the toolchain locations specified here are stored in the project, it is generally not a good idea to \
specify paths here. Instead prefer to specify toolchain locations either at the Workspace or Global \
preferences.\n\
Only the toolchains in use by this project are shown on this page.\
\n

WorkspaceToolchainsPathsPreferencesPage_description=\
Configure the locations where various GNU Arm toolchains are installed. \
The paths are stored in the workspace and override the global paths. \
A path specified on this page is stored in the workspace and override the global paths. \
Unless redefined per project, they are used for all \
projects in this workspace. \
projects in this workspace.\n\
Only the toolchains in use by projects in the workspace are shown on this page. \
\n

GlobalToolchainsPathsPreferencesPage_description=\
Configure the locations where various GNU Arm toolchains are installed. \
The values are stored within Eclipse. \
Unless redefined more specifically, they are used for all \
projects in all workspaces. \
projects in all workspaces.\n\
Only the toolchains in use by projects in the workspace are shown on this page. \
\n
GlobalToolchainsPathsPreferencesPage_ToolchainDefaultGroup_label=Select the default toolchain to be used when creating new projects
GlobalToolchainsPathsPreferencesPage_ToolchainMessageDefault_label=Toolchain used by default for new projects
GlobalToolchainsPathsPreferencesPage_ToolchainMessageWithProjects_label=Toolchain used by the following projects: {0}
GlobalToolchainsPathsPreferencesPage_ToolchainPathGroup_label=Specify toolchain paths for in use toolchains

SetCrossCommandWizardPage_text=\
On macOS use Shift+Cmd+'.' to show the hidden folders while browsing the file system. \
xpm uses a .content folder to store the binaries.\n
xpm uses a .content folder to store the binaries.


Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2015 Liviu Ionescu.
* Copyright (c) 2015, 2023 Liviu Ionescu and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -15,8 +15,12 @@

package org.eclipse.embedcdt.internal.managedbuild.cross.arm.ui.preferences;

import java.util.HashSet;
import java.util.Comparator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.stream.Collectors;

import org.eclipse.cdt.managedbuilder.core.BuildException;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
Expand All @@ -35,10 +39,15 @@
import org.eclipse.embedcdt.managedbuild.cross.core.preferences.PersistentPreferences;
import org.eclipse.embedcdt.ui.LabelFakeFieldEditor;
import org.eclipse.embedcdt.ui.XpackDirectoryNotStrictFieldEditor;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
Expand Down Expand Up @@ -97,21 +106,22 @@ public void init(IWorkbench workbench) {
*/
@Override
protected void createFieldEditors() {
final Composite parent = getFieldEditorParent();
final GridLayout layout = new GridLayout();
layout.marginWidth = 0;
parent.setLayout(layout);

boolean isStrict;

FieldEditor toolchainNameField = new ToolchainsFieldEditor(PersistentPreferences.TOOLCHAIN_ID_KEY,
Messages.ToolchainName_label, getFieldEditorParent());
addField(toolchainNameField);

Set<ToolchainDefinition> toolchains = new HashSet<>();
Map<ToolchainDefinition, Map<String, Set<String>>> toolchains = new TreeMap<>(
Comparator.comparing(ToolchainDefinition::getName));

IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
for (int i = 0; i < projects.length; ++i) {
IConfiguration[] configs = EclipseUtils.getConfigurationsForProject(projects[i]);
for (IProject project : projects) {
IConfiguration[] configs = EclipseUtils.getConfigurationsForProject(project);
boolean allConfigsUseSameToolchain = true;
ToolchainDefinition toolchainInUse = null;
if (configs != null) {
for (int j = 0; j < configs.length; ++j) {
IToolChain toolchain = configs[j].getToolChain();
for (IConfiguration config : configs) {
IToolChain toolchain = config.getToolChain();
if (toolchain == null) {
continue;
}
Expand All @@ -120,7 +130,16 @@ protected void createFieldEditors() {
try {
String toolchainId = optionId.getStringValue();
int ix = ToolchainDefinition.findToolchainById(toolchainId);
toolchains.add(ToolchainDefinition.getToolchain(ix));

ToolchainDefinition toolchainDefinition = ToolchainDefinition.getToolchain(ix);
if (toolchainInUse == null) {
toolchainInUse = toolchainDefinition;
} else if (!toolchainInUse.equals(toolchainDefinition)) {
allConfigsUseSameToolchain = false;
}
var projectMap = toolchains.computeIfAbsent(toolchainDefinition, x -> new TreeMap<>());
var buildConfigsSet = projectMap.computeIfAbsent(project.getName(), x -> new TreeSet<>());
buildConfigsSet.add(config.getName());
continue;
} catch (BuildException e) {
} catch (IndexOutOfBoundsException e) {
Expand All @@ -131,20 +150,36 @@ protected void createFieldEditors() {
try {
String toolchainName = optionName.getStringValue();
int ix = ToolchainDefinition.findToolchainByName(toolchainName);
toolchains.add(ToolchainDefinition.getToolchain(ix));

ToolchainDefinition toolchainDefinition = ToolchainDefinition.getToolchain(ix);
if (toolchainInUse == null) {
toolchainInUse = toolchainDefinition;
} else if (!toolchainInUse.equals(toolchainDefinition)) {
allConfigsUseSameToolchain = false;
}
var projectMap = toolchains.computeIfAbsent(toolchainDefinition, x -> new TreeMap<>());
var buildConfigsSet = projectMap.computeIfAbsent(project.getName(), x -> new TreeSet<>());
buildConfigsSet.add(config.getName());
} catch (BuildException e) {
} catch (IndexOutOfBoundsException e) {
}
}
}
}

if (allConfigsUseSameToolchain && toolchainInUse != null) {
Set<String> set = toolchains.get(toolchainInUse).get(project.getName());
// If all the configurations use the same toolchain, don't display
// any of the configurations in the UI
set.clear();
}
}

if (toolchains.isEmpty()) {
try {
String toolchainId = fPersistentPreferences.getToolchainId();
int ix = ToolchainDefinition.findToolchainById(toolchainId);
toolchains.add(ToolchainDefinition.getToolchain(ix));
toolchains.computeIfAbsent(ToolchainDefinition.getToolchain(ix), x -> Map.of());
} catch (IndexOutOfBoundsException e) {
}
}
Expand All @@ -153,37 +188,111 @@ protected void createFieldEditors() {
try {
String toolchainName = fPersistentPreferences.getToolchainName();
int ix = ToolchainDefinition.findToolchainByName(toolchainName);
toolchains.add(ToolchainDefinition.getToolchain(ix));
toolchains.computeIfAbsent(ToolchainDefinition.getToolchain(ix), x -> Map.of());
} catch (IndexOutOfBoundsException e) {
}
}

if (toolchains.isEmpty()) {
int ix = ToolchainDefinition.getDefault();
toolchains.add(ToolchainDefinition.getToolchain(ix));
toolchains.computeIfAbsent(ToolchainDefinition.getToolchain(ix), x -> Map.of());
}

for (ToolchainDefinition toolchain : toolchains) {
final Group group = new Group(parent, SWT.NONE);
group.setText(Messages.GlobalToolchainsPathsPreferencesPage_ToolchainPathGroup_label);
GridLayout groupLayout = new GridLayout(4, false);
group.setLayout(groupLayout);
group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

boolean first = true;
for (var entry : toolchains.entrySet()) {
if (first) {
first = false;
} else {
Label verticalSpacer = new Label(group, SWT.NONE);
GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false, 4, 1);
verticalSpacer.setLayoutData(layoutData);
verticalSpacer.setText("");
}

ToolchainDefinition toolchain = entry.getKey();
var projectToConfigsMap = entry.getValue();

Label message = new Label(group, SWT.WRAP);
GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false, 4, 1);
message.setLayoutData(layoutData);
if (projectToConfigsMap.isEmpty()) {
message.setText(Messages.GlobalToolchainsPathsPreferencesPage_ToolchainMessageDefault_label);
} else {
String collected = projectToConfigsMap.entrySet().stream().map(e -> {
String projectName = e.getKey();
Set<String> configNames = e.getValue();
if (configNames.isEmpty()) {
return projectName;
} else {
return projectName + " (" + String.join(", ", configNames) + ")";
}
}).collect(Collectors.joining(", "));
message.setText(NLS.bind(
Messages.GlobalToolchainsPathsPreferencesPage_ToolchainMessageWithProjects_label, collected));

}
PixelConverter pixelConverter = new PixelConverter(message);
layoutData.widthHint = pixelConverter
.convertWidthInCharsToPixels(Math.min(message.getText().length(), 100));

FieldEditor labelField = new LabelFakeFieldEditor(toolchain.getFullName(),
Messages.ToolsPaths_ToolchainName_label, getFieldEditorParent());
Messages.ToolsPaths_ToolchainName_label, group);
labelField.fillIntoGrid(group, 4);
addField(labelField);

isStrict = fDefaultPreferences.getBoolean(PersistentPreferences.WORKSPACE_TOOLCHAIN_PATH_STRICT, true);
boolean isStrict = fDefaultPreferences.getBoolean(PersistentPreferences.WORKSPACE_TOOLCHAIN_PATH_STRICT,
true);

String[] xpackNames = fDefaultPreferences.getToolchainXpackNames(toolchain.getId(), toolchain.getName());

String key = PersistentPreferences.getToolchainKey(toolchain.getId(), toolchain.getName());
FieldEditor toolchainPathField = new XpackDirectoryNotStrictFieldEditor(xpackNames, key,
Messages.ToolchainPaths_label, getFieldEditorParent(), isStrict);

Messages.ToolchainPaths_label, group, isStrict);
toolchainPathField.fillIntoGrid(group, 4);
addField(toolchainPathField);
}

Label message = new Label(getFieldEditorParent(), SWT.NONE);
Label verticalSpacer = new Label(group, SWT.NONE);
GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false, 4, 1);
message.setLayoutData(layoutData);
message.setText(Messages.SetCrossCommandWizardPage_text);
verticalSpacer.setLayoutData(layoutData);
verticalSpacer.setText("");

Label macOSMessage = new Label(group, SWT.NONE);
layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false, 4, 1);
macOSMessage.setLayoutData(layoutData);
macOSMessage.setText(Messages.SetCrossCommandWizardPage_text);

// Layout need to be reset after fields are added
group.setLayout(groupLayout);

final Group group1 = new Group(parent, SWT.NONE);
group1.setText(Messages.GlobalToolchainsPathsPreferencesPage_ToolchainDefaultGroup_label);
GridLayout group1Layout = new GridLayout(2, false);
group1.setLayout(group1Layout);
group1.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

FieldEditor toolchainNameField = new ToolchainsFieldEditor(PersistentPreferences.TOOLCHAIN_ID_KEY,
Messages.ToolchainName_label, group1);
toolchainNameField.fillIntoGrid(group1, 2);
// ComboFieldEditor does not grab excess space (like StringFieldEditor does) therefore
// we need to specify that here. ComboFieldEditor also doesn't provide an equivalent
// to StringFieldEditor.getTextControl, hence the need to get control's layout data
// like this
((GridData) group1.getChildren()[1].getLayoutData()).grabExcessHorizontalSpace = true;
addField(toolchainNameField);
// Layout need to be reset after fields are added
group1.setLayout(group1Layout);
}

@Override
protected void adjustGridLayout() {
// do nothing as we are manually handling the grid layout in createFieldEditors
}

// ------------------------------------------------------------------------
Expand Down
Loading

0 comments on commit fd62f0b

Please sign in to comment.