package com.robonobo.gui.platform;
import java.awt.Event;
import java.io.*;
import java.util.List;
import javax.swing.*;
import javax.swing.filechooser.FileSystemView;
import com.apple.eawt.*;
import com.robonobo.common.exceptions.SeekInnerCalmException;
import com.robonobo.core.itunes.ITunesService;
import com.robonobo.gui.itunes.mac.MacITunesService;
public class MacPlatform extends UnknownPlatform {
MacAppListener appListener;
@Override
public void init() {
System.setProperty("apple.laf.useScreenMenuBar", "true");
System.setProperty("com.apple.mrj.application.apple.menu.about.name", "robonobo");
}
@Override
public void setLookAndFeel() {
// For the menu bar, we keep the L&F from the platform default so that it appears in the expected place for the
// mac
// Mad props to Marian Bouček, re http://www.ptakopysk.cz/algi/index.html
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
throw new SeekInnerCalmException();
}
String mbUI = UIManager.getString("MenuBarUI");
super.setLookAndFeel();
UIManager.put("MenuBarUI", mbUI);
}
@Override
public void initMainWindow(JFrame jFrame) throws Exception {
Application app = Application.getApplication();
// Don't do anything if we're already registered (this means we're restarting)
if (appListener != null)
return;
appListener = new MacAppListener();
// Use all this stuff even though it's deprecated as we want to keep working with old versions of the apple java
// sdk
app.addApplicationListener(appListener);
app.addAboutMenuItem();
app.setEnabledAboutMenu(true);
app.addPreferencesMenuItem();
app.setEnabledPreferencesMenu(true);
registerUriHandler(app);
}
private void registerUriHandler(Application app) {
// We do this buggering about with reflection as the OpenURIHandler only exists in later versions of the OSX
// Java API, and we still want to work on previous versions (with a warning message)
try {
// This next line will throw ClassNotFoundException if we cannot handle URIs
Class.forName("com.apple.eawt.OpenURIHandler");
Class.forName("com.apple.eawt.OpenFilesHandler");
Class<?> uriClass = Class.forName("com.robonobo.gui.platform.URIHandler");
Class<?> filesClass = Class.forName("com.robonobo.gui.platform.FileHandler");
app.setOpenURIHandler((OpenURIHandler) uriClass.newInstance());
app.setOpenFileHandler((OpenFilesHandler) filesClass.newInstance());
} catch (ClassNotFoundException e) {
// Old version of apple java
// TODO Tell them to update
} catch (Exception e) {
throw new SeekInnerCalmException("Exception registering URI handler", e);
}
}
@Override
public boolean frameContainsMenuBar() {
return false;
}
@Override
public boolean shouldSetMenuBarOnDialogs() {
return true;
}
@Override
public boolean shouldShowPrefsInFileMenu() {
return false;
}
@Override
public boolean shouldShowQuitInFileMenu() {
return false;
}
@Override
public boolean shouldShowOptionsMenu() {
return false;
}
@Override
public boolean shouldShowAboutInHelpMenu() {
return false;
}
@Override
public KeyStroke getAccelKeystroke(int key) {
return KeyStroke.getKeyStroke(key, Event.META_MASK);
}
@Override
public int getCommandModifierMask() {
return Event.META_MASK;
}
@Override
public boolean iTunesAvailable() {
return true;
}
@Override
public ITunesService getITunesService() {
return new MacITunesService();
}
@Override
public void customizeMainbarButtons(List<? extends JButton> btns) {
for (int i = 0; i < btns.size(); i++) {
JButton btn = btns.get(i);
btn.putClientProperty("JButton.buttonType", "bevel");
}
}
@Override
public void customizeSearchTextField(JTextField field) {
field.putClientProperty("JTextField.variant", "search");
}
@Override
public File getDefaultHomeDirectory() {
File libDir = new File(FileSystemView.getFileSystemView().getDefaultDirectory(), "Library");
File appSupDir = new File(libDir, "Application Support");
return new File(appSupDir, "robonobo");
}
@Override
public String fileManagerName() {
return "Finder";
}
@Override
public void showFileInFileManager(File file) {
// We create a temporary file then execute it in applescript - not very elegant, but it works
File tmpFile;
try {
tmpFile = File.createTempFile("robonobo", "script");
PrintWriter writer = new PrintWriter(new FileOutputStream(tmpFile));
writer.println("tell application \"Finder\"");
writer.println("\tactivate");
if (file.isDirectory())
writer.println("\topen folder POSIX file \"" + file.getAbsolutePath() + "\"");
else {
writer.println("\topen folder POSIX file \"" + file.getParentFile().getAbsolutePath() + "\"");
writer.println("\tselect item \"" + file.getName() + "\" of window 1");
}
writer.println("end tell");
writer.close();
Runtime.getRuntime().exec("osascript " + tmpFile.getAbsolutePath());
tmpFile.deleteOnExit();
} catch (IOException e) {
log.error("Caught exception showing file in finder", e);
}
}
}