/*******************************************************************************
* Copyright (c) 2015 Bruno Medeiros and other Contributors.
* 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:
* Bruno Medeiros - initial API and implementation
*******************************************************************************/
package melnorme.lang.ide.ui.preferences;
import java.util.Map.Entry;
import org.eclipse.core.resources.IProject;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import melnorme.lang.ide.core.LangCore;
import melnorme.lang.ide.core.launch.BuildTargetSource;
import melnorme.lang.ide.core.operations.build.BuildManager;
import melnorme.lang.ide.core.operations.build.BuildTarget;
import melnorme.lang.ide.core.operations.build.BuildTargetData;
import melnorme.lang.ide.core.operations.build.ProjectBuildInfo;
import melnorme.lang.ide.core.utils.ProjectValidator;
import melnorme.lang.ide.ui.build.BuildTargetEditor;
import melnorme.lang.ide.ui.launch.BuildTargetField;
import melnorme.lang.ide.ui.preferences.common.IPreferencesEditor;
import melnorme.lang.ide.ui.utils.UIOperationsStatusHandler;
import melnorme.lang.tooling.commands.CommandInvocation;
import melnorme.util.swt.SWTFactoryUtil;
import melnorme.util.swt.components.CompositeWidget;
import melnorme.util.swt.components.IDisableableWidget;
import melnorme.utilbox.collections.Collection2;
import melnorme.utilbox.collections.HashMap2;
import melnorme.utilbox.core.CommonException;
import melnorme.utilbox.status.Severity;
public class ProjectBuildConfigurationComponent extends CompositeWidget
implements IPreferencesEditor {
protected final BuildManager buildManager = LangCore.getBuildManager();
protected final IProject project;
protected final BuildTargetField buildTargetField;
protected final BuildTargetEditor buildTargetEditor;
protected final HashMap2<String, BuildTargetData> buildOptionsToChange = new HashMap2<>();
public ProjectBuildConfigurationComponent(IProject project) {
super(false);
this.project = project;
this.buildTargetField = init_createBuildTargetField();
this.buildTargetEditor = init_createBuildTargetSettingsComponent();
addChildWidget(buildTargetField);
addChildWidget(buildTargetEditor);
buildTargetField.addListener(true, (__) -> handleBuildTargetChanged());
initialize();
}
protected BuildTargetField init_createBuildTargetField() {
return new BuildTargetField();
}
protected BuildTargetEditor init_createBuildTargetSettingsComponent() {
return new BuildTargetEditor(
getBuildManager(),
true,
this::getDefaultBuildCommand,
this::getDefaultExecutablePath
);
}
public BuildTargetField getBuildTargetField() {
return buildTargetField;
}
public BuildTargetEditor getBuildTargetEditor() {
return buildTargetEditor;
}
/* ----------------- ----------------- */
protected BuildManager getBuildManager() {
return buildManager;
}
public IProject getValidProject() throws CommonException {
if(project == null) {
throw new CommonException(new ProjectValidator().msg_ProjectNotSpecified());
}
return project;
}
public String getBuildTargetName() {
return buildTargetField.getFieldValue();
}
protected ProjectBuildInfo getBuildInfo() throws CommonException {
return getBuildManager().getValidBuildInfo(getValidProject());
}
/* ----------------- ----------------- */
protected void initialize() {
ProjectBuildInfo buildInfo;
try {
buildInfo = getBuildInfo();
} catch(CommonException ce) {
handleStatusException(ce);
return;
}
buildOptionsToChange.clear();
Collection2<BuildTarget> buildTargets = buildInfo.getBuildTargets();
for(BuildTarget buildTarget : buildTargets) {
buildOptionsToChange.put(buildTarget.getTargetName(), buildTarget.getDataCopy());
}
buildTargetField.setFieldOptions(
buildInfo.getBuildTargets().map((buildTarget) -> buildTarget.getTargetName()));
}
protected void handleBuildTargetChanged() {
String buildTargetName = getBuildTargetName();
buildTargetEditor.setEnabled(buildTargetName != null);
if(buildTargetName == null) {
return;
}
BuildTargetData buildTargetData = buildOptionsToChange.get(buildTargetName);
buildTargetEditor.setInput(buildTargetData);
}
/* ----------------- ----------------- */
protected final BuildTargetSource buildTargetSource = new BuildTargetSource() {
@Override
public String getProjectName(){
return project == null ? null : project.getName();
};
@Override
public String getBuildTargetName() {
return ProjectBuildConfigurationComponent.this.getBuildTargetName();
}
};
public BuildTarget getOriginalBuildTarget() throws CommonException {
return buildTargetSource.getBuildTarget();
}
public CommandInvocation getDefaultBuildCommand() throws CommonException {
String defaultBuildCommandArgs = getOriginalBuildTarget().getDefaultBuildCommand();
return new CommandInvocation(defaultBuildCommandArgs);
}
public String getDefaultExecutablePath() throws CommonException {
return getOriginalBuildTarget().getDefaultExecutablePath();
}
protected void handleStatusException(CommonException ce) {
UIOperationsStatusHandler.handleStatus(true, "Error", ce.toStatusException(Severity.ERROR));
}
/* ----------------- ----------------- */
@Override
protected void createContents(Composite topControl) {
super.createContents(topControl);
SWTFactoryUtil.createPushButton(topControl,
"Restore all targets to defaults", null,
new GridData(GridData.HORIZONTAL_ALIGN_END),
(e) -> loadDefaults()
);
}
@Override
protected GridData getLayoutData(IDisableableWidget subComponent) {
return super.getLayoutData(subComponent);
}
/* ----------------- apply/restore ----------------- */
@Override
public boolean saveSettings() {
if(project == null) {
return false;
}
try {
doSaveSettings();
} catch(CommonException e) {
return false;
}
updateWidgetFromInput();
return true;
}
@Override
public void doSaveSettings() throws CommonException {
for(Entry<String, BuildTargetData> entry : buildOptionsToChange.entrySet()) {
String targetName = entry.getKey();
BuildTargetData value = entry.getValue();
getBuildInfo().changeBuildTarget(targetName, value);
}
}
@Override
public void loadDefaults() {
if(project == null) {
return;
}
ProjectBuildInfo buildInfo;
try {
buildInfo = getBuildInfo();
} catch(CommonException e) {
UIOperationsStatusHandler.handleStatus(true, "Error loading defaults", e);
return;
}
for (Entry<String, BuildTargetData> entry : buildOptionsToChange) {
String targetName = entry.getKey();
BuildTargetData newData = buildInfo.getDefaultBuildTarget(targetName).getDataCopy();
entry.setValue(newData);
}
handleBuildTargetChanged();
}
}