diff --git a/qt/org.eclipse.cdt.qt.core/META-INF/MANIFEST.MF b/qt/org.eclipse.cdt.qt.core/META-INF/MANIFEST.MF index 82018a33421..5624d3662a5 100644 --- a/qt/org.eclipse.cdt.qt.core/META-INF/MANIFEST.MF +++ b/qt/org.eclipse.cdt.qt.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.qt.core;singleton:=true -Bundle-Version: 2.0.0.qualifier +Bundle-Version: 2.1.0.qualifier Bundle-Activator: org.eclipse.cdt.internal.qt.core.Activator Bundle-Vendor: %providerName Require-Bundle: org.eclipse.core.runtime, diff --git a/qt/org.eclipse.cdt.qt.core/pom.xml b/qt/org.eclipse.cdt.qt.core/pom.xml index 190105947ab..231985bf8da 100644 --- a/qt/org.eclipse.cdt.qt.core/pom.xml +++ b/qt/org.eclipse.cdt.qt.core/pom.xml @@ -11,7 +11,7 @@ ../../pom.xml - 2.0.0-SNAPSHOT + 2.1.0-SNAPSHOT org.eclipse.cdt.qt.core eclipse-plugin \ No newline at end of file diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtInstallManager.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtInstallManager.java index abe183c208a..c8cbcd0ac89 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtInstallManager.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtInstallManager.java @@ -9,16 +9,21 @@ package org.eclipse.cdt.internal.qt.core; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.eclipse.cdt.core.build.IToolChain; import org.eclipse.cdt.qt.core.IQtInstall; +import org.eclipse.cdt.qt.core.IQtInstallListener; import org.eclipse.cdt.qt.core.IQtInstallManager; import org.eclipse.cdt.qt.core.IQtInstallProvider; +import org.eclipse.cdt.qt.core.QtInstallEvent; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionPoint; @@ -31,6 +36,7 @@ public class QtInstallManager implements IQtInstallManager { private Map installs; private Map toolChainMap; + private List listeners = new LinkedList<>(); private Preferences getPreferences() { return ConfigurationScope.INSTANCE.getNode(Activator.ID).node("qtInstalls"); //$NON-NLS-1$ @@ -108,8 +114,21 @@ public class QtInstallManager implements IQtInstallManager { return installs.get(qmakePath); } + @Override + public Collection getInstall(String spec) { + initInstalls(); + List installList = new ArrayList<>(); + for (IQtInstall install : installs.values()) { + if (install.getSpec().equals(spec)) { + installList.add(install); + } + } + return installList; + } + @Override public void removeInstall(IQtInstall install) { + fireEvent(new QtInstallEvent(QtInstallEvent.REMOVED, install)); installs.remove(install.getQmakePath()); saveInstalls(); } @@ -150,4 +169,20 @@ public class QtInstallManager implements IQtInstallManager { } } + @Override + public void addListener(IQtInstallListener listener) { + listeners.add(listener); + } + + @Override + public void removeListener(IQtInstallListener listener) { + listeners.remove(listener); + } + + private void fireEvent(QtInstallEvent event) { + for (IQtInstallListener listener : listeners) { + listener.installChanged(event); + } + } + } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java index b49a689e3c9..8b19c1b3172 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java @@ -15,6 +15,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -34,7 +35,9 @@ import org.eclipse.cdt.core.resources.IConsole; import org.eclipse.cdt.internal.qt.core.Activator; import org.eclipse.cdt.qt.core.IQtBuildConfiguration; import org.eclipse.cdt.qt.core.IQtInstall; +import org.eclipse.cdt.qt.core.IQtInstallListener; import org.eclipse.cdt.qt.core.IQtInstallManager; +import org.eclipse.cdt.qt.core.QtInstallEvent; import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -47,25 +50,43 @@ import org.eclipse.core.runtime.Status; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; -public class QtBuildConfiguration extends CBuildConfiguration implements ICBuildConfiguration, IQtBuildConfiguration { +public class QtBuildConfiguration extends CBuildConfiguration + implements ICBuildConfiguration, IQtBuildConfiguration, IQtInstallListener { private static final String QTINSTALL_NAME = "cdt.qt.install.name"; //$NON-NLS-1$ + private static final String QTINSTALL_SPEC = "cdt.qt.install.spec"; //$NON-NLS-1$ private static final String LAUNCH_MODE = "cdt.qt.launchMode"; //$NON-NLS-1$ - private final IQtInstall qtInstall; private final String launchMode; + private final String qtInstallSpec; + private IQtInstall qtInstall; private Map properties; public QtBuildConfiguration(IBuildConfiguration config, String name) throws CoreException { super(config, name); + IQtInstallManager manager = Activator.getService(IQtInstallManager.class); + manager.addListener(this); + Preferences settings = getSettings(); String installName = settings.get(QTINSTALL_NAME, ""); //$NON-NLS-1$ + qtInstallSpec = settings.get(QTINSTALL_SPEC, ""); //$NON-NLS-1$ if (!installName.isEmpty()) { - IQtInstallManager manager = Activator.getService(IQtInstallManager.class); qtInstall = manager.getInstall(Paths.get(installName)); - } else { - qtInstall = null; + if (qtInstallSpec.isEmpty()) { + // save the spec if it wasn't set + settings.put(QTINSTALL_SPEC, qtInstall.getSpec()); + try { + settings.flush(); + } catch (BackingStoreException e) { + Activator.log(e); + } + } + } + + if (getQtInstall() == null) { + throw new CoreException( + Activator.error(String.format("Qt Install for build configuration %s not found.", name))); } launchMode = settings.get(LAUNCH_MODE, null); // $NON-NLS-1$ @@ -75,10 +96,15 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild String launchMode) throws CoreException { super(config, name, toolChain); this.qtInstall = qtInstall; + this.qtInstallSpec = qtInstall.getSpec(); this.launchMode = launchMode; + IQtInstallManager manager = Activator.getService(IQtInstallManager.class); + manager.addListener(this); + Preferences settings = getSettings(); settings.put(QTINSTALL_NAME, qtInstall.getQmakePath().toString()); + settings.put(QTINSTALL_SPEC, qtInstallSpec); if (launchMode != null) { settings.put(LAUNCH_MODE, launchMode); } @@ -95,9 +121,25 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild } public IQtInstall getQtInstall() { + if (qtInstall == null && !qtInstallSpec.isEmpty()) { + // find one that matches the spec + IQtInstallManager manager = Activator.getService(IQtInstallManager.class); + Collection candidates = manager.getInstall(qtInstallSpec); + if (!candidates.isEmpty()) { + qtInstall = candidates.iterator().next(); + } + } return qtInstall; } + @Override + public void installChanged(QtInstallEvent event) { + if (event.getType() == QtInstallEvent.REMOVED && event.getInstall().equals(qtInstall)) { + // clear the cache so we refetch later + qtInstall = null; + } + } + @Override public String getLaunchMode() { return launchMode; @@ -105,7 +147,7 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild @Override public Path getQmakeCommand() { - return qtInstall.getQmakePath(); + return getQtInstall().getQmakePath(); } @Override diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallListener.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallListener.java new file mode 100644 index 00000000000..ff2f3a3c16b --- /dev/null +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallListener.java @@ -0,0 +1,10 @@ +package org.eclipse.cdt.qt.core; + +/** + * @since 2.1 + */ +public interface IQtInstallListener { + + void installChanged(QtInstallEvent event); + +} diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallManager.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallManager.java index ee65f0dc517..fb5fa2cde66 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallManager.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallManager.java @@ -13,20 +13,82 @@ import java.util.Collection; import org.eclipse.cdt.core.build.IToolChain; /** - * The manager for Qt installs. + * The manager for Qt Installs. Qt Installs are Qt installation trees that are produced in a Qt + * platform build. They have a spec which selects the os and cpu architecture and are managed by an + * instance of the qmake builder. * * @noimplement */ public interface IQtInstallManager { + /** + * Returns all the registered Qt installs. + * + * @return all Qt Installs + */ public Collection getInstalls(); + /** + * Register a new Qt Install + * + * @param install + * new Qt Install + */ public void addInstall(IQtInstall install); + /** + * Return a Qt install that is managed by the given qmake. + * + * @param qmakePath + * path to qmake + * @return QT install managed by that qmake + */ public IQtInstall getInstall(Path qmakePath); + /** + * Returns the Qt installs that have the matching spec. + * + * @param spec + * spec for the Qt installs, e.g. macosx-clang + * @return all Qt installs that have that spec + */ + public Collection getInstall(String spec); + + /** + * Deregister a given Qt install + * + * @param install + * Qt install to deregister + */ public void removeInstall(IQtInstall install); + /** + * Check whether the given toolchain supports the given Qt Install. This is done by checking the + * OS and CPU arch of the toolchain and returning whether the Qt install supports that + * combination. + * + * @param install + * Qt Install to check + * @param toolChain + * Toolchain to check against + * @return whether the Qt install supports that toolchain + */ public boolean supports(IQtInstall install, IToolChain toolChain); + /** + * Add a listener for Qt install changes + * + * @param listener + * listener to add + */ + public void addListener(IQtInstallListener listener); + + /** + * Remove a listener for Qt install changes + * + * @param listener + * listener to remove + */ + public void removeListener(IQtInstallListener listener); + } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtInstallEvent.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtInstallEvent.java new file mode 100644 index 00000000000..d54b733d089 --- /dev/null +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtInstallEvent.java @@ -0,0 +1,41 @@ +package org.eclipse.cdt.qt.core; + +/** + * Event that a Qt install change has occured. + * + * @since 2.1 + */ +public class QtInstallEvent { + + /** + * Qt Install has been removed. Called before it is actually removed. + */ + public static int REMOVED = 1; + + private final int type; + private final IQtInstall install; + + public QtInstallEvent(int type, IQtInstall install) { + this.type = type; + this.install = install; + } + + /** + * Type of the event + * + * @return type of the event + */ + public int getType() { + return type; + } + + /** + * Qt install involved in the event + * + * @return Qt install for the event + */ + public IQtInstall getInstall() { + return install; + } + +}