/*
* $Id$
*
* Copyright (c) 2000-2013 by Rodney Kinney, Joel Uckelman, Brent Easton
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License (LGPL) as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, copies are available
* at http://www.opensource.org.
*/
package VASSAL.launch;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import org.apache.commons.lang.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import VASSAL.Info;
import VASSAL.build.GameModule;
import VASSAL.build.module.metadata.AbstractMetaData;
import VASSAL.build.module.metadata.ImportMetaData;
import VASSAL.build.module.metadata.MetaDataFactory;
import VASSAL.build.module.metadata.ModuleMetaData;
import VASSAL.i18n.Resources;
import VASSAL.tools.DataArchive;
import VASSAL.tools.ErrorDialog;
import VASSAL.tools.ThrowableUtils;
import VASSAL.tools.WarningDialog;
import VASSAL.tools.filechooser.FileChooser;
import VASSAL.tools.imports.ImportAction;
import VASSAL.tools.ipc.IPCMessage;
import VASSAL.tools.menu.MacOSXMenuManager;
import VASSAL.tools.menu.MenuBarProxy;
import VASSAL.tools.menu.MenuManager;
public class Editor extends Launcher {
public static void main(String[] args) {
new Editor(args);
}
private static final Logger logger = LoggerFactory.getLogger(Editor.class);
protected Editor(String[] args) {
// the ctor is protected to enforce that it's called via main()
super(args);
}
protected MenuManager createMenuManager() {
return SystemUtils.IS_OS_MAC_OSX ?
new MacOSXMenuManager() : new EditorMenuManager();
}
protected void launch() throws IOException {
IPCMessage msg = null;
switch (lr.mode) {
case EDIT:
new EditModuleAction(lr.module).loadModule(lr.module);
msg = new AbstractLaunchAction.NotifyOpenModuleOk(lr);
break;
case IMPORT:
new ImportAction(null).loadModule(lr.importFile);
msg = new AbstractLaunchAction.NotifyImportModuleOk(lr);
break;
case NEW:
new CreateModuleAction(null).performAction(null);
msg = new AbstractLaunchAction.NotifyNewModuleOk(lr);
break;
case EDIT_EXT:
GameModule.init(new BasicModule(new DataArchive(lr.module.getPath())));
GameModule.getGameModule().getFrame().setVisible(true);
new EditExtensionAction(lr.extension).performAction(null);
msg = new AbstractLaunchAction.NotifyOpenModuleOk(lr);
break;
case NEW_EXT:
GameModule.init(new BasicModule(new DataArchive(lr.module.getPath())));
final JFrame f = GameModule.getGameModule().getFrame();
f.setVisible(true);
new NewExtensionAction(f).performAction(null);
msg = new AbstractLaunchAction.NotifyOpenModuleOk(lr);
}
if (ipc != null) {
try {
ipc.send(msg);
}
catch (IOException e) {
// This is not fatal, since we've successfully opened the module,
// but possibly this means that the Module Manager has died.
ErrorDialog.showDetails(
e,
ThrowableUtils.getStackTrace(e),
"Error.socket_error"
);
}
}
}
public static class NewModuleLaunchAction extends AbstractLaunchAction {
private static final long serialVersionUID = 1L;
public NewModuleLaunchAction(ModuleManagerWindow mm) {
super(Resources.getString("Main.new_module"), mm,
Editor.class.getName(),
new LaunchRequest(LaunchRequest.Mode.NEW)
);
}
@Override
protected LaunchTask getLaunchTask() {
return new LaunchTask();
}
}
public static class ImportLaunchAction extends AbstractLaunchAction {
private static final long serialVersionUID = 1L;
public ImportLaunchAction(ModuleManagerWindow mm, File module) {
super(Resources.getString("Main.import_module"), mm,
Editor.class.getName(),
new LaunchRequest(LaunchRequest.Mode.IMPORT, module)
);
}
@Override
protected LaunchTask getLaunchTask() {
return new LaunchTask();
}
}
public static class PromptImportLaunchAction extends ImportLaunchAction {
private static final long serialVersionUID = 1L;
public PromptImportLaunchAction(ModuleManagerWindow mm) {
super(mm, null);
}
@Override
public void actionPerformed(ActionEvent e) {
// prompt the user to pick a module
if (promptForFile() == null) return;
super.actionPerformed(e);
}
@Override
protected File promptForFile() {
// prompt the use to pick a module
final FileChooser fc = ImportAction.getFileChooser(window);
if (fc.showOpenDialog() == FileChooser.APPROVE_OPTION) {
lr.importFile = fc.getSelectedFile();
if (lr.importFile != null) {
if (lr.importFile.exists()) {
final AbstractMetaData metadata =
MetaDataFactory.buildMetaData(lr.importFile);
if (metadata == null || ! (metadata instanceof ImportMetaData)) {
ErrorDialog.show(
"Error.invalid_import_file", lr.importFile.getAbsolutePath());
logger.error("Import of " + lr.importFile.getAbsolutePath() +
" failed: unrecognized import type");
lr.importFile = null;
}
}
else {
lr.importFile = null;
}
}
}
return lr.importFile;
}
}
public static class LaunchAction extends AbstractLaunchAction {
private static final long serialVersionUID = 1L;
public LaunchAction(ModuleManagerWindow mm, File module) {
super(Resources.getString("Main.edit_module_specific"), mm,
Editor.class.getName(),
new LaunchRequest(LaunchRequest.Mode.EDIT, module)
);
setEnabled(!editing.contains(module) && !using.containsKey(module));
}
@Override
public void actionPerformed(ActionEvent e) {
final AbstractMetaData data = MetaDataFactory.buildMetaData(lr.module);
if (data != null) {
final String vv = data.getVassalVersion();
// don't permit editing of modules significantly newer than us
if (Info.isModuleTooNew(vv)) {
ErrorDialog.show(
"Error.module_too_new",
lr.module.getPath(),
vv,
Info.getVersion()
);
return;
}
// don't permit loading of VASL saved with 3.1 or earlier
if (data instanceof ModuleMetaData) {
final ModuleMetaData md = (ModuleMetaData) data;
if (Info.compareVersions(md.getVassalVersion(), "3.2.0") < 0) {
if ("VASL".equals(md.getName())) {
ErrorDialog.show(
"Error.VASL_too_old",
Info.getVersion()
);
return;
}
else if ("VSQL".equals(md.getName())) {
ErrorDialog.show(
"Error.VSQL_too_old",
Info.getVersion()
);
return;
}
}
}
// warn user if editing this module would update it to our version
if (Info.hasOldFormat(vv)) {
WarningDialog.show(
"Warning.module_will_be_updated",
lr.module.getPath(),
Info.getVersion(),
"3.2"
);
}
}
// register that this module is being edited
if (editing.contains(lr.module) || using.containsKey(lr.module)) return;
editing.add(lr.module);
super.actionPerformed(e);
}
@Override
protected LaunchTask getLaunchTask() {
return new LaunchTask() {
@Override
protected void done() {
super.done();
// register that this module is no longer being edited
editing.remove(lr.module);
setEnabled(true);
}
};
}
}
public static class ListLaunchAction extends LaunchAction {
private static final long serialVersionUID = 1L;
public ListLaunchAction(ModuleManagerWindow mm, File module) {
super(mm, module);
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
setEnabled(false);
}
}
public static class PromptLaunchAction extends LaunchAction {
private static final long serialVersionUID = 1L;
public PromptLaunchAction(ModuleManagerWindow mm) {
super(mm, null);
putValue(Action.NAME, Resources.getString("Main.edit_module"));
}
@Override
public void actionPerformed(ActionEvent e) {
// prompt the user to pick a module
if (promptForFile() == null) return;
super.actionPerformed(e);
}
}
private static class EditorMenuManager extends MenuManager {
private final MenuBarProxy editorBar = new MenuBarProxy();
private final MenuBarProxy playerBar = new MenuBarProxy();
@Override
public JMenuBar getMenuBarFor(JFrame fc) {
if (fc instanceof PlayerWindow) return playerBar.createPeer();
else if (fc instanceof EditorWindow) return editorBar.createPeer();
else return null;
}
@Override
public MenuBarProxy getMenuBarProxyFor(JFrame fc) {
if (fc instanceof PlayerWindow) return playerBar;
else if (fc instanceof EditorWindow) return editorBar;
else return null;
}
}
}