Skip to content

Commit e09f7d1

Browse files
committed
initial support for reading sketches from a zipped file
1 parent cef4787 commit e09f7d1

File tree

3 files changed

+163
-124
lines changed

3 files changed

+163
-124
lines changed

app/src/processing/app/Base.java

Lines changed: 97 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
* The base class for the main processing application.
4747
* Primary role of this class is for platform identification and
4848
* general interaction with the system (launching URLs, loading
49-
* files and images, etc) that comes from that.
49+
* files and images, etc.) that comes from that.
5050
*/
5151
public class Base {
5252
// Added accessors for 0218 because the UpdateCheck class was not properly
@@ -55,6 +55,9 @@ public class Base {
5555
/** This might be replaced by main() if there's a lib/version.txt file. */
5656
static private String VERSION_NAME = "1276"; //$NON-NLS-1$
5757

58+
static final String SKETCH_BUNDLE_EXT = ".pskz";
59+
static final String CONTRIB_BUNDLE_EXT = ".pcbz";
60+
5861
/**
5962
* True if heavy debugging error/log messages are enabled. Set to true
6063
* if an empty file named 'debug' is found in the settings folder.
@@ -168,7 +171,7 @@ static private void createAndShowGUI(String[] args) {
168171
DEBUG = true;
169172
}
170173

171-
// Use native popups so they don't look so crappy on OS X
174+
// Use native popups so they don't look crappy on macOS
172175
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
173176

174177
// Don't put anything above this line that might make GUI,
@@ -285,7 +288,7 @@ static private void handleWelcomeScreen(Base base) {
285288
}
286289

287290

288-
// Remove this code in a couple months [fry 170211]
291+
// Remove this code in a couple of months [fry 170211]
289292
// https://github.com/processing/processing/issues/4853
290293
// Or maybe not, if NVIDIA keeps doing this [fry 170423]
291294
// https://github.com/processing/processing/issues/4997
@@ -1302,6 +1305,41 @@ public String getDescription() {
13021305
* Open a sketch from the path specified. Do not use for untitled sketches.
13031306
*/
13041307
public Editor handleOpen(String path) {
1308+
if (path.endsWith(SKETCH_BUNDLE_EXT)) {
1309+
File zipFile = new File(path);
1310+
try {
1311+
File destFolder = File.createTempFile("zip", "tmp", untitledFolder);
1312+
if (!destFolder.delete() || !destFolder.mkdirs()) {
1313+
// Hard to imagine why this would happen, but...
1314+
System.err.println("Could not create temporary folder " + destFolder);
1315+
return null;
1316+
}
1317+
Util.unzip(zipFile, destFolder);
1318+
File[] fileList = destFolder.listFiles(File::isDirectory);
1319+
if (fileList != null) {
1320+
if (fileList.length == 1) {
1321+
File sketchFile = checkSketchFolder(fileList[0]);
1322+
if (sketchFile != null) {
1323+
return handleOpen(sketchFile.getAbsolutePath(), true);
1324+
}
1325+
} else {
1326+
System.err.println("Expecting one folder inside " +
1327+
SKETCH_BUNDLE_EXT + " file, found " + fileList.length + ".");
1328+
}
1329+
} else {
1330+
System.err.println("Could not read " + destFolder);
1331+
}
1332+
} catch (IOException e) {
1333+
e.printStackTrace();
1334+
}
1335+
return null; // no luck
1336+
1337+
} else if (path.endsWith(CONTRIB_BUNDLE_EXT)) {
1338+
// TODO Install a contrib here
1339+
return null;
1340+
1341+
}
1342+
13051343
return handleOpen(path, false);
13061344
}
13071345

@@ -1645,35 +1683,6 @@ public void populateSketchbookMenu(JMenu menu) {
16451683
}
16461684

16471685

1648-
/*
1649-
public JMenu getRecentMenu() {
1650-
return recent.getMenu();
1651-
}
1652-
1653-
1654-
public JMenu getToolbarRecentMenu() {
1655-
return recent.getToolbarMenu();
1656-
}
1657-
1658-
1659-
public void handleRecent(Editor editor) {
1660-
recent.handle(editor);
1661-
}
1662-
1663-
1664-
public void handleRecentRename(Editor editor, String oldPath) {
1665-
recent.handleRename(editor, oldPath);
1666-
}
1667-
1668-
1669-
// Called before a sketch is renamed so that its old name is
1670-
// no longer in the menu.
1671-
public void removeRecent(Editor editor) {
1672-
recent.remove(editor);
1673-
}
1674-
*/
1675-
1676-
16771686
/**
16781687
* Scan a folder recursively, and add any sketches found to the menu
16791688
* specified. Set the openReplaces parameter to true when opening the sketch
@@ -1711,12 +1720,6 @@ protected boolean addSketches(JMenu menu, File folder) {
17111720
ActionListener listener = e -> {
17121721
String path = e.getActionCommand();
17131722
if (new File(path).exists()) {
1714-
/*
1715-
boolean replace = replaceExisting;
1716-
if ((e.getModifiers() & ActionEvent.SHIFT_MASK) != 0) {
1717-
replace = !replace;
1718-
}
1719-
*/
17201723
handleOpen(path);
17211724
} else {
17221725
Messages.showWarning("Sketch Disappeared",
@@ -1730,41 +1733,51 @@ protected boolean addSketches(JMenu menu, File folder) {
17301733

17311734
boolean found = false;
17321735

1733-
// for (int i = 0; i < list.length; i++) {
1734-
// if ((list[i].charAt(0) == '.') ||
1735-
// list[i].equals("CVS")) continue;
17361736
for (String name : list) {
17371737
if (name.charAt(0) == '.') {
17381738
continue;
17391739
}
17401740

1741-
File subfolder = new File(folder, name);
1742-
if (subfolder.isDirectory()) {
1743-
File entry = checkSketchFolder(subfolder, name);
1744-
if (entry != null) {
1741+
// TODO Is this necessary any longer? This seems gross [fry 210804]
1742+
if (name.equals("old")) { // Don't add old contributions
1743+
continue;
1744+
}
17451745

1746-
JMenuItem item = new JMenuItem(name);
1747-
item.addActionListener(listener);
1748-
item.setActionCommand(entry.getAbsolutePath());
1749-
menu.add(item);
1746+
File entry = new File(folder, name);
1747+
File sketchFile = null;
1748+
if (entry.isDirectory()) {
1749+
sketchFile = checkSketchFolder(entry);
1750+
} else if (name.toLowerCase().endsWith(SKETCH_BUNDLE_EXT)) {
1751+
name = name.substring(0, name.length() - SKETCH_BUNDLE_EXT.length());
1752+
sketchFile = entry;
1753+
}
1754+
1755+
if (sketchFile != null) {
1756+
JMenuItem item = new JMenuItem(name);
1757+
item.addActionListener(listener);
1758+
item.setActionCommand(sketchFile.getAbsolutePath());
1759+
menu.add(item);
1760+
found = true;
1761+
1762+
} else if (entry.isDirectory()) {
1763+
// not a sketch folder, but may be a subfolder containing sketches
1764+
JMenu submenu = new JMenu(name);
1765+
// needs to be separate var otherwise would set found to false
1766+
boolean anything = addSketches(submenu, entry);
1767+
if (anything) {
1768+
menu.add(submenu);
17501769
found = true;
1751-
1752-
} else {
1753-
// not a sketch folder, but maybe a subfolder containing sketches
1754-
JMenu submenu = new JMenu(name);
1755-
// needs to be separate var otherwise would set found to false
1756-
boolean anything = addSketches(submenu, subfolder);
1757-
if (anything && !name.equals("old")) { //Don't add old contributions
1758-
menu.add(submenu);
1759-
found = true;
1760-
}
17611770
}
17621771
}
17631772
}
17641773
return found;
17651774
}
17661775

17671776

1777+
/**
1778+
* Mostly identical to the JMenu version above, however the rules are
1779+
* slightly different for how examples are handled, etc.
1780+
*/
17681781
public boolean addSketches(DefaultMutableTreeNode node, File folder,
17691782
boolean examples) throws IOException {
17701783
// skip .DS_Store files, etc (this shouldn't actually be necessary)
@@ -1809,25 +1822,30 @@ public boolean addSketches(DefaultMutableTreeNode node, File folder,
18091822
continue;
18101823
}
18111824

1812-
File subfolder = new File(folder, name);
1813-
if (subfolder.isDirectory()) {
1814-
File entry = checkSketchFolder(subfolder, name);
1815-
if (entry != null) {
1816-
DefaultMutableTreeNode item =
1817-
new DefaultMutableTreeNode(new SketchReference(name, entry));
1825+
File entry = new File(folder, name);
1826+
File sketchFile = null;
1827+
if (entry.isDirectory()) {
1828+
sketchFile = checkSketchFolder(entry);
1829+
} else if (name.toLowerCase().endsWith(SKETCH_BUNDLE_EXT)) {
1830+
name = name.substring(0, name.length() - SKETCH_BUNDLE_EXT.length());
1831+
sketchFile = entry;
1832+
}
18181833

1819-
node.add(item);
1820-
found = true;
1834+
if (sketchFile != null) {
1835+
DefaultMutableTreeNode item =
1836+
new DefaultMutableTreeNode(new SketchReference(name, sketchFile));
18211837

1822-
} else {
1823-
// not a sketch folder, but maybe a subfolder containing sketches
1824-
DefaultMutableTreeNode subNode = new DefaultMutableTreeNode(name);
1825-
// needs to be separate var otherwise would set found to false
1826-
boolean anything = addSketches(subNode, subfolder, examples);
1827-
if (anything) {
1828-
node.add(subNode);
1829-
found = true;
1830-
}
1838+
node.add(item);
1839+
found = true;
1840+
1841+
} else if (entry.isDirectory()) {
1842+
// not a sketch folder, but maybe a subfolder containing sketches
1843+
DefaultMutableTreeNode subNode = new DefaultMutableTreeNode(name);
1844+
// needs to be separate var otherwise would set found to false
1845+
boolean anything = addSketches(subNode, entry, examples);
1846+
if (anything) {
1847+
node.add(subNode);
1848+
found = true;
18311849
}
18321850
}
18331851
}
@@ -1840,10 +1858,10 @@ public boolean addSketches(DefaultMutableTreeNode node, File folder,
18401858
* Because the default mode will be the first in the list, this will always
18411859
* prefer that one over the others.
18421860
*/
1843-
File checkSketchFolder(File subfolder, String item) {
1861+
private File checkSketchFolder(File folder) {
18441862
for (Mode mode : getModeList()) {
1845-
File entry = new File(subfolder, item + "." + mode.getDefaultExtension()); //$NON-NLS-1$
1846-
// if a .pde file of the same prefix as the folder exists..
1863+
// Test whether a .pde file of the same name as its parent folder exists.
1864+
File entry = new File(folder, folder.getName() + "." + mode.getDefaultExtension()); //$NON-NLS-1$
18471865
if (entry.exists()) {
18481866
return entry;
18491867
}

build/build.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,18 @@
548548
role="Editor">
549549
</bundledocument>
550550

551+
<bundledocument extensions="pskz"
552+
icon="macosx/document.icns"
553+
name="Processing Sketch Bundle"
554+
role="Editor">
555+
</bundledocument>
556+
557+
<bundledocument extensions="pcbz"
558+
icon="macosx/document.icns"
559+
name="Processing Contribution Bundle"
560+
role="None">
561+
</bundledocument>
562+
551563
<!-- !@#*&$ the @2x splash screen implementation was removed by Oracle -->
552564
<!-- tiffutil -cathidpicheck about.png about\@2x.png -out about.tiff -->
553565
<!--<option value="-splash:$APP_ROOT/Contents/Java/lib/about.png" />-->

0 commit comments

Comments
 (0)