/*
* Copyright (C) 2007, 2009 Quadduc <quadduc@gmail.com>
* Copyright (C) 2007, 2008 Clam <clamisgood@gmail.com>
* Copyright (C) 2006, 2010, 2011 IsmAvatar <IsmAvatar@gmail.com>
* Copyright (C) 2006, 2007 TGMG <thegamemakerguru@gmail.com>
* Copyright (C) 2013 Robert B. Colton
*
* This file is part of LateralGM.
* LateralGM is free software and comes with ABSOLUTELY NO WARRANTY.
* See LICENSE for details.
*/
package org.lateralgm.subframes;
import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.InternalFrameEvent;
import org.lateralgm.components.CodeTextArea;
import org.lateralgm.components.MarkerCache;
import org.lateralgm.components.impl.ResNode;
import org.lateralgm.components.impl.TextAreaFocusTraversalPolicy;
import org.lateralgm.file.FileChangeMonitor;
import org.lateralgm.file.FileChangeMonitor.FileUpdateEvent;
import org.lateralgm.main.LGM;
import org.lateralgm.main.Prefs;
import org.lateralgm.main.UpdateSource.UpdateEvent;
import org.lateralgm.main.UpdateSource.UpdateListener;
import org.lateralgm.messages.Messages;
import org.lateralgm.resources.Script;
import org.lateralgm.resources.Script.PScript;
import org.lateralgm.ui.swing.util.SwingExecutor;
public class ScriptFrame extends InstantiableResourceFrame<Script,PScript>
{
private static final long serialVersionUID = 1L;
public JToolBar tool;
public CodeTextArea code;
public JButton edit;
public JPanel status;
private ScriptEditor editor;
public ScriptFrame(Script res, ResNode node)
{
super(res,node);
setSize(700,430);
setLayout(new BorderLayout());
code = new CodeTextArea((String) res.get(PScript.CODE),MarkerCache.getMarker("gml"));
add(code,BorderLayout.CENTER);
// Setup the toolbar
tool = new JToolBar();
tool.setFloatable(false);
tool.setAlignmentX(0);
add(tool,BorderLayout.NORTH);
tool.add(save);
tool.addSeparator();
if (Prefs.useExternalScriptEditor) {
edit = new JButton(LGM.getIconForKey("ScriptFrame.EDIT")); //$NON-NLS-1$
edit.setToolTipText(Messages.getString("ScriptFrame.EDIT"));
edit.addActionListener(this);
tool.add(edit);
tool.addSeparator();
}
code.addEditorButtons(tool);
tool.addSeparator();
name.setColumns(13);
name.setMaximumSize(name.getPreferredSize());
tool.add(new JLabel(Messages.getString("ScriptFrame.NAME"))); //$NON-NLS-1$
tool.add(name);
status = new JPanel(new FlowLayout());
BoxLayout layout = new BoxLayout(status,BoxLayout.X_AXIS);
status.setLayout(layout);
status.setMaximumSize(new Dimension(Integer.MAX_VALUE,11));
final JLabel caretPos = new JLabel(" INS | UTF-8 | " + (code.getCaretLine() + 1) + " : "
+ (code.getCaretColumn() + 1));
status.add(caretPos);
code.addCaretListener(new CaretListener()
{
public void caretUpdate(CaretEvent e)
{
caretPos.setText(" INS | UTF-8 | " + (code.getCaretLine() + 1) + " : "
+ (code.getCaretColumn() + 1));
}
});
add(status,BorderLayout.SOUTH);
setFocusTraversalPolicy(new TextAreaFocusTraversalPolicy(code.text));
}
public void commitChanges()
{
res.put(PScript.CODE,code.getTextCompat());
res.setName(name.getText());
}
public void fireInternalFrameEvent(int id)
{
if (id == InternalFrameEvent.INTERNAL_FRAME_CLOSED)
LGM.currentFile.updateSource.removeListener(code);
super.fireInternalFrameEvent(id);
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == edit)
{
try
{
if (editor == null)
new ScriptEditor();
else
editor.start();
}
catch (IOException ex)
{
ex.printStackTrace();
}
return;
}
super.actionPerformed(e);
}
private class ScriptEditor implements UpdateListener
{
public final FileChangeMonitor monitor;
private File f;
public ScriptEditor() throws IOException
{
f = File.createTempFile(res.getName(),"." + Prefs.externalScriptExtension,LGM.tempDir); //$NON-NLS-1$
f.deleteOnExit();
monitor = new FileChangeMonitor(f,SwingExecutor.INSTANCE);
monitor.updateSource.addListener(this,true);
editor = this;
start();
}
public void start() throws IOException
{
FileWriter out = null;
try
{
out = new FileWriter(f);
out.write(code.getTextCompat());
}
finally
{
if (out != null)
{
out.close();
}
}
if (!Prefs.useExternalScriptEditor || Prefs.externalScriptEditorCommand == null)
try
{
System.out.println(Desktop.getDesktop());
// Desktop d = Desktop.getDesktop();
// Desktop.Action.EDIT;
// Toolkit.getDefaultToolkit().createDesktopPeer(d);
Desktop.getDesktop().edit(monitor.file);
}
catch (UnsupportedOperationException e)
{
throw new UnsupportedOperationException("no internal or system script editor",e);
}
else
Runtime.getRuntime().exec(
String.format(Prefs.externalScriptEditorCommand,monitor.file.getAbsolutePath()));
}
public void stop()
{
monitor.stop();
monitor.file.delete();
editor = null;
}
public void updated(UpdateEvent e)
{
if (!(e instanceof FileUpdateEvent)) return;
switch (((FileUpdateEvent) e).flag)
{
case CHANGED:
StringBuffer sb = new StringBuffer(1024);
BufferedReader reader = null;
try
{
reader = new BufferedReader(new FileReader(monitor.file));
char[] chars = new char[1024];
int len = 0;
while ((len = reader.read(chars)) > -1)
sb.append(chars,0,len);
}
catch (IOException ioe)
{
LGM.showDefaultExceptionHandler(ioe);
return;
}
finally
{
if (reader != null)
{
try
{
reader.close();
}
catch (IOException ex)
{
LGM.showDefaultExceptionHandler(ex);
}
}
}
String s = sb.toString();
res.put(PScript.CODE,s);
code.setText(s);
break;
case DELETED:
editor = null;
}
}
}
public void dispose()
{
if (editor != null) editor.stop();
super.dispose();
}
}