1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-02-21 15:54:39 +01:00

Merge remote-tracking branch 'origin/master' into merge-1.0.1

This commit is contained in:
Cristian Maglie 2012-10-18 20:31:51 +02:00
commit 05a2d77f15
25 changed files with 226 additions and 145 deletions

View File

@ -2596,24 +2596,43 @@ 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);
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);
File sourceFile = new File(directory, filename);
if (returnVal != JFileChooser.APPROVE_OPTION) {
return;
}
File sourceFile = fileChooser.getSelectedFile();
if (sourceFile.isDirectory()) {
File destinationFolder = new File(getSketchbookLibrariesFolder(), sourceFile.getName());
if (!destinationFolder.mkdir()) {
editor.statusError("Can't create folder: " + sourceFile.getName() + " into libraries folder");
return;
}
try {
FileUtils.copy(sourceFile, destinationFolder);
} catch (IOException e) {
editor.statusError(e);
return;
}
} else {
try {
ZipDeflater zipDeflater = new ZipDeflater(sourceFile, getSketchbookLibrariesFolder());
zipDeflater.deflate();
editor.statusNotice(_("Library added to your libraries. Check \"Import library\" menu"));
} catch (IOException e) {
editor.statusError(e);
return;
}
}
editor.statusNotice(_("Library added to your libraries. Check \"Import library\" menu"));
}
}

View File

@ -634,10 +634,10 @@ public class Editor extends JFrame implements RunnerListener {
}
sketchMenu.add(importMenu);
item = new JMenuItem(_("Add Library from ZIP"));
item = new JMenuItem(_("Add Library..."));
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
base.handleAddZipLibrary(Editor.this);
base.handleAddLibrary(Editor.this);
base.onBoardOrPortChange();
base.rebuildImportMenu(Editor.importMenu);
}
@ -693,7 +693,7 @@ public class Editor extends JFrame implements RunnerListener {
if (boardsMenu == null) {
boardsMenu = new JMenu(_("Board"));
cpuTypeMenu = new JMenu(_("CPUType"));
cpuTypeMenu = new JMenu(_("Processor"));
base.rebuildBoardsMenu(boardsMenu, cpuTypeMenu);
//Debug: rebuild imports
importMenu.removeAll();

View File

@ -1,13 +1,14 @@
package processing.app.helpers;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileUtils {
/**
* Checks, whether the child directory is a subdirectory of the base
* directory.
* Checks, whether the child directory is a subdirectory of the base directory.
*
* @param base
* the base directory.
@ -32,4 +33,49 @@ public class FileUtils {
}
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.isDirectory()) {
for (File current : file.listFiles()) {
if (current.isDirectory()) {
recursiveDelete(current);
} else {
current.delete();
}
}
}
file.delete();
}
}

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;
}
private String tempFolderNameFromZip() {
String folderName = zipFile.getName();
if (folderName.lastIndexOf(".") != -1) {
folderName = folderName.substring(0, folderName.lastIndexOf("."));
files[0].renameTo(new File(folder.getParentFile(), files[0].getName()));
FileUtils.recursiveDelete(folder);
}
if (folderName.lastIndexOf(File.separator) != -1) {
folderName = folderName.substring(folderName.lastIndexOf(File.separator) + 1);
private String folderNameFromZip() {
String filename = file.getName();
if (filename.lastIndexOf(".") != -1) {
filename = filename.substring(0, filename.lastIndexOf("."));
}
return folderName;
return filename;
}
}

BIN
app/test/Keypad_mac.zip Normal file

Binary file not shown.

Binary file not shown.

View File

@ -10,7 +10,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import processing.app.tools.ZipDeflater;
import processing.app.helpers.FileUtils;
public class ZipDeflaterTest {
@ -62,20 +62,50 @@ public class ZipDeflaterTest {
assertEquals("readme.txt", files[4]);
}
@Test
public void shouldDeflateMacZip() throws Exception {
File file = new File(ZipDeflater.class.getResource("/Keypad_mac.zip").getFile());
new ZipDeflater(file, destFolder).deflate();
String[] files = destFolder.list();
assertEquals(1, files.length);
assertEquals("Keypad", files[0]);
file = destFolder.listFiles()[0];
files = file.list();
assertEquals(4, files.length);
Arrays.sort(files);
assertEquals("Keypad.cpp", files[0]);
assertEquals("Keypad.h", files[1]);
assertEquals("examples", files[2]);
assertEquals("keywords.txt", files[3]);
files = new File(file, "examples").list();
assertEquals(4, files.length);
Arrays.sort(files);
assertEquals("CustomKeypad", files[0]);
assertEquals("DynamicKeypad", files[1]);
assertEquals("EventKeypad", files[2]);
assertEquals("HelloKeypad", files[3]);
}
@Test
public void shouldDeleteHiddenFiles() throws Exception {
File file = new File(ZipDeflater.class.getResource("/Keypad_with_hidden_files.zip").getFile());
new ZipDeflater(file, destFolder).deflate();
String[] files = destFolder.list();
assertEquals(1, files.length);
assertEquals("Keypad_with_hidden_files", files[0]);
file = destFolder.listFiles()[0];
files = file.list();
assertEquals(4, files.length);
}
@After
public void deleteTempFolder() {
recursiveDelete(destFolder);
}
private void recursiveDelete(File folder) {
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
recursiveDelete(file);
} else {
file.delete();
}
}
folder.delete();
FileUtils.recursiveDelete(destFolder);
}
}

View File

@ -11,6 +11,7 @@
This example code is in the public domain.
*/
String stringOne, stringTwo;
void setup() {

View File

@ -11,6 +11,7 @@
This example code is in the public domain.
*/
String txtMsg = ""; // a string for incoming text
int lastStringLength = txtMsg.length(); // previous length of the String

View File

@ -51,7 +51,9 @@ char server[] = "api.cosm.com"; // name address for cosm API
unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
boolean lastConnected = false; // state of the connection last time through the main loop
const unsigned long postingInterval = 10*1000; //delay between updates to cosm.com
const unsigned long postingInterval = 10L*1000L; // delay between updates to cosm.com
// the "L" is needed to use long type numbers
void setup() {
// start serial port:

View File

@ -53,8 +53,8 @@ char server[] = "api.cosm.com"; // name address for Cosm API
unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
boolean lastConnected = false; // state of the connection last time through the main loop
const unsigned long postingInterval = 10*1000; //delay between updates to Cosm.com
const unsigned long postingInterval = 10L*1000L; // delay between updates to Cosm.com
// the "L" is needed to use long type numbers
void setup() {
// start serial port:
Serial.begin(9600);

View File

@ -41,7 +41,8 @@ char server[] = "www.arduino.cc";
unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
boolean lastConnected = false; // state of the connection last time through the main loop
const unsigned long postingInterval = 60*1000; // delay between updates, in milliseconds
const unsigned long postingInterval = 60L*1000L; // delay between updates, in milliseconds
// the "L" is needed to use long type numbers
void setup() {
// start serial port:

View File

@ -1,5 +1,5 @@
arduino_due_x_dbg.name=Arduino Due Dev. Ed. (Programming port)
arduino_due_x_dbg.name=Arduino Due (Programming Port)
arduino_due_x_dbg.upload.tool=bossac
arduino_due_x_dbg.upload.protocol=sam-ba
arduino_due_x_dbg.upload.maximum_size=524288
@ -16,7 +16,7 @@ arduino_due_x_dbg.build.variant_system_lib=libsam_sam3x8e_gcc_rel.a
arduino_due_x_dbg.build.vid=0x2341
arduino_due_x_dbg.build.pid=0x003e
arduino_due_x.name=Arduino Due Dev. Ed. (Native port)
arduino_due_x.name=Arduino Due (Native USB Port)
arduino_due_x.upload.tool=bossac
arduino_due_x.upload.protocol=sam-ba
arduino_due_x.upload.maximum_size=524288

View File

@ -51,7 +51,8 @@ char server[] = "api.cosm.com"; // name address for cosm API
unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
boolean lastConnected = false; // state of the connection last time through the main loop
const unsigned long postingInterval = 10*1000; //delay between updates to cosm.com
const unsigned long postingInterval = 10L*1000L; // delay between updates to cosm.com
// the "L" is needed to use long type numbers
void setup() {
// start serial port:

View File

@ -53,7 +53,8 @@ char server[] = "api.cosm.com"; // name address for Cosm API
unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
boolean lastConnected = false; // state of the connection last time through the main loop
const unsigned long postingInterval = 10*1000; //delay between updates to Cosm.com
const unsigned long postingInterval = 10L*1000L; // delay between updates to Cosm.com
// the "L" is needed to use long type numbers
void setup() {
// start serial port:

View File

@ -46,7 +46,6 @@ void setup() {
Serial.println("connecting...");
// if you get a connection, report back via serial:
if (client.connect(serverName, 80)) {
Serial.println("connected");
// Make a HTTP request:
@ -54,7 +53,7 @@ void setup() {
client.println();
}
else {
// kf you didn't get a connection to the server:
// if you didn't get a connection to the server:
Serial.println("connection failed");
}
}

View File

@ -1,5 +1,6 @@
/*
UDPSendReceive.pde:
UDPSendReceive
This sketch receives UDP message strings, prints them to the serial port
and sends an "acknowledge" string back to the sender
@ -10,6 +11,7 @@
by Michael Margolis
This code is in the public domain.
*/

View File

@ -1,5 +1,4 @@
/*
Udp NTP Client
Get the time from a Network Time Protocol (NTP) time server

View File

@ -52,7 +52,7 @@ void setup() {
client.println();
}
else {
// kf you didn't get a connection to the server:
// if you didn't get a connection to the server:
Serial.println("connection failed");
}
}

View File

@ -41,7 +41,8 @@ char server[] = "www.arduino.cc";
unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
boolean lastConnected = false; // state of the connection last time through the main loop
const unsigned long postingInterval = 60*1000; // delay between updates, in milliseconds
const unsigned long postingInterval = 60L*1000L; // delay between updates, in milliseconds
// the "L" is needed to use long type numbers
void setup() {
// start serial port:

View File

@ -1,37 +0,0 @@
#include <SPI.h>
// Flash memory is connected on SPI pin SS3
#define FLASH PIN_SPI_SS3
void setup() {
Serial.begin(9600);
// Start SPI with FLASH device
SPI.begin(FLASH);
// Half clock speed: we are too fast with 1
SPI.setClockDivider(FLASH, 2);
}
void loop() {
// Send "identify" command (9f) and receive response
// on the same SPI transaction. Parameter SPI_CONTINUE
// keeps the SS pin active.
Serial.println("Sending 'Identify' cmd to flash => 9F");
SPI.transfer(FLASH, 0x9f, SPI_CONTINUE);
char a1 = SPI.transfer(FLASH, 0x00, SPI_CONTINUE);
char a2 = SPI.transfer(FLASH, 0x00, SPI_CONTINUE);
char a3 = SPI.transfer(FLASH, 0x00, SPI_CONTINUE);
char a4 = SPI.transfer(FLASH, 0x00, SPI_CONTINUE);
char a5 = SPI.transfer(FLASH, 0x00);
// Print response over serial port
Serial.print("Received signature: ");
Serial.print(a1, HEX);
Serial.print(a2, HEX);
Serial.print(a3, HEX);
Serial.print(a4, HEX);
Serial.println(a5, HEX);
delay(1000);
}