diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 5e27138c0..19429e2c7 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -29,6 +29,7 @@ import java.util.*; import java.util.List; import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; import processing.app.debug.TargetPackage; import processing.app.debug.TargetPlatform; @@ -954,8 +955,19 @@ public class Base { return userLibs; } - public void rebuildImportMenu(JMenu importMenu) { + public void rebuildImportMenu(JMenu importMenu, final Editor editor) { importMenu.removeAll(); + + JMenuItem addLibraryMenuItem = new JMenuItem(_("Add Library...")); + addLibraryMenuItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Base.this.handleAddLibrary(editor); + Base.this.onBoardOrPortChange(); + Base.this.rebuildImportMenu(Editor.importMenu, editor); + Base.this.rebuildExamplesMenu(Editor.examplesMenu); + } + }); + importMenu.add(addLibraryMenuItem); // Split between user supplied libraries and IDE libraries Map ideLibs = getIDELibs(); @@ -1108,7 +1120,7 @@ public class Base { } - public void rebuildBoardsMenu(JMenu boardsMenu, final JMenu cpuTypeMenu) { + public void rebuildBoardsMenu(JMenu boardsMenu, final JMenu cpuTypeMenu, final Editor editor) { String selPackage = Preferences.get("target_package"); String selPlatform = Preferences.get("target_platform"); String selBoard = Preferences.get("board"); @@ -1172,7 +1184,7 @@ public class Base { onBoardOrPortChange(); Sketch.buildSettingChanged(); - rebuildImportMenu(Editor.importMenu); + rebuildImportMenu(Editor.importMenu, editor); rebuildExamplesMenu(Editor.examplesMenu); } }; @@ -2600,10 +2612,11 @@ public class Base { JFileChooser fileChooser = new JFileChooser(System.getProperty("user.home")); fileChooser.setDialogTitle(_("Select a zip file or a folder containing the library you'd like to add")); fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + fileChooser.setFileFilter(new FileNameExtensionFilter("ZIP files or folders", "zip")); Dimension preferredSize = fileChooser.getPreferredSize(); fileChooser.setPreferredSize(new Dimension(preferredSize.width + 200, preferredSize.height + 200)); - + int returnVal = fileChooser.showOpenDialog(editor); if (returnVal != JFileChooser.APPROVE_OPTION) { @@ -2611,11 +2624,42 @@ public class Base { } File sourceFile = fileChooser.getSelectedFile(); + File tmpFolder = null; - if (sourceFile.isDirectory()) { + try { + // unpack ZIP + if (!sourceFile.isDirectory()) { + try { + tmpFolder = FileUtils.createTempFolder(); + ZipDeflater zipDeflater = new ZipDeflater(sourceFile, tmpFolder); + zipDeflater.deflate(); + File[] foldersInTmpFolder = tmpFolder.listFiles(new OnlyDirs()); + if (foldersInTmpFolder.length != 1) { + throw new IOException("Zip doesn't contain one library"); + } + sourceFile = foldersInTmpFolder[0]; + } catch (IOException e) { + editor.statusError(e); + return; + } + } + + // is there a library? + File libFolder = scanFatLibrary(sourceFile); + if (libFolder == null) { + editor.statusError("Not a valid library"); + return; + } + String[] headerFiles = headerListFromIncludePath(libFolder); + if (headerFiles == null || headerFiles.length == 0) { + editor.statusError("Not a valid library"); + return; + } + + // copy folder File destinationFolder = new File(getSketchbookLibrariesFolder(), sourceFile.getName()); if (!destinationFolder.mkdir()) { - editor.statusError("Can't create folder: " + sourceFile.getName() + " into libraries folder"); + editor.statusError("A library named " + sourceFile.getName() + " already exists"); return; } try { @@ -2624,15 +2668,10 @@ public class Base { editor.statusError(e); return; } - } else { - try { - ZipDeflater zipDeflater = new ZipDeflater(sourceFile, getSketchbookLibrariesFolder()); - zipDeflater.deflate(); - } catch (IOException e) { - editor.statusError(e); - return; - } + editor.statusNotice(_("Library added to your libraries. Check \"Import library\" menu")); + } finally { + // delete zip created temp folder, if exists + FileUtils.recursiveDelete(tmpFolder); } - editor.statusNotice(_("Library added to your libraries. Check \"Import library\" menu")); } } diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index a34979552..536b36a13 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -630,20 +630,10 @@ public class Editor extends JFrame implements RunnerListener { if (importMenu == null) { importMenu = new JMenu(_("Import Library...")); - base.rebuildImportMenu(importMenu); + base.rebuildImportMenu(importMenu, this); } sketchMenu.add(importMenu); - item = new JMenuItem(_("Add Library...")); - item.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - base.handleAddLibrary(Editor.this); - base.onBoardOrPortChange(); - base.rebuildImportMenu(Editor.importMenu); - } - }); - sketchMenu.add(item); - item = newJMenuItem(_("Show Sketch Folder"), 'K'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -694,10 +684,10 @@ public class Editor extends JFrame implements RunnerListener { if (boardsMenu == null) { boardsMenu = new JMenu(_("Board")); cpuTypeMenu = new JMenu(_("Processor")); - base.rebuildBoardsMenu(boardsMenu, cpuTypeMenu); + base.rebuildBoardsMenu(boardsMenu, cpuTypeMenu, this); //Debug: rebuild imports importMenu.removeAll(); - base.rebuildImportMenu(importMenu); + base.rebuildImportMenu(importMenu, this); } menu.add(boardsMenu); menu.add(cpuTypeMenu); diff --git a/app/src/processing/app/helpers/FileUtils.java b/app/src/processing/app/helpers/FileUtils.java index 5902db40b..47c5b0a32 100644 --- a/app/src/processing/app/helpers/FileUtils.java +++ b/app/src/processing/app/helpers/FileUtils.java @@ -4,6 +4,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.util.Random; public class FileUtils { @@ -66,6 +67,9 @@ public class FileUtils { } public static void recursiveDelete(File file) { + if (file == null) { + return; + } if (file.isDirectory()) { for (File current : file.listFiles()) { if (current.isDirectory()) { @@ -78,4 +82,12 @@ public class FileUtils { file.delete(); } + public static File createTempFolder() throws IOException { + File tmpFolder = new File(System.getProperty("java.io.tmpdir"), "arduino_" + new Random().nextInt(1000000)); + if (!tmpFolder.mkdir()) { + throw new IOException("Unable to create temp folder " + tmpFolder); + } + return tmpFolder; + } + } diff --git a/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp b/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp index a6b319180..f4607d2f0 100644 --- a/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp +++ b/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp @@ -385,11 +385,14 @@ static bool USBD_SendDescriptor(Setup& setup) if (USB_DEVICE_DESCRIPTOR_TYPE == t) { TRACE_CORE(puts("=> USBD_SendDescriptor : USB_DEVICE_DESCRIPTOR_TYPE\r\n");) - if (setup.wLength == 8) + if (setup.wLength >= 8) { _cdcComposite = 1; } desc_addr = _cdcComposite ? (const uint8_t*)&USB_DeviceDescriptorA : (const uint8_t*)&USB_DeviceDescriptor; + if( *desc_addr > setup.wLength ) { + desc_length = setup.wLength; + } } else if (USB_STRING_DESCRIPTOR_TYPE == t) {