//----------------------------------------------------------------------------//
// //
// M a c A p p l i c a t i o n //
// //
//----------------------------------------------------------------------------//
// <editor-fold defaultstate="collapsed" desc="hdr"> //
// Copyright (C) Brenton Partridge 2007-2008. 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.ui;
import omr.WellKnowns;
import omr.score.Score;
import omr.script.Script;
import omr.script.ScriptManager;
import org.slf4j.Logger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import javax.swing.SwingWorker;
/**
* Class {@code MacApplication} provides dynamic hooks into the
* OSX-only eawt package, registering Audiveris actions for the
* Preferences, About, and Quit menu items.
*
* @author Brenton Partridge
*/
public class MacApplication
implements InvocationHandler
{
//~ Static fields/initializers ---------------------------------------------
/** Usual logger utility */
private static final Logger logger = LoggerFactory.getLogger(
MacApplication.class);
/** Cached ApplicationEvent class */
private static Class<?> eventClass;
static {
try {
eventClass = Class.forName("com.apple.eawt.ApplicationEvent");
} catch (Exception e) {
eventClass = null;
}
}
//~ Methods ----------------------------------------------------------------
/**
* Invocation handler for
* <code>
* com.apple.eawt.ApplicationListener</code>.
* This method should not be manually called;
* it is used by the proxy to forward calls.
*
* @throws Throwable
*/
@Override
public Object invoke (Object proxy,
Method method,
Object[] args)
throws Throwable
{
String name = method.getName();
String filename = null;
Object event = getEvent(args);
if (event != null) {
setHandled(event);
filename = getFilename(event);
}
logger.debug(name);
switch (name) {
case "handlePreferences":
GuiActions.getInstance()
.defineOptions(null);
break;
case "handleQuit":
GuiActions.getInstance()
.exit(null);
break;
case "handleAbout":
GuiActions.getInstance()
.showAbout(null);
break;
case "handleOpenFile":
logger.debug(filename);
if (filename.toLowerCase()
.endsWith(".script")) {
final File file = new File(filename);
final SwingWorker<?, ?> worker = new SwingWorker<Object, Object>()
{
@Override
protected Object doInBackground ()
{
// Actually load the script
logger.info("Loading script file {} ...", file);
try {
final Script script = ScriptManager.getInstance()
.load(
new FileInputStream(file));
if (logger.isDebugEnabled()) {
script.dump();
}
script.run();
} catch (Exception ex) {
logger.warn("Error loading script file {}", file);
}
return null;
}
};
worker.execute();
} else {
// Actually load the sheet picture
Score score = new Score(new File(filename));
}
break;
}
return null;
}
/**
* Registers actions for preferences, about, and quit.
*
* @return true if successful, false if platform is not
* Mac OS X or if an error occurs
*/
@SuppressWarnings("unchecked")
public static boolean setupMacMenus ()
{
if (!WellKnowns.MAC_OS_X) {
return false;
}
try {
//The class used to register hooks
Class<?> appClass = Class.forName("com.apple.eawt.Application");
Object app = appClass.newInstance();
//Enable the about menu item and the preferences menu item
for (String methodName : new String[]{
"setEnabledAboutMenu", "setEnabledPreferencesMenu"
}) {
Method method = appClass.getMethod(methodName, boolean.class);
method.invoke(app, true);
}
//The interface used to register hooks
Class<?> listenerClass = Class.forName(
"com.apple.eawt.ApplicationListener");
//Using the current class loader,
//generate, load, and instantiate a class implementing listenerClass,
//providing an instance of this class as a callback for any method invocation
Object listenerProxy = Proxy.newProxyInstance(
MacApplication.class.getClassLoader(),
new Class<?>[]{listenerClass},
new MacApplication());
//Add the generated class as a hook
Method addListener = appClass.getMethod(
"addApplicationListener",
listenerClass);
addListener.invoke(app, listenerProxy);
return true;
} catch (Exception ex) {
logger.warn("Unable to setup Mac OS X GUI integration", ex);
return false;
}
}
private static Object getEvent (Object[] args)
{
if (args.length > 0) {
Object arg = args[0];
if (arg != null) {
try {
if ((eventClass != null)
&& eventClass.isAssignableFrom(arg.getClass())) {
return arg;
}
} catch (Exception e) {
}
}
}
return null;
}
private static String getFilename (Object event)
{
try {
Method filename = eventClass.getMethod("getFilename");
Object rval = filename.invoke(event);
if (rval == null) {
return null;
} else {
return (String) rval;
}
} catch (Exception e) {
return null;
}
}
private static void setHandled (Object event)
{
try {
Method handled = eventClass.getMethod("setHandled", boolean.class);
handled.invoke(event, true);
} catch (Exception e) {
}
}
}