Package de.sciss.eisenkraut.gui

Source Code of de.sciss.eisenkraut.gui.MenuFactory$ActionObserver

/*
*  MenuFactory.java
*  Eisenkraut
*
*  Copyright (c) 2004-2014 Hanns Holger Rutz. All rights reserved.
*
*  This software is published under the GNU General Public License v3+
*
*
*  For further information, please contact Hanns Holger Rutz at
*  contact@sciss.de
*
*
*  Changelog:
*    25-Jan-05  created from de.sciss.meloncillo.gui.MenuFactory
*    02-Aug-05  confirms to new document handler
*    15-Sep-05  openDocument checks if file is already open
*/

package de.sciss.eisenkraut.gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.util.StringTokenizer;
import java.util.prefs.PreferenceChangeEvent;
import java.util.prefs.PreferenceChangeListener;
import java.util.prefs.Preferences;
import javax.swing.Action;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

import de.sciss.eisenkraut.Main;
import de.sciss.eisenkraut.io.AudioStake;
import de.sciss.eisenkraut.io.PrefCacheManager;
import de.sciss.eisenkraut.net.SuperColliderClient;
import de.sciss.eisenkraut.session.Session;
import de.sciss.eisenkraut.util.PrefsUtil;

import de.sciss.app.AbstractApplication;
import de.sciss.app.AbstractWindow;
import de.sciss.app.DynamicPrefChangeManager;
import de.sciss.common.BasicApplication;
import de.sciss.common.BasicMenuFactory;
import de.sciss.common.BasicWindowHandler;
import de.sciss.common.ProcessingThread;
import de.sciss.gui.AbstractWindowHandler;
import de.sciss.gui.BooleanPrefsMenuAction;
import de.sciss.gui.IntPrefsMenuAction;
import de.sciss.gui.MenuAction;
import de.sciss.gui.MenuCheckItem;
import de.sciss.gui.MenuGroup;
import de.sciss.gui.MenuItem;
import de.sciss.gui.MenuRadioGroup;
import de.sciss.gui.MenuRadioItem;
import de.sciss.gui.MenuSeparator;
import de.sciss.io.AudioFileDescr;
import de.sciss.io.AudioFileFormatPane;
import de.sciss.io.Span;
import de.sciss.util.Flag;
import de.sciss.util.Param;

import de.sciss.jcollider.Server;

/**
<code>JMenu</code>s cannot be added to more than
*  one frame. Since on MacOS there's one
*  global menu for all the application windows
*  we need to 'duplicate' a menu prototype.
*  Synchronizing all menus is accomplished
*  by using the same action objects for all
*  menu copies. However when items are added
*  or removed, synchronization needs to be
*  performed manually. That's the point about
*  this class.
<p>
*  There can be only one instance of <code>MenuFactory</code>
*  for the application, and that will be created by the
<code>Main</code> class.
*
@author    Hanns Holger Rutz
@version  0.70, 31-May-08
*
@see  de.sciss.eisenkraut.Main#menuFactory
*/
public class MenuFactory
extends BasicMenuFactory
{
  // ---- misc actions ----
  private ActionOpen        actionOpen;
  private ActionOpenMM      actionOpenMM;
  private ActionNewEmpty      actionNewEmpty;

//  private final List          collGlobalKeyCmd  = new ArrayList();
 
//  private static final String      CLIENT_BG  = "de.sciss.gui.BG";  // radio button group

  /**
   *  The constructor is called only once by
   *  the <code>Main</code> class and will create a prototype
   *  main menu from which all copies are
   *  derived.
   *
   *  @param  root  application root
   */
  public MenuFactory( BasicApplication app )
  {
    super( app );
    createActions();
  }
 
  public ProcessingThread closeAll( boolean force, Flag confirmed )
  {
    final de.sciss.app.DocumentHandler  dh  = AbstractApplication.getApplication().getDocumentHandler();
    Session                doc;
    ProcessingThread          pt;

    while( dh.getDocumentCount() > 0 ) {
      doc  = (Session) dh.getDocument( 0 );
if( doc.getFrame() == null ) {
  System.err.println( "Yukk, no doc frame for "+doc.getDisplayDescr().file );
  try {
    Thread.sleep( 4000 );
  } catch( InterruptedException e1 ) { /* ignore */ }
  confirmed.set( true );
  return null;
}
      pt  = doc.getFrame().closeDocument( force, confirmed );
      if( pt == null ) {
        if( !confirmed.isSet() ) return null;
      } else {
        return pt;
      }
    }
    confirmed.set( true );
    return null;
  }

  /**
   *  Sets all JMenuBars enabled or disabled.
   *  When time taking asynchronous processing
   *  is done, like loading a session or bouncing
   *  it to disk, the menus need to be disabled
   *  to prevent the user from accidentally invoking
   *  menu actions that can cause deadlocks if they
   *  try to gain access to blocked doors. This
   *  method traverses the list of known frames and
   *  sets each frame's menu bar enabled or disabled.
   *
   *  @param  enabled    <code>true</code> to enable
   *            all menu bars, <code>false</code>
   *            to disable them.
   *  @synchronization  must be called in the event thread
   */
//  public void setMenuBarsEnabled( boolean enabled )
//  {
//    MenuHost  host;
//    JMenuBar  mb;
// 
//    for( int i = 0; i < collMenuHosts.size(); i++ ) {
//      host  = (MenuHost) collMenuHosts.get( i );
//      mb    = host.who.getJMenuBar();
//      if( mb != null ) mb.setEnabled( enabled );
//    }
//  }

//  private static int uniqueNumber = 0;  // increased by addGlobalKeyCommand()
  /**
   *  Adds an action object invisibly to all
   *  menu bars, enabling its keyboard shortcut
   *  to be accessed no matter what window
   *  has the focus.
   *
   *  @param  a   the <code>Action</code> whose
   *        accelerator key should be globally
   *        accessible. The action
   *        is stored in the input and action map of each
   *        registered frame's root pane, thus being
   *        independant of calls to <code>setMenuBarsEnabled/code>.
   *
   *  @throws java.lang.IllegalArgumentException  if the action does
   *                        not have an associated
   *                        accelerator key
   *
   *  @see  javax.swing.Action#ACCELERATOR_KEY
   *  @synchronization  must be called in the event thread
   */
//  public void addGlobalKeyCommand( Action a )
//  {
//System.err.println( "addGlobalKeyCommand : NOT YET FULLY WORKING" );
//    final KeyStroke    acc    = (KeyStroke) a.getValue( Action.ACCELERATOR_KEY );
//    final String    entry;
//    MenuHost      host;
////    JRootPane      rp;
//    InputMap      imap;
//    ActionMap      amap;
//   
//    if( acc == null ) throw new IllegalArgumentException();
//   
//    entry = "key" + String.valueOf( uniqueNumber++ );
//    a.putValue( Action.NAME, entry );
//
//    for( int i = 0; i < collMenuHosts.size(); i++ ) {
//      host  = (MenuHost) collMenuHosts.get( i );
//      imap  = host.who.getInputMap( JComponent.WHEN_IN_FOCUSED_WINDOW );
////      rp    = host.who.getRootPane();
////      imap  = rp.getInputMap( JComponent.WHEN_IN_FOCUSED_WINDOW );
////      amap  = rp.getActionMap();
//      amap  = host.who.getActionMap();
//      imap.put( acc, entry );
//      amap.put( entry, a );
//    }
//    collGlobalKeyCmd.add( a );
//  }

  private void createActions()
  {
    // --- file menu ---
    actionNewEmpty  = new ActionNewEmpty( getResourceString( "menuNewEmpty" ),
                        KeyStroke.getKeyStroke( KeyEvent.VK_N, MENU_SHORTCUT ));
    actionOpen    = new ActionOpengetResourceString( "menuOpen" ),
                        KeyStroke.getKeyStroke( KeyEvent.VK_O, MENU_SHORTCUT ));
    actionOpenMM  = new ActionOpenMM( getResourceString( "menuOpenMM" ),
                        KeyStroke.getKeyStroke( KeyEvent.VK_O, MENU_SHORTCUT + InputEvent.SHIFT_MASK ));
  }
 
  // @todo  this should eventually read the tree from an xml file
  protected void addMenuItems()
  {
    final Preferences    prefs = getApplication().getUserPrefs();
    MenuGroup        mg, smg;
    MenuCheckItem      mci;
    MenuRadioGroup      rg;
//    Action          a;
    BooleanPrefsMenuAction  ba;
    IntPrefsMenuAction    ia;
    int            i;
   
    // Ctrl on Mac / Ctrl+Alt on PC
    final int myCtrl = MENU_SHORTCUT == InputEvent.CTRL_MASK ? InputEvent.CTRL_MASK | InputEvent.ALT_MASK : InputEvent.CTRL_MASK;

    // --- file menu ---
   
    mg  = (MenuGroup) get( "file" );
    smg = new MenuGroup( "new", getResourceString( "menuNew" ));
    smg.add( new MenuItem( "empty", actionNewEmpty ));
    smg.add( new MenuItem( "fromSelection", getResourceString( "menuNewFromSelection" )));
    mg.add( smg, 0 );
    i  = mg.indexOf( "open" );
    mg.add( new MenuItem( "openMultipleMono", actionOpenMM ), i + 1 );
    i  = mg.indexOf( "closeAll" );
    mg.add( new MenuSeparator(), i + 3 );
    i = mg.indexOf( "saveCopyAs" );
    mg.add( new MenuItem( "saveSelectionAs", getResourceString( "menuSaveSelectionAs" )), i + 1 );

    // --- timeline menu ---
    i  = indexOf( "edit" );
    mg  = new MenuGroup( "timeline", getResourceString( "menuTimeline" ));
    mg.add( new MenuItem( "trimToSelection", getResourceString( "menuTrimToSelection" ),
                KeyStroke.getKeyStroke( KeyEvent.VK_F5, MENU_SHORTCUT )));

    mg.add( new MenuItem( "insertSilence", getResourceString( "menuInsertSilence" ),
                KeyStroke.getKeyStroke( KeyEvent.VK_E, MENU_SHORTCUT + InputEvent.SHIFT_MASK )));
    mg.add( new MenuItem( "insertRecording", getResourceString( "menuInsertRec" )));
    add( mg, i + 1 );

    // --- process menu ---
    mg  = new MenuGroup( "process", getResourceString( "menuProcess" ));
    mg.add( new MenuItem( "again", getResourceString( "menuProcessAgain" ), KeyStroke.getKeyStroke( KeyEvent.VK_F, MENU_SHORTCUT )));
    mg.addSeparator();
    smg  = new MenuGroup( "fscape", getResourceString( "menuFScape" ));
    smg.add( new MenuItem( "needlehole", getResourceString( "menuFScNeedlehole" )));
    mg.add( smg );
    smg = new MenuGroup( "sc", getResourceString( "menuSuperCollider" ));
    mg.add( smg );
    mg.addSeparator();
    mg.add( new MenuItem( "fadeIn", getResourceString( "menuFadeIn" ), KeyStroke.getKeyStroke( KeyEvent.VK_I, myCtrl )));
    mg.add( new MenuItem( "fadeOut", getResourceString( "menuFadeOut" ), KeyStroke.getKeyStroke( KeyEvent.VK_O, myCtrl )));
    mg.add( new MenuItem( "gain", getResourceString( "menuGain" ), KeyStroke.getKeyStroke( KeyEvent.VK_N, myCtrl )));
    mg.add( new MenuItem( "invert", getResourceString( "menuInvert" )));
//    mg.add( new MenuItem( "mix", getResourceString( "menuMix" )));
    mg.add( new MenuItem( "reverse", getResourceString( "menuReverse" )));
    mg.add( new MenuItem( "rotateChannels", getResourceString( "menuRotateChannels" )));
    add( mg, i + 2 );

    // --- operation menu ---
    mg      = new MenuGroup( "operation", getResourceString( "menuOperation" ));
    ba      = new BooleanPrefsMenuAction( getResourceString( "menuInsertionFollowsPlay" ), null );
    mci      = new MenuCheckItem( "insertionFollowsPlay", ba );
    ba.setCheckItem( mci );
    ba.setPreferences( prefs, PrefsUtil.KEY_INSERTIONFOLLOWSPLAY );
    mg.add( mci );
    add( mg, i + 3 );

    // --- view menu ---
    mg      = new MenuGroup( "view", getResourceString( "menuView" ));
    smg      = new MenuGroup( "timeUnits", getResourceString( "menuTimeUnits" ));
    ia      = new IntPrefsMenuAction( getResourceString( "menuTimeUnitsSamples" ), null, PrefsUtil.TIME_SAMPLES );
    rg      = new MenuRadioGroup();
    smg.add( new MenuRadioItem( rg, "samples", ia ))// crucial reihenfolge : erst item erzeugen, dann gruppe setzen, dann prefs
    ia.setRadioGroup( rg );
    ia.setPreferences( prefs, PrefsUtil.KEY_TIMEUNITS );
    ia      = new IntPrefsMenuAction( getResourceString( "menuTimeUnitsMinSecs" ), null, PrefsUtil.TIME_MINSECS );
    smg.add( new MenuRadioItem( rg, "minSecs", ia ));
    ia.setRadioGroup( rg );
    ia.setPreferences( prefs, PrefsUtil.KEY_TIMEUNITS );
    mg.add( smg );

    smg      = new MenuGroup( "vertscale", getResourceString( "menuVertScale" ));
    ia      = new IntPrefsMenuAction( getResourceString( "menuVertScaleAmpLin" ), null, PrefsUtil.VSCALE_AMP_LIN );
    rg      = new MenuRadioGroup();
    smg.add( new MenuRadioItem( rg, "amplin", ia ))// crucial reihenfolge : erst item erzeugen, dann gruppe setzen, dann prefs
    ia.setRadioGroup( rg );
    ia.setPreferences( prefs, PrefsUtil.KEY_VERTSCALE );
    ia      = new IntPrefsMenuAction( getResourceString( "menuVertScaleAmpLog" ), null, PrefsUtil.VSCALE_AMP_LOG );
    smg.add( new MenuRadioItem( rg, "amplog", ia ));
    ia.setRadioGroup( rg );
    ia.setPreferences( prefs, PrefsUtil.KEY_VERTSCALE );
    ia      = new IntPrefsMenuAction( getResourceString( "menuVertScaleFreqSpect" ), null, PrefsUtil.VSCALE_FREQ_SPECT );
    smg.add( new MenuRadioItem( rg, "freqspect", ia ));
    ia.setRadioGroup( rg );
    ia.setPreferences( prefs, PrefsUtil.KEY_VERTSCALE );
    final IntPrefsMenuAction freqSpectAction = ia;
//    ia.setEnabled( prefs.node( PrefsUtil.NODE_VIEW ).getBoolean( PrefsUtil.KEY_SONAENABLED, false ));
    new DynamicPrefChangeManager( prefs.node( PrefsUtil.NODE_VIEW ), new String[] {
      PrefsUtil.KEY_SONAENABLED }, new PreferenceChangeListener() {
      public void preferenceChange( PreferenceChangeEvent pce )
      {
        freqSpectAction.setEnabled( prefs.node( PrefsUtil.NODE_VIEW ).getBoolean( PrefsUtil.KEY_SONAENABLED, false ));
      }
    }).startListening();
   
    mg.add( smg );

    ba      = new BooleanPrefsMenuAction( getResourceString( "menuViewNullLinie" ), null );
    mci      = new MenuCheckItem( "nullLinie", ba );
    ba.setCheckItem( mci );
    ba.setPreferences( prefs, PrefsUtil.KEY_VIEWNULLLINIE );
    mg.add( mci );
    ba      = new BooleanPrefsMenuAction( getResourceString( "menuViewVerticalRulers" ), null );
    mci      = new MenuCheckItem( "verticalRulers", ba );
    ba.setCheckItem( mci );
    ba.setPreferences( prefs, PrefsUtil.KEY_VIEWVERTICALRULERS );
    mg.add( mci );
    ba      = new BooleanPrefsMenuAction( getResourceString( "menuViewChanMeters" ), null );
    mci      = new MenuCheckItem( "channelMeters", ba );
    ba.setCheckItem( mci );
    ba.setPreferences( prefs, PrefsUtil.KEY_VIEWCHANMETERS );
    mg.add( mci );
    ba      = new BooleanPrefsMenuAction( getResourceString( "menuViewMarkers" ), null );
    mci      = new MenuCheckItem( "markers", ba );
    ba.setCheckItem( mci );
    ba.setPreferences( prefs, PrefsUtil.KEY_VIEWMARKERS );
    mg.add( mci );
    add( mg, i + 4 );

    // --- window menu ---
//    mWindowRadioGroup = new MenuRadioGroup();
//    mgWindow = new MenuGroup( "window", getResourceString( "menuWindow" ));
    mg  = (MenuGroup) get( "window" );
    mg.add( new MenuItem( "ioSetup", new ActionIOSetup( getResourceString( "frameIOSetup" ), null )), 0 );
    mg.add( new MenuSeparator(), 1 );
    mg.add( new MenuItem( "main", new ActionShowWindow( getResourceString( "frameMain" ), null, Main.COMP_MAIN )), 2 );
    mg.add( new MenuItem( "observer", new ActionObserver( getResourceString( "paletteObserver" ), KeyStroke.getKeyStroke( KeyEvent.VK_3, MENU_SHORTCUT ))), 3 );
    mg.add( new MenuItem( "ctrlRoom", new ActionCtrlRoom( getResourceString( "paletteCtrlRoom" ), KeyStroke.getKeyStroke( KeyEvent.VK_2, MENU_SHORTCUT ))), 4 );
//    mg.add( new MenuSeparator(), 5 );
//    mgWindow.add( new MenuItem( "collect", ((WindowHandler) root.getWindowHandler()).getCollectAction() ));
//    mgWindow.addSeparator();
//    add( mgWindow );

    // --- debug menu ---
    mg   = new MenuGroup( "debug", "Debug" );
    mg.add( new MenuItem( "dumpPrefs", PrefsUtil.getDebugDumpAction() ));
    mg.add( new MenuItem( "dumpRegions", "Dump Region Structure" ));
    mg.add( new MenuItem( "verifyRegions", "Verify Regions Consistency" ));
    mg.add( new MenuItem( "dumpCache", PrefCacheManager.getInstance().getDebugDumpAction() ));
    mg.add( new MenuItem( "dumpAudioStakes", AudioStake.getDebugDumpAction() ));
    mg.add( new MenuItem( "dumpNodeTree", SuperColliderClient.getInstance().getDebugNodeTreeAction() ));
    mg.add( new MenuItem( "dumpKillAll", SuperColliderClient.getInstance().getDebugKillAllAction() ));
    i  = indexOf( "help" );
    add( mg, i );

//    // --- help menu ---
//    mg  = new MenuGroup( "help", getResourceString( "menuHelp" ));
//    mg.add( new MenuItem( "manual", new actionURLViewerClass( getResourceString( "menuHelpManual" ), null, "index", false )));
//    mg.add( new MenuItem( "shortcuts", new actionURLViewerClass( getResourceString( "menuHelpShortcuts" ), null, "Shortcuts", false )));
//    mg.addSeparator();
//    mg.add( new MenuItem( "website", new actionURLViewerClass( getResourceString( "menuHelpWebsite" ), null, getResourceString( "appURL" ), true )));
//    a = new actionAboutClass( getResourceString( "menuAbout" ), null );
//    if( AboutJMenuItem.isAutomaticallyPresent() ) {
//      root.getAboutJMenuItem().setAction( a );
//    } else {
//      mg.addSeparator();
//      mg.add( new MenuItem( "about", a ));
//    }
//
//    add( mg );
  }
 
  public void showPreferences()
  {
    PrefsFrame prefsFrame = (PrefsFrame) getApplication().getComponent( Main.COMP_PREFS );
 
    if( prefsFrame == null ) {
      prefsFrame = new PrefsFrame();
    }
    prefsFrame.setVisible( true );
    prefsFrame.toFront();
  }
 
  protected Action getOpenAction()
  {
    return actionOpen;
  }

  protected ActionOpenRecent createOpenRecentAction( String name, File path )
  {
    return new ActionEisKOpenRecent( name, path );
  }

    public void openDocument( File f )
     {
       openDocument( f, true );
     }

  public void openDocument( File f, boolean postAction )
  {
    if( actionOpen.perform( f ) && postAction ) {
            final Preferences audioPrefs = getApplication().getUserPrefs().node( PrefsUtil.NODE_AUDIO );
            final String postActionValue = audioPrefs.get(PrefsUtil.KEY_AUTOPLAYFROMFINDER, PrefsUtil.AUTOPLAYFROMFINDER_NONE);
            if( !postActionValue.equals( PrefsUtil.AUTOPLAYFROMFINDER_NONE )) {
                final Session doc = findDocumentForPath( f );
                if( doc != null ) {
                    if( postActionValue.equals( PrefsUtil.AUTOPLAYFROMFINDER_LOOP )) {
                        final Span loopSpan = doc.getAudioTrail().getSpan();
                        // hmmm.... bit shaky all because we don't have a clean MVC
                        doc.timeline.setSelectionSpan( this, loopSpan );
                        doc.getFrame().setLoop( true );
//                        doc.getTransport().setLoop( loopSpan );
                    }
                    doc.getTransport().play( 1.0 );
                }
            }
        }
  }

  public void openDocument( File[] fs )
  {
    actionOpenMM.perform( fs );
  }

  public Session newDocument( AudioFileDescr afd )
  {
    return actionNewEmpty.perform( afd );
  }

  public void addSCPlugIn( Action a, String[] hierarchy )
  {
System.err.println( "addSCPlugIn : NOT YET WORKING" );
//    final JMenuItem mi = new JMenuItem( a );
////    sma.setProtoType( rbmi );
////    rbmi.putClientProperty( CLIENT_BG, CLIENT_BG + "window" );
//    addMenuItem( mSuperCollider, mi );  // XXX traverse hierarchy
  }

  public void removeSCPlugIn( Action a )
  {
System.err.println( "removeSCPlugIn : NOT YET WORKING" );
//    removeMenuItem( mSuperCollider, a );
  }
 
  protected Session findDocumentForPath( File f )
  {
    final de.sciss.app.DocumentHandler  dh  = AbstractApplication.getApplication().getDocumentHandler();
    Session                doc;
    AudioFileDescr[]          afds;
 
    for( int i = 0; i < dh.getDocumentCount(); i++ ) {
      doc    = (Session) dh.getDocument( i );
      afds  = doc.getDescr();
      for( int j = 0; j < afds.length; j++ ) {
        if( (afds[ j ].file != null) && afds[ j ].file.equals( f )) {
          return doc;
        }
      }
    }
    return null;
  }

// ---------------- Action objects for file (session) operations ----------------

  // action for the New-Empty Document menu item
  private class ActionNewEmpty
  extends MenuAction
  {
    private JPanel        p  = null;
    private AudioFileFormatPane  affp;
 
    protected ActionNewEmpty( String text, KeyStroke shortcut )
    {
      super( text, shortcut );
    }

    public void actionPerformed( ActionEvent e )
    {
      final AudioFileDescr afd = query();
      if( afd != null ) {
//        // XXX there is a bug with
//        // FloatingPaletteHandler
//        // causing infinite mutual window
//        // refresh if we open the new window
//        // straight away. The bug disappears
//        // if we defer the window opening...
//        EventQueue.invokeLater( new Runnable() {
//          public void run()
//          {
            perform( afd );
//          }
//        });
      }
    }
   
    private AudioFileDescr query()
    {
      final AudioFileDescr    afd      = new AudioFileDescr();
//      final JOptionPane      dlg;
      final String[]        queryOptions = { getResourceString( "buttonCreate" ),
                             getResourceString( "buttonCancel" )};
      final int          result;
//      final Object        result;
//      final Component        c      = ((AbstractWindow) root.getComponent( Main.COMP_MAIN )).getWindow();
      final Server.Status      status;
      final double        sampleRate;
      final Param          param;
      final Preferences      audioPrefs;

      if( p == null ) {
        affp    = new AudioFileFormatPane( AudioFileFormatPane.NEW_FILE_FLAGS );
        p      = new JPanel( new BorderLayout() );
        p.add( affp, BorderLayout.NORTH );
        AbstractWindowHandler.setDeepFont( affp );
      }

      status    = SuperColliderClient.getInstance().getStatus();
      if( status != null ) {
        sampleRate  = status.sampleRate;
      } else {
        audioPrefs  = getApplication().getUserPrefs().node( PrefsUtil.NODE_AUDIO );
        param    = Param.fromPrefs( audioPrefs, PrefsUtil.KEY_AUDIORATE, null );
        if( param != null ) {
          sampleRate = param.val;
        } else {
          sampleRate = 0.0;
        }
      }
     
//      System.out.println( "sampleRate " + sampleRate );
     
      if( sampleRate != 0.0 ) {
        affp.toDescr( afd );
        afd.rate = sampleRate;
        affp.fromDescr( afd );
      }
       
//      result    = JOptionPane.showOptionDialog( null, p, getValue( NAME ).toString(),
//          JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
//          null, queryOptions, queryOptions[ 0 ]);
     
      //  Object message, String title, int optionType, int messageType, Icon icon, Object[] options, Object initialValue)
      // (Object message, int messageType, int optionType, Icon icon, Object[] options, Object initialValue)
      final JOptionPane op = new JOptionPane( p, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION, null, queryOptions, queryOptions[ 0 ]);
//        final JDialog dlg = op.createDialog( null, getValue( NAME ).toString() );
//        dlg.show();
//        result = op.getValue();
      result = BasicWindowHandler.showDialog( op, null, getValue( NAME ).toString() );

//      if( queryOptions[ 0 ].equals( result )) {}
      if( result == 0 ) {
        affp.toDescr( afd );
        return afd;
      } else {
        return null;
      }
    }
   
    protected Session perform( AudioFileDescr afd )
    {
      final Session doc;

      try {
        doc = Session.newEmpty( afd );
        AbstractApplication.getApplication().getDocumentHandler().addDocument( this, doc );
        doc.createFrame();
        return doc;
      }
      catch( IOException e1 ) {  // should never happen
        BasicWindowHandler.showErrorDialog( null, e1, getValue( Action.NAME ).toString() );
        return null;
      }
    }
  }
 
  // action for the Open-Session menu item
  private class ActionOpen
  extends MenuAction
  {
//    private String text;
 
    protected ActionOpen( String text, KeyStroke shortcut )
    {
      super( text, shortcut );
     
//      this.text = text;
    }
   
    /*
     *  Open a Session. If the current Session
     *  contains unsaved changes, the user is prompted
     *  to confirm. A file chooser will pop up for
     *  the user to select the session to open.
     */
    public void actionPerformed( ActionEvent e )
    {
      File f = queryFile();
      if( f != null ) perform( f );
    }

    private File queryFile()
    {
      final FileDialog    fDlg;
      final String      strFile, strDir;
      final AbstractWindow  w    = (AbstractWindow) getApplication().getComponent( Main.COMP_MAIN );
      final Frame        frame  = (w.getWindow() instanceof Frame) ? (Frame) w.getWindow() : null;
      final Preferences    prefs  = getApplication().getUserPrefs();

//System.err.println( "frame : "+frame );

      fDlg  = new FileDialog( frame, getResourceString( "fileDlgOpen" ), FileDialog.LOAD );
//      fDlg.setFilenameFilter( doc );
      fDlg.setDirectory( prefs.get( PrefsUtil.KEY_FILEOPENDIR, System.getProperty( "user.home" )));
      // fDlg.setFile();
      fDlg.setVisible( true );
      strDir  = fDlg.getDirectory();
      strFile  = fDlg.getFile();
     
      if( strFile == null ) return null;   // means the dialog was cancelled
     
      // save dir prefs
      prefs.put( PrefsUtil.KEY_FILEOPENDIR, strDir );

      return( new File( strDir, strFile ));
    }
   
    /**
     *  Loads a new document file.
     *  a <code>ProcessingThread</code>
     *  started which loads the new session.
     *
     *  @param  path  the file of the document to be loaded
     * 
     *  @synchronization  this method must be called in event thread
     */
    protected boolean perform( File path )
    {
      Session  doc;
     
      // check if the document is already open
      doc = findDocumentForPath( path );
      if( doc != null ) {
        doc.getFrame().setVisible( true );
        doc.getFrame().toFront();
        return true;
      }

      try {
        doc    = Session.newFrom( path );
        addRecent( doc.getDisplayDescr().file );
        AbstractApplication.getApplication().getDocumentHandler().addDocument( this, doc );
        doc.createFrame()// must be performed after the doc was added
                return true;
      }
      catch( IOException e1 ) {
        BasicWindowHandler.showErrorDialog( null, e1, getValue( Action.NAME ).toString() );
                return false;
      }
    }
  }
 
  // action for the Open-Multiple-Mono menu item
  private class ActionOpenMM
  extends MenuAction
  {
    protected ActionOpenMM( String text, KeyStroke shortcut )
    {
      super( text, shortcut );
    }
   
    public void actionPerformed( ActionEvent e )
    {
      File[] fs = queryFiles();
      if( fs != null ) {
        if( fs.length == 0 ) {
          final JOptionPane op = new JOptionPane( getResourceString( "errFileSelectionEmpty" ), JOptionPane.ERROR_MESSAGE );
          BasicWindowHandler.showDialog( op, null, getValue( NAME ).toString() );
          return;
        }
        perform( fs );
      }
    }

    private File[] queryFiles()
    {
      final JFileChooser  fDlg  = new JFileChooser();
      final int      result;
      final Component    c    = ((AbstractWindow) getApplication().getComponent( Main.COMP_MAIN )).getWindow();
      final Preferences  prefs  = getApplication().getUserPrefs();
      final File[]    files;

      fDlg.setMultiSelectionEnabled( true );
      fDlg.setDialogTitle( getValue( Action.NAME ).toString() );
      fDlg.setCurrentDirectory( new File( prefs.get( PrefsUtil.KEY_FILEOPENDIR, System.getProperty( "user.home" ))));
      result  = fDlg.showOpenDialog( c );
     
      if( result == JFileChooser.APPROVE_OPTION ) {
        files = fDlg.getSelectedFiles();
        // save dir prefs
        if( files.length > 0 ) {
          prefs.put( PrefsUtil.KEY_FILEOPENDIR, files[ 0 ].getParent() );
        }
        return files;
      } else {
        return null;
      }
    }
   
    /**
     *  Loads a new document file.
     *  a <code>ProcessingThread</code>
     *  started which loads the new session.
     *
     *  @param  path  the file of the document to be loaded
     * 
     *  @synchronization  this method must be called in event thread
     */
    protected void perform( File[] paths )
    {
      if( paths.length == 0 ) return;
   
      Session    doc;
//      File    f;
     
      // check if the document is already open
      for( int j = 0; j < paths.length; j++ ) {
        doc = findDocumentForPath( paths[ j ]);
        if( doc != null ) {
          doc.getFrame().setVisible( true );
          doc.getFrame().toFront();
          return;
        }
      }
   
      try {
        doc  = Session.newFrom( paths );
        addRecent( doc.getDisplayDescr().file );
        AbstractApplication.getApplication().getDocumentHandler().addDocument( this, doc );
        doc.createFrame()// must be performed after the doc was added
      }
      catch( IOException e1 ) {
        BasicWindowHandler.showErrorDialog( null, e1, getValue( Action.NAME ).toString() );
      }
    }
  }

  // action for the Open-Recent menu
  private class ActionEisKOpenRecent
  extends ActionOpenRecent
  {
    private File[]  paths;

    // new action with path set to null
    protected ActionEisKOpenRecent( String text, File path )
    {
      super( text, path );
    }
   
    // set the path of the action. this
    // is the file that will be loaded
    // if the action is performed
    protected void setPath( File path )
    {
      paths      = new File[] { path };
      boolean enable  = false;
      try {
        if( path == null ) return;
        if( path.isFile() ) {
          enable  = true;
          return;
        }
       
        final String      name    = path.getName();
        final int        idxOpenBr  = name.indexOf( '[' );
        final int        idxCloseBr  = name.indexOf( ']', idxOpenBr + 1 );
//        System.out.println( "for '" + name + "' idxOpenBr = " + idxOpenBr + "; idxCloseBr = " + idxCloseBr );
        if( (idxOpenBr < 0) || ((idxOpenBr + 1) >= (idxCloseBr - 1)) ) return;
       
        final File        parent    = path.getParentFile();
        final String      pre      = name.substring( 0, idxOpenBr );
        final String      post    = name.substring( idxCloseBr + 1 );
        final StringTokenizer  tok      = new StringTokenizer(
          name.substring( idxOpenBr + 1, idxCloseBr ), "," );
        paths  = new File[ tok.countTokens() ];
        enable  = true;
        for( int i = 0; i < paths.length; i++ ) {
          paths[ i ] = new File( parent, pre + tok.nextToken() + post );
//          System.out.println( "testing path: '" + paths[ i ].getAbsolutePath() + "'" );
          enable   &= paths[ i ].isFile();
        }
      }
      finally {
        setEnabled( enable );
      }
    }
   
    /**
     *  If a path was set for the
     *  action and the user confirms
     *  an intermitting confirm-unsaved-changes
     *  dialog, the new session will be loaded
     */
    public void actionPerformed( ActionEvent e )
    {
      if( paths.length == 1 ) {
        if( paths[ 0 ] == null ) return;
        openDocument( paths[ 0 ], false );
      } else {
        openDocument( paths );
      }
    }
  } // class actionOpenRecentClass

// ---------------- Action objects for window operations ----------------

  // action for the IOSetup menu item
  private class ActionIOSetup
  extends MenuAction
  {
    protected ActionIOSetup( String text, KeyStroke shortcut )
    {
      super( text, shortcut );
    }

    /**
     *  Brings up the IOSetup
     */
    public void actionPerformed( ActionEvent e )
    {
      IOSetupFrame f = (IOSetupFrame) getApplication().getComponent( Main.COMP_IOSETUP );
   
      if( f == null ) {
        f = new IOSetupFrame();    // automatically adds component
      }
      f.setVisible( true );
      f.toFront();
    }
  }

  // action for the Control Room menu item
  private class ActionCtrlRoom
  extends MenuAction
  {
    protected ActionCtrlRoom( String text, KeyStroke shortcut )
    {
      super( text, shortcut );
    }

    /**
     *  Brings up the IOSetup
     */
    public void actionPerformed( ActionEvent e )
    {
      ControlRoomFrame f = (ControlRoomFrame) getApplication().getComponent( Main.COMP_CTRLROOM );
   
      if( f == null ) {
        f = new ControlRoomFrame()// automatically adds component
      }
      f.setVisible( true );
      f.toFront();
    }
  }

  // action for the Observer menu item
  private class ActionObserver
  extends MenuAction
  {
    protected ActionObserver( String text, KeyStroke shortcut )
    {
      super( text, shortcut );
    }

    /**
     *  Brings up the IOSetup
     */
    public void actionPerformed( ActionEvent e )
    {
      ObserverPalette f = (ObserverPalette) getApplication().getComponent( Main.COMP_OBSERVER );
   
      if( f == null ) {
        f = new ObserverPalette()// automatically adds component
      }
      f.setVisible( true );
      f.toFront();
    }
  }
}
TOP

Related Classes of de.sciss.eisenkraut.gui.MenuFactory$ActionObserver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.