//----------------------------------------------------------------------------// // // // S c r i p t A c t i o n s // // // //----------------------------------------------------------------------------// // <editor-fold defaultstate="collapsed" desc="hdr"> // // Copyright © Hervé Bitteur and others 2000-2013. All rights reserved. // // This software is released under the GNU General Public License. // // Goto http://kenai.com/projects/audiveris to report bugs or suggestions. // //----------------------------------------------------------------------------// // </editor-fold> package omr.script; import omr.Main; import omr.WellKnowns; import omr.constant.Constant; import omr.constant.ConstantSet; import omr.score.Score; import omr.score.ui.ScoreController; import omr.sheet.ui.SheetActions; import omr.ui.util.OmrFileFilter; import omr.ui.util.UIUtil; import omr.util.BasicTask; import omr.util.Param; import org.jdesktop.application.Action; import org.jdesktop.application.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.awt.event.ActionEvent; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import javax.swing.JOptionPane; import javax.xml.bind.JAXBException; /** * Class {@code ScriptActions} gathers UI actions related to script * handling. These static member classes are ready to be picked by the plugins * mechanism. * * @author Hervé Bitteur */ public class ScriptActions extends SheetActions { //~ Static fields/initializers --------------------------------------------- /** Specific application parameters */ private static final Constants constants = new Constants(); /** Usual logger utility */ private static final Logger logger = LoggerFactory.getLogger( ScriptActions.class); /** Singleton */ private static ScriptActions INSTANCE; /** Default parameter. */ public static final Param<Boolean> defaultPrompt = new Default(); //~ Constructors ----------------------------------------------------------- //---------------// // ScriptActions // //---------------// /** * Not meant to be instantiated */ protected ScriptActions () { } //~ Methods ---------------------------------------------------------------- //-------------// // checkStored // //-------------// /** * Check whether the provided script has been safely saved if needed * (and therefore, if the sheet can be closed) * * @param script the script to check * @return true if close is allowed, false if not */ public static boolean checkStored (Script script) { if (script.isModified() && defaultPrompt.getSpecific()) { int answer = JOptionPane.showConfirmDialog( null, "Save script for score " + script.getScore().getRadix() + "?"); if (answer == JOptionPane.YES_OPTION) { Task<Void, Void> task = getInstance() .storeScript(null); if (task != null) { task.execute(); } // Here user has saved the script return true; } if (answer == JOptionPane.NO_OPTION) { // Here user specifically chooses NOT to save the script return true; } // // Here user says Oops!, cancelling the current close request return false; } else { return true; } } //-------------// // getInstance // //-------------// /** * Report the singleton * * @return the unique instance of this class */ public static synchronized ScriptActions getInstance () { if (INSTANCE == null) { INSTANCE = new ScriptActions(); } return INSTANCE; } //------------// // loadScript // //------------// @Action public Task<Void, Void> loadScript (ActionEvent e) { final File file = UIUtil.fileChooser( false, Main.getGui().getFrame(), new File(constants.defaultScriptDirectory.getValue()), new OmrFileFilter( "Score script files", new String[]{ScriptManager.SCRIPT_EXTENSION})); if (file != null) { return new LoadScriptTask(file); } else { return null; } } //-------------// // storeScript // //-------------// @Action(enabledProperty = SHEET_AVAILABLE) public Task<Void, Void> storeScript (ActionEvent e) { final Score score = ScoreController.getCurrentScore(); if (score == null) { return null; } final File scriptFile = score.getScriptFile(); if (scriptFile != null) { return new StoreScriptTask(score.getScript(), scriptFile); } else { return storeScriptAs(e); } } //---------------// // storeScriptAs // //---------------// @Action(enabledProperty = SHEET_AVAILABLE) public Task<Void, Void> storeScriptAs (ActionEvent e) { final Score score = ScoreController.getCurrentScore(); if (score == null) { return null; } // Let the user select a script output file File scriptFile = UIUtil.fileChooser( true, Main.getGui().getFrame(), getDefaultScriptFile(score), new OmrFileFilter( "Script files", new String[]{ScriptManager.SCRIPT_EXTENSION})); if (scriptFile != null) { return new StoreScriptTask(score.getScript(), scriptFile); } else { return null; } } //----------------------// // getDefaultScriptFile // //----------------------// /** * Report the default file where the script should be written to * * @param score the owning score * @return the default file for saving the script */ private File getDefaultScriptFile (Score score) { return (score.getScriptFile() != null) ? score.getScriptFile() : new File( constants.defaultScriptDirectory.getValue(), score.getRadix() + ScriptManager.SCRIPT_EXTENSION); } //~ Inner Classes ---------------------------------------------------------- //-----------// // Constants // //-----------// private static final class Constants extends ConstantSet { //~ Instance fields ---------------------------------------------------- /** Default directory for saved scripts */ Constant.String defaultScriptDirectory = new Constant.String( WellKnowns.DEFAULT_SCRIPTS_FOLDER.toString(), "Default directory for saved scripts"); /** User confirmation for closing unsaved script */ Constant.Boolean closeConfirmation = new Constant.Boolean( true, "Should we ask confirmation for closing a sheet with unsaved script?"); } //---------// // Default // //---------// private static class Default extends Param<Boolean> { //~ Methods ------------------------------------------------------------ @Override public Boolean getSpecific () { return constants.closeConfirmation.getValue(); } @Override public boolean setSpecific (Boolean specific) { if (!getSpecific() .equals(specific)) { constants.closeConfirmation.setValue(specific); logger.info( "You will {} be prompted to save script when" + " closing score", specific ? "now" : "no longer"); return true; } else { return false; } } } //----------------// // LoadScriptTask // //----------------// private static class LoadScriptTask extends BasicTask { //~ Instance fields ---------------------------------------------------- private File file; //~ Constructors ------------------------------------------------------- LoadScriptTask (File file) { this.file = file; } //~ Methods ------------------------------------------------------------ @Override protected Void doInBackground () throws InterruptedException { // Actually run the script logger.info("Running script file {} ...", file); try { final Script script = ScriptManager.getInstance() .load( new FileInputStream(file)); if (logger.isDebugEnabled()) { script.dump(); } // Remember (even across runs) the parent directory constants.defaultScriptDirectory.setValue(file.getParent()); script.run(); } catch (FileNotFoundException ex) { logger.warn("Cannot find script file {}", file); } return null; } } //-----------------// // StoreScriptTask // //-----------------// private static class StoreScriptTask extends BasicTask { //~ Instance fields ---------------------------------------------------- private Script script; private File file; //~ Constructors ------------------------------------------------------- StoreScriptTask (Script script, File file) { this.script = script; this.file = file; } //~ Methods ------------------------------------------------------------ @Override protected Void doInBackground () throws InterruptedException { FileOutputStream fos = null; try { File folder = new File(file.getParent()); if (folder.mkdirs()) { logger.info("Creating folder {}", folder); } fos = new FileOutputStream(file); omr.script.ScriptManager.getInstance() .store(script, fos); logger.info("Script stored as {}", file); constants.defaultScriptDirectory.setValue(file.getParent()); script.getScore() .setScriptFile(file); } catch (FileNotFoundException ex) { logger.warn("Cannot find script file " + file, ex); } catch (JAXBException ex) { logger.warn("Cannot marshal script", ex); } catch (Throwable ex) { logger.warn("Error storing script", ex); } finally { if (fos != null) { try { fos.close(); } catch (IOException ignored) { } } } return null; } } }