diff --git a/app/src/cc/arduino/view/preferences/Preferences.java b/app/src/cc/arduino/view/preferences/Preferences.java index 005d2f83e54..89af1f7df76 100644 --- a/app/src/cc/arduino/view/preferences/Preferences.java +++ b/app/src/cc/arduino/view/preferences/Preferences.java @@ -40,13 +40,17 @@ import processing.app.Theme; import processing.app.Theme.ZippedTheme; import processing.app.helpers.FileUtils; +import processing.app.javax.swing.filechooser.FileNameExtensionFilter; import processing.app.legacy.PApplet; import javax.swing.*; import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.WindowEvent; import java.io.File; +import java.io.IOException; import java.util.Collection; import java.util.LinkedList; @@ -792,7 +796,10 @@ private void savePreferencesData() { if (comboTheme.getSelectedIndex() == 0) { PreferencesData.set("theme.file", ""); } else { - PreferencesData.set("theme.file", ((ZippedTheme) comboTheme.getSelectedItem()).getKey()); + Object selectedItem = comboTheme.getSelectedItem(); + if(selectedItem instanceof ZippedTheme) { + PreferencesData.set("theme.file", ((ZippedTheme) selectedItem).getKey()); + } } String newSizeText = fontSizeField.getText(); @@ -869,6 +876,22 @@ private void showPreferencesData() { comboTheme.setSelectedItem(theme); } } + + // Allow install new themes. + String installItem = "-- " + tr( "Install from Zip" + " --"); + comboTheme.addItem(installItem); + + comboTheme.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + Object item = comboTheme.getSelectedItem(); + if (item != null && item.toString().startsWith(installItem)) { + SwingUtilities.invokeLater(() -> comboTheme.getUI().setPopupVisible(comboTheme, false)); + handleInstallTheme(); + } + } + }); Font editorFont = PreferencesData.getFont("editor.font"); fontSizeField.setText(String.valueOf(editorFont.getSize())); @@ -975,4 +998,40 @@ private void disableAllProxyFields() { autoProxyFieldsSetEnabled(false); manualProxyFieldsSetEnabled(false); } + + + public void handleInstallTheme() { + + JFileChooser fileChooser = new JFileChooser(System.getProperty("user.home")); + fileChooser.setDialogTitle(tr("Select a zip file containing the theme you'd like to add")); + fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + fileChooser.setFileFilter(new FileNameExtensionFilter(tr("ZIP files"), "zip")); + + Dimension preferredSize = fileChooser.getPreferredSize(); + fileChooser.setPreferredSize(new Dimension(preferredSize.width + 200, preferredSize.height + 200)); + + int returnVal = fileChooser.showOpenDialog(this); + + if (returnVal != JFileChooser.APPROVE_OPTION) { + return; + } + + File sourceFile = fileChooser.getSelectedFile(); + + if (!sourceFile.isDirectory()) { + try { + + ZippedTheme theme = Theme.install(sourceFile); + + if(theme != null) { + comboTheme.addItem(theme); + comboTheme.setSelectedItem(theme); + } + + } catch (IOException e) { + base.getActiveEditor().statusError(e); + return; + } + } + } } diff --git a/app/src/processing/app/Theme.java b/app/src/processing/app/Theme.java index d38875b3597..34c9d2b9d34 100644 --- a/app/src/processing/app/Theme.java +++ b/app/src/processing/app/Theme.java @@ -47,6 +47,8 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -66,6 +68,7 @@ import org.apache.batik.transcoder.image.PNGTranscoder; import org.apache.commons.compress.utils.IOUtils; import org.apache.commons.lang3.StringUtils; + import processing.app.helpers.OSUtils; import processing.app.helpers.PreferencesHelper; import processing.app.helpers.PreferencesMap; @@ -724,4 +727,30 @@ static URL getUrl(ZipEntry entry) { return null; } } + + /** + * Intalll theme in skecthboot + * @param zipTheme + */ + static public ZippedTheme install(File zipTheme) throws IOException{ + + // Validate... + ZippedTheme theme = ZippedTheme.load(NAMESPACE_USER, zipTheme); + + if(theme == null) { + throw new IOException(format(tr("Error loading theme: {0}"), zipTheme.getAbsolutePath())); + } + + // Create themes folder. + File themesFolder = new File(PreferencesData.get("sketchbook.path"), "theme"); + if (!themesFolder.exists()) { + themesFolder.mkdir(); + } + + // Copy + File dest = new File(themesFolder, zipTheme.getName()); + Files.copy(zipTheme.toPath(), dest.toPath(),StandardCopyOption.REPLACE_EXISTING); + + return theme; + } }