46
46
* The base class for the main processing application.
47
47
* Primary role of this class is for platform identification and
48
48
* 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.
50
50
*/
51
51
public class Base {
52
52
// Added accessors for 0218 because the UpdateCheck class was not properly
@@ -55,6 +55,9 @@ public class Base {
55
55
/** This might be replaced by main() if there's a lib/version.txt file. */
56
56
static private String VERSION_NAME = "1276" ; //$NON-NLS-1$
57
57
58
+ static final String SKETCH_BUNDLE_EXT = ".pskz" ;
59
+ static final String CONTRIB_BUNDLE_EXT = ".pcbz" ;
60
+
58
61
/**
59
62
* True if heavy debugging error/log messages are enabled. Set to true
60
63
* if an empty file named 'debug' is found in the settings folder.
@@ -168,7 +171,7 @@ static private void createAndShowGUI(String[] args) {
168
171
DEBUG = true ;
169
172
}
170
173
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
172
175
JPopupMenu .setDefaultLightWeightPopupEnabled (false );
173
176
174
177
// Don't put anything above this line that might make GUI,
@@ -285,7 +288,7 @@ static private void handleWelcomeScreen(Base base) {
285
288
}
286
289
287
290
288
- // Remove this code in a couple months [fry 170211]
291
+ // Remove this code in a couple of months [fry 170211]
289
292
// https://github.com/processing/processing/issues/4853
290
293
// Or maybe not, if NVIDIA keeps doing this [fry 170423]
291
294
// https://github.com/processing/processing/issues/4997
@@ -1302,6 +1305,41 @@ public String getDescription() {
1302
1305
* Open a sketch from the path specified. Do not use for untitled sketches.
1303
1306
*/
1304
1307
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
+
1305
1343
return handleOpen (path , false );
1306
1344
}
1307
1345
@@ -1645,35 +1683,6 @@ public void populateSketchbookMenu(JMenu menu) {
1645
1683
}
1646
1684
1647
1685
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
-
1677
1686
/**
1678
1687
* Scan a folder recursively, and add any sketches found to the menu
1679
1688
* specified. Set the openReplaces parameter to true when opening the sketch
@@ -1711,12 +1720,6 @@ protected boolean addSketches(JMenu menu, File folder) {
1711
1720
ActionListener listener = e -> {
1712
1721
String path = e .getActionCommand ();
1713
1722
if (new File (path ).exists ()) {
1714
- /*
1715
- boolean replace = replaceExisting;
1716
- if ((e.getModifiers() & ActionEvent.SHIFT_MASK) != 0) {
1717
- replace = !replace;
1718
- }
1719
- */
1720
1723
handleOpen (path );
1721
1724
} else {
1722
1725
Messages .showWarning ("Sketch Disappeared" ,
@@ -1730,41 +1733,51 @@ protected boolean addSketches(JMenu menu, File folder) {
1730
1733
1731
1734
boolean found = false ;
1732
1735
1733
- // for (int i = 0; i < list.length; i++) {
1734
- // if ((list[i].charAt(0) == '.') ||
1735
- // list[i].equals("CVS")) continue;
1736
1736
for (String name : list ) {
1737
1737
if (name .charAt (0 ) == '.' ) {
1738
1738
continue ;
1739
1739
}
1740
1740
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
+ }
1745
1745
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 );
1750
1769
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
- }
1761
1770
}
1762
1771
}
1763
1772
}
1764
1773
return found ;
1765
1774
}
1766
1775
1767
1776
1777
+ /**
1778
+ * Mostly identical to the JMenu version above, however the rules are
1779
+ * slightly different for how examples are handled, etc.
1780
+ */
1768
1781
public boolean addSketches (DefaultMutableTreeNode node , File folder ,
1769
1782
boolean examples ) throws IOException {
1770
1783
// skip .DS_Store files, etc (this shouldn't actually be necessary)
@@ -1809,25 +1822,30 @@ public boolean addSketches(DefaultMutableTreeNode node, File folder,
1809
1822
continue ;
1810
1823
}
1811
1824
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
+ }
1818
1833
1819
- node .add (item );
1820
- found = true ;
1834
+ if (sketchFile != null ) {
1835
+ DefaultMutableTreeNode item =
1836
+ new DefaultMutableTreeNode (new SketchReference (name , sketchFile ));
1821
1837
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 ;
1831
1849
}
1832
1850
}
1833
1851
}
@@ -1840,10 +1858,10 @@ public boolean addSketches(DefaultMutableTreeNode node, File folder,
1840
1858
* Because the default mode will be the first in the list, this will always
1841
1859
* prefer that one over the others.
1842
1860
*/
1843
- File checkSketchFolder (File subfolder , String item ) {
1861
+ private File checkSketchFolder (File folder ) {
1844
1862
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$
1847
1865
if (entry .exists ()) {
1848
1866
return entry ;
1849
1867
}
0 commit comments