//----------------------------------------------------------------------------
// COMPONENT NAME: LPEX Editor
//
// All Rights Reserved.
//
// DESCRIPTION:
// MinLpex - sample/test class for the SWT LPEX text-edit widget
//----------------------------------------------------------------------------
package com.ibm.lpex.samples;
import java.io.File;
import com.ibm.lpex.core.LpexAction;
import com.ibm.lpex.core.LpexCommand;
import com.ibm.lpex.core.LpexView;
import com.ibm.lpex.core.LpexViewAdapter;
import com.ibm.lpex.core.LpexWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
/**
* Sample minimal stand-alone editor used to test the LPEX edit widget.
* Modifying this sample allows you to test easily your extensions to the LPEX widget.
*
* <p>Here is the MinLpex <a href="doc-files/MinLpex.java.html">source code</a>.</p>
*
* <p>To run this sample from the command line:
* <pre>
* java [<i>options</i>] com.ibm.lpex.samples.MinLpex [<i>filename</i>] </pre>
* A possible Windows batch program is:
* <pre>
* @start /b java com.ibm.lpex.samples.MinLpex %1 </pre>
* To disable the JIT compiler, run it with this option:
* <pre>
* -Djava.compiler= </pre>
* You can run MinLpex in a particular locale. For example, in order to run it in
* Simplified Chinese (zh_CN), use these two options:
* <pre>
* -Duser.language=zh -Duser.region=CN </pre></p>
*
* Commands and actions defined in here:
* <ul>
* <li><b>MinLpex</b> command - open a new MinLpex window
* <li><b>quit</b> command - unconditionally quit the MinLpex window.
* </ul>
*
* <p>Example of opening a file with MinLpex via a user-defined editor command:</p>
* <table bgcolor="#f0f0f0"><tr><td><pre>
* lpexView.defineCommand(<font color="#800080">"MinLpex"</font>, <font color="#0000ff"><b>new</b></font> LpexCommand() {
* <font color="#0000ff"><b>public boolean</b></font> doCommand(LpexView view, <font color="#0000ff"><b>final</b></font> String parameters)
* {
* Display display = getDisplay();
* display.asyncExec(<font color="#0000ff"><b>new</b></font> Runnable() {
* <font color="#0000ff"><b>public void</b></font> run() {
* <font color="#0000ff"><b>try</b></font>
* {
* Class cl = Class.forName(<font color="#800080">"com.ibm.lpex.samples.MinLpex"</font>);
* Method mainMethod = cl.getDeclaredMethod(<font color="#800080">"main"</font>, <font color="#0000ff"><b>new</b></font> Class[] {String[].class});
* String[] args = <font color="#0000ff"><b>new</b></font> String[] {parameters};
* mainMethod.invoke(<font color="#0000ff"><b>null</b></font>, <font color="#0000ff"><b>new</b></font> Object[] {args});
* }
* <font color="#0000ff"><b>catch</b></font> (Exception e) {}
* }});
* <font color="#0000ff"><b>return true</b></font>;
* }
* }); </pre></td></tr></table>
*
* @see com.ibm.lpex.samples All the samples
*/
public final class MinLpex
{
private Shell _shell;
private LpexWindow _lpexWindow;
private LpexView _lpexView;
/**
* Entry point.
*/
public static void main(String[] args)
{
new MinLpex((args.length == 0)? null : args[0], new Rectangle(10, 10, 648, 711)).run();
}
/**
* Constructor.
* @param filename file name
* @param bounds size and position for the window
*/
public MinLpex(String filename, Rectangle bounds)
{
// ensure canonical file name
if (filename != null)
{
if (filename.trim().length() == 0)
{
filename = null;
}
else
{
try
{
filename = new File(filename).getCanonicalPath();
}
catch(Exception e) {}
}
}
// create an LpexView for the given file, do the "updateProfile" later
_lpexView = new LpexView(filename, "" /*auto-detect encoding*/, false);
// create a new Shell, set its title
_shell = new Shell();
String name = _lpexView.query("name");
if (name == null)
{
name = "Untitled Document " + _lpexView.query("documentId");
}
_shell.setText("SWT MinLpex - " + name);
// create & set a window for our LpexView
_lpexWindow = new LpexWindow(_shell);
_lpexView.setWindow(_lpexWindow);
// add an LpexViewListener to handle all the LPEX listening needed here
_lpexView.addLpexViewListener(new LpexViewAdapter() {
// called after an "updateProfile" command was run
public void updateProfile(LpexView lpexView)
{ MinLpex.this.updateProfile(lpexView); }
// called when the LpexView is disposed
public void disposed(LpexView lpexView)
{ _lpexView = null; }
});
// run the "updateProfile" command
_lpexView.doDefaultCommand("updateProfile");
// listen to a few Shell events
_shell.addListener(SWT.Close, new Listener() {
public void handleEvent(Event event) { closeShell(event); }});
_shell.addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) { disposeShell(event); }});
_shell.addListener(SWT.Resize, new Listener() {
public void handleEvent(Event event) { resizeShell(event); }});
// set Shell's position & size, open it
_shell.setBounds(bounds);
_shell.open();
// display view, set input focus in the edit area
//_lpexView.doDefaultCommand("screenShow");
//_lpexWindow.textWindow().setFocus();
}
private void run()
{
Display display = _shell.getDisplay();
while (!_shell.isDisposed())
{
if (!display.readAndDispatch())
{
display.sleep();
}
}
_shell = null;
}
/*======================*/
/* LPEX notifications */
/*======================*/
// Defines editor commands, actions, and associated keys.
// Called whenever the "updateProfile" command has been processed.
private void updateProfile(LpexView lpexView)
{
// "MinLpex" command - open a MinLpex window
lpexView.defineCommand("MinLpex", new LpexCommand() {
public boolean doCommand(LpexView view, String parameters)
{ return newWindow(parameters); } });
// "quit" command - unconditionally quit this MinLpex window
// (also used by base profile vi's ":q" commands)
lpexView.defineCommand("quit", new LpexCommand() {
public boolean doCommand(LpexView view, String parameters)
{ view.dispose(); _shell.dispose(); return true; } });
}
// Creates a new MinLpex window for a file.
private boolean newWindow(final String filename)
{
_shell.getDisplay().asyncExec(new Runnable() { // à la SwingUtilities#invokeLater()
public void run()
{
Rectangle newBounds = _shell.getBounds();
newBounds.x += 20;
newBounds.y += 20;
new MinLpex(filename, newBounds).run();
}
});
return true;
}
/*=============================*/
/* Shell event notifications */
/*=============================*/
// Shell being disposed.
private void disposeShell(Event event)
{
// dispose of our view & its resources (document parser, etc.)
if (_lpexView != null)
{
_lpexView.dispose();
}
}
// Shell size was set / Shell was resized.
private void resizeShell(Event event)
{
Rectangle rect = _shell.getClientArea();
_lpexWindow.setBounds(0, 0, rect.width, rect.height);
}
// Shell close request.
private void closeShell(Event event)
{
event.doit = closeWindow();
}
// Check whether this MinLpex window can be safely closed (saved / user-abandoned).
private boolean closeWindow()
{
boolean close = true;
if (_lpexView != null && (_lpexView.queryInt("changes") != 0 || _lpexView.queryOn("dirty")))
{
String document = _lpexView.query("name");
if (document == null)
{
document = "document";
}
MessageBox box = new MessageBox(_shell, SWT.ICON_QUESTION | SWT.YES | SWT.NO | SWT.CANCEL);
box.setText(_shell.getText());
box.setMessage ("Save latest changes to " + document + "?");
int rc = box.open();
if (rc == SWT.YES)
{
_lpexView.doCommand("save");
if (_lpexView.query("status") != null) // save failed / was cancelled
{
close = false;
}
}
else if (rc == SWT.CANCEL)
{
close = false;
}
}
return close;
}
}