1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-01-17 06:52:18 +01:00

Merge branch 'master' of github.com:arduino/Arduino

This commit is contained in:
Fede85 2013-05-13 21:25:16 +02:00
commit bd240670ba
6 changed files with 247 additions and 41 deletions

View File

@ -28,9 +28,12 @@ import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import processing.app.debug.Compiler;
import processing.app.debug.Target;
import processing.app.helpers.FileUtils;
import processing.app.helpers.filefilters.OnlyDirs;
import processing.app.tools.ZipDeflater;
import processing.core.*;
import static processing.app.I18n._;
@ -949,9 +952,10 @@ public class Base {
JMenuItem addLibraryMenuItem = new JMenuItem(_("Add Library..."));
addLibraryMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Base.this.handleAddZipLibrary(editor);
Base.this.handleAddLibrary(editor);
Base.this.onBoardOrPortChange();
Base.this.rebuildImportMenu(Editor.importMenu, editor);
Base.this.rebuildExamplesMenu(Editor.examplesMenu);
}
});
importMenu.add(addLibraryMenuItem);
@ -2374,24 +2378,70 @@ public class Base {
}
}
public void handleAddLibrary(Editor editor) {
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"));
public void handleAddZipLibrary(Editor editor) {
String prompt = _("Select a zip file containing the library you'd like to add");
FileDialog fd = new FileDialog(editor, prompt, FileDialog.LOAD);
fd.setDirectory(System.getProperty("user.home"));
fd.setVisible(true);
Dimension preferredSize = fileChooser.getPreferredSize();
fileChooser.setPreferredSize(new Dimension(preferredSize.width + 200, preferredSize.height + 200));
String directory = fd.getDirectory();
String filename = fd.getFile();
if (filename == null) return;
int returnVal = fileChooser.showOpenDialog(editor);
if (returnVal != JFileChooser.APPROVE_OPTION) {
return;
}
File sourceFile = fileChooser.getSelectedFile();
File tmpFolder = null;
File sourceFile = new File(directory, filename);
try {
ZipDeflater zipDeflater = new ZipDeflater(sourceFile, getSketchbookLibrariesFolder());
zipDeflater.deflate();
// 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 a library"));
}
sourceFile = foldersInTmpFolder[0];
} catch (IOException e) {
editor.statusError(e);
return;
}
}
// is there a valid library?
File libFolder = sourceFile;
String libName = libFolder.getName();
if (!Sketch.isSanitaryName(libName)) {
String mess = I18n.format(_("The library \"{0}\" cannot be used.\n"
+ "Library names must contain only basic letters and numbers.\n"
+ "(ASCII only and no spaces, and it cannot start with a number)"),
libName);
editor.statusError(mess);
return;
}
// copy folder
File destinationFolder = new File(getSketchbookLibrariesFolder(), sourceFile.getName());
if (!destinationFolder.mkdir()) {
editor.statusError(I18n.format(_("A library named {0} already exists"), sourceFile.getName()));
return;
}
try {
FileUtils.copy(sourceFile, destinationFolder);
} catch (IOException e) {
editor.statusError(e);
return;
}
editor.statusNotice(_("Library added to your libraries. Check \"Import library\" menu"));
} catch (IOException e) {
editor.statusError(e);
} finally {
// delete zip created temp folder, if exists
FileUtils.recursiveDelete(tmpFolder);
}
}
}

View File

@ -177,7 +177,7 @@ public class Editor extends JFrame implements RunnerListener {
// re-add the sub-menus that are shared by all windows
fileMenu.insert(sketchbookMenu, 2);
fileMenu.insert(examplesMenu, 3);
//sketchMenu.insert(importMenu, 4);
sketchMenu.insert(importMenu, 4);
toolsMenu.insert(boardsMenu, numTools);
toolsMenu.insert(serialMenu, numTools + 1);
}
@ -188,7 +188,7 @@ public class Editor extends JFrame implements RunnerListener {
// System.err.println("deactivate"); // not coming through
fileMenu.remove(sketchbookMenu);
fileMenu.remove(examplesMenu);
//sketchMenu.remove(importMenu);
sketchMenu.remove(importMenu);
toolsMenu.remove(boardsMenu);
toolsMenu.remove(serialMenu);
}

View File

@ -0,0 +1,93 @@
package processing.app.helpers;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
public class FileUtils {
/**
* Checks, whether the child directory is a subdirectory of the base directory.
*
* @param base
* the base directory.
* @param child
* the suspected child directory.
* @return true, if the child is a subdirectory of the base directory.
*/
public static boolean isSubDirectory(File base, File child) {
try {
base = base.getCanonicalFile();
child = child.getCanonicalFile();
} catch (IOException e) {
return false;
}
File parentFile = child;
while (parentFile != null) {
if (base.equals(parentFile)) {
return true;
}
parentFile = parentFile.getParentFile();
}
return false;
}
public static void copy(File sourceFolder, File destFolder) throws IOException {
for (File file : sourceFolder.listFiles()) {
File destFile = new File(destFolder, file.getName());
if (file.isDirectory()) {
if (!destFile.mkdir()) {
throw new IOException("Unable to create folder: " + destFile);
}
copy(file, destFile);
} else {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(file);
fos = new FileOutputStream(destFile);
byte[] buf = new byte[4096];
int readBytes = -1;
while ((readBytes = fis.read(buf, 0, buf.length)) != -1) {
fos.write(buf, 0, readBytes);
}
} finally {
if (fis != null) {
fis.close();
}
if (fos != null) {
fos.close();
}
}
}
}
}
public static void recursiveDelete(File file) {
if (file == null) {
return;
}
if (file.isDirectory()) {
for (File current : file.listFiles()) {
if (current.isDirectory()) {
recursiveDelete(current);
} else {
current.delete();
}
}
}
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;
}
}

View File

@ -0,0 +1,42 @@
/*
OnlyDirs - FilenameFilter that accepts only directories (CVS, .svn,
.DS_Store files are excluded as well)
Part of the Arduino project - http://www.arduino.cc/
Copyright (c) 2011 Cristian Maglie
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package processing.app.helpers.filefilters;
import java.io.File;
import java.io.FilenameFilter;
/**
* This filter accepts only directories (excluding .DS_Store files, .svn
* folders, etc)
*
* @author Cristian Maglie
*/
public class OnlyDirs implements FilenameFilter {
public boolean accept(File dir, String name) {
if (name.charAt(0) == '.')
return false;
if (name.equals("CVS"))
return false;
return new File(dir, name).isDirectory();
}
}

View File

@ -10,30 +10,36 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import processing.app.helpers.FileUtils;
public class ZipDeflater {
private final ZipFile zipFile;
private final File destFolder;
private final Random random;
private final File file;
public ZipDeflater(File file, File destFolder) throws ZipException, IOException {
this.file = file;
this.destFolder = destFolder;
this.zipFile = new ZipFile(file);
this.random = new Random();
}
public void deflate() throws IOException {
String folderName = tempFolderNameFromZip();
String tmpFolderName = folderNameFromZip() + random.nextInt(1000000);
File folder = new File(destFolder, folderName);
File tmpFolder = new File(destFolder, tmpFolderName);
if (!folder.mkdir()) {
throw new IOException("Unable to create folder " + folderName);
if (!tmpFolder.mkdir()) {
throw new IOException("Unable to create folder " + tmpFolderName);
}
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
ensureFoldersOfEntryExist(folder, entry);
File entryFile = new File(folder, entry.getName());
ensureFoldersOfEntryExist(tmpFolder, entry);
File entryFile = new File(tmpFolder, entry.getName());
if (entry.isDirectory()) {
entryFile.mkdir();
} else {
@ -58,8 +64,20 @@ public class ZipDeflater {
}
}
// Test.zip may or may not contain Test folder. We use zip name to create libraries folder. Therefore, a contained Test folder is useless and must be removed
ensureOneLevelFolder(folder);
deleteUndesiredFoldersAndFiles(tmpFolder);
// Test.zip may or may not contain Test folder. If it does, we keep it. If not, we use zip name.
ensureOneLevelFolder(tmpFolder);
}
private void deleteUndesiredFoldersAndFiles(File folder) {
for (File file : folder.listFiles()) {
if (file.isDirectory() && "__MACOSX".equals(file.getName())) {
FileUtils.recursiveDelete(file);
} else if (file.getName().startsWith(".")) {
FileUtils.recursiveDelete(file);
}
}
}
private void ensureFoldersOfEntryExist(File folder, ZipEntry entry) {
@ -73,25 +91,22 @@ public class ZipDeflater {
private void ensureOneLevelFolder(File folder) {
File[] files = folder.listFiles();
if (files.length == 1 && files[0].isDirectory()) {
File tempFile = new File(files[0].getPath() + new Random().nextInt(1000));
files[0].renameTo(tempFile);
for (File file : tempFile.listFiles()) {
file.renameTo(new File(folder, file.getName()));
}
tempFile.delete();
if (files.length != 1) {
folder.renameTo(new File(folder.getParentFile(), folderNameFromZip()));
return;
}
files[0].renameTo(new File(folder.getParentFile(), files[0].getName()));
FileUtils.recursiveDelete(folder);
}
private String tempFolderNameFromZip() {
String folderName = zipFile.getName();
if (folderName.lastIndexOf(".") != -1) {
folderName = folderName.substring(0, folderName.lastIndexOf("."));
private String folderNameFromZip() {
String filename = file.getName();
if (filename.lastIndexOf(".") != -1) {
filename = filename.substring(0, filename.lastIndexOf("."));
}
if (folderName.lastIndexOf(File.separator) != -1) {
folderName = folderName.substring(folderName.lastIndexOf(File.separator) + 1);
}
return folderName;
return filename;
}
}

View File

@ -1,15 +1,18 @@
ARDUINO 1.0.5 - 2013.04.08
ARDUINO 1.0.5 - 2013.05.15
[core]
* [avr] malloc bug: backported avr-libc 1.8.0 implementation
* [avr] removed deprecated interrupt handlers causing compiler issues
with newer avr-gcc.
* [avr] added c_str() method to String
* [avr] Stream "_timeout" field and related methods are now protected
[libraries]
* Upgrades to WiFi library
* Fixed a bunch of examples
[firmwares]
@ -17,7 +20,10 @@ ARDUINO 1.0.5 - 2013.04.08
[ide]
* Backport from 1.5: install Library from file
* Backport from 1.5: install Library from .zip file or folder
* Added button "Copy error to clipboard" (Paul Stoffregen)
* Updated windows drivers
* Added Windows installer
ARDUINO 1.0.4 - 2013.03.11