From c2316a0b184372b1420aad32a5cc83619ff1d5db Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Thu, 19 May 2016 21:09:23 -0400 Subject: [PATCH] Arduino Downloads Manager and lots of cleanup around that. Change-Id: Ie2e4d987849831006d443bae98349861871a4057 --- .../arduino/core/tests/BoardManagerTests.java | 2 +- .../build.properties | 1 - .../org.eclipse.cdt.arduino.core/plugin.xml | 1 - .../schema/consoleService.exsd | 102 ---- .../cdt/arduino/core/internal/Activator.java | 13 + .../core/internal/ArduinoPreferences.java | 18 + .../core/internal/board/ArduinoLibrary.java | 111 +++- .../core/internal/board/ArduinoManager.java | 557 +++++++++++++----- .../core/internal/board/ArduinoPackage.java | 142 +++-- .../core/internal/board/ArduinoPlatform.java | 220 ++++--- .../core/internal/board/ArduinoTool.java | 26 +- .../internal/board/ArduinoToolSystem.java | 13 +- .../core/internal/board/LibraryIndex.java | 62 +- .../core/internal/board/PackageIndex.java | 18 +- .../core/internal/board/ToolDependency.java | 29 +- .../build/ArduinoBuildConfiguration.java | 9 +- .../ArduinoBuildConfigurationProvider.java | 11 +- .../remote/ArduinoRemoteConnection.java | 5 +- .../org.eclipse.cdt.arduino.ui/.classpath | 2 +- .../.settings/org.eclipse.jdt.core.prefs | 6 +- .../META-INF/MANIFEST.MF | 15 +- .../plugin.properties | 2 + .../org.eclipse.cdt.arduino.ui/plugin.xml | 27 +- .../org.eclipse.cdt.arduino.ui/pom.xml | 2 +- .../cdt/arduino/ui/internal/Activator.java | 14 +- .../ui/internal/FormTextHoverManager.java | 372 ++++++++++++ .../cdt/arduino/ui/internal/LibraryTree.java | 301 ++++++++++ .../cdt/arduino/ui/internal/Messages.java | 16 - .../downloads/ArduinoDownloadsManager.java | 90 +++ .../downloads/LibrariesTabControl.java | 282 +++++++++ .../downloads/OpenDownloadsManager.java | 23 + .../downloads/PlatformsTabControl.java | 276 +++++++++ .../downloads/SelectLibrariesDialog.java | 100 ++++ .../downloads/SelectPlatformsDialog.java | 126 ++++ .../downloads/UpdateLibrariesDialog.java | 131 ++++ .../downloads/UpdatePlatformsDialog.java | 137 +++++ .../arduino/ui/internal/messages.properties | 16 - .../ArduinoPlatformsPreferencePage.java | 264 --------- .../preferences/ArduinoPreferencePage.java | 3 - .../preferences/PlatformDetailsDialog.java | 72 --- .../project/LibrariesPropertyPage.java | 236 +------- .../remote/ArduinoTargetPropertyPage.java | 4 +- .../internal/remote/BoardPropertyControl.java | 7 +- 43 files changed, 2695 insertions(+), 1169 deletions(-) delete mode 100644 toolchains/arduino/org.eclipse.cdt.arduino.core/schema/consoleService.exsd create mode 100644 toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/FormTextHoverManager.java create mode 100644 toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/LibraryTree.java create mode 100644 toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/ArduinoDownloadsManager.java create mode 100644 toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/LibrariesTabControl.java create mode 100644 toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/OpenDownloadsManager.java create mode 100644 toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/PlatformsTabControl.java create mode 100644 toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/SelectLibrariesDialog.java create mode 100644 toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/SelectPlatformsDialog.java create mode 100644 toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/UpdateLibrariesDialog.java create mode 100644 toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/UpdatePlatformsDialog.java delete mode 100644 toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoPlatformsPreferencePage.java delete mode 100644 toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/PlatformDetailsDialog.java diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core.tests/src/org/eclipse/cdt/arduino/core/tests/BoardManagerTests.java b/toolchains/arduino/org.eclipse.cdt.arduino.core.tests/src/org/eclipse/cdt/arduino/core/tests/BoardManagerTests.java index 9af23ec77f3..451a2529628 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core.tests/src/org/eclipse/cdt/arduino/core/tests/BoardManagerTests.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core.tests/src/org/eclipse/cdt/arduino/core/tests/BoardManagerTests.java @@ -17,7 +17,7 @@ public class BoardManagerTests { @Test public void loadPackagesTest() throws Exception { - assertNotEquals(0, Activator.getService(ArduinoManager.class).getPackageIndices().size()); + assertNotEquals(0, Activator.getService(ArduinoManager.class).getInstalledPlatforms().size()); } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/build.properties b/toolchains/arduino/org.eclipse.cdt.arduino.core/build.properties index f4f2e1fae5d..ecdb91d85a3 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/build.properties +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/build.properties @@ -4,5 +4,4 @@ bin.includes = META-INF/,\ plugin.xml,\ templates/,\ about.html,\ - schema/,\ plugin.properties diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml b/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml index 8ececf48b6a..a513f8502e6 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml @@ -1,7 +1,6 @@ - - - - - - - - - [Enter description of this extension point.] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [Enter the first release in which this extension point appears.] - - - - - - - - - [Enter extension point usage example here.] - - - - - - - - - [Enter API information here.] - - - - - - - - - [Enter information about supplied implementation of this extension point.] - - - - - diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/Activator.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/Activator.java index e34ed5e625d..85aaa0a2f49 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/Activator.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/Activator.java @@ -59,4 +59,17 @@ public class Activator extends Plugin { return ref != null ? context.getService(ref) : null; } + public static CoreException coreException(Throwable e) { + if (e instanceof RuntimeException && e.getCause() instanceof CoreException) { + return (CoreException) e.getCause(); + } else if (e instanceof CoreException) { + return (CoreException) e; + } + return new CoreException(new Status(IStatus.ERROR, getId(), e.getLocalizedMessage(), e)); + } + + public static CoreException coreException(String message, Throwable e) { + return new CoreException(new Status(IStatus.ERROR, getId(), message, e)); + } + } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoPreferences.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoPreferences.java index 07d3d81bfa5..c8ac61c5258 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoPreferences.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoPreferences.java @@ -7,9 +7,15 @@ *******************************************************************************/ package org.eclipse.cdt.arduino.core.internal; +import java.net.MalformedURLException; +import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.InstanceScope; import org.osgi.service.prefs.BackingStoreException; @@ -36,6 +42,18 @@ public class ArduinoPreferences { return getPrefs().get(BOARD_URLS, defaultBoardUrls); } + public static Collection getBoardUrlList() throws CoreException { + List urlList = new ArrayList<>(); + for (String url : getBoardUrls().split("\n")) { //$NON-NLS-1$ + try { + urlList.add(new URL(url.trim())); + } catch (MalformedURLException e) { + throw Activator.coreException(e); + } + } + return urlList; + } + public static void setBoardUrls(String boardUrls) { IEclipsePreferences prefs = getPrefs(); prefs.put(BOARD_URLS, boardUrls); diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoLibrary.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoLibrary.java index 162c3ab0497..0cd02f6a424 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoLibrary.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoLibrary.java @@ -10,6 +10,7 @@ package org.eclipse.cdt.arduino.core.internal.board; import java.io.File; import java.io.FileReader; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; @@ -18,14 +19,15 @@ import java.util.Collections; import java.util.List; import java.util.Properties; +import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; public class ArduinoLibrary { + // JSON fields private String name; private String version; private String author; @@ -40,18 +42,22 @@ public class ArduinoLibrary { private String archiveFileName; private int size; private String checksum; + // end JSON fields private Path installPath; + private ArduinoPlatform platform; public ArduinoLibrary() { } - public ArduinoLibrary(Path propertiesFile) throws IOException { + public ArduinoLibrary(Path propertiesFile) throws CoreException { installPath = propertiesFile.getParent(); Properties props = new Properties(); try (FileReader reader = new FileReader(propertiesFile.toFile())) { props.load(reader); + } catch (IOException e) { + throw Activator.coreException(e); } name = props.getProperty("name"); //$NON-NLS-1$ @@ -64,6 +70,11 @@ public class ArduinoLibrary { architectures = Arrays.asList(props.getProperty("architectures").split(",")); //$NON-NLS-1$ //$NON-NLS-2$ } + public ArduinoLibrary(Path propertiesFile, ArduinoPlatform platform) throws CoreException { + this(propertiesFile); + this.platform = platform; + } + public String getName() { return name; } @@ -177,21 +188,33 @@ public class ArduinoLibrary { } public Path getInstallPath() { - return installPath != null ? installPath - : ArduinoPreferences.getArduinoHome().resolve("libraries").resolve(name.replace(' ', '_')) //$NON-NLS-1$ - .resolve(version); + return installPath == null + ? ArduinoPreferences.getArduinoHome().resolve("libraries").resolve(name.replace(' ', '_')) //$NON-NLS-1$ + : installPath; } - public boolean isInstalled() { - return getInstallPath().toFile().exists(); + public ArduinoPlatform getPlatform() { + return platform; } - public IStatus install(IProgressMonitor monitor) { - if (isInstalled()) { - return Status.OK_STATUS; + public void install(IProgressMonitor monitor) throws CoreException { + if (Files.exists(getInstallPath())) { + uninstall(monitor); } - return ArduinoManager.downloadAndInstall(url, archiveFileName, getInstallPath(), monitor); + try { + ArduinoManager.downloadAndInstall(url, archiveFileName, getInstallPath(), monitor); + } catch (IOException e) { + throw Activator.coreException(e); + } + } + + public void uninstall(IProgressMonitor monitor) throws CoreException { + try { + ArduinoManager.recursiveDelete(getInstallPath()); + } catch (IOException e) { + throw Activator.coreException(e); + } } public Collection getIncludePath() { @@ -240,17 +263,69 @@ public class ArduinoLibrary { } @Override - public boolean equals(Object obj) { - if (obj instanceof ArduinoLibrary) { - return getName().equals(((ArduinoLibrary) obj).getName()); - } else { - return false; + public String toString() { + return getName(); + } + + private String fixText(String text) { + String fixed = text.replaceAll("&", "&"); //$NON-NLS-1$ //$NON-NLS-2$ + fixed = fixed.replaceAll("<", "<"); //$NON-NLS-1$ //$NON-NLS-2$ + return fixed; + } + + public String toFormText() { + StringBuilder text = new StringBuilder(); + + text.append("
"); //$NON-NLS-1$ + text.append(String.format("

%s: %s

", "Library", fixText(getName()))); //$NON-NLS-1$ + + if (getMaintainer() != null) { + text.append(String.format("

%s: %s

", "Maintainer", fixText(getMaintainer()))); //$NON-NLS-1$ } + + if (getWebsite() != null) { + text.append(String.format("

%s

", getWebsite(), "Online help")); //$NON-NLS-1$ + } + + text.append(String.format("

%s

", getSentence())); + if (getParagraph() != null && !getParagraph().equals(getSentence())) { + text.append(String.format("

%s

", getParagraph())); + } + + text.append("
"); + + return text.toString(); } @Override public int hashCode() { - return getName().hashCode(); + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((platform == null) ? 0 : platform.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ArduinoLibrary other = (ArduinoLibrary) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (platform == null) { + if (other.platform != null) + return false; + } else if (!platform.equals(other.platform)) + return false; + return true; } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java index 87af37bc380..556c80082ce 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java @@ -11,13 +11,12 @@ package org.eclipse.cdt.arduino.core.internal.board; import java.io.BufferedInputStream; -import java.io.File; import java.io.FileInputStream; import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.Reader; -import java.lang.reflect.Type; import java.net.URL; import java.net.URLConnection; import java.nio.file.FileVisitResult; @@ -30,8 +29,13 @@ import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.PosixFilePermission; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Properties; import java.util.Set; import org.apache.commons.compress.archivers.ArchiveEntry; @@ -43,23 +47,21 @@ import org.apache.commons.compress.compressors.CompressorException; import org.apache.commons.compress.compressors.CompressorStreamFactory; import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; -import org.eclipse.cdt.arduino.core.internal.Messages; -import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration; -import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.osgi.service.prefs.BackingStoreException; import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; public class ArduinoManager { @@ -70,205 +72,460 @@ public class ArduinoManager { public static final String AVR_TOOLCHAIN_ID = "org.eclipse.cdt.arduino.toolChain.avr"; //$NON-NLS-1$ public static final String LIBRARIES_URL = "http://downloads.arduino.cc/libraries/library_index.json"; //$NON-NLS-1$ + public static final String LIBRARIES_FILE = "library_index.json"; //$NON-NLS-1$ - private List packageIndices; - private LibraryIndex libraryIndex; + private static final String LIBRARIES = "libraries"; //$NON-NLS-1$ - public void loadIndices() { - new Job(Messages.ArduinoBoardManager_0) { - @Override - protected IStatus run(IProgressMonitor monitor) { - synchronized (ArduinoManager.this) { - String[] boardUrls = ArduinoPreferences.getBoardUrls().split("\n"); //$NON-NLS-1$ - packageIndices = new ArrayList<>(boardUrls.length); - for (String boardUrl : boardUrls) { - loadPackageIndex(boardUrl, true); - } + // arduinocdt install properties + private static final String VERSION_KEY = "version"; //$NON-NLS-1$ + private static final String ACCEPTED_KEY = "accepted"; //$NON-NLS-1$ + private static final String VERSION = "2"; //$NON-NLS-1$ - loadLibraryIndex(true); - return Status.OK_STATUS; - } - } - }.schedule(); + private Properties props; + + private Map packages; + private Map installedLibraries; + + private Path getVersionFile() { + return ArduinoPreferences.getArduinoHome().resolve(".version"); //$NON-NLS-1$ } - private void loadPackageIndex(String url, boolean download) { - try { - URL packageUrl = new URL(url.trim()); - Path packagePath = ArduinoPreferences.getArduinoHome() - .resolve(Paths.get(packageUrl.getPath()).getFileName()); - File packageFile = packagePath.toFile(); - if (download) { - Files.createDirectories(ArduinoPreferences.getArduinoHome()); + private void init() throws CoreException { + if (props == null) { + if (!Files.exists(ArduinoPreferences.getArduinoHome())) { try { - Files.copy(packageUrl.openStream(), packagePath, StandardCopyOption.REPLACE_EXISTING); + Files.createDirectories(ArduinoPreferences.getArduinoHome()); } catch (IOException e) { - // make sure we add the package anyway if it exists - Activator.log(e); + throw Activator.coreException(e); } } - if (packageFile.exists()) { - try (Reader reader = new FileReader(packageFile)) { - PackageIndex index = new Gson().fromJson(reader, PackageIndex.class); - index.setOwners(ArduinoManager.this); - packageIndices.add(index); + + props = new Properties(); + Path propsFile = getVersionFile(); + if (Files.exists(propsFile)) { + try (FileReader reader = new FileReader(propsFile.toFile())) { + props.load(reader); + } catch (IOException e) { + throw Activator.coreException(e); + } + } + + // See if we need a conversion + int version = Integer.parseInt(props.getProperty(VERSION_KEY, "1")); //$NON-NLS-1$ + if (version < Integer.parseInt(VERSION)) { + // Need to move the directories around + convertPackageDirs(); + + props.setProperty(VERSION_KEY, VERSION); + try (FileWriter writer = new FileWriter(getVersionFile().toFile())) { + props.store(writer, ""); //$NON-NLS-1$ + } catch (IOException e) { + throw Activator.coreException(e); } } - } catch (IOException e) { - Activator.log(e); } } - public synchronized List getPackageIndices() { - if (packageIndices == null) { - String[] boardUrls = ArduinoPreferences.getBoardUrls().split("\n"); //$NON-NLS-1$ - packageIndices = new ArrayList<>(boardUrls.length); - for (String boardUrl : boardUrls) { - loadPackageIndex(boardUrl, false); - } + private void convertPackageDirs() throws CoreException { + Path packagesDir = ArduinoPreferences.getArduinoHome().resolve("packages"); //$NON-NLS-1$ + if (!Files.isDirectory(packagesDir)) { + return; } - return packageIndices; - } - public void loadLibraryIndex(boolean download) { try { - URL librariesUrl = new URL(LIBRARIES_URL); - Path librariesPath = ArduinoPreferences.getArduinoHome() - .resolve(Paths.get(librariesUrl.getPath()).getFileName()); - File librariesFile = librariesPath.toFile(); - if (download) { - Files.createDirectories(ArduinoPreferences.getArduinoHome()); - Files.copy(librariesUrl.openStream(), librariesPath, StandardCopyOption.REPLACE_EXISTING); - } - if (librariesFile.exists()) { - try (Reader reader = new FileReader(librariesFile)) { - libraryIndex = new Gson().fromJson(reader, LibraryIndex.class); - libraryIndex.resolve(); + Files.list(packagesDir).forEach(path -> { + try { + Path hardwarePath = path.resolve("hardware"); //$NON-NLS-1$ + Path badPath = hardwarePath.resolve(path.getFileName()); + Path tmpDir = Files.createTempDirectory(packagesDir, "tbd"); //$NON-NLS-1$ + Path badPath2 = tmpDir.resolve(badPath.getFileName()); + Files.move(badPath, badPath2); + Files.list(badPath2).forEach(archPath -> { + try { + Optional latest = Files.list(archPath) + .reduce((path1, path2) -> compareVersions(path1.getFileName().toString(), + path2.getFileName().toString()) > 0 ? path1 : path2); + if (latest.isPresent()) { + Files.move(latest.get(), hardwarePath.resolve(archPath.getFileName())); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + recursiveDelete(tmpDir); + } catch (IOException e) { + throw new RuntimeException(e); } - } - } catch (IOException e) { - Activator.log(e); + }); + } catch (RuntimeException | IOException e) { + throw Activator.coreException(e); } - } - public LibraryIndex getLibraryIndex() throws CoreException { - if (libraryIndex == null) { - loadLibraryIndex(false); + public void convertLibrariesDir() throws CoreException { + Path librariesDir = ArduinoPreferences.getArduinoHome().resolve("libraries"); //$NON-NLS-1$ + if (!Files.isDirectory(librariesDir)) { + return; } - return libraryIndex; - } - public ArduinoBoard getBoard(String boardName, String platformName, String packageName) throws CoreException { - for (PackageIndex index : getPackageIndices()) { - ArduinoPackage pkg = index.getPackage(packageName); - if (pkg != null) { - ArduinoPlatform platform = pkg.getPlatform(platformName); - if (platform != null) { - ArduinoBoard board = platform.getBoard(boardName); - if (board != null) { - return board; + try { + Path tmpDir = Files.createTempDirectory("alib"); //$NON-NLS-1$ + Path tmpLibDir = tmpDir.resolve("libraries"); //$NON-NLS-1$ + Files.move(librariesDir, tmpLibDir); + Files.list(tmpLibDir).forEach(path -> { + try { + Optional latest = Files.list(path) + .reduce((path1, path2) -> compareVersions(path1.getFileName().toString(), + path2.getFileName().toString()) > 0 ? path1 : path2); + if (latest.isPresent()) { + Files.move(latest.get(), librariesDir.resolve(path.getFileName())); } + } catch (IOException e) { + throw new RuntimeException(e); } - } + }); + recursiveDelete(tmpDir); + } catch (RuntimeException | IOException e) { + throw Activator.coreException(e); } - return null; + } - public List getInstalledBoards() throws CoreException { - List boards = new ArrayList<>(); - for (PackageIndex index : getPackageIndices()) { - for (ArduinoPackage pkg : index.getPackages()) { - for (ArduinoPlatform platform : pkg.getInstalledPlatforms().values()) { - boards.addAll(platform.getBoards()); + public boolean licenseAccepted() throws CoreException { + init(); + return Boolean.getBoolean(props.getProperty(ACCEPTED_KEY, Boolean.FALSE.toString())); + } + + public void acceptLicense() throws CoreException { + init(); + props.setProperty(ACCEPTED_KEY, Boolean.TRUE.toString()); + try (FileWriter writer = new FileWriter(getVersionFile().toFile())) { + props.store(writer, ""); //$NON-NLS-1$ + } catch (IOException e) { + throw Activator.coreException(e); + } + } + + public Collection getInstalledPlatforms() throws CoreException { + List platforms = new ArrayList<>(); + for (ArduinoPackage pkg : getPackages()) { + platforms.addAll(pkg.getInstalledPlatforms()); + } + return platforms; + } + + public ArduinoPlatform getInstalledPlatform(String packageName, String architecture) throws CoreException { + ArduinoPackage pkg = getPackage(packageName); + return pkg != null ? pkg.getInstalledPlatform(architecture) : null; + } + + public Collection getAvailablePlatforms(IProgressMonitor monitor) throws CoreException { + List platforms = new ArrayList<>(); + Collection urls = ArduinoPreferences.getBoardUrlList(); + SubMonitor sub = SubMonitor.convert(monitor, urls.size() + 1); + + sub.beginTask("Downloading package descriptions", urls.size()); //$NON-NLS-1$ + for (URL url : urls) { + Path packagePath = ArduinoPreferences.getArduinoHome() + .resolve(Paths.get(url.getPath()).getFileName()); + try { + Files.createDirectories(ArduinoPreferences.getArduinoHome()); + try (InputStream in = url.openStream()) { + Files.copy(in, packagePath, StandardCopyOption.REPLACE_EXISTING); } + } catch (IOException e) { + throw Activator.coreException(String.format("Error loading %s", url.toString()), e); //$NON-NLS-1$ } + sub.worked(1); + } + + sub.beginTask("Loading available packages", 1); //$NON-NLS-1$ + resetPackages(); + for (ArduinoPackage pkg : getPackages()) { + platforms.addAll(pkg.getAvailablePlatforms()); + } + sub.done(); + + return platforms; + } + + public void installPlatforms(Collection platforms, IProgressMonitor monitor) throws CoreException { + SubMonitor sub = SubMonitor.convert(monitor, platforms.size()); + for (ArduinoPlatform platform : platforms) { + sub.setTaskName(String.format("Installing %s", platform.getName())); //$NON-NLS-1$ + platform.install(sub); + sub.worked(1); + } + sub.done(); + } + + public void uninstallPlatforms(Collection platforms, IProgressMonitor monitor) { + SubMonitor sub = SubMonitor.convert(monitor, platforms.size()); + for (ArduinoPlatform platform : platforms) { + sub.setTaskName(String.format("Uninstalling %s", platform.getName())); //$NON-NLS-1$ + platform.uninstall(sub); + sub.worked(1); + } + sub.done(); + } + + public static List getSortedPlatforms(Collection platforms) { + List result = new ArrayList<>(platforms); + Collections.sort(result, (plat1, plat2) -> { + int c1 = plat1.getPackage().getName().compareToIgnoreCase(plat2.getPackage().getName()); + if (c1 > 0) { + return 1; + } else if (c1 < 0) { + return -1; + } else { + return plat1.getArchitecture().compareToIgnoreCase(plat2.getArchitecture()); + } + }); + return result; + } + + public static List getSortedLibraries(Collection libraries) { + List result = new ArrayList<>(libraries); + Collections.sort(result, (lib1, lib2) -> { + return lib1.getName().compareToIgnoreCase(lib2.getName()); + }); + return result; + } + + private void initPackages() throws CoreException { + if (packages == null) { + init(); + packages = new HashMap<>(); + + try { + Files.list(ArduinoPreferences.getArduinoHome()) + .filter(path -> path.getFileName().toString().startsWith("package_")) //$NON-NLS-1$ + .forEach(path -> { + try (Reader reader = new FileReader(path.toFile())) { + PackageIndex index = new Gson().fromJson(reader, PackageIndex.class); + for (ArduinoPackage pkg : index.getPackages()) { + pkg.init(); + packages.put(pkg.getName(), pkg); + } + } catch (IOException e) { + Activator.log(e); + } + }); + } catch (IOException e) { + throw Activator.coreException(e); + } + } + } + + private Collection getPackages() throws CoreException { + initPackages(); + return packages.values(); + } + + public void resetPackages() { + packages = null; + } + + private ArduinoPackage getPackage(String packageName) throws CoreException { + if (packageName == null) { + return null; + } else { + initPackages(); + return packages.get(packageName); + } + } + + public Collection getInstalledBoards() throws CoreException { + List boards = new ArrayList<>(); + for (ArduinoPlatform platform : getInstalledPlatforms()) { + boards.addAll(platform.getBoards()); } return boards; } - public ArduinoPackage getPackage(String packageName) throws CoreException { - for (PackageIndex index : getPackageIndices()) { - ArduinoPackage pkg = index.getPackage(packageName); - if (pkg != null) { - return pkg; + public ArduinoBoard getBoard(String packageName, String architecture, String boardId) throws CoreException { + for (ArduinoPlatform platform : getInstalledPlatforms()) { + if (platform.getPackage().getName().equals(packageName) + && platform.getArchitecture().equals(architecture)) { + return platform.getBoard(boardId); } } + + // For backwards compat, check platform name + for (ArduinoPlatform platform : getInstalledPlatforms()) { + if (platform.getPackage().getName().equals(packageName) + && platform.getName().equals(architecture)) { + return platform.getBoardByName(boardId); + } + } + return null; } - public ArduinoTool getTool(String packageName, String toolName, String version) throws CoreException { - for (PackageIndex index : getPackageIndices()) { - ArduinoPackage pkg = index.getPackage(packageName); - if (pkg != null) { - ArduinoTool tool = pkg.getTool(toolName, version); - if (tool != null) { - return tool; + public ArduinoTool getTool(String packageName, String toolName, String version) { + ArduinoPackage pkg = packages.get(packageName); + return pkg != null ? pkg.getTool(toolName, version) : null; + } + + public void initInstalledLibraries() throws CoreException { + init(); + if (installedLibraries == null) { + installedLibraries = new HashMap<>(); + + Path librariesDir = ArduinoPreferences.getArduinoHome().resolve("libraries"); //$NON-NLS-1$ + if (Files.isDirectory(librariesDir)) { + try { + Files.find(librariesDir, 2, + (path, attrs) -> path.getFileName().toString().equals("library.properties")) //$NON-NLS-1$ + .forEach(path -> { + try { + ArduinoLibrary library = new ArduinoLibrary(path); + installedLibraries.put(library.getName(), library); + } catch (CoreException e) { + throw new RuntimeException(e); + } + }); + } catch (IOException e) { + throw Activator.coreException(e); } } } - return null; } - private static final String LIBRARIES = "libraries"; //$NON-NLS-1$ - - private IEclipsePreferences getSettings(IProject project) { - return new ProjectScope(project).getNode(Activator.getId()); + public Collection getInstalledLibraries() throws CoreException { + initInstalledLibraries(); + return installedLibraries.values(); } - public Collection getLibraries(IProject project) throws CoreException { + public ArduinoLibrary getInstalledLibrary(String name) throws CoreException { + initInstalledLibraries(); + return installedLibraries.get(name); + } + + public Collection getAvailableLibraries(IProgressMonitor monitor) throws CoreException { + try { + initInstalledLibraries(); + Map libs = new HashMap<>(); + + SubMonitor sub = SubMonitor.convert(monitor, "Downloading library index", 2); + Path librariesPath = ArduinoPreferences.getArduinoHome().resolve(LIBRARIES_FILE); + URL librariesUrl = new URL(LIBRARIES_URL); + Files.createDirectories(ArduinoPreferences.getArduinoHome()); + Files.copy(librariesUrl.openStream(), librariesPath, StandardCopyOption.REPLACE_EXISTING); + sub.worked(1); + + try (Reader reader = new FileReader(librariesPath.toFile())) { + sub.setTaskName("Calculating available libraries"); + LibraryIndex libraryIndex = new Gson().fromJson(reader, LibraryIndex.class); + for (ArduinoLibrary library : libraryIndex.getLibraries()) { + String libraryName = library.getName(); + if (!installedLibraries.containsKey(libraryName)) { + ArduinoLibrary current = libs.get(libraryName); + if (current == null || compareVersions(library.getVersion(), current.getVersion()) > 0) { + libs.put(libraryName, library); + } + } + } + } + sub.done(); + return libs.values(); + } catch (IOException e) { + throw Activator.coreException(e); + } + } + + public void installLibraries(Collection libraries, IProgressMonitor monitor) throws CoreException { + SubMonitor sub = SubMonitor.convert(monitor, libraries.size()); + for (ArduinoLibrary library : libraries) { + sub.setTaskName(String.format("Installing %s", library.getName())); //$NON-NLS-1$ + library.install(sub); + try { + ArduinoLibrary newLibrary = new ArduinoLibrary(library.getInstallPath().resolve("library.properties")); //$NON-NLS-1$ + installedLibraries.put(newLibrary.getName(), newLibrary); + } catch (CoreException e) { + throw new RuntimeException(e); + } + sub.worked(1); + } + sub.done(); + } + + public void uninstallLibraries(Collection libraries, IProgressMonitor monitor) + throws CoreException { + SubMonitor sub = SubMonitor.convert(monitor, libraries.size()); + for (ArduinoLibrary library : libraries) { + sub.setTaskName(String.format("Installing %s", library.getName())); //$NON-NLS-1$ + library.uninstall(sub); + installedLibraries.remove(library.getName()); + sub.worked(1); + } + sub.done(); + } + + public Collection getLibraries(IProject project) + throws CoreException { + initInstalledLibraries(); IEclipsePreferences settings = getSettings(project); String librarySetting = settings.get(LIBRARIES, "[]"); //$NON-NLS-1$ - Type stringSet = new TypeToken>() { - }.getType(); - Set libraryNames = new Gson().fromJson(librarySetting, stringSet); - LibraryIndex index = Activator.getService(ArduinoManager.class).getLibraryIndex(); + JsonArray libArray = new JsonParser().parse(librarySetting).getAsJsonArray(); - ICBuildConfiguration cconfig = project.getActiveBuildConfig().getAdapter(ICBuildConfiguration.class); - ArduinoPlatform platform = cconfig.getAdapter(ArduinoBuildConfiguration.class).getBoard().getPlatform(); - List libraries = new ArrayList<>(libraryNames.size()); - for (String name : libraryNames) { - ArduinoLibrary lib = index.getLibrary(name); - if (lib == null) { - lib = platform.getLibrary(name); - } - if (lib != null) { - libraries.add(lib); + List libraries = new ArrayList<>(libArray.size()); + for (JsonElement libElement : libArray) { + if (libElement.isJsonPrimitive()) { + String libName = libElement.getAsString(); + ArduinoLibrary lib = installedLibraries.get(libName); + if (lib != null) { + libraries.add(lib); + } + } else { + JsonObject libObj = libElement.getAsJsonObject(); + String packageName = libObj.get("package").getAsString(); //$NON-NLS-1$ + String platformName = libObj.get("platform").getAsString(); //$NON-NLS-1$ + String libName = libObj.get("library").getAsString(); //$NON-NLS-1$ + ArduinoPackage pkg = getPackage(packageName); + if (pkg != null) { + ArduinoPlatform platform = pkg.getInstalledPlatform(platformName); + if (platform != null) { + ArduinoLibrary lib = platform.getLibrary(libName); + if (lib != null) { + libraries.add(lib); + } + } + } } } return libraries; } public void setLibraries(final IProject project, final Collection libraries) throws CoreException { - List libraryNames = new ArrayList<>(libraries.size()); + JsonArray elements = new JsonArray(); for (ArduinoLibrary library : libraries) { - libraryNames.add(library.getName()); + ArduinoPlatform platform = library.getPlatform(); + if (platform != null) { + JsonObject libObj = new JsonObject(); + libObj.addProperty("package", platform.getPackage().getName()); //$NON-NLS-1$ + libObj.addProperty("platform", platform.getArchitecture()); //$NON-NLS-1$ + libObj.addProperty("library", library.getName()); //$NON-NLS-1$ + elements.add(libObj); + } else { + elements.add(new JsonPrimitive(library.getName())); + } } IEclipsePreferences settings = getSettings(project); - settings.put(LIBRARIES, new Gson().toJson(libraryNames)); + settings.put(LIBRARIES, new Gson().toJson(elements)); try { settings.flush(); } catch (BackingStoreException e) { - Activator.log(e); + throw Activator.coreException(e); } - - new Job(Messages.ArduinoManager_0) { - @Override - protected IStatus run(IProgressMonitor monitor) { - MultiStatus mstatus = new MultiStatus(Activator.getId(), 0, Messages.ArduinoManager_1, null); - for (ArduinoLibrary library : libraries) { - IStatus status = library.install(monitor); - if (!status.isOK()) { - mstatus.add(status); - } - } - return mstatus; - } - }.schedule(); } - public static IStatus downloadAndInstall(String url, String archiveFileName, Path installPath, - IProgressMonitor monitor) { + private IEclipsePreferences getSettings(IProject project) { + return new ProjectScope(project).getNode(Activator.getId()); + } + + public static void downloadAndInstall(String url, String archiveFileName, Path installPath, + IProgressMonitor monitor) throws IOException { Exception error = null; for (int retries = 3; retries > 0 && !monitor.isCanceled(); --retries) { try { @@ -351,15 +608,19 @@ public class ArduinoManager { archiveIn.close(); } } - - return Status.OK_STATUS; + return; } catch (IOException | CompressorException | ArchiveException e) { error = e; // retry } } + // out of retries - return new Status(IStatus.ERROR, Activator.getId(), Messages.ArduinoManager_2, error); + if (error instanceof IOException) { + throw (IOException) error; + } else { + throw new IOException(error); + } } public static int compareVersions(String version1, String version2) { diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPackage.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPackage.java index 1d18767598a..3aba4a82eda 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPackage.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPackage.java @@ -7,17 +7,25 @@ *******************************************************************************/ package org.eclipse.cdt.arduino.core.internal.board; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Properties; +import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; +import org.eclipse.core.runtime.CoreException; public class ArduinoPackage { + // JSON fields private String name; private String maintainer; private String websiteURL; @@ -25,22 +33,9 @@ public class ArduinoPackage { private ArduinoHelp help; private List platforms; private List tools; + // end JSON fields - private transient ArduinoManager manager; - - void setOwner(ArduinoManager manager) { - this.manager = manager; - for (ArduinoPlatform platform : platforms) { - platform.setOwner(this); - } - for (ArduinoTool tool : tools) { - tool.setOwner(this); - } - } - - ArduinoManager getManager() { - return manager; - } + private Map installedPlatforms; public String getName() { return name; @@ -66,51 +61,96 @@ public class ArduinoPackage { return Collections.unmodifiableCollection(platforms); } + void init() { + for (ArduinoPlatform platform : platforms) { + platform.init(this); + } + for (ArduinoTool tool : tools) { + tool.init(this); + } + } + + public ArduinoPlatform getPlatform(String architecture, String version) { + if (platforms != null) { + for (ArduinoPlatform plat : platforms) { + if (plat.getArchitecture().equals(architecture) && plat.getVersion().equals(version)) { + return plat; + } + } + } + return null; + } + public Path getInstallPath() { return ArduinoPreferences.getArduinoHome().resolve("packages").resolve(getName()); //$NON-NLS-1$ } - /** - * Only the latest versions of the platforms. - * - * @return latest platforms - */ - public Map getAvailablePlatforms() { - Map platformMap = new HashMap<>(); - for (ArduinoPlatform platform : platforms) { - ArduinoPlatform p = platformMap.get(platform.getName()); - if (p == null || ArduinoManager.compareVersions(platform.getVersion(), p.getVersion()) > 0) { - platformMap.put(platform.getName(), platform); - } - } - return platformMap; - } + private void initInstalledPlatforms() throws CoreException { + if (installedPlatforms == null) { + installedPlatforms = new HashMap<>(); - public Map getInstalledPlatforms() { - Map platformMap = new HashMap<>(); - for (ArduinoPlatform platform : platforms) { - if (platform.isInstalled()) { - platformMap.put(platform.getName(), platform); - } - } - return platformMap; - } + if (Files.isDirectory(getInstallPath())) { + Path platformTxt = Paths.get("platform.txt"); //$NON-NLS-1$ + try { + Files.find(getInstallPath().resolve("hardware"), 2, //$NON-NLS-1$ + (path, attrs) -> path.getFileName().equals(platformTxt)) + .forEach(path -> { + try (FileReader reader = new FileReader(path.toFile())) { + Properties platformProperties = new Properties(); + platformProperties.load(reader); + String arch = path.getName(path.getNameCount() - 2).toString(); + String version = platformProperties.getProperty("version"); //$NON-NLS-1$ - public ArduinoPlatform getPlatform(String name) { - ArduinoPlatform foundPlatform = null; - for (ArduinoPlatform platform : platforms) { - if (platform.getName().equals(name)) { - if (foundPlatform == null) { - foundPlatform = platform; - } else { - if (platform.isInstalled() - && ArduinoManager.compareVersions(platform.getVersion(), foundPlatform.getVersion()) > 0) { - foundPlatform = platform; - } + ArduinoPlatform platform = getPlatform(arch, version); + if (platform != null) { + platform.setPlatformProperties(platformProperties); + installedPlatforms.put(arch, platform); + } // TODO manually add it if was removed from index + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } catch (IOException e) { + throw Activator.coreException(e); } } } - return foundPlatform; + } + + public Collection getInstalledPlatforms() throws CoreException { + initInstalledPlatforms(); + return installedPlatforms.values(); + } + + public ArduinoPlatform getInstalledPlatform(String architecture) throws CoreException { + if (architecture == null) { + return null; + } else { + initInstalledPlatforms(); + return installedPlatforms.get(architecture); + } + } + + void platformInstalled(ArduinoPlatform platform) { + installedPlatforms.put(platform.getArchitecture(), platform); + } + + void platformUninstalled(ArduinoPlatform platform) { + installedPlatforms.remove(platform.getArchitecture()); + } + + public Collection getAvailablePlatforms() throws CoreException { + initInstalledPlatforms(); + Map platformMap = new HashMap<>(); + for (ArduinoPlatform platform : platforms) { + if (!installedPlatforms.containsKey(platform.getArchitecture())) { + ArduinoPlatform p = platformMap.get(platform.getName()); + if (p == null || ArduinoManager.compareVersions(platform.getVersion(), p.getVersion()) > 0) { + platformMap.put(platform.getName(), platform); + } + } + } + return platformMap.values(); } public List getTools() { diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java index 55eaddf405a..3e85fa1b87a 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java @@ -37,9 +37,11 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; public class ArduinoPlatform { + // JSON fields private String name; private String architecture; private String version; @@ -50,6 +52,7 @@ public class ArduinoPlatform { private String size; private List boards; private List toolsDependencies; + // end JSON fields private ArduinoPackage pkg; private HierarchicalProperties boardsProperties; @@ -57,13 +60,13 @@ public class ArduinoPlatform { private Map menus = new HashMap<>(); private Map libraries; - void setOwner(ArduinoPackage pkg) { + void init(ArduinoPackage pkg) { this.pkg = pkg; + for (ArduinoBoard board : boards) { - board.setOwners(this); - } - for (ToolDependency toolDep : toolsDependencies) { - toolDep.setOwner(this); + if (board != null) { + board.setOwners(this); + } } } @@ -103,33 +106,39 @@ public class ArduinoPlatform { return size; } + public void setPlatformProperties(Properties platformProperties) { + this.platformProperties = platformProperties; + } + public List getBoards() { - if (isInstalled() && boardsProperties == null) { + if (boardsProperties == null) { Properties boardProps = new Properties(); - try (InputStream is = new FileInputStream(getInstallPath().resolve("boards.txt").toFile()); //$NON-NLS-1$ - Reader reader = new InputStreamReader(is, "UTF-8")) { //$NON-NLS-1$ - boardProps.load(reader); - } catch (IOException e) { - Activator.log(e); - } - - boardsProperties = new HierarchicalProperties(boardProps); - - // Replace the boards with a real ones - boards = new ArrayList<>(); - for (Map.Entry entry : boardsProperties.getChildren().entrySet()) { - if (entry.getValue().getChild("name") != null) { //$NON-NLS-1$ - // assume things with names are boards - boards.add(new ArduinoBoard(entry.getKey(), entry.getValue()).setOwners(this)); + if (Files.exists(getInstallPath())) { + try (InputStream is = new FileInputStream(getInstallPath().resolve("boards.txt").toFile()); //$NON-NLS-1$ + Reader reader = new InputStreamReader(is, "UTF-8")) { //$NON-NLS-1$ + boardProps.load(reader); + } catch (IOException e) { + Activator.log(e); } - } - // Build the menu - HierarchicalProperties menuProp = boardsProperties.getChild("menu"); //$NON-NLS-1$ - if (menuProp != null) { - for (Map.Entry entry : menuProp.getChildren().entrySet()) { - menus.put(entry.getKey(), entry.getValue().getValue()); + boardsProperties = new HierarchicalProperties(boardProps); + + // Replace the boards with a real ones + boards = new ArrayList<>(); + for (Map.Entry entry : boardsProperties.getChildren().entrySet()) { + if (entry.getValue().getChild("name") != null) { //$NON-NLS-1$ + // assume things with names are boards + boards.add(new ArduinoBoard(entry.getKey(), entry.getValue()).setOwners(this)); + } + } + + // Build the menu + HierarchicalProperties menuProp = boardsProperties.getChild("menu"); //$NON-NLS-1$ + if (menuProp != null) { + for (Map.Entry entry : menuProp.getChildren().entrySet()) { + menus.put(entry.getKey(), entry.getValue().getValue()); + } } } } @@ -140,7 +149,16 @@ public class ArduinoPlatform { return boardsProperties; } - public ArduinoBoard getBoard(String name) throws CoreException { + public ArduinoBoard getBoard(String id) throws CoreException { + for (ArduinoBoard board : getBoards()) { + if (id.equals(board.getId())) { + return board; + } + } + return null; + } + + public ArduinoBoard getBoardByName(String name) throws CoreException { for (ArduinoBoard board : getBoards()) { if (name.equals(board.getName())) { return board; @@ -187,32 +205,8 @@ public class ArduinoPlatform { return platformProperties; } - public boolean isInstalled() { - return getInstallPath().resolve("boards.txt").toFile().exists(); //$NON-NLS-1$ - } - public Path getInstallPath() { - // TODO remove migration in Neon - Path oldPath = ArduinoPreferences.getArduinoHome().resolve("hardware").resolve(pkg.getName()) //$NON-NLS-1$ - .resolve(architecture).resolve(version); - Path newPath = getPackage().getInstallPath().resolve("hardware").resolve(pkg.getName()).resolve(architecture) //$NON-NLS-1$ - .resolve(version); - if (Files.exists(oldPath)) { - try { - Files.createDirectories(newPath.getParent()); - Files.move(oldPath, newPath); - for (Path parent = oldPath.getParent(); parent != null; parent = parent.getParent()) { - if (Files.newDirectoryStream(parent).iterator().hasNext()) { - break; - } else { - Files.delete(parent); - } - } - } catch (IOException e) { - Activator.log(e); - } - } - return newPath; + return getPackage().getInstallPath().resolve("hardware").resolve(architecture); //$NON-NLS-1$ } public List getIncludePath() { @@ -249,18 +243,17 @@ public class ArduinoPlatform { } private void initLibraries() throws CoreException { - libraries = new HashMap<>(); - File[] libraryDirs = getInstallPath().resolve("libraries").toFile().listFiles(); //$NON-NLS-1$ - if (libraryDirs != null) { - for (File libraryDir : libraryDirs) { - Path propsPath = libraryDir.toPath().resolve("library.properties"); //$NON-NLS-1$ - if (propsPath.toFile().exists()) { - try { - ArduinoLibrary lib = new ArduinoLibrary(propsPath); - libraries.put(lib.getName(), lib); - } catch (IOException e) { - throw new CoreException( - new Status(IStatus.ERROR, Activator.getId(), "Loading " + propsPath, e)); //$NON-NLS-1$ + if (libraries == null) { + libraries = new HashMap<>(); + if (Files.exists(getInstallPath())) { + File[] libraryDirs = getInstallPath().resolve("libraries").toFile().listFiles(); //$NON-NLS-1$ + if (libraryDirs != null) { + for (File libraryDir : libraryDirs) { + Path propsPath = libraryDir.toPath().resolve("library.properties"); //$NON-NLS-1$ + if (propsPath.toFile().exists()) { + ArduinoLibrary lib = new ArduinoLibrary(propsPath, this); + libraries.put(lib.getName(), lib); + } } } } @@ -268,24 +261,35 @@ public class ArduinoPlatform { } public synchronized Collection getLibraries() throws CoreException { - if (libraries == null && isInstalled()) { - initLibraries(); - } + initLibraries(); return libraries.values(); } public synchronized ArduinoLibrary getLibrary(String name) throws CoreException { - if (libraries == null && isInstalled()) { - initLibraries(); - } + initLibraries(); return libraries != null ? libraries.get(name) : null; } - public IStatus install(IProgressMonitor monitor) { + public void install(IProgressMonitor monitor) throws CoreException { + int work = 1 + toolsDependencies.size(); + + boolean exists = Files.exists(getInstallPath()); + if (exists) + work++; + + Path makePath = ArduinoPreferences.getArduinoHome().resolve("make.exe"); //$NON-NLS-1$ + boolean needMake = Platform.getOS().equals(Platform.OS_WIN32) && !Files.exists(makePath); + if (needMake) + work++; + + SubMonitor sub = SubMonitor.convert(monitor, work); + // Check if we're installed already - if (isInstalled()) { + if (exists) { try { + sub.setTaskName(String.format("Removing old package %s", getName())); ArduinoManager.recursiveDelete(getInstallPath()); + sub.worked(1); } catch (IOException e) { // just log it, shouldn't break the install Activator.log(e); @@ -294,39 +298,41 @@ public class ArduinoPlatform { // Install the tools for (ToolDependency toolDep : toolsDependencies) { - IStatus status = toolDep.install(monitor); - if (!status.isOK()) { - return status; - } + sub.setTaskName(String.format("Installing tool %s", toolDep.getName())); + toolDep.install(monitor); + sub.worked(1); } // On Windows install make from bintray - if (Platform.getOS().equals(Platform.OS_WIN32)) { + if (needMake) { try { - Path makePath = ArduinoPreferences.getArduinoHome().resolve("make.exe"); //$NON-NLS-1$ - if (!makePath.toFile().exists()) { - Files.createDirectories(makePath.getParent()); - URL makeUrl = new URL("https://bintray.com/artifact/download/cdtdoug/tools/make.exe"); //$NON-NLS-1$ - Files.copy(makeUrl.openStream(), makePath); - makePath.toFile().setExecutable(true, false); - } + sub.setTaskName("Installing make"); + Files.createDirectories(makePath.getParent()); + URL makeUrl = new URL("https://bintray.com/artifact/download/cdtdoug/tools/make.exe"); //$NON-NLS-1$ + Files.copy(makeUrl.openStream(), makePath); + makePath.toFile().setExecutable(true, false); + sub.worked(1); } catch (IOException e) { - return new Status(IStatus.ERROR, Activator.getId(), Messages.ArduinoPlatform_0, e); + throw Activator.coreException(e); } } // Download platform archive - IStatus status = ArduinoManager.downloadAndInstall(url, archiveFileName, getInstallPath(), monitor); - if (!status.isOK()) { - return status; + sub.setTaskName(String.format("Downloading and installing %s", getName())); + try { + ArduinoManager.downloadAndInstall(url, archiveFileName, getInstallPath(), monitor); + } catch (IOException e) { + throw Activator.coreException(e); } + sub.done(); - return Status.OK_STATUS; + pkg.platformInstalled(this); } public IStatus uninstall(IProgressMonitor monitor) { try { ArduinoManager.recursiveDelete(getInstallPath()); + pkg.platformUninstalled(this); // TODO delete tools that aren't needed any more return Status.OK_STATUS; } catch (IOException e) { @@ -334,6 +340,40 @@ public class ArduinoPlatform { } } + @Override + public String toString() { + return name; + } + + private String fixText(String text) { + String fixed = text.replaceAll("&", "&"); //$NON-NLS-1$ //$NON-NLS-2$ + fixed = fixed.replaceAll("<", ">"); //$NON-NLS-1$ //$NON-NLS-2$ + fixed = fixed.replaceAll("<", "<"); //$NON-NLS-1$ //$NON-NLS-2$ + return fixed; + } + + public String toFormText() { + StringBuilder text = new StringBuilder(); + + text.append("
"); //$NON-NLS-1$ + text.append(String.format("

%s: %s

", "Package", getName())); //$NON-NLS-1$ + text.append(String.format("

%s: %s

", "Maintainer", fixText(getPackage().getMaintainer()))); //$NON-NLS-1$ + + ArduinoHelp help = getPackage().getHelp(); + if (help != null && help.getOnline() != null) { + text.append(String.format("

%s

", help.getOnline(), "Online help")); //$NON-NLS-1$ + } + + text.append(String.format("

%s:

", "Supported boards")); //$NON-NLS-1$ + for (ArduinoBoard board : getBoards()) { + text.append(String.format("
  • %s
  • ", fixText(board.getName()))); //$NON-NLS-1$ + } + + text.append("
    "); //$NON-NLS-1$ + + return text.toString(); + } + @Override public int hashCode() { final int prime = 31; diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoTool.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoTool.java index 5361b1d7727..c3a9bf42af2 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoTool.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoTool.java @@ -16,6 +16,7 @@ import java.util.Properties; import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; @@ -28,13 +29,6 @@ public class ArduinoTool { private transient ArduinoPackage pkg; - public void setOwner(ArduinoPackage pkg) { - this.pkg = pkg; - for (ArduinoToolSystem system : systems) { - system.setOwner(this); - } - } - public ArduinoPackage getPackage() { return pkg; } @@ -51,6 +45,13 @@ public class ArduinoTool { return systems; } + void init(ArduinoPackage pkg) { + this.pkg = pkg; + for (ArduinoToolSystem system : systems) { + system.setOwner(this); + } + } + public Path getInstallPath() { // TODO remove migration in Neon Path oldPath = ArduinoPreferences.getArduinoHome().resolve("tools").resolve(pkg.getName()).resolve(name) //$NON-NLS-1$ @@ -78,24 +79,25 @@ public class ArduinoTool { return getInstallPath().toFile().exists(); } - public IStatus install(IProgressMonitor monitor) { + public void install(IProgressMonitor monitor) throws CoreException { if (isInstalled()) { - return Status.OK_STATUS; + return; } for (ArduinoToolSystem system : systems) { if (system.isApplicable()) { - return system.install(monitor); + system.install(monitor); } } // No valid system - return new Status(IStatus.ERROR, Activator.getId(), "No valid system found for " + name); //$NON-NLS-1$ + throw new CoreException( + new Status(IStatus.ERROR, Activator.getId(), String.format("No valid system found for %s", name))); //$NON-NLS-1$ } public Properties getToolProperties() { Properties properties = new Properties(); - properties.put("runtime.tools." + name + ".path", ArduinoBuildConfiguration.pathString(getInstallPath())); //$NON-NLS-1$ //$NON-NLS-1$//$NON-NLS-2$ + properties.put("runtime.tools." + name + ".path", ArduinoBuildConfiguration.pathString(getInstallPath())); //$NON-NLS-1$//$NON-NLS-2$ properties.put("runtime.tools." + name + '-' + version + ".path", //$NON-NLS-1$//$NON-NLS-2$ ArduinoBuildConfiguration.pathString(getInstallPath())); //$NON-NLS-1$ return properties; diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoToolSystem.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoToolSystem.java index 7fa5b1b20f0..cf457af06ff 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoToolSystem.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoToolSystem.java @@ -7,8 +7,11 @@ *******************************************************************************/ package org.eclipse.cdt.arduino.core.internal.board; +import java.io.IOException; + +import org.eclipse.cdt.arduino.core.internal.Activator; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; public class ArduinoToolSystem { @@ -83,8 +86,12 @@ public class ArduinoToolSystem { } } - public IStatus install(IProgressMonitor monitor) { - return ArduinoManager.downloadAndInstall(url, archiveFileName, tool.getInstallPath(), monitor); + public void install(IProgressMonitor monitor) throws CoreException { + try { + ArduinoManager.downloadAndInstall(url, archiveFileName, tool.getInstallPath(), monitor); + } catch (IOException e) { + throw Activator.coreException(e); + } } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/LibraryIndex.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/LibraryIndex.java index 6643f0292b9..e6551672d48 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/LibraryIndex.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/LibraryIndex.java @@ -7,72 +7,14 @@ *******************************************************************************/ package org.eclipse.cdt.arduino.core.internal.board; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Set; public class LibraryIndex { private List libraries; - public static final String UNCATEGORIZED = "Uncategorized"; //$NON-NLS-1$ - // category name to library name - private Map> categories = new HashMap<>(); - // library name to latest version of library - private Map latestLibs = new HashMap<>(); - - public void resolve() throws IOException { - for (ArduinoLibrary library : libraries) { - String name = library.getName(); - - String category = library.getCategory(); - if (category == null) { - category = UNCATEGORIZED; - } - - Set categoryLibs = categories.get(category); - if (categoryLibs == null) { - categoryLibs = new HashSet<>(); - categories.put(category, categoryLibs); - } - categoryLibs.add(name); - - ArduinoLibrary current = latestLibs.get(name); - if (current != null) { - if (ArduinoManager.compareVersions(library.getVersion(), current.getVersion()) > 0) { - latestLibs.put(name, library); - } - } else { - latestLibs.put(name, library); - } - } - } - - public ArduinoLibrary getLibrary(String name) { - return latestLibs.get(name); - } - - public Collection getCategories() { - return Collections.unmodifiableCollection(categories.keySet()); - } - - public Collection getLibraries(String category) { - Set categoryLibs = categories.get(category); - if (categoryLibs == null) { - return new ArrayList<>(0); - } - - List libs = new ArrayList<>(categoryLibs.size()); - for (String name : categoryLibs) { - libs.add(latestLibs.get(name)); - } - return libs; + public List getLibraries() { + return libraries; } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/PackageIndex.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/PackageIndex.java index 9a1abc96c8b..4ad0157a512 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/PackageIndex.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/PackageIndex.java @@ -7,29 +7,15 @@ *******************************************************************************/ package org.eclipse.cdt.arduino.core.internal.board; +import java.util.Collection; import java.util.List; public class PackageIndex { private List packages; - public List getPackages() { + public Collection getPackages() { return packages; } - public ArduinoPackage getPackage(String packageName) { - for (ArduinoPackage pkg : packages) { - if (pkg.getName().equals(packageName)) { - return pkg; - } - } - return null; - } - - void setOwners(ArduinoManager manager) { - for (ArduinoPackage pkg : packages) { - pkg.setOwner(manager); - } - } - } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ToolDependency.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ToolDependency.java index 8bd1ef3635d..ac9f5c0dff0 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ToolDependency.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ToolDependency.java @@ -19,12 +19,6 @@ public class ToolDependency { private String name; private String version; - private transient ArduinoPlatform platform; - - public void setOwner(ArduinoPlatform platform) { - this.platform = platform; - } - public String getPackager() { return packager; } @@ -38,25 +32,16 @@ public class ToolDependency { } public ArduinoTool getTool() throws CoreException { - ArduinoPackage pkg = platform.getPackage(); - if (!pkg.getName().equals(packager)) { - pkg = pkg.getManager().getPackage(packager); - } - - return pkg.getTool(name, version); + return Activator.getService(ArduinoManager.class).getTool(packager, name, version); } - public IStatus install(IProgressMonitor monitor) { - try { - ArduinoTool tool = getTool(); - if (tool == null) { - return new Status(IStatus.ERROR, Activator.getId(), - String.format("Tool not found %s %s", name, version)); - } - return getTool().install(monitor); - } catch (CoreException e) { - return e.getStatus(); + public void install(IProgressMonitor monitor) throws CoreException { + ArduinoTool tool = getTool(); + if (tool == null) { + throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), + String.format("Tool not found %s %s", name, version))); } + getTool().install(monitor); } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java index 6ef03d51bd5..39af24d8fd0 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java @@ -98,15 +98,15 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration implements Te String packageName = settings.get(PACKAGE_NAME, ""); //$NON-NLS-1$ String platformName = settings.get(PLATFORM_NAME, ""); //$NON-NLS-1$ String boardName = settings.get(BOARD_NAME, ""); //$NON-NLS-1$ - ArduinoBoard b = manager.getBoard(boardName, platformName, packageName); + ArduinoBoard b = manager.getBoard(packageName, platformName, boardName); if (b == null) { // Default to Uno or first one we find b = manager.getBoard("Arduino/Genuino Uno", "Arduino AVR Boards", "arduino"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (b == null) { - List boards = manager.getInstalledBoards(); + Collection boards = manager.getInstalledBoards(); if (!boards.isEmpty()) { - b = boards.get(0); + b = boards.iterator().next(); } } } @@ -116,7 +116,8 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration implements Te this.launchMode = name.substring(i + 1); } - ArduinoBuildConfiguration(IBuildConfiguration config, String name, ArduinoBoard board, String launchMode, IToolChain toolChain) + ArduinoBuildConfiguration(IBuildConfiguration config, String name, ArduinoBoard board, String launchMode, + IToolChain toolChain) throws CoreException { super(config, name, toolChain); this.board = board; diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfigurationProvider.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfigurationProvider.java index ead1a26531f..0dfda4599c2 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfigurationProvider.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfigurationProvider.java @@ -7,7 +7,7 @@ *******************************************************************************/ package org.eclipse.cdt.arduino.core.internal.build; -import java.util.List; +import java.util.Collection; import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard; @@ -44,11 +44,11 @@ public class ArduinoBuildConfigurationProvider implements ICBuildConfigurationPr @Override public ICBuildConfiguration getDefaultCBuildConfiguration(IProject project) throws CoreException { - ArduinoBoard board = arduinoManager.getBoard("Arduino/Genuino Uno", "Arduino AVR Boards", "arduino"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + ArduinoBoard board = arduinoManager.getBoard("arduino", "avr", "Arduino/Genuino Uno"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (board == null) { - List boards = arduinoManager.getInstalledBoards(); + Collection boards = arduinoManager.getInstalledBoards(); if (!boards.isEmpty()) { - board = boards.get(0); + board = boards.iterator().next(); } } if (board != null) { @@ -112,7 +112,8 @@ public class ArduinoBuildConfigurationProvider implements ICBuildConfigurationPr IToolChainProvider provider = toolChainManager.getProvider(ArduinoToolChainProvider.ID); IToolChain toolChain = new ArduinoToolChain(provider, config); toolChainManager.addToolChain(toolChain); - ArduinoBuildConfiguration arduinoConfig = new ArduinoBuildConfiguration(config, configName, target, launchMode, toolChain); + ArduinoBuildConfiguration arduinoConfig = new ArduinoBuildConfiguration(config, configName, target, launchMode, + toolChain); configManager.addBuildConfiguration(config, arduinoConfig); return arduinoConfig; } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/remote/ArduinoRemoteConnection.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/remote/ArduinoRemoteConnection.java index f66344b7fef..380ec26be88 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/remote/ArduinoRemoteConnection.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/remote/ArduinoRemoteConnection.java @@ -95,14 +95,15 @@ public class ArduinoRemoteConnection } public ArduinoBoard getBoard() throws CoreException { - return Activator.getService(ArduinoManager.class).getBoard(remoteConnection.getAttribute(BOARD_NAME), - remoteConnection.getAttribute(PLATFORM_NAME), remoteConnection.getAttribute(PACKAGE_NAME)); + return Activator.getService(ArduinoManager.class).getBoard(remoteConnection.getAttribute(PACKAGE_NAME), + remoteConnection.getAttribute(PLATFORM_NAME), remoteConnection.getAttribute(BOARD_NAME)); } public String getPortName() { return remoteConnection.getAttribute(PORT_NAME); } + @Override public IRemoteProcess getCommandShell(int flags) throws IOException { if (serialPort != null && serialPort.isOpen()) { // can only have one open at a time diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/.classpath b/toolchains/arduino/org.eclipse.cdt.arduino.ui/.classpath index b9a5b1ec649..43b986286a9 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/.classpath +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/.classpath @@ -1,6 +1,6 @@ - + diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/.settings/org.eclipse.jdt.core.prefs b/toolchains/arduino/org.eclipse.cdt.arduino.ui/.settings/org.eclipse.jdt.core.prefs index f42de363afa..0c68a61dca8 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/.settings/org.eclipse.jdt.core.prefs +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,7 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/META-INF/MANIFEST.MF b/toolchains/arduino/org.eclipse.cdt.arduino.ui/META-INF/MANIFEST.MF index c66654bacc6..329d73319a3 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/META-INF/MANIFEST.MF +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/META-INF/MANIFEST.MF @@ -2,26 +2,23 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.arduino.ui;singleton:=true -Bundle-Version: 1.0.0.qualifier +Bundle-Version: 2.0.0.qualifier Bundle-Activator: org.eclipse.cdt.arduino.ui.internal.Activator Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.expressions, + org.eclipse.jface.text, org.eclipse.ui, - org.eclipse.ui.forms, - org.eclipse.jface.text;bundle-version="3.10.0", - org.eclipse.ui.console, org.eclipse.ui.ide, + org.eclipse.ui.forms, org.eclipse.debug.ui, org.eclipse.launchbar.core, - org.eclipse.launchbar.ui, org.eclipse.cdt.arduino.core, org.eclipse.remote.core;bundle-version="2.0.0", org.eclipse.remote.ui;bundle-version="2.0.0", - org.eclipse.cdt.core, org.eclipse.cdt.native.serial;bundle-version="1.0.0", - org.eclipse.launchbar.remote.ui;bundle-version="1.0.0", - org.eclipse.tools.templates.ui;bundle-version="1.0.0" -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 + org.eclipse.tools.templates.ui;bundle-version="1.0.0", + org.eclipse.launchbar.remote.ui;bundle-version="1.0.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.properties b/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.properties index 9d2161d5f3f..6bc840fb93f 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.properties +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.properties @@ -11,3 +11,5 @@ pluginName=Arduino C++ UI providerName=Eclipse CDT preferencePage.name=Arduino + +arduinoDownloadsManager=Arduino Downloads Manager \ No newline at end of file diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml b/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml index 2d5f0e6d659..fa5d081dea3 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml @@ -30,12 +30,6 @@ project="true">
    - - - - + + + + + + + + + +
    diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/pom.xml b/toolchains/arduino/org.eclipse.cdt.arduino.ui/pom.xml index 191e3bed244..e8aba96f99b 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/pom.xml +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/pom.xml @@ -12,6 +12,6 @@ org.eclipse.cdt.arduino.ui - 1.0.0-SNAPSHOT + 2.0.0-SNAPSHOT eclipse-plugin diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/Activator.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/Activator.java index 1f57d190028..cd5c0b1ce32 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/Activator.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/Activator.java @@ -1,16 +1,12 @@ /******************************************************************************* - * Copyright (c) 2015 QNX Software Systems and others. + * Copyright (c) 2015, 2016 QNX Software Systems 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 * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * QNX Software Systems - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.arduino.ui.internal; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; @@ -29,19 +25,19 @@ public class Activator extends AbstractUIPlugin { public static final String IMG_ARDUINO = PLUGIN_ID + ".arduino"; //$NON-NLS-1$ public static final String IMG_CONNECTION_TYPE = PLUGIN_ID + ".connectionType"; //$NON-NLS-1$ - public static final String IMG_ADD = PLUGIN_ID + ".add"; - public static final String IMG_DELETE = PLUGIN_ID + ".delete"; + public static final String IMG_ADD = PLUGIN_ID + ".add"; //$NON-NLS-1$ + public static final String IMG_DELETE = PLUGIN_ID + ".delete"; //$NON-NLS-1$ // The shared instance private static Activator plugin; + @Override public void start(BundleContext context) throws Exception { super.start(context); plugin = this; - // Load up the Arduino indices - getService(ArduinoManager.class).loadIndices(); } + @Override public void stop(BundleContext context) throws Exception { plugin = null; super.stop(context); diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/FormTextHoverManager.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/FormTextHoverManager.java new file mode 100644 index 00000000000..a7ee9326fa2 --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/FormTextHoverManager.java @@ -0,0 +1,372 @@ +/** + * Copyright (c) 2012,2016 Eclipse contributors 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 + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.cdt.arduino.ui.internal; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.eclipse.jface.internal.text.InformationControlReplacer; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.text.AbstractHoverInformationControlManager; +import org.eclipse.jface.text.AbstractInformationControl; +import org.eclipse.jface.text.AbstractReusableInformationControlCreator; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.IInformationControlExtension3; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +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.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.widgets.FormText; + +/** + * A utility class for showing rich JDT-style HTML content in tool tip hovers. This class is final + * to avoid long term API commitments. If you feel the need to specialize it, please open a bugzilla + * to explain what your use case and requirements. + */ +@SuppressWarnings("restriction") +public abstract class FormTextHoverManager extends AbstractHoverInformationControlManager { + + private static class FormTextInformationControl extends AbstractInformationControl { + private ScrolledComposite comp; + private FormText formText; + private String text; + + public FormTextInformationControl(Shell parentShell, boolean inFocus) { + super(parentShell, true); + + // Need to do our own status bar if not in focus + if (!inFocus) { + Shell shell = getShell(); + Composite statusComposite = new Composite(shell, SWT.NONE); + GridData gridData = new GridData(SWT.FILL, SWT.BOTTOM, true, false); + statusComposite.setLayoutData(gridData); + GridLayout statusLayout = new GridLayout(1, false); + statusLayout.marginHeight = 0; + statusLayout.marginWidth = 0; + statusLayout.verticalSpacing = 1; + statusComposite.setLayout(statusLayout); + + Label separator = new Label(statusComposite, SWT.SEPARATOR | SWT.HORIZONTAL); + separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Label statusLabel = new Label(statusComposite, SWT.RIGHT); + statusLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + statusLabel.setText("Press F2 for focus"); + + FontData[] fontDatas = JFaceResources.getDialogFont().getFontData(); + for (int i = 0; i < fontDatas.length; i++) { + fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10); + } + Font statusLabelFont = new Font(statusLabel.getDisplay(), fontDatas); + statusLabel.setFont(statusLabelFont); + } + + create(); + } + + @Override + public boolean hasContents() { + return text != null; + } + + @Override + public void setInformation(String information) { + this.text = information; + if (text != null) { + formText.setText(text, true, true); + comp.setMinSize(formText.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } + } + + @Override + protected void createContent(Composite parent) { + comp = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL); + comp.setExpandHorizontal(true); + comp.setExpandVertical(true); + + formText = new FormText(comp, SWT.NONE); + comp.setContent(formText); + formText.addHyperlinkListener(new HyperlinkAdapter() { + @Override + public void linkActivated(HyperlinkEvent event) { + try { + PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser() + .openURL(new URL((String) event.getHref())); + } catch (MalformedURLException | PartInitException e) { + Activator.log(e); + } + } + }); + } + + @Override + public IInformationControlCreator getInformationPresenterControlCreator() { + return new IInformationControlCreator() { + @Override + public IInformationControl createInformationControl(Shell parent) { + return new FormTextInformationControl(parent, true); + } + }; + } + + public Control getControl() { + return getShell(); + } + } + + protected IInformationControlCloser closer; + + public FormTextHoverManager() { + super(new AbstractReusableInformationControlCreator() { + @Override + protected IInformationControl doCreateInformationControl(Shell parent) { + return new FormTextInformationControl(parent, false); + } + }); + + getInternalAccessor().setInformationControlReplacer(new InformationControlReplacer( + new AbstractReusableInformationControlCreator() { + @Override + protected IInformationControl doCreateInformationControl(Shell parent) { + return new FormTextInformationControl(parent, true); + } + }) { + { + this.setCloser(new Closer()); + } + + class Closer implements IInformationControlCloser, ControlListener, MouseListener, KeyListener, + FocusListener, Listener { + protected boolean isActive; + protected Display display; + protected Control subjectControl; + protected IInformationControl informationControl; + + @Override + public void setSubjectControl(Control control) { + subjectControl = control; + } + + @Override + public void setInformationControl(IInformationControl control) { + this.informationControl = control; + } + + @Override + public void start(Rectangle informationArea) { + if (!isActive) { + isActive = true; + + if (subjectControl != null && !subjectControl.isDisposed()) { + subjectControl.addControlListener(this); + subjectControl.addMouseListener(this); + subjectControl.addKeyListener(this); + } + + if (informationControl != null) { + informationControl.addFocusListener(this); + } + + display = subjectControl.getDisplay(); + if (!display.isDisposed()) { + display.addFilter(SWT.MouseMove, this); + display.addFilter(SWT.FocusOut, this); + } + } + } + + @Override + public void stop() { + if (isActive) { + isActive = false; + + if (subjectControl != null && !subjectControl.isDisposed()) { + subjectControl.removeControlListener(this); + subjectControl.removeMouseListener(this); + subjectControl.removeKeyListener(this); + } + + if (informationControl != null) { + informationControl.removeFocusListener(this); + } + + if (display != null && !display.isDisposed()) { + display.removeFilter(SWT.MouseMove, this); + display.removeFilter(SWT.FocusOut, this); + } + display = null; + } + } + + @Override + public void controlResized(ControlEvent event) { + hideInformationControl(); + } + + @Override + public void controlMoved(ControlEvent event) { + hideInformationControl(); + } + + @Override + public void mouseDown(MouseEvent event) { + hideInformationControl(); + } + + @Override + public void mouseUp(MouseEvent event) { + // Ignore. + } + + @Override + public void mouseDoubleClick(MouseEvent event) { + hideInformationControl(); + } + + @Override + public void keyPressed(KeyEvent event) { + hideInformationControl(); + } + + @Override + public void keyReleased(KeyEvent event) { + // Ignore. + } + + @Override + public void focusGained(FocusEvent event) { + // Ignore. + } + + @Override + public void focusLost(FocusEvent event) { + if (display != null && !display.isDisposed()) { + display.asyncExec(new Runnable() { + @Override + public void run() { + hideInformationControl(); + } + }); + } + } + + @Override + public void handleEvent(Event event) { + if (event.type == SWT.MouseMove) { + if (event.widget instanceof Control && event.widget.isDisposed()) { + if (informationControl != null && !informationControl.isFocusControl() + && informationControl instanceof IInformationControlExtension3) { + Rectangle controlBounds = ((IInformationControlExtension3) informationControl) + .getBounds(); + if (controlBounds != null) { + Point mouseLocation = event.display.map((Control) event.widget, null, event.x, + event.y); + if (!controlBounds.contains(mouseLocation)) { + hideInformationControl(); + } + } + } else { + if (display != null && !display.isDisposed()) { + display.removeFilter(SWT.MouseMove, this); + } + } + } + } else if (event.type == SWT.FocusOut) { + if (informationControl != null && !informationControl.isFocusControl()) { + hideInformationControl(); + } + } + } + } + }); + } + + @Override + protected void setCloser(IInformationControlCloser closer) { + this.closer = closer; + super.setCloser(closer); + } + + @Override + protected boolean canClearDataOnHide() { + return false; + } + + protected KeyListener keyListener = new KeyListener() { + @Override + public void keyReleased(KeyEvent event) { + if (event.keyCode == SWT.F2) { + IInformationControl informationControl = getInformationControl(); + if (informationControl instanceof FormTextInformationControl) { + Control myControl = ((FormTextInformationControl) informationControl).getControl(); + Event mouseEvent = new Event(); + mouseEvent.display = myControl.getDisplay(); + mouseEvent.widget = myControl; + mouseEvent.type = SWT.MouseUp; + ((Listener) closer).handleEvent(mouseEvent); + event.doit = false; + } + } + } + + @Override + public void keyPressed(KeyEvent event) { + // Ignore. + } + }; + + @Override + public void install(Control subjectControl) { + Control oldSubjectControl = getSubjectControl(); + + if (oldSubjectControl != null && !oldSubjectControl.isDisposed()) { + oldSubjectControl.removeKeyListener(keyListener); + } + + if (subjectControl != null) { + subjectControl.addKeyListener(keyListener); + } + + super.install(subjectControl); + getInternalAccessor().getInformationControlReplacer().install(subjectControl); + } + + @Override + public void dispose() { + Control subjectControl = getSubjectControl(); + if (subjectControl != null && !subjectControl.isDisposed()) { + subjectControl.removeKeyListener(keyListener); + } + super.dispose(); + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/LibraryTree.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/LibraryTree.java new file mode 100644 index 00000000000..75829b4df77 --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/LibraryTree.java @@ -0,0 +1,301 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems 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 + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.arduino.ui.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.arduino.core.internal.board.ArduinoLibrary; +import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; +import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.viewers.BaseLabelProvider; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.ICheckStateProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.ui.dialogs.FilteredTree; +import org.eclipse.ui.dialogs.PatternFilter; + +public class LibraryTree extends FilteredTree { + + private static final String PLATFORMS = "Platform Libraries"; + private static final String UNCATEGORIZED = "Others"; + + private boolean includePlatforms; + private Set checkedLibs = new HashSet<>(); + private ArduinoManager manager = Activator.getService(ArduinoManager.class); + + private static class LibPatternFilter extends PatternFilter { + @Override + protected boolean isLeafMatch(Viewer viewer, Object element) { + if (element instanceof String) { + return wordMatches((String) element); + } else if (element instanceof ArduinoLibrary) { + ArduinoLibrary lib = (ArduinoLibrary) element; + return wordMatches(lib.getName()) || wordMatches(lib.getSentence()) + || wordMatches(lib.getParagraph()); + } else { + return false; + } + } + } + + public class ContentProvider implements ITreeContentProvider { + public Map> categories = new HashMap<>(); + public List uncategorized; + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (newInput == null) { + return; + } + + @SuppressWarnings("unchecked") + Collection libraries = (Collection) newInput; + for (ArduinoLibrary library : libraries) { + if (library.getPlatform() == null) { + String category = library.getCategory(); + if (category != null) { + List libs = categories.get(category); + if (libs == null) { + libs = new ArrayList<>(); + categories.put(category, libs); + } + libs.add(library); + } else { + if (uncategorized == null) { + uncategorized = new ArrayList<>(); + } + uncategorized.add(library); + } + } + } + } + + @Override + public Object[] getElements(Object inputElement) { + List elements = new ArrayList<>(categories.keySet()); + Collections.sort(elements, (o1, o2) -> o1.compareToIgnoreCase(o2)); + if (uncategorized != null) { + elements.add(UNCATEGORIZED); + } + if (includePlatforms) { + elements.add(PLATFORMS); + } + return elements.toArray(); + } + + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof String) { + if (parentElement == UNCATEGORIZED) { + return uncategorized.toArray(); + } else if (parentElement == PLATFORMS) { + List platforms = new ArrayList<>(); + try { + for (ArduinoPlatform platform : manager.getInstalledPlatforms()) { + if (!platform.getLibraries().isEmpty()) { + platforms.add(platform); + } + } + } catch (CoreException e) { + Activator.log(e); + } + Collections.sort(platforms, (o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName())); + return platforms.toArray(); + } else { + String category = (String) parentElement; + List libs = categories.get(category); + Collections.sort(libs, (o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName())); + return libs.toArray(); + } + } else if (parentElement instanceof ArduinoPlatform) { + try { + List libs = new ArrayList<>(((ArduinoPlatform) parentElement).getLibraries()); + Collections.sort(libs, (o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName())); + return libs.toArray(); + } catch (CoreException e) { + Activator.log(e); + } + } + return null; + } + + @Override + public Object getParent(Object element) { + if (element instanceof ArduinoLibrary) { + ArduinoLibrary library = (ArduinoLibrary) element; + ArduinoPlatform platform = library.getPlatform(); + if (platform != null) { + return platform; + } + + String category = library.getCategory(); + return category != null ? category : UNCATEGORIZED; + } else if (element instanceof ArduinoPlatform) { + return ((ArduinoPlatform) element).getName(); + } + return null; + } + + @Override + public boolean hasChildren(Object element) { + return element instanceof String || element instanceof ArduinoPlatform; + } + } + + private static class LabelProvider extends BaseLabelProvider implements ITableLabelProvider { + @Override + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + if (element instanceof String) { + return columnIndex == 0 ? (String) element : null; + } else if (element instanceof ArduinoPlatform) { + return columnIndex == 0 ? ((ArduinoPlatform) element).getName() : null; + } else if (element instanceof ArduinoLibrary) { + ArduinoLibrary library = (ArduinoLibrary) element; + switch (columnIndex) { + case 0: + return library.getName(); + case 1: + return library.getVersion(); + case 2: + return library.getSentence(); + default: + return null; + } + } else { + return null; + } + } + + } + + public LibraryTree(Composite parent) { + super(parent, SWT.CHECK | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL, new LibPatternFilter(), true); + + TreeViewer viewer = getViewer(); + viewer.setContentProvider(new ContentProvider()); + viewer.setLabelProvider(new LabelProvider()); + + Tree tree = viewer.getTree(); + tree.setHeaderVisible(true); + TreeColumn column1 = new TreeColumn(tree, SWT.LEFT); + column1.setText("Library"); + column1.setWidth(200); + TreeColumn column2 = new TreeColumn(tree, SWT.LEFT); + column2.setText("Version"); + column2.setWidth(100); + TreeColumn column3 = new TreeColumn(tree, SWT.LEFT); + column3.setText("Description"); + column3.setWidth(300); + } + + public void setIncludePlatforms(boolean includePlatforms) { + this.includePlatforms = includePlatforms; + } + + public void setChecked(Collection checkedLibs) { + this.checkedLibs = new HashSet<>(checkedLibs); + } + + public Collection getChecked() { + return checkedLibs; + } + + @Override + protected TreeViewer doCreateTreeViewer(Composite parent, int style) { + CheckboxTreeViewer viewer = new CheckboxTreeViewer(parent, style); + viewer.setCheckStateProvider(new ICheckStateProvider() { + @Override + public boolean isGrayed(Object element) { + if (element instanceof String) { + String category = (String) element; + if (category == PLATFORMS) { + for (ArduinoLibrary lib : checkedLibs) { + if (lib.getPlatform() != null) { + return true; + } + } + } else if (category == UNCATEGORIZED) { + for (ArduinoLibrary lib : checkedLibs) { + if (lib.getPlatform() == null && lib.getCategory() == null) { + return true; + } + } + } else { + for (ArduinoLibrary lib : checkedLibs) { + if (element.equals(lib.getCategory())) { + return true; + } + } + } + } else if (element instanceof ArduinoPlatform) { + for (ArduinoLibrary lib : checkedLibs) { + if (element == lib.getPlatform()) { + return true; + } + } + } + return false; + } + + @Override + public boolean isChecked(Object element) { + if (element instanceof ArduinoLibrary) { + return checkedLibs.contains(element); + } else { + return isGrayed(element); + } + } + }); + + viewer.addCheckStateListener(new ICheckStateListener() { + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + Object element = event.getElement(); + if (element instanceof ArduinoLibrary) { + if (event.getChecked()) { + checkedLibs.add((ArduinoLibrary) element); + } else { + checkedLibs.remove(element); + } + } else if (element instanceof String) { + if (!event.getChecked()) { + for (ArduinoLibrary lib : new ArrayList<>(checkedLibs)) { + if (element.equals(lib.getCategory())) { + checkedLibs.remove(lib); + } + } + } + } + } + }); + return viewer; + } +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/Messages.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/Messages.java index 1ec2ce693d3..cbf5f0e2d42 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/Messages.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/Messages.java @@ -27,22 +27,6 @@ public class Messages extends NLS { public static String LibrariesPropertyPage_0; public static String LibrariesPropertyPage_1; public static String LibrariesPropertyPage_desc; - public static String ArduinoPlatformsPreferencePage_0; - public static String ArduinoPlatformsPreferencePage_1; - public static String ArduinoPlatformsPreferencePage_10; - public static String ArduinoPlatformsPreferencePage_11; - public static String ArduinoPlatformsPreferencePage_12; - public static String ArduinoPlatformsPreferencePage_13; - public static String ArduinoPlatformsPreferencePage_14; - public static String ArduinoPlatformsPreferencePage_15; - public static String ArduinoPlatformsPreferencePage_2; - public static String ArduinoPlatformsPreferencePage_3; - public static String ArduinoPlatformsPreferencePage_4; - public static String ArduinoPlatformsPreferencePage_5; - public static String ArduinoPlatformsPreferencePage_6; - public static String ArduinoPlatformsPreferencePage_7; - public static String ArduinoPlatformsPreferencePage_8; - public static String ArduinoPlatformsPreferencePage_9; public static String ArduinoPreferencePage_desc; public static String PlatformDetailsDialog_0; public static String PlatformDetailsDialog_1; diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/ArduinoDownloadsManager.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/ArduinoDownloadsManager.java new file mode 100644 index 00000000000..1c47fc9d11f --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/ArduinoDownloadsManager.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems 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 + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.arduino.ui.internal.downloads; + +import org.eclipse.cdt.arduino.ui.internal.Activator; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.events.FocusAdapter; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Composite; + +public class ArduinoDownloadsManager extends WizardDialog { + + public ArduinoDownloadsManager() { + super(null, new Wizard() { + { + setNeedsProgressMonitor(true); + } + + @Override + public void addPages() { + addPage(new WizardPage(ArduinoDownloadsManager.class.getName()) { + { + setTitle("Arduino Download Manager"); + setDescription("Manage installed Platforms and Libraries."); + } + + @Override + public void createControl(Composite parent) { + final CTabFolder tabFolder = new CTabFolder(parent, SWT.BORDER); + tabFolder.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + tabFolder.getSelection().getControl().setFocus(); + } + }); + tabFolder.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + tabFolder.getSelection().getControl().setFocus(); + } + }); + + CTabItem platformsTab = new CTabItem(tabFolder, SWT.NONE); + platformsTab.setText("Platforms"); + platformsTab.setImage(Activator.getDefault().getImageRegistry().get(Activator.IMG_ARDUINO)); + PlatformsTabControl platformsControl = new PlatformsTabControl(tabFolder, SWT.NONE); + platformsControl.setContainer(getContainer()); + platformsTab.setControl(platformsControl); + + CTabItem librariesTab = new CTabItem(tabFolder, SWT.NONE); + librariesTab.setText("Libraries"); + librariesTab.setImage(Activator.getDefault().getImageRegistry().get(Activator.IMG_ARDUINO)); + LibrariesTabControl librariesControl = new LibrariesTabControl(tabFolder, SWT.NONE); + librariesControl.setContainer(getContainer()); + librariesTab.setControl(librariesControl); + + applyDialogFont(tabFolder); + setControl(tabFolder); + } + }); + } + + @Override + public boolean performFinish() { + return true; + } + }); + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + super.createButtonsForButtonBar(parent); + getButton(IDialogConstants.CANCEL_ID).setVisible(false); + getButton(IDialogConstants.FINISH_ID).setText("OK"); + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/LibrariesTabControl.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/LibrariesTabControl.java new file mode 100644 index 00000000000..401a79b4ccb --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/LibrariesTabControl.java @@ -0,0 +1,282 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems 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 + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.arduino.ui.internal.downloads; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.eclipse.cdt.arduino.core.internal.board.ArduinoLibrary; +import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; +import org.eclipse.cdt.arduino.ui.internal.Activator; +import org.eclipse.cdt.arduino.ui.internal.FormTextHoverManager; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.IWizardContainer; +import org.eclipse.swt.SWT; +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.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +public class LibrariesTabControl extends Composite { + + private ArduinoManager manager = Activator.getService(ArduinoManager.class); + private Table table; + private IWizardContainer container; + private Collection availableLibraries; + + public LibrariesTabControl(Composite parent, int style) { + super(parent, style); + setLayout(new GridLayout()); + + Text desc = new Text(this, SWT.READ_ONLY | SWT.WRAP); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false); + layoutData.widthHint = 500; + desc.setLayoutData(layoutData); + desc.setBackground(parent.getBackground()); + desc.setText("Installed Platforms. Details available in their tooltips"); + + Composite comp = new Composite(this, SWT.NONE); + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = 0; + comp.setLayout(layout); + comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + Composite tableComp = new Composite(comp, SWT.NONE); + tableComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + table = new Table(tableComp, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION); + table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + TableColumnLayout tableLayout = new TableColumnLayout(); + + TableColumn packageColumn = new TableColumn(table, SWT.LEAD); + packageColumn.setText("Library"); + tableLayout.setColumnData(packageColumn, new ColumnWeightData(5, 150, true)); + + TableColumn platformColumn = new TableColumn(table, SWT.LEAD); + platformColumn.setText("Version"); + tableLayout.setColumnData(platformColumn, new ColumnWeightData(2, 75, true)); + + TableColumn versionColumn = new TableColumn(table, SWT.LEAD); + versionColumn.setText("Description"); + tableLayout.setColumnData(versionColumn, new ColumnWeightData(5, 150, true)); + + tableComp.setLayout(tableLayout); + + Composite buttonComp = new Composite(comp, SWT.NONE); + buttonComp.setLayout(new GridLayout()); + buttonComp.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false)); + + final Button uninstallButton = new Button(buttonComp, SWT.PUSH); + uninstallButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); + uninstallButton.setText("Uninstall"); + uninstallButton.setEnabled(false); + uninstallButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + uninstall(); + } + }); + + Button updatesButton = new Button(buttonComp, SWT.PUSH); + updatesButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); + updatesButton.setText("Updates"); + updatesButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + checkForUpdates(); + } + }); + + Button addButton = new Button(buttonComp, SWT.PUSH); + addButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); + addButton.setText("Add"); + addButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + addLibraries(); + } + }); + + populateTable(); + + table.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TableItem[] selection = table.getSelection(); + uninstallButton.setEnabled(selection.length > 0); + } + }); + + FormTextHoverManager hoverManager = new FormTextHoverManager() { + @Override + protected void computeInformation() { + TableItem item = table.getItem(getHoverEventLocation()); + if (item != null) { + ArduinoLibrary library = (ArduinoLibrary) item.getData(); + setInformation(library.toFormText(), item.getBounds()); + } else { + setInformation(null, null); + } + } + }; + hoverManager.install(table); + + } + + public void setContainer(IWizardContainer container) { + this.container = container; + } + + private void populateTable() { + table.removeAll(); + try { + List libraries = new ArrayList<>(manager.getInstalledLibraries()); + Collections.sort(libraries, new Comparator() { + @Override + public int compare(ArduinoLibrary o1, ArduinoLibrary o2) { + return o1.getName().compareTo(o2.getName()); + } + }); + + for (ArduinoLibrary library : libraries) { + TableItem item = new TableItem(table, SWT.NONE); + item.setData(library); + item.setText(0, library.getName()); + item.setText(1, library.getVersion()); + item.setText(2, library.getSentence()); + } + + } catch (CoreException e) { + Activator.log(e); + } + } + + private void uninstall() { + List selectedLibraries = new ArrayList<>(table.getSelectionCount()); + for (TableItem item : table.getSelection()) { + selectedLibraries.add((ArduinoLibrary) item.getData()); + } + try { + container.run(true, true, monitor -> { + try { + manager.uninstallLibraries(selectedLibraries, monitor); + } catch (CoreException e) { + Activator.log(e); + } + }); + } catch (InterruptedException | InvocationTargetException e) { + Activator.log(e); + return; + } + populateTable(); + } + + private void checkForUpdates() { + Collection updates = new ArrayList<>(); + try { + container.run(true, true, monitor -> { + try { + for (ArduinoLibrary available : manager.getAvailableLibraries(monitor)) { + ArduinoLibrary installed = manager.getInstalledLibrary(available.getName()); + if (installed != null) { + if (ArduinoManager.compareVersions(available.getVersion(), installed.getVersion()) > 0) { + updates.add(available); + } + } + } + } catch (CoreException e) { + getDisplay().syncExec(() -> ErrorDialog.openError(getShell(), null, null, e.getStatus())); + Activator.log(e); + } + }); + + if (updates.isEmpty()) { + MessageDialog.openInformation(getShell(), "Library Updates", "All libraries are up to date"); + return; + } + } catch (InvocationTargetException | InterruptedException e) { + Activator.log(e); + return; + } + + if (updates.isEmpty()) { + MessageDialog.openInformation(getShell(), "Platform Updates", "All platforms are up to date"); + return; + } else { + UpdateLibrariesDialog updateDialog = new UpdateLibrariesDialog(getShell(), updates); + if (updateDialog.open() == Window.OK) { + Collection toUpdate = updateDialog.getSelectedLibraries(); + if (!toUpdate.isEmpty()) { + try { + container.run(true, true, monitor -> { + try { + manager.installLibraries(toUpdate, monitor); + } catch (CoreException e) { + getDisplay() + .syncExec(() -> ErrorDialog.openError(getShell(), null, null, e.getStatus())); + Activator.log(e); + } + }); + } catch (InvocationTargetException | InterruptedException e) { + Activator.log(e); + } + populateTable(); + } + } + } + } + + private void addLibraries() { + try { + container.run(true, true, monitor -> { + try { + availableLibraries = manager.getAvailableLibraries(monitor); + } catch (CoreException e) { + getDisplay().syncExec(() -> ErrorDialog.openError(getShell(), null, null, e.getStatus())); + Activator.log(e); + } + }); + + SelectLibrariesDialog selectDialog = new SelectLibrariesDialog(getShell()); + selectDialog.setLibraries(availableLibraries); + if (selectDialog.open() == Window.OK) { + Collection selectedLibraries = selectDialog.getChecked(); + container.run(true, true, monitor -> { + try { + manager.installLibraries(selectedLibraries, monitor); + } catch (CoreException e) { + Activator.log(e); + } + }); + } + populateTable(); + } catch (InterruptedException | InvocationTargetException e) { + Activator.log(e); + return; + } + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/OpenDownloadsManager.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/OpenDownloadsManager.java new file mode 100644 index 00000000000..05ddf1473b0 --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/OpenDownloadsManager.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems 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 + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.arduino.ui.internal.downloads; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.Status; + +public class OpenDownloadsManager extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + new ArduinoDownloadsManager().open(); + return Status.OK_STATUS; + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/PlatformsTabControl.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/PlatformsTabControl.java new file mode 100644 index 00000000000..2861a7d7fad --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/PlatformsTabControl.java @@ -0,0 +1,276 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems 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 + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.arduino.ui.internal.downloads; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; +import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform; +import org.eclipse.cdt.arduino.ui.internal.Activator; +import org.eclipse.cdt.arduino.ui.internal.FormTextHoverManager; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.IWizardContainer; +import org.eclipse.swt.SWT; +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.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +public class PlatformsTabControl extends Composite { + + private ArduinoManager manager = Activator.getService(ArduinoManager.class); + private Table table; + private IWizardContainer container; + private Collection availablePlatforms; + + public PlatformsTabControl(Composite parent, int style) { + super(parent, style); + setLayout(new GridLayout()); + + Text desc = new Text(this, SWT.READ_ONLY | SWT.WRAP); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false); + layoutData.widthHint = 500; + desc.setLayoutData(layoutData); + desc.setBackground(parent.getBackground()); + desc.setText("Installed Platforms. Details available in their tooltips"); + + Composite comp = new Composite(this, SWT.NONE); + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = 0; + comp.setLayout(layout); + comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + Composite tableComp = new Composite(comp, SWT.NONE); + tableComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + table = new Table(tableComp, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION); + table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + TableColumnLayout tableLayout = new TableColumnLayout(); + + TableColumn packageColumn = new TableColumn(table, SWT.LEAD); + packageColumn.setText("Package"); + tableLayout.setColumnData(packageColumn, new ColumnWeightData(2, 75, true)); + + TableColumn platformColumn = new TableColumn(table, SWT.LEAD); + platformColumn.setText("Platform"); + tableLayout.setColumnData(platformColumn, new ColumnWeightData(5, 150, true)); + + TableColumn versionColumn = new TableColumn(table, SWT.LEAD); + versionColumn.setText("Version"); + tableLayout.setColumnData(versionColumn, new ColumnWeightData(2, 75, true)); + + tableComp.setLayout(tableLayout); + + Composite buttonComp = new Composite(comp, SWT.NONE); + buttonComp.setLayout(new GridLayout()); + buttonComp.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false)); + + final Button uninstallButton = new Button(buttonComp, SWT.PUSH); + uninstallButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); + uninstallButton.setText("Uninstall"); + uninstallButton.setEnabled(false); + uninstallButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + uninstall(); + } + }); + + Button updatesButton = new Button(buttonComp, SWT.PUSH); + updatesButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); + updatesButton.setText("Updates"); + updatesButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + checkForUpdates(); + } + }); + + Button addButton = new Button(buttonComp, SWT.PUSH); + addButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); + addButton.setText("Add"); + addButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + addPlatforms(); + } + }); + + populateTable(); + + table.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TableItem[] selection = table.getSelection(); + uninstallButton.setEnabled(selection.length > 0); + } + }); + + FormTextHoverManager hoverManager = new FormTextHoverManager() { + @Override + protected void computeInformation() { + TableItem item = table.getItem(getHoverEventLocation()); + if (item != null) { + ArduinoPlatform platform = (ArduinoPlatform) item.getData(); + setInformation(platform.toFormText(), item.getBounds()); + } else { + setInformation(null, null); + } + } + }; + hoverManager.install(table); + } + + @Override + public boolean setFocus() { + return table.setFocus(); + } + + public void setContainer(IWizardContainer container) { + this.container = container; + } + + private void populateTable() { + table.removeAll(); + try { + List platforms = new ArrayList<>(manager.getInstalledPlatforms()); + Collections.sort(platforms, new Comparator() { + @Override + public int compare(ArduinoPlatform o1, ArduinoPlatform o2) { + return o1.getName().compareTo(o2.getName()); + } + }); + + for (ArduinoPlatform platform : platforms) { + TableItem item = new TableItem(table, SWT.NONE); + item.setData(platform); + item.setText(0, platform.getPackage().getName()); + item.setText(1, platform.getName()); + item.setText(2, platform.getVersion()); + } + + } catch (CoreException e) { + Activator.log(e); + } + } + + private void uninstall() { + List selectedPlatforms = new ArrayList<>(table.getSelectionCount()); + for (TableItem item : table.getSelection()) { + selectedPlatforms.add((ArduinoPlatform) item.getData()); + } + try { + container.run(true, true, monitor -> manager.uninstallPlatforms(selectedPlatforms, monitor)); + } catch (InterruptedException | InvocationTargetException e) { + Activator.log(e); + return; + } + populateTable(); + } + + private void checkForUpdates() { + Collection updates = new ArrayList<>(); + try { + container.run(true, true, monitor -> { + try { + for (ArduinoPlatform available : manager.getAvailablePlatforms(monitor)) { + ArduinoPlatform installed = manager.getInstalledPlatform(available.getPackage().getName(), + available.getArchitecture()); + if (installed != null) { + if (ArduinoManager.compareVersions(available.getVersion(), installed.getVersion()) > 0) { + updates.add(available); + } + } + } + } catch (CoreException e) { + getDisplay().syncExec(() -> ErrorDialog.openError(getShell(), null, null, e.getStatus())); + Activator.log(e); + } + }); + } catch (InvocationTargetException | InterruptedException e) { + Activator.log(e); + return; + } + + if (updates.isEmpty()) { + MessageDialog.openInformation(getShell(), "Platform Updates", "All platforms are up to date"); + return; + } else { + UpdatePlatformsDialog updateDialog = new UpdatePlatformsDialog(getShell(), updates); + if (updateDialog.open() == Window.OK) { + Collection toUpdate = updateDialog.getSelectedPlatforms(); + if (!toUpdate.isEmpty()) { + try { + container.run(true, true, monitor -> { + try { + manager.installPlatforms(toUpdate, monitor); + } catch (CoreException e) { + getDisplay() + .syncExec(() -> ErrorDialog.openError(getShell(), null, null, e.getStatus())); + Activator.log(e); + } + }); + } catch (InvocationTargetException | InterruptedException e) { + Activator.log(e); + } + populateTable(); + } + } + } + } + + private void addPlatforms() { + try { + container.run(true, true, monitor -> { + try { + availablePlatforms = manager.getAvailablePlatforms(monitor); + } catch (CoreException e) { + getDisplay().syncExec(() -> ErrorDialog.openError(getShell(), null, null, e.getStatus())); + Activator.log(e); + } + }); + + SelectPlatformsDialog selectDialog = new SelectPlatformsDialog(getShell()); + selectDialog.setPlatforms(availablePlatforms); + if (selectDialog.open() == Window.OK) { + Collection selectedPlatforms = selectDialog.getSelectedPlatforms(); + container.run(true, true, monitor -> { + try { + manager.installPlatforms(selectedPlatforms, monitor); + } catch (CoreException e) { + Activator.log(e); + } + }); + } + populateTable(); + } catch (InterruptedException | InvocationTargetException e) { + Activator.log(e); + return; + } + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/SelectLibrariesDialog.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/SelectLibrariesDialog.java new file mode 100644 index 00000000000..d8536da43f9 --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/SelectLibrariesDialog.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems 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 + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.arduino.ui.internal.downloads; + +import java.util.Collection; + +import org.eclipse.cdt.arduino.core.internal.board.ArduinoLibrary; +import org.eclipse.cdt.arduino.ui.internal.FormTextHoverManager; +import org.eclipse.cdt.arduino.ui.internal.LibraryTree; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; + +public class SelectLibrariesDialog extends Dialog { + + private Collection libraries; + private Collection checkedLibraries; + private LibraryTree libraryTree; + + public SelectLibrariesDialog(Shell parentShell) { + super(parentShell); + } + + @Override + protected boolean isResizable() { + return true; + } + + @Override + protected Point getInitialSize() { + Point size = super.getInitialSize(); + if (size.x < 600 || size.y < 400) { + return new Point(600, 400); + } else { + return size; + } + } + + public void setLibraries(Collection libraries) { + this.libraries = libraries; + } + + public Collection getChecked() { + return checkedLibraries; + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite comp = new Composite(parent, SWT.NONE); + comp.setLayoutData(new GridData(GridData.FILL_BOTH)); + comp.setLayout(new GridLayout()); + + libraryTree = new LibraryTree(comp); + libraryTree.setLayoutData(new GridData(GridData.FILL_BOTH)); + libraryTree.setIncludePlatforms(false); + libraryTree.getViewer().setInput(libraries); + + FormTextHoverManager hoverManager = new FormTextHoverManager() { + @Override + protected void computeInformation() { + TreeViewer viewer = libraryTree.getViewer(); + Tree tree = viewer.getTree(); + TreeItem item = tree.getItem(getHoverEventLocation()); + if (item != null) { + Object data = item.getData(); + if (data instanceof ArduinoLibrary) { + ArduinoLibrary library = (ArduinoLibrary) data; + setInformation(library.toFormText(), item.getBounds()); + } + } else { + setInformation(null, null); + } + } + }; + hoverManager.install(libraryTree.getViewer().getTree()); + + applyDialogFont(comp); + return comp; + } + + @Override + protected void okPressed() { + checkedLibraries = libraryTree.getChecked(); + super.okPressed(); + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/SelectPlatformsDialog.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/SelectPlatformsDialog.java new file mode 100644 index 00000000000..3118a84daae --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/SelectPlatformsDialog.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems 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 + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.arduino.ui.internal.downloads; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; +import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform; +import org.eclipse.cdt.arduino.ui.internal.FormTextHoverManager; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; + +public class SelectPlatformsDialog extends Dialog { + + private Collection platforms; + private Collection selectedPlatforms; + private Table table; + + protected SelectPlatformsDialog(Shell parentShell) { + super(parentShell); + } + + @Override + protected boolean isResizable() { + return true; + } + + @Override + protected Point getInitialSize() { + Point size = super.getInitialSize(); + if (size.x < 500 || size.y < 300) { + return new Point(500, 300); + } else { + return size; + } + } + + public void setPlatforms(Collection platforms) { + this.platforms = platforms; + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite comp = new Composite(parent, SWT.NONE); + comp.setLayoutData(new GridData(GridData.FILL_BOTH)); + + table = new Table(comp, SWT.CHECK | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION); + table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + TableColumnLayout tableLayout = new TableColumnLayout(); + + TableColumn packageColumn = new TableColumn(table, SWT.LEAD); + packageColumn.setText("Package"); + tableLayout.setColumnData(packageColumn, new ColumnWeightData(2, 75, true)); + + TableColumn platformColumn = new TableColumn(table, SWT.LEAD); + platformColumn.setText("Platform"); + tableLayout.setColumnData(platformColumn, new ColumnWeightData(5, 150, true)); + + TableColumn versionColumn = new TableColumn(table, SWT.LEAD); + versionColumn.setText("Version"); + tableLayout.setColumnData(versionColumn, new ColumnWeightData(2, 75, true)); + + comp.setLayout(tableLayout); + + for (ArduinoPlatform platform : ArduinoManager.getSortedPlatforms(platforms)) { + TableItem item = new TableItem(table, SWT.NONE); + item.setData(platform); + item.setText(0, platform.getPackage().getName()); + item.setText(1, platform.getName()); + item.setText(2, platform.getVersion()); + } + + FormTextHoverManager hoverManager = new FormTextHoverManager() { + @Override + protected void computeInformation() { + TableItem item = table.getItem(getHoverEventLocation()); + if (item != null) { + ArduinoPlatform platform = (ArduinoPlatform) item.getData(); + setInformation(platform.toFormText(), item.getBounds()); + } else { + setInformation(null, null); + } + } + }; + hoverManager.install(table); + + applyDialogFont(comp); + return comp; + } + + @Override + protected void okPressed() { + selectedPlatforms = new ArrayList<>(); + for (TableItem item : table.getItems()) { + if (item.getChecked()) { + selectedPlatforms.add((ArduinoPlatform) item.getData()); + } + } + + super.okPressed(); + } + + public Collection getSelectedPlatforms() { + return selectedPlatforms; + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/UpdateLibrariesDialog.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/UpdateLibrariesDialog.java new file mode 100644 index 00000000000..bf3796ccc5a --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/UpdateLibrariesDialog.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems 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 + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.arduino.ui.internal.downloads; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.cdt.arduino.core.internal.board.ArduinoLibrary; +import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; +import org.eclipse.cdt.arduino.ui.internal.Activator; +import org.eclipse.cdt.arduino.ui.internal.FormTextHoverManager; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; + +public class UpdateLibrariesDialog extends Dialog { + + private final Collection libraries; + private Collection selectedLibraries; + private Table table; + + protected UpdateLibrariesDialog(Shell parentShell, Collection libraries) { + super(parentShell); + this.libraries = libraries; + } + + @Override + protected boolean isResizable() { + return true; + } + + @Override + protected Point getInitialSize() { + Point size = super.getInitialSize(); + if (size.x < 500 || size.y < 300) { + return new Point(500, 300); + } else { + return size; + } + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite comp = new Composite(parent, SWT.NONE); + comp.setLayoutData(new GridData(GridData.FILL_BOTH)); + + table = new Table(comp, SWT.CHECK | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION); + table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + TableColumnLayout tableLayout = new TableColumnLayout(); + + TableColumn platformColumn = new TableColumn(table, SWT.LEAD); + platformColumn.setText("Library"); + tableLayout.setColumnData(platformColumn, new ColumnWeightData(5, 150, true)); + + TableColumn versionColumn = new TableColumn(table, SWT.LEAD); + versionColumn.setText("Current"); + tableLayout.setColumnData(versionColumn, new ColumnWeightData(2, 75, true)); + + TableColumn updateColumn = new TableColumn(table, SWT.LEAD); + updateColumn.setText("Available"); + tableLayout.setColumnData(updateColumn, new ColumnWeightData(2, 75, true)); + + comp.setLayout(tableLayout); + + ArduinoManager manager = Activator.getService(ArduinoManager.class); + for (ArduinoLibrary library : ArduinoManager.getSortedLibraries(libraries)) { + try { + ArduinoLibrary installed = manager.getInstalledLibrary(library.getName()); + TableItem item = new TableItem(table, SWT.NONE); + item.setData(library); + item.setText(0, library.getName()); + item.setText(1, installed.getVersion()); + item.setText(2, library.getVersion()); + } catch (CoreException e) { + Activator.log(e); + } + } + + FormTextHoverManager hoverManager = new FormTextHoverManager() { + @Override + protected void computeInformation() { + TableItem item = table.getItem(getHoverEventLocation()); + if (item != null) { + ArduinoLibrary library = (ArduinoLibrary) item.getData(); + setInformation(library.toFormText(), item.getBounds()); + } else { + setInformation(null, null); + } + } + }; + hoverManager.install(table); + + applyDialogFont(comp); + return comp; + } + + @Override + protected void okPressed() { + selectedLibraries = new ArrayList<>(); + for (TableItem item : table.getItems()) { + if (item.getChecked()) { + selectedLibraries.add((ArduinoLibrary) item.getData()); + } + } + + super.okPressed(); + } + + public Collection getSelectedLibraries() { + return selectedLibraries; + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/UpdatePlatformsDialog.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/UpdatePlatformsDialog.java new file mode 100644 index 00000000000..5488cccb461 --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/UpdatePlatformsDialog.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems 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 + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.arduino.ui.internal.downloads; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; +import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform; +import org.eclipse.cdt.arduino.ui.internal.Activator; +import org.eclipse.cdt.arduino.ui.internal.FormTextHoverManager; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; + +public class UpdatePlatformsDialog extends Dialog { + + private final Collection platforms; + private Collection selectedPlatforms; + private Table table; + + protected UpdatePlatformsDialog(Shell parentShell, Collection platforms) { + super(parentShell); + this.platforms = platforms; + } + + @Override + protected boolean isResizable() { + return true; + } + + @Override + protected Point getInitialSize() { + Point size = super.getInitialSize(); + if (size.x < 500 || size.y < 300) { + return new Point(500, 300); + } else { + return size; + } + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite comp = new Composite(parent, SWT.NONE); + comp.setLayoutData(new GridData(GridData.FILL_BOTH)); + + table = new Table(comp, SWT.CHECK | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION); + table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + TableColumnLayout tableLayout = new TableColumnLayout(); + + TableColumn packageColumn = new TableColumn(table, SWT.LEAD); + packageColumn.setText("Package"); + tableLayout.setColumnData(packageColumn, new ColumnWeightData(2, 75, true)); + + TableColumn platformColumn = new TableColumn(table, SWT.LEAD); + platformColumn.setText("Platform"); + tableLayout.setColumnData(platformColumn, new ColumnWeightData(5, 150, true)); + + TableColumn versionColumn = new TableColumn(table, SWT.LEAD); + versionColumn.setText("Current"); + tableLayout.setColumnData(versionColumn, new ColumnWeightData(2, 75, true)); + + TableColumn updateColumn = new TableColumn(table, SWT.LEAD); + updateColumn.setText("Available"); + tableLayout.setColumnData(updateColumn, new ColumnWeightData(2, 75, true)); + + comp.setLayout(tableLayout); + + ArduinoManager manager = Activator.getService(ArduinoManager.class); + for (ArduinoPlatform platform : ArduinoManager.getSortedPlatforms(platforms)) { + try { + ArduinoPlatform installed = manager.getInstalledPlatform(platform.getPackage().getName(), + platform.getArchitecture()); + TableItem item = new TableItem(table, SWT.NONE); + item.setData(platform); + item.setText(0, platform.getPackage().getName()); + item.setText(1, platform.getName()); + item.setText(2, installed.getVersion()); + item.setText(3, platform.getVersion()); + } catch (CoreException e) { + Activator.log(e); + } + } + + FormTextHoverManager hoverManager = new FormTextHoverManager() { + @Override + protected void computeInformation() { + TableItem item = table.getItem(getHoverEventLocation()); + if (item != null) { + ArduinoPlatform platform = (ArduinoPlatform) item.getData(); + setInformation(platform.toFormText(), item.getBounds()); + } else { + setInformation(null, null); + } + } + }; + hoverManager.install(table); + + applyDialogFont(comp); + return comp; + } + + @Override + protected void okPressed() { + selectedPlatforms = new ArrayList<>(); + for (TableItem item : table.getItems()) { + if (item.getChecked()) { + selectedPlatforms.add((ArduinoPlatform) item.getData()); + } + } + + super.okPressed(); + } + + public Collection getSelectedPlatforms() { + return selectedPlatforms; + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/messages.properties b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/messages.properties index bca27033acc..eb1d9049e7a 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/messages.properties +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/messages.properties @@ -23,22 +23,6 @@ LibrariesPropertyPage_1=Description LibrariesPropertyPage_desc=Select libraries to use in your project and click OK or Apply. \ If necessary the library will be installed. By adding libraries you agree to the licenses of those \ libraries. For more information, see http://arduino.cc -ArduinoPlatformsPreferencePage_0=Select a platform then click a button to install, uninstall, or find more details about the platform. -ArduinoPlatformsPreferencePage_1=Platform -ArduinoPlatformsPreferencePage_10=Information on the licenses can be found at arduino.cc web site. -ArduinoPlatformsPreferencePage_11=Arduino License -ArduinoPlatformsPreferencePage_12=Accept -ArduinoPlatformsPreferencePage_13=Decline -ArduinoPlatformsPreferencePage_14=Installing Arduino Board Platforms -ArduinoPlatformsPreferencePage_15=Installing Arduino Board Platforms -ArduinoPlatformsPreferencePage_2=Installed -ArduinoPlatformsPreferencePage_3=Available -ArduinoPlatformsPreferencePage_4=Install -ArduinoPlatformsPreferencePage_5=Upgrade -ArduinoPlatformsPreferencePage_6=Details -ArduinoPlatformsPreferencePage_7=Install -ArduinoPlatformsPreferencePage_8=Uninstall -ArduinoPlatformsPreferencePage_9=Do you accept the licenses for the Arduino SDK and libraries? ArduinoPreferencePage_desc=Enter URLs for package_index.json files one per line. PlatformDetailsDialog_0=Platform: PlatformDetailsDialog_1=Supports boards:\n diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoPlatformsPreferencePage.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoPlatformsPreferencePage.java deleted file mode 100644 index bfbceb248b1..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoPlatformsPreferencePage.java +++ /dev/null @@ -1,264 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 QNX Software Systems 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 - * http://www.eclipse.org/legal/epl-v10.html - *******************************************************************************/ -package org.eclipse.cdt.arduino.ui.internal.preferences; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; - -import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoPackage; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform; -import org.eclipse.cdt.arduino.core.internal.board.PackageIndex; -import org.eclipse.cdt.arduino.ui.internal.Activator; -import org.eclipse.cdt.arduino.ui.internal.Messages; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.core.runtime.jobs.Job; -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.swt.SWT; -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.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; - -public class ArduinoPlatformsPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { - - private Table table; - private Button installButton; - private Button uninstallButton; - private Button detailButton; - - private Collection toInstall = new HashSet<>(); - private Collection toUninstall = new HashSet<>(); - - private static ArduinoManager manager = Activator.getService(ArduinoManager.class); - - @Override - public void init(IWorkbench workbench) { - } - - @Override - protected Control createContents(Composite parent) { - Composite control = new Composite(parent, SWT.NONE); - control.setLayout(new GridLayout()); - - Text desc = new Text(control, SWT.READ_ONLY | SWT.WRAP); - GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false); - layoutData.widthHint = 500; - desc.setLayoutData(layoutData); - desc.setBackground(parent.getBackground()); - desc.setText(Messages.ArduinoPlatformsPreferencePage_0); - - Composite comp = new Composite(control, SWT.NONE); - GridLayout layout = new GridLayout(2, false); - layout.marginWidth = 0; - comp.setLayout(layout); - comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - Composite tableComp = new Composite(comp, SWT.NONE); - tableComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - table = new Table(tableComp, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION); - table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - table.setHeaderVisible(true); - table.setLinesVisible(true); - - TableColumn platformColumn = new TableColumn(table, SWT.LEAD); - platformColumn.setText(Messages.ArduinoPlatformsPreferencePage_1); - TableColumn installedColumn = new TableColumn(table, SWT.LEAD); - installedColumn.setText(Messages.ArduinoPlatformsPreferencePage_2); - TableColumn availableColumn = new TableColumn(table, SWT.LEAD); - availableColumn.setText(Messages.ArduinoPlatformsPreferencePage_3); - - TableColumnLayout tableLayout = new TableColumnLayout(); - tableLayout.setColumnData(platformColumn, new ColumnWeightData(5, 150, true)); - tableLayout.setColumnData(installedColumn, new ColumnWeightData(2, 75, true)); - tableLayout.setColumnData(availableColumn, new ColumnWeightData(2, 75, true)); - tableComp.setLayout(tableLayout); - - table.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - TableItem[] selection = table.getSelection(); - if (selection.length > 0) { - TableItem item = selection[0]; - detailButton.setEnabled(true); - ArduinoPlatform aplat = (ArduinoPlatform) item.getData(); - ArduinoPlatform iplat = aplat.getPackage().getInstalledPlatforms().get(aplat.getName()); - if (iplat == null) { - installButton.setEnabled(true); - installButton.setText(Messages.ArduinoPlatformsPreferencePage_4); - uninstallButton.setEnabled(false); - } else { - installButton.setText(Messages.ArduinoPlatformsPreferencePage_5); - if (!aplat.getVersion().equals(iplat.getVersion())) { - // Assuming upgrade if not equal, dangerous - installButton.setEnabled(true); - } else { - installButton.setEnabled(false); - } - uninstallButton.setEnabled(true); - } - } else { - detailButton.setEnabled(false); - installButton.setEnabled(false); - uninstallButton.setEnabled(false); - } - } - }); - - Composite buttonComp = new Composite(comp, SWT.NONE); - buttonComp.setLayout(new GridLayout()); - buttonComp.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false)); - - detailButton = new Button(buttonComp, SWT.PUSH); - detailButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); - detailButton.setText(Messages.ArduinoPlatformsPreferencePage_6); - detailButton.setEnabled(false); - detailButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - TableItem[] selection = table.getSelection(); - // We are only enabled when there is a selection - ArduinoPlatform platform = (ArduinoPlatform) selection[0].getData(); - PlatformDetailsDialog dialog = new PlatformDetailsDialog(getShell(), platform); - dialog.open(); - } - }); - - installButton = new Button(buttonComp, SWT.PUSH); - installButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); - installButton.setText(Messages.ArduinoPlatformsPreferencePage_7); - installButton.setEnabled(false); - installButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - TableItem[] selection = table.getSelection(); - if (selection.length > 0) { - TableItem item = selection[0]; - toInstall.add(((ArduinoPlatform) item.getData())); - item.setImage(Activator.getDefault().getImageRegistry().get(Activator.IMG_ADD)); - } - } - }); - - uninstallButton = new Button(buttonComp, SWT.PUSH); - uninstallButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); - uninstallButton.setText(Messages.ArduinoPlatformsPreferencePage_8); - uninstallButton.setEnabled(false); - uninstallButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - TableItem[] selection = table.getSelection(); - if (selection.length > 0) { - TableItem item = selection[0]; - toUninstall.add(((ArduinoPlatform) item.getData())); - item.setImage(Activator.getDefault().getImageRegistry().get(Activator.IMG_DELETE)); - } - } - }); - - populateTable(); - - return control; - } - - private void populateTable() { - table.removeAll(); - for (PackageIndex packageIndex : manager.getPackageIndices()) { - for (ArduinoPackage pkg : packageIndex.getPackages()) { - Map available = pkg.getAvailablePlatforms(); - Map installed = pkg.getInstalledPlatforms(); - List names = new ArrayList<>(available.keySet()); - Collections.sort(names); - for (String name : names) { - TableItem item = new TableItem(table, SWT.NONE); - item.setText(0, name); - ArduinoPlatform iplat = installed.get(name); - item.setText(1, iplat != null ? iplat.getVersion() : "---"); //$NON-NLS-1$ - ArduinoPlatform aplat = available.get(name); - item.setText(2, aplat.getVersion()); - item.setData(aplat); - } - } - } - } - - @Override - public boolean performOk() { - File acceptedFile = ArduinoPreferences.getArduinoHome().resolve(".accepted").toFile(); //$NON-NLS-1$ - if (!acceptedFile.exists()) { - String message = Messages.ArduinoPlatformsPreferencePage_9 + Messages.ArduinoPlatformsPreferencePage_10; - MessageDialog dialog = new MessageDialog(getShell(), - Messages.ArduinoPlatformsPreferencePage_11, null, message, MessageDialog.QUESTION, new String[] { - Messages.ArduinoPlatformsPreferencePage_12, Messages.ArduinoPlatformsPreferencePage_13 }, - 0); - int rc = dialog.open(); - if (rc == 0) { - try { - acceptedFile.createNewFile(); - } catch (IOException e) { - Activator.log(e); - } - } else { - return false; - } - } - - new Job(Messages.ArduinoPlatformsPreferencePage_14) { - @Override - protected IStatus run(IProgressMonitor monitor) { - MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, 0, Messages.ArduinoPlatformsPreferencePage_15, - null); - - for (ArduinoPlatform platform : toUninstall) { - status.add(platform.uninstall(monitor)); - } - toUninstall.clear(); - - for (ArduinoPlatform platform : toInstall) { - status.add(platform.install(monitor)); - } - toInstall.clear(); - - if (table != null && !table.isDisposed()) { - table.getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - populateTable(); - } - }); - } - - return status; - } - }.schedule(); - return true; - } - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoPreferencePage.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoPreferencePage.java index 8aaaf4b7450..55414d233e9 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoPreferencePage.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoPreferencePage.java @@ -11,8 +11,6 @@ package org.eclipse.cdt.arduino.ui.internal.preferences; import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; -import org.eclipse.cdt.arduino.ui.internal.Activator; import org.eclipse.cdt.arduino.ui.internal.Messages; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.swt.SWT; @@ -54,7 +52,6 @@ public class ArduinoPreferencePage extends PreferencePage implements IWorkbenchP @Override public boolean performOk() { ArduinoPreferences.setBoardUrls(urlsText.getText()); - Activator.getService(ArduinoManager.class).loadIndices(); return true; } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/PlatformDetailsDialog.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/PlatformDetailsDialog.java deleted file mode 100644 index 20037f4333c..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/PlatformDetailsDialog.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 QNX Software Systems 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 - * http://www.eclipse.org/legal/epl-v10.html - *******************************************************************************/ -package org.eclipse.cdt.arduino.ui.internal.preferences; - -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform; -import org.eclipse.cdt.arduino.ui.internal.Messages; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -public class PlatformDetailsDialog extends Dialog { - - private final ArduinoPlatform platform; - - protected PlatformDetailsDialog(Shell parentShell, ArduinoPlatform platform) { - super(parentShell); - setShellStyle(getShellStyle() | SWT.RESIZE); - this.platform = platform; - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite control = (Composite) super.createDialogArea(parent); - - Text text = new Text(control, SWT.BORDER | SWT.READ_ONLY | SWT.MULTI | SWT.V_SCROLL); - text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - StringBuilder str = new StringBuilder(); - - str.append(Messages.PlatformDetailsDialog_0); - str.append(platform.getName()); - str.append('\n'); - - str.append(Messages.PlatformDetailsDialog_1); - List boards = platform.getBoards(); - Collections.sort(boards, new Comparator() { - @Override - public int compare(ArduinoBoard o1, ArduinoBoard o2) { - return o1.getName().compareTo(o2.getName()); - } - }); - for (ArduinoBoard board : platform.getBoards()) { - str.append(" "); //$NON-NLS-1$ - str.append(board.getName()); - str.append('\n'); - } - - text.setText(str.toString()); - return control; - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); - } - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/LibrariesPropertyPage.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/LibrariesPropertyPage.java index 1a1a3a26dd2..c54e3f3d8b9 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/LibrariesPropertyPage.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/LibrariesPropertyPage.java @@ -7,158 +7,25 @@ *******************************************************************************/ package org.eclipse.cdt.arduino.ui.internal.project; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.cdt.arduino.core.internal.board.ArduinoLibrary; import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform; -import org.eclipse.cdt.arduino.core.internal.board.LibraryIndex; -import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration; import org.eclipse.cdt.arduino.ui.internal.Activator; +import org.eclipse.cdt.arduino.ui.internal.LibraryTree; import org.eclipse.cdt.arduino.ui.internal.Messages; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; -import org.eclipse.jface.viewers.BaseLabelProvider; -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTreeViewer; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.ICheckStateProvider; -import org.eclipse.jface.viewers.ITableLabelProvider; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.TreeViewer; -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.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeColumn; -import org.eclipse.ui.dialogs.FilteredTree; -import org.eclipse.ui.dialogs.PatternFilter; import org.eclipse.ui.dialogs.PropertyPage; public class LibrariesPropertyPage extends PropertyPage { private static ArduinoManager manager = Activator.getService(ArduinoManager.class); - private Set checkedLibs; - private class ContentProvider implements ITreeContentProvider { - private LibraryIndex index; - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - index = (LibraryIndex) newInput; - } - - @Override - public void dispose() { - } - - @Override - public boolean hasChildren(Object element) { - if (element instanceof LibraryIndex) { - return true; - } else if (element instanceof String) { // category - return true; - } else if (element instanceof ArduinoLibrary) { - return false; - } else { - return false; - } - } - - @Override - public Object getParent(Object element) { - if (element instanceof ArduinoLibrary) { - ArduinoLibrary lib = (ArduinoLibrary) element; - String category = lib.getCategory(); - return category != null ? category : LibraryIndex.UNCATEGORIZED; - } else if (element instanceof String || element instanceof ArduinoPlatform) { - return index; - } else { - return null; - } - } - - @Override - public Object[] getElements(Object inputElement) { - Set categories = new HashSet<>(); - categories.addAll(((LibraryIndex) inputElement).getCategories()); - - try { - for (ArduinoLibrary lib : getPlatform().getLibraries()) { - String category = lib.getCategory(); - categories.add(category != null ? category : LibraryIndex.UNCATEGORIZED); - } - } catch (CoreException e) { - Activator.log(e); - } - - return categories.toArray(); - } - - @Override - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof String) { - String category = (String) parentElement; - List libs = new ArrayList<>(); - libs.addAll(index.getLibraries(category)); - try { - for (ArduinoLibrary lib : getPlatform().getLibraries()) { - String cat = lib.getCategory(); - if (cat != null) { - if (cat.equals(category)) { - libs.add(lib); - } - } else if (category.equals(LibraryIndex.UNCATEGORIZED)) { // cat - // == - // null - libs.add(lib); - } - } - } catch (CoreException e) { - Activator.log(e); - } - return libs.toArray(); - } else { - return new Object[0]; - } - } - } - - private static class LabelProvider extends BaseLabelProvider implements ITableLabelProvider { - @Override - public Image getColumnImage(Object element, int columnIndex) { - return null; - } - - @Override - public String getColumnText(Object element, int columnIndex) { - if (element instanceof String) { - return columnIndex == 0 ? (String) element : null; - } else if (element instanceof ArduinoLibrary) { - switch (columnIndex) { - case 0: - return ((ArduinoLibrary) element).getName(); - case 1: - return ((ArduinoLibrary) element).getSentence(); - default: - return null; - } - } else { - return null; - } - } - - } - - private FilteredTree filteredTree; + private LibraryTree libraryTree; @Override protected Control createContents(Composite parent) { @@ -172,97 +39,14 @@ public class LibrariesPropertyPage extends PropertyPage { desc.setBackground(parent.getBackground()); desc.setText(Messages.LibrariesPropertyPage_desc); - filteredTree = new FilteredTree(comp, SWT.CHECK | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL, - new PatternFilter() { - @Override - protected boolean isLeafMatch(Viewer viewer, Object element) { - if (element instanceof String) { - return wordMatches((String) element); - } else if (element instanceof ArduinoLibrary) { - ArduinoLibrary lib = (ArduinoLibrary) element; - return wordMatches(lib.getName()) || wordMatches(lib.getSentence()) - || wordMatches(lib.getParagraph()); - } else { - return false; - } - } - }, true) { - - @Override - protected TreeViewer doCreateTreeViewer(Composite parent, int style) { - CheckboxTreeViewer viewer = new CheckboxTreeViewer(parent, style); - viewer.setCheckStateProvider(new ICheckStateProvider() { - @Override - public boolean isGrayed(Object element) { - if (element instanceof String) { - for (ArduinoLibrary lib : checkedLibs) { - if (element.equals(lib.getCategory())) { - return true; - } - } - } - return false; - } - - @Override - public boolean isChecked(Object element) { - if (element instanceof ArduinoLibrary) { - return checkedLibs.contains(element); - } else if (element instanceof String) { - for (ArduinoLibrary lib : checkedLibs) { - if (element.equals(lib.getCategory())) { - return true; - } - } - } - - return false; - } - }); - viewer.addCheckStateListener(new ICheckStateListener() { - @Override - public void checkStateChanged(CheckStateChangedEvent event) { - Object element = event.getElement(); - if (element instanceof ArduinoLibrary) { - if (event.getChecked()) { - checkedLibs.add((ArduinoLibrary) element); - } else { - checkedLibs.remove(element); - } - } else if (element instanceof String) { - if (!event.getChecked()) { - for (ArduinoLibrary lib : new ArrayList<>(checkedLibs)) { - if (element.equals(lib.getCategory())) { - checkedLibs.remove(lib); - } - } - } - } - } - }); - return viewer; - } - }; - filteredTree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - TreeViewer viewer = filteredTree.getViewer(); - - Tree tree = viewer.getTree(); - tree.setHeaderVisible(true); - TreeColumn column1 = new TreeColumn(tree, SWT.LEFT); - column1.setText(Messages.LibrariesPropertyPage_0); - column1.setWidth(200); - TreeColumn column2 = new TreeColumn(tree, SWT.LEFT); - column2.setText(Messages.LibrariesPropertyPage_1); - column2.setWidth(200); - - viewer.setContentProvider(new ContentProvider()); - viewer.setLabelProvider(new LabelProvider()); + libraryTree = new LibraryTree(comp); + libraryTree.setLayoutData(new GridData(GridData.FILL_BOTH)); try { IProject project = getElement().getAdapter(IProject.class); - checkedLibs = new HashSet<>(manager.getLibraries(project)); - viewer.setInput(manager.getLibraryIndex()); + libraryTree.setIncludePlatforms(true); + libraryTree.setChecked(manager.getLibraries(project)); + libraryTree.getViewer().setInput(manager.getInstalledLibraries()); } catch (CoreException e) { Activator.log(e); } @@ -274,14 +58,10 @@ public class LibrariesPropertyPage extends PropertyPage { return getElement().getAdapter(IProject.class); } - private ArduinoPlatform getPlatform() throws CoreException { - return getProject().getActiveBuildConfig().getAdapter(ArduinoBuildConfiguration.class).getBoard().getPlatform(); - } - @Override public boolean performOk() { try { - manager.setLibraries(getProject(), checkedLibs); + manager.setLibraries(getProject(), libraryTree.getChecked()); } catch (CoreException e) { Activator.log(e); } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/ArduinoTargetPropertyPage.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/ArduinoTargetPropertyPage.java index 1b848f57268..63cdd9dbaaa 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/ArduinoTargetPropertyPage.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/ArduinoTargetPropertyPage.java @@ -100,9 +100,9 @@ public class ArduinoTargetPropertyPage extends PropertyPage implements IWorkbenc workingCopy.setAttribute(ArduinoRemoteConnection.PORT_NAME, portName); ArduinoBoard board = boards[boardSelector.getSelectionIndex()]; - workingCopy.setAttribute(ArduinoRemoteConnection.BOARD_NAME, board.getName()); + workingCopy.setAttribute(ArduinoRemoteConnection.BOARD_NAME, board.getId()); ArduinoPlatform platform = board.getPlatform(); - workingCopy.setAttribute(ArduinoRemoteConnection.PLATFORM_NAME, platform.getName()); + workingCopy.setAttribute(ArduinoRemoteConnection.PLATFORM_NAME, platform.getArchitecture()); ArduinoPackage pkg = platform.getPackage(); workingCopy.setAttribute(ArduinoRemoteConnection.PACKAGE_NAME, pkg.getName()); diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/BoardPropertyControl.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/BoardPropertyControl.java index ada2671dfb5..b0bfacd1808 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/BoardPropertyControl.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/BoardPropertyControl.java @@ -88,7 +88,8 @@ public class BoardPropertyControl extends Composite { boardCombo = new Combo(this, SWT.READ_ONLY); boardCombo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); try { - List boardList = Activator.getService(ArduinoManager.class).getInstalledBoards(); + List boardList = new ArrayList<>( + Activator.getService(ArduinoManager.class).getInstalledBoards()); Collections.sort(boardList, new Comparator() { @Override public int compare(ArduinoBoard o1, ArduinoBoard o2) { @@ -189,10 +190,10 @@ public class BoardPropertyControl extends Composite { public void apply(IRemoteConnectionWorkingCopy workingCopy) { workingCopy.setAttribute(ArduinoRemoteConnection.PORT_NAME, portName); - workingCopy.setAttribute(ArduinoRemoteConnection.BOARD_NAME, board.getName()); + workingCopy.setAttribute(ArduinoRemoteConnection.BOARD_NAME, board.getId()); ArduinoPlatform platform = board.getPlatform(); - workingCopy.setAttribute(ArduinoRemoteConnection.PLATFORM_NAME, platform.getName()); + workingCopy.setAttribute(ArduinoRemoteConnection.PLATFORM_NAME, platform.getArchitecture()); ArduinoPackage pkg = platform.getPackage(); workingCopy.setAttribute(ArduinoRemoteConnection.PACKAGE_NAME, pkg.getName());