diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java index 00e17865bf4..c89e5edf07b 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java @@ -482,8 +482,6 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti return; } - System.out.println("in execute"); - WorkspaceJob job = new WorkspaceJob(ManagedMakeMessages.getResourceString("AbstractBuiltinSpecsDetector.DiscoverBuiltInSettingsJobName")) { //$NON-NLS-1$ @Override public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { @@ -534,9 +532,6 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti * @return status of operation. */ protected IStatus runForEachLanguage(IProgressMonitor monitor) { - - System.out.println("in runForEachLanguage"); - MultiStatus status = new MultiStatus(ManagedBuilderCorePlugin.PLUGIN_ID, IStatus.OK, "Problem running CDT Scanner Discovery provider " + getId(), null); //$NON-NLS-1$ if (monitor == null) { @@ -547,6 +542,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti boolean isChanged = false; List languageIds = getLanguageScope(); + if (languageIds != null) { monitor.beginTask(ManagedMakeMessages.getResourceString("AbstractBuiltinSpecsDetector.ScannerDiscoveryTaskTitle"), //$NON-NLS-1$ TICKS_REMOVE_MARKERS + languageIds.size()*TICKS_RUN_FOR_ONE_LANGUAGE + TICKS_SERIALIZATION); @@ -643,9 +639,6 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti * has not been called yet. */ private void runForLanguage(IProgressMonitor monitor) throws CoreException { - - System.out.println("run for language"); - buildRunnerHelper = new BuildRunnerHelper(currentProject); if (monitor == null) { @@ -764,7 +757,6 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti } protected int runProgramForLanguage(String languageId, String command, String[] envp, URI workingDirectoryURI, OutputStream consoleOut, OutputStream consoleErr, IProgressMonitor monitor) throws CoreException, IOException { - System.out.println("runProgramForLanguage"); return buildRunnerHelper.build(monitor); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java index 91851f784b4..a7c5be0c706 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java @@ -28,6 +28,7 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.jface.layout.PixelConverter; import org.eclipse.jface.viewers.IDecoration; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.TreeViewer; @@ -39,6 +40,7 @@ import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; @@ -375,7 +377,7 @@ public class LanguageSettingsEntriesTab extends AbstractCPropertyTab { */ private void createTreeForEntries(Composite parent) { treeEntries = new Tree(parent, SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL); - treeEntries.setLayoutData(new GridData(GridData.FILL_VERTICAL)); + treeEntries.setLayoutData(new GridData(GridData.FILL_VERTICAL | GridData.GRAB_HORIZONTAL)); treeEntries.setHeaderVisible(true); treeEntries.setLinesVisible(true); @@ -383,13 +385,14 @@ public class LanguageSettingsEntriesTab extends AbstractCPropertyTab { treeEntries.addPaintListener(new PaintListener() { @Override public void paintControl(PaintEvent e) { - int x = treeEntries.getClientArea().width; - if (treeCol.getWidth() != x) - treeCol.setWidth(x); + Point p = treeEntries.computeSize(SWT.DEFAULT, SWT.DEFAULT); + if (treeCol.getWidth() != p.x) + treeCol.setWidth(p.x); } }); treeCol.setText(Messages.LanguageSettingsProviderTab_SettingEntries); + treeCol.setWidth(200); treeCol.setResizable(false); treeCol.setToolTipText(Messages.LanguageSettingsProviderTab_SettingEntriesTooltip); diff --git a/launch/org.eclipse.cdt.docker.launcher/plugin.properties b/launch/org.eclipse.cdt.docker.launcher/plugin.properties index aae650077a0..245288bb62e 100644 --- a/launch/org.eclipse.cdt.docker.launcher/plugin.properties +++ b/launch/org.eclipse.cdt.docker.launcher/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2015 Red Hat Inc. and others. +# Copyright (c) 2015,2017 Red Hat Inc. 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 @@ -15,7 +15,8 @@ Delegate.desc=This launcher runs C/C++ applications in a specified Docker Contai must be set-up to supply the C/C++ application what it needs to run. LaunchConfigurationType.name=C/C++ Container Launcher Shortcut.label=C/C++ Container Application -DockerLaunchPreferencePage.name=Docker Container Launch +DockerLaunchPreferencePage.name=Docker Container +DockerHeaderPreferencePage.name=Cached Headers ContainerCommandLauncherFactory.name=Container Command Launcher Factory Container.settings=Container Settings ContainerBuild.property.enablement=Container Build Enablement diff --git a/launch/org.eclipse.cdt.docker.launcher/plugin.xml b/launch/org.eclipse.cdt.docker.launcher/plugin.xml index 48250b94186..15eecdc8c0d 100644 --- a/launch/org.eclipse.cdt.docker.launcher/plugin.xml +++ b/launch/org.eclipse.cdt.docker.launcher/plugin.xml @@ -65,6 +65,12 @@ id="org.eclipse.cdt.docker.launcher.page1" name="%DockerLaunchPreferencePage.name"> + + diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java index 1df8ebe8f13..8ed61068f76 100644 --- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java +++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java @@ -10,6 +10,10 @@ *******************************************************************************/ package org.eclipse.cdt.docker.launcher; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -85,9 +89,6 @@ public class ContainerCommandLauncherFactory Messages.ContainerCommandLauncher_invalid_values); return; } - String prefix = getCleanName(connectionName) - + IPath.SEPARATOR - + getCleanName(imageName); //$NON-NLS-1$ //$NON-NLS-2$ ContainerLauncher launcher = new ContainerLauncher(); List paths = new ArrayList<>(); for (ICLanguageSettingEntry entry : entries) { @@ -96,9 +97,57 @@ public class ContainerCommandLauncherFactory } } if (paths.size() > 0) { + // Create a directory to put the header files for + // the image. Use the connection name to form + // the directory name as the connection may be + // connected to a different repo using the same + // image name. IPath pluginPath = Platform.getStateLocation(Platform - .getBundle(DockerLaunchUIPlugin.PLUGIN_ID)); - IPath hostDir = pluginPath.append(prefix); + .getBundle(DockerLaunchUIPlugin.PLUGIN_ID)) + .append("HEADERS"); //$NON-NLS-1$ + pluginPath.toFile().mkdir(); + pluginPath = pluginPath + .append(getCleanName(connectionName)); + pluginPath.toFile().mkdir(); + // To allow the user to later manage the headers, store + // the + // real connection name in a file. + IPath connectionNamePath = pluginPath.append(".name"); //$NON-NLS-1$ + File f = connectionNamePath.toFile(); + try { + f.createNewFile(); + try (FileWriter writer = new FileWriter(f); + BufferedWriter bufferedWriter = new BufferedWriter( + writer);) { + bufferedWriter.write(connectionName); + bufferedWriter.newLine(); + } catch (IOException e) { + DockerLaunchUIPlugin.log(e); + return; + } + pluginPath = pluginPath + .append(getCleanName(imageName)); + pluginPath.toFile().mkdir(); + // To allow the user to later manage the headers, + // store the + // real image name in a file. + IPath imageNamePath = pluginPath.append(".name"); //$NON-NLS-1$ + f = imageNamePath.toFile(); + f.createNewFile(); + try (FileWriter writer = new FileWriter(f); + BufferedWriter bufferedWriter = new BufferedWriter( + writer);) { + bufferedWriter.write(imageName); + bufferedWriter.newLine(); + } catch (IOException e) { + DockerLaunchUIPlugin.log(e); + return; + } + } catch (IOException e) { + DockerLaunchUIPlugin.log(e); + return; + } + IPath hostDir = pluginPath; @SuppressWarnings("unused") int status = launcher.fetchContainerDirs(connectionName, imageName, @@ -145,9 +194,9 @@ public class ContainerCommandLauncherFactory List newEntries = new ArrayList<>(); IPath pluginPath = Platform.getStateLocation( Platform.getBundle(DockerLaunchUIPlugin.PLUGIN_ID)); - String prefix = getCleanName(connectionName) - + IPath.SEPARATOR + getCleanName(imageName); // $NON-NLS-1$ - IPath hostDir = pluginPath.append(prefix); + IPath hostDir = pluginPath.append("HEADERS") //$NON-NLS-1$ + .append(getCleanName(connectionName)) + .append(getCleanName(imageName)); for (ICLanguageSettingEntry entry : entries) { if (entry instanceof ICIncludePathEntry) { @@ -176,7 +225,9 @@ public class ContainerCommandLauncherFactory } private String getCleanName(String name) { - return name.replaceAll("[:/]", "_"); //$NON-NLS-1$ //$NON-NLS-2$ + String cleanName = name.replace("unix:///", "unix_"); //$NON-NLS-1$ //$NON-NLS-2$ + cleanName = cleanName.replace("tcp://", "tcp_"); //$NON-NLS-1$ //$NON-NLS-2$ + return cleanName.replaceAll("[:/.]", "_"); //$NON-NLS-1$ //$NON-NLS-2$ } } diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerPropertyTab.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerPropertyTab.java index c2dd35b9959..0aa9eb15693 100644 --- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerPropertyTab.java +++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerPropertyTab.java @@ -60,12 +60,13 @@ public class ContainerPropertyTab extends AbstractCBuildPropertyTab private String connectionName; private String connectionUri = ""; //$NON-NLS-1$ - private boolean defaultEnabled; - private String defaultConnection; - private String defaultImage; + private boolean initialEnabled; + private String initialConnection; + private String initialImageId; + + private boolean multiChange; private IConfiguration iCfg; - private IOptionalBuildProperties properties; private ModifyListener connectionModifyListener = new ModifyListener() { @@ -83,11 +84,10 @@ public class ContainerPropertyTab extends AbstractCBuildPropertyTab connectionUri = connection.getUri(); if (!connectionName.equals(connection.getName())) { imageCombo.setText(""); - defaultImage = null; + initialImageId = null; } connectionName = connection.getName(); - properties.setProperty(ContainerCommandLauncher.CONNECTION_ID, - connectionUri); + setConnection(connectionUri); } }; @@ -111,7 +111,6 @@ public class ContainerPropertyTab extends AbstractCBuildPropertyTab enableButton.setText(Messages.ContainerPropertyTab_Enable_Msg); iCfg = getCfg(); - properties = iCfg.getOptionalBuildProperties(); gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 5; @@ -126,7 +125,7 @@ public class ContainerPropertyTab extends AbstractCBuildPropertyTab connectionSelectorLabel.setLayoutData(gd); connectionSelector = new Combo(usercomp, SWT.BORDER | SWT.READ_ONLY); - initializeConnectionSelector(iCfg); + initializeConnectionSelector(); connectionSelector.addModifyListener(connectionModifyListener); // Following is a kludge so that on Linux the Combo is read-only but // has a white background. @@ -153,14 +152,13 @@ public class ContainerPropertyTab extends AbstractCBuildPropertyTab gd.grabExcessHorizontalSpace = true; imageCombo.setLayoutData(gd); - initializeImageCombo(iCfg); + initializeImageCombo(); imageCombo.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { - properties.setProperty(ContainerCommandLauncher.IMAGE_ID, - imageCombo.getText()); + setImageId(imageCombo.getText()); } @Override @@ -169,15 +167,13 @@ public class ContainerPropertyTab extends AbstractCBuildPropertyTab }); - initializeEnablementButton(iCfg); + initializeEnablementButton(); enableButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { setControlsEnabled(enableButton.getSelection()); - properties.setProperty( - ContainerCommandLauncher.CONTAINER_BUILD_ENABLED, - Boolean.toString(enableButton.getSelection())); + setEnablement(enableButton.getSelection()); } @Override @@ -189,31 +185,79 @@ public class ContainerPropertyTab extends AbstractCBuildPropertyTab } + private void setEnablement(boolean enabled) { + if (iCfg instanceof IMultiConfiguration) { + IConfiguration[] cfs = (IConfiguration[]) ((IMultiConfiguration) iCfg) + .getItems(); + for (int i = 0; i < cfs.length; i++) { + IConfiguration cfg = cfs[i]; + IOptionalBuildProperties p = cfg.getOptionalBuildProperties(); + p.setProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED, + Boolean.toString(enableButton.getSelection())); + } + } else { + IOptionalBuildProperties p = iCfg.getOptionalBuildProperties(); + p.setProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED, + Boolean.toString(enableButton.getSelection())); + } + } + + private void setImageId(String imageId) { + if (iCfg instanceof IMultiConfiguration) { + IConfiguration[] cfs = (IConfiguration[]) ((IMultiConfiguration) iCfg) + .getItems(); + for (int i = 0; i < cfs.length; i++) { + IConfiguration cfg = cfs[i]; + IOptionalBuildProperties p = cfg.getOptionalBuildProperties(); + p.setProperty(ContainerCommandLauncher.IMAGE_ID, imageId); + } + } else { + IOptionalBuildProperties p = iCfg.getOptionalBuildProperties(); + p.setProperty(ContainerCommandLauncher.IMAGE_ID, imageId); + } + } + + private void setConnection(String uri) { + if (iCfg instanceof IMultiConfiguration) { + IConfiguration[] cfs = (IConfiguration[]) ((IMultiConfiguration) iCfg) + .getItems(); + for (int i = 0; i < cfs.length; i++) { + IConfiguration cfg = cfs[i]; + IOptionalBuildProperties p = cfg.getOptionalBuildProperties(); + p.setProperty(ContainerCommandLauncher.CONNECTION_ID, uri); + } + } else { + IOptionalBuildProperties p = iCfg.getOptionalBuildProperties(); + p.setProperty(ContainerCommandLauncher.CONNECTION_ID, uri); + } + } + private void setControlsEnabled(boolean enabled) { imageCombo.setEnabled(enabled); connectionSelector.setEnabled(enabled); } - private void initializeEnablementButton(IConfiguration cfg) { - defaultEnabled = false; - IOptionalBuildProperties properties = cfg.getOptionalBuildProperties(); + private void initializeEnablementButton() { + initialEnabled = false; + IOptionalBuildProperties properties = iCfg.getOptionalBuildProperties(); String savedEnabled = properties .getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED); if (savedEnabled != null) { - defaultEnabled = Boolean + initialEnabled = Boolean .parseBoolean(savedEnabled); } - enableButton.setSelection(defaultEnabled); - setControlsEnabled(defaultEnabled); + enableButton.setSelection(initialEnabled); + setControlsEnabled(initialEnabled); } - private void initializeConnectionSelector(IConfiguration cfg) { + private void initializeConnectionSelector() { int defaultIndex = -1; - defaultConnection = null; + initialConnection = null; + IOptionalBuildProperties properties = iCfg.getOptionalBuildProperties(); String id = properties .getProperty(ContainerCommandLauncher.CONNECTION_ID); if (id != null) { - defaultConnection = id; + initialConnection = id; } connections = DockerConnectionManager.getInstance().getConnections(); if (connections.length == 0) { @@ -223,11 +267,11 @@ public class ContainerPropertyTab extends AbstractCBuildPropertyTab String[] connectionNames = new String[connections.length]; for (int i = 0; i < connections.length; ++i) { connectionNames[i] = connections[i].getName(); - if (connections[i].getUri().equals(defaultConnection)) + if (connections[i].getUri().equals(initialConnection)) defaultIndex = i; } if (defaultIndex < 0) { - defaultEnabled = false; + initialEnabled = false; defaultIndex = 0; } connectionSelector.setItems(connectionNames); @@ -236,16 +280,17 @@ public class ContainerPropertyTab extends AbstractCBuildPropertyTab connection = connections[defaultIndex]; connectionName = connection.getName(); connectionUri = connection.getUri(); - defaultConnection = connectionUri; + initialConnection = connectionUri; } } - private void initializeImageCombo(IConfiguration cfg) { - defaultImage = null; + private void initializeImageCombo() { + initialImageId = null; + IOptionalBuildProperties properties = iCfg.getOptionalBuildProperties(); String id = properties .getProperty(ContainerCommandLauncher.IMAGE_ID); if (id != null) { - defaultImage = id; + initialImageId = id; } if (connection != null) { java.util.List images = connection.getImages(); @@ -265,8 +310,8 @@ public class ContainerPropertyTab extends AbstractCBuildPropertyTab } } imageCombo.setItems(imageNames.toArray(new String[0])); - if (defaultImage != null) { - int index = imageCombo.indexOf(defaultImage); + if (initialImageId != null) { + int index = imageCombo.indexOf(initialImageId); if (index > -1) { imageCombo.select(index); } else { @@ -279,6 +324,8 @@ public class ContainerPropertyTab extends AbstractCBuildPropertyTab @Override protected void performApply(ICResourceDescription src, ICResourceDescription dst) { + boolean needToRecalculate = false; + ICConfigurationDescription defaultCfg = null; if (page.isMultiCfg()) { ICMultiConfigDescription mc1 = (ICMultiConfigDescription) src .getConfiguration(); @@ -288,37 +335,67 @@ public class ContainerPropertyTab extends AbstractCBuildPropertyTab .getItems(); ICConfigurationDescription[] cds2 = (ICConfigurationDescription[]) mc2 .getItems(); + defaultCfg = cds1[0]; for (int i = 0; i < cds1.length; i++) - applyToCfg(cds1[i], cds2[i]); - } else - applyToCfg(src.getConfiguration(), dst.getConfiguration()); - + needToRecalculate |= applyToCfg(cds1[i], cds2[i]); + } else { + defaultCfg = src.getConfiguration(); + needToRecalculate = applyToCfg(src.getConfiguration(), + dst.getConfiguration()); + } + if (needToRecalculate) { + recalculateSpecs(defaultCfg, true); + } } - private void applyToCfg(ICConfigurationDescription c1, + private boolean applyToCfg(ICConfigurationDescription c1, ICConfigurationDescription c2) { Configuration cfg01 = (Configuration) getCfg(c1); Configuration cfg02 = (Configuration) getCfg(c2); IOptionalBuildProperties prop1 = cfg01.getOptionalBuildProperties(); IOptionalBuildProperties prop2 = cfg02.getOptionalBuildProperties(); + boolean needToRecalculate = false; String enablementProperty = prop1 .getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED); + String enablementProperty2 = prop2 + .getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED); + if (!enablementProperty.equals(enablementProperty2)) { + needToRecalculate = true; + } prop2.setProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED, enablementProperty); String connectionProperty = prop1 .getProperty(ContainerCommandLauncher.CONNECTION_ID); + String connectionProperty2 = prop2 + .getProperty(ContainerCommandLauncher.CONNECTION_ID); + if (connectionProperty != null + && !connectionProperty.equals(connectionProperty2)) { + needToRecalculate = true; + } prop2.setProperty(ContainerCommandLauncher.CONNECTION_ID, connectionProperty); String imageProperty = prop1 .getProperty(ContainerCommandLauncher.IMAGE_ID); + String imageProperty2 = prop2 + .getProperty(ContainerCommandLauncher.IMAGE_ID); + if (imageProperty != null && !imageProperty.equals(imageProperty2)) { + needToRecalculate = true; + } prop2.setProperty(ContainerCommandLauncher.IMAGE_ID, imageProperty); + return needToRecalculate; } - @Override - protected void performOK() { - ICConfigurationDescription cfgd = ManagedBuildManager - .getDescriptionForConfiguration(iCfg); + protected void recalculateSpecs(ICConfigurationDescription cfgd, + boolean performingApply) { + IConfiguration cfg = getCfg(cfgd); + IOptionalBuildProperties properties = cfg.getOptionalBuildProperties(); + initialEnabled = Boolean.parseBoolean(properties + .getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED)); + initialConnection = properties + .getProperty(ContainerCommandLauncher.CONNECTION_ID); + initialImageId = properties + .getProperty(ContainerCommandLauncher.IMAGE_ID); List providers = ((ILanguageSettingsProvidersKeeper) cfgd) .getLanguageSettingProviders(); for (ILanguageSettingsProvider provider : providers) { @@ -326,11 +403,40 @@ public class ContainerPropertyTab extends AbstractCBuildPropertyTab GCCBuiltinSpecsDetector d = (GCCBuiltinSpecsDetector) provider; // force recalculation of gcc include path d.clear(); - d.handleEvent(null); + if (performingApply) { + d.handleEvent(null); + } + // final IProject project = getProject(); + // CCorePlugin.getIndexManager().reindex(CoreModel.getDefault().create(project)); } } + } - super.performOK(); + + @Override + protected void performOK() { + boolean needToRecalculate = false; + if (iCfg instanceof IMultiConfiguration) { + needToRecalculate = multiChange; + } else { + IOptionalBuildProperties p = iCfg.getOptionalBuildProperties(); + if (initialEnabled != Boolean.parseBoolean(p.getProperty( + ContainerCommandLauncher.CONTAINER_BUILD_ENABLED))) { + needToRecalculate = true; + } else if (initialEnabled == true) { + if (!initialConnection.equals( + p.getProperty(ContainerCommandLauncher.CONNECTION_ID)) + || !initialImageId.equals(p.getProperty( + ContainerCommandLauncher.IMAGE_ID))) { + needToRecalculate = true; + } + } + } + if (needToRecalculate) { + recalculateSpecs( + ManagedBuildManager.getDescriptionForConfiguration(iCfg), + false); + } } @Override @@ -365,7 +471,9 @@ public class ContainerPropertyTab extends AbstractCBuildPropertyTab } props.setProperty(ContainerCommandLauncher.IMAGE_ID, null); } - defaultEnabled = false; + initialEnabled = false; + initialConnection = null; + initialImageId = null; if (connections.length > 0) { connectionSelector.select(0); } @@ -379,9 +487,12 @@ public class ContainerPropertyTab extends AbstractCBuildPropertyTab if (cfgd == null) return; iCfg = getCfg(cfgd.getConfiguration()); - initializeConnectionSelector(iCfg); - initializeImageCombo(iCfg); - initializeEnablementButton(iCfg); + + multiChange = false; + + initializeConnectionSelector(); + initializeImageCombo(); + initializeEnablementButton(); } @Override diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/Messages.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/Messages.java index 68bde816821..dc90a4e3144 100644 --- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/Messages.java +++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/Messages.java @@ -47,6 +47,13 @@ public class Messages extends NLS { public static String ContainerTab_Warning_Connection_Not_Found; public static String ContainerTab_Warning_Image_Not_Found; + public static String HeaderPreferencePage_Connection_Label; + public static String HeaderPreferencePage_Image_Label; + public static String HeaderPreferencePage_Remove_Label; + public static String HeaderPreferencePage_Remove_Tooltip; + public static String HeaderPreferencePage_Confirm_Removal_Title; + public static String HeaderPreferencePage_Confirm_Removal_Msg; + public static String Remote_GDB_Debugger_Options; public static String Gdbserver_Settings_Tab_Name; public static String Gdbserver_name_textfield_label; diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/messages.properties b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/messages.properties index 3fef4817508..06609d611cf 100644 --- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/messages.properties +++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/messages.properties @@ -43,6 +43,13 @@ ContainerTab_Warning_Image_Not_Found=Docker Image: {0} is not a valid pulled ima ContainerPropertyTab_Title=Container Settings ContainerPropertyTab_Enable_Msg=Build inside Docker Image +HeaderPreferencePage_Connection_Label=Connection +HeaderPreferencePage_Image_Label=Image +HeaderPreferencePage_Remove_Label=Remove +HeaderPreferencePage_Remove_Tooltip=Remove headers cached from Docker image +HeaderPreferencePage_Confirm_Removal_Title=Confirm Header File Removal +HeaderPreferencePage_Confirm_Removal_Msg=Confirm removal of specified cached header files + ContainerCommandLauncher_image_msg=[Running in image <{0}>] ContainerCommandLauncher_invalid_values=Invalid values for Connection and/or Image name diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/preferences/DockerHeaderPreferencePage.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/preferences/DockerHeaderPreferencePage.java new file mode 100644 index 00000000000..0e0269ab90d --- /dev/null +++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/preferences/DockerHeaderPreferencePage.java @@ -0,0 +1,356 @@ +package org.eclipse.cdt.internal.docker.launcher.ui.preferences; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin; +import org.eclipse.cdt.internal.docker.launcher.Messages; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.TableLayout; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +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.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +public class DockerHeaderPreferencePage extends PreferencePage + implements IWorkbenchPreferencePage, Listener { + + // SWT Widgets and content providers + private Table hdrTable; + private TableViewer hdrTableViewer; + private HeaderContentProvider provider; + private Button removeButton; + private List directories; + + private final class HeaderContentProvider + implements IStructuredContentProvider, ITableLabelProvider { + + /** + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object) + */ + @Override + public Object[] getElements(Object inputElement) { + return directories.toArray(); + } + + /** + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + @Override + public void dispose() { + } + + /** + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(Viewer, + * Object, Object) + */ + @Override + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + } + + /** + * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(Object, + * int) + */ + @Override + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + private String readNameFile(IPath path) { + // try and read real name from special .name file found in + // directory. + IPath namePath = path.append(".name"); //$NON-NLS-1$ + // default to use last directory segment if any problems occur. + String name = path.lastSegment(); + if (namePath.toFile().exists()) { + try (FileReader reader = new FileReader(namePath.toFile()); + BufferedReader bufferReader = new BufferedReader( + reader);) { + name = bufferReader.readLine(); + } catch (IOException e) { + // ignore + } + } + return name; + } + + /** + * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(Object, + * int) + */ + @Override + public String getColumnText(Object element, int columnIndex) { + IPath path = (IPath) element; + if (columnIndex == 0) { + IPath connectionPath = path.removeLastSegments(1); + String connectionName = readNameFile(connectionPath); + return connectionName; + } + String imageName = readNameFile(path); + return imageName; + } + + /** + * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(ILabelProviderListener) + */ + @Override + public void addListener(ILabelProviderListener listener) { + } + + /** + * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(Object, + * String) + */ + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } + + /** + * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(ILabelProviderListener) + */ + @Override + public void removeListener(ILabelProviderListener listener) { + } + + } + + public DockerHeaderPreferencePage() { + noDefaultAndApplyButton(); + provider = new HeaderContentProvider(); + } + + @Override + public void init(IWorkbench workbench) { + directories = new ArrayList<>(); + IPath pluginPath = Platform + .getStateLocation( + Platform.getBundle(DockerLaunchUIPlugin.PLUGIN_ID)) + .append("HEADERS"); //$NON-NLS-1$ + File d = pluginPath.toFile(); + + if (d.exists() && d.isDirectory()) { + File[] connections = d.listFiles(); + for (File connection : connections) { + if (connection.isDirectory()) { + File[] images = connection.listFiles(); + for (File image : images) { + if (image.isDirectory()) { + directories + .add(pluginPath.append(connection.getName()) + .append(image.getName())); + } + } + } + } + } + } + + @Override + protected Control createContents(Composite parent) { + Composite page = createComposite(parent, 1, 2, false, null, -1, -1, + GridData.FILL); + GridData gd = (GridData) page.getLayoutData(); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + + // SystemWidgetHelpers.createLabel(page, + // SystemResources.RESID_PREF_SIGNON_DESCRIPTION, 2); + + // Header table + hdrTable = new Table(page, SWT.FULL_SELECTION | SWT.MULTI | SWT.V_SCROLL + | SWT.H_SCROLL | SWT.BORDER); + hdrTable.setLinesVisible(true); + hdrTable.setHeaderVisible(true); + hdrTable.addListener(SWT.Selection, this); + + TableLayout tableLayout = new TableLayout(); + tableLayout.addColumnData(new ColumnWeightData(60, true)); + tableLayout.addColumnData(new ColumnWeightData(40, true)); + hdrTable.setLayout(tableLayout); + + gd = new GridData(GridData.FILL_BOTH); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + + hdrTable.setLayoutData(gd); + + // Connection column + TableColumn connectionColumn = new TableColumn(hdrTable, SWT.NONE); + connectionColumn + .setText(Messages.HeaderPreferencePage_Connection_Label); + + // Image column + TableColumn imageColumn = new TableColumn(hdrTable, SWT.NONE); + imageColumn.setText(Messages.HeaderPreferencePage_Image_Label); + + hdrTableViewer = new TableViewer(hdrTable); + hdrTableViewer.setContentProvider(provider); + hdrTableViewer.setLabelProvider(provider); + hdrTableViewer.setInput(directories); + + // Create the Button bar for add, change and remove + Composite buttonBar = createComposite(page, 1, 1, false, null, -1, -1, + GridData.FILL); + gd = (GridData) buttonBar.getLayoutData(); + gd.grabExcessHorizontalSpace = false; + gd.grabExcessVerticalSpace = true; + + removeButton = createPushButton(buttonBar, this, + Messages.HeaderPreferencePage_Remove_Label, + Messages.HeaderPreferencePage_Remove_Tooltip); + + removeButton.setEnabled(false); + return parent; + } + + private static Composite createComposite(Composite parent, int parentSpan, + int numColumns, boolean border, String label, int marginSize, + int spacingSize, int verticalAlignment) { + // border = true; + boolean borderNeeded = border; + if (label != null) + borderNeeded = true; // force the case + int style = SWT.NULL; + if (borderNeeded) + style |= SWT.SHADOW_ETCHED_IN; + Composite composite = null; + if (borderNeeded) { + composite = new Group(parent, style); + if (label != null) + ((Group) composite).setText(label); + } else { + composite = new Composite(parent, style); + } + // GridLayout + GridLayout layout = new GridLayout(); + layout.numColumns = numColumns; + if (marginSize != -1) { + layout.marginWidth = 0; + layout.marginHeight = 0; + } + if (spacingSize != -1) { + layout.horizontalSpacing = 0; + layout.verticalSpacing = 0; + } + composite.setLayout(layout); + // GridData + GridData data = new GridData(); + data.horizontalSpan = parentSpan; + data.horizontalAlignment = GridData.FILL; + data.grabExcessHorizontalSpace = true; + + data.verticalAlignment = verticalAlignment; + data.grabExcessVerticalSpace = false; + + composite.setLayoutData(data); + return composite; + } + + public static Button createPushButton(Composite group, Listener listener, + String label, String tooltip) { + Button button = new Button(group, SWT.PUSH); + button.setText(label); + if (listener != null) + button.addListener(SWT.Selection, listener); + GridData data = new GridData(); + data.horizontalAlignment = GridData.FILL; + data.grabExcessHorizontalSpace = true; + button.setLayoutData(data); + if (tooltip != null) + button.setToolTipText(tooltip); + return button; + } + + private class DialogStatus { + private boolean status; + + public DialogStatus(boolean status) { + this.status = status; + } + + public void setStatus(boolean status) { + this.status = status; + } + + public boolean getStatus() { + return status; + } + } + + /** + * @see org.eclipse.swt.widgets.Listener#handleEvent(Event) + */ + @Override + public void handleEvent(Event event) { + if (event.type == SWT.Selection) { + if (event.widget == removeButton) { + final DialogStatus confirmed = new DialogStatus(false); + Display.getDefault().syncExec(() -> { + boolean status = MessageDialog.openConfirm(getShell(), + Messages.HeaderPreferencePage_Confirm_Removal_Title, + Messages.HeaderPreferencePage_Confirm_Removal_Msg); + confirmed.setStatus(status); + }); + if (!confirmed.getStatus()) { + return; + } + int[] indicies = hdrTable.getSelectionIndices(); + for (int idx = indicies.length - 1; idx >= 0; idx--) { + IPath dirPath = directories.get(idx); + File f = dirPath.toFile(); + if (f.exists() && f.isDirectory()) { + recursiveDelete(f); + } + directories.remove(idx); + } + + hdrTableViewer.refresh(); + } + + // Update table buttons based on changes + if (hdrTable.getSelectionCount() > 0) { + removeButton.setEnabled(true); + } else { + removeButton.setEnabled(false); + } + } + } + + private void recursiveDelete(File dir) { + File[] contents = dir.listFiles(); + if (contents != null) { + for (File f : contents) { + recursiveDelete(f); + } + } + dir.delete(); + } +} +