//----------------------------------------------------------------------------// // // // S t e p M e n u // // // //----------------------------------------------------------------------------// // <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.step; import omr.script.StepTask; import omr.sheet.Sheet; import omr.sheet.ui.SheetsController; import omr.util.BasicTask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.JCheckBoxMenuItem; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; /** * Class {@code StepMenu} encapsulates the user interface needed to * deal with application steps. * Steps are represented by menu items, each one being a check box, to indicate * the current status regarding the execution of the step (done or not done). * * @author Hervé Bitteur */ public class StepMenu { //~ Static fields/initializers --------------------------------------------- /** Usual logger utility */ private static final Logger logger = LoggerFactory.getLogger( StepMenu.class); //~ Instance fields -------------------------------------------------------- // /** The concrete UI menu. */ private final JMenu menu; //~ Constructors ----------------------------------------------------------- //----------// // StepMenu // //----------// /** * Generates the menu to be inserted in the application pull-down * menus. * * @param menu the hosting menu, or null */ public StepMenu (JMenu menu) { if (menu == null) { menu = new JMenu(); } this.menu = menu; // Build the menu content updateMenu(); // Listener to modify attributes on-the-fly menu.addMenuListener(new MyMenuListener()); } //~ Methods ---------------------------------------------------------------- //------------// // updateMenu // //------------// /** * Update/rebuild the content of menu. */ public final void updateMenu () { menu.removeAll(); Step prevStep = null; // List of Steps classes in proper order for (Step step : Steps.values()) { if ((prevStep != null) && (prevStep.isMandatory() != step.isMandatory())) { menu.addSeparator(); } menu.add(new StepItem(step)); prevStep = step; } } //---------// // getMenu // //---------// /** * Report the concrete UI menu. * * @return the menu entity */ public JMenu getMenu () { return menu; } //~ Inner Classes ---------------------------------------------------------- //------------// // StepAction // //------------// /** * Action to be performed when the related step item is selected. */ private static class StepAction extends AbstractAction { //~ Instance fields ---------------------------------------------------- // The related step final Step step; //~ Constructors ------------------------------------------------------- public StepAction (Step step) { super(step.toString()); this.step = step; putValue(SHORT_DESCRIPTION, step.getDescription()); } //~ Methods ------------------------------------------------------------ @Override public void actionPerformed (ActionEvent e) { final Sheet sheet = SheetsController.getCurrentSheet(); new BasicTask() { @Override protected Void doInBackground () throws Exception { Step sofar = Stepping.getLatestMandatoryStep(sheet); if ((sofar == null) || (Steps.compare(sofar, step) <= 0)) { // Here we progress on all sheets of the score new StepTask(step).run(sheet); } else { // There we rebuild just the current sheet Stepping.reprocessSheet(step, sheet, null, true); } return null; } @Override protected void finished () { // Select the assembly tab related to the target step if (sheet != null) { Stepping.notifyStep(sheet, step); } } }.execute(); } } //----------// // StepItem // //----------// /** * Class {@code StepItem} implements a checkable menu item linked * to a given step. */ private static class StepItem extends JCheckBoxMenuItem { //~ Constructors ------------------------------------------------------- public StepItem (Step step) { super(new StepAction(step)); } //~ Methods ------------------------------------------------------------ public void displayState (Sheet sheet, boolean isIdle) { StepAction action = (StepAction) getAction(); if (sheet == null) { setState(false); action.setEnabled(false); } else { action.setEnabled(true); if (action.step.isMandatory()) { final boolean done = action.step.isDone(sheet); setState(done); } else { setState(false); action.setEnabled(true); } if (!isIdle) { action.setEnabled(false); } } } } //----------------// // MyMenuListener // //----------------// /** * Class {@code MyMenuListener} is triggered when the whole sub-menu * is entered. * This is done with respect to currently displayed sheet. * The steps already done are flagged as such. */ private class MyMenuListener implements MenuListener { //~ Methods ------------------------------------------------------------ @Override public void menuCanceled (MenuEvent e) { } @Override public void menuDeselected (MenuEvent e) { } @Override public void menuSelected (MenuEvent e) { Sheet sheet = SheetsController.getCurrentSheet(); boolean isIdle = (sheet != null) && (sheet.getCurrentStep() == null); for (int i = 0; i < menu.getItemCount(); i++) { JMenuItem menuItem = menu.getItem(i); // Adjust the status for each step if (menuItem instanceof StepItem) { StepItem item = (StepItem) menuItem; item.displayState(sheet, isIdle); } } } } }