//---------------------------------------------------------------------------- // 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> * &#64;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>&nbsp; * 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});&nbsp; * 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; } }