//----------------------------------------------------------------------------
// COMPONENT NAME: LPEX Editor
//
// All Rights Reserved.
//
// DESCRIPTION:
// TestUserProfile - sample user profile
//----------------------------------------------------------------------------
package com.ibm.lpex.samples;
import com.ibm.lpex.core.LpexAction;
import com.ibm.lpex.core.LpexCommand;
import com.ibm.lpex.core.LpexDocumentLocation;
import com.ibm.lpex.core.LpexView;
/**
* Sample user profile - customize keys, commands, actions.
* It customizes the base editor profile (if not "vi") by redefining several
* settings and keys:
* <ul>
* <li>restricts the action of the Backspace and Delete keys to the current line
* <li>sets the Enter keys to go to the next line rather than split
* <li>sets the Home and End keys to actions <b>contextHome</b> and <b>contextEnd</b>
* <li>sets Alt+F1 to action <b>compose</b> (defined in
* {@link ComposeAction}) to enter special characters
* <li>redefines Alt+J (join) to remove extra spaces between the joined segments
* <li>sets Alt+T to action <b>blockTransfer</b> (defined in
* {@link BlockTransferAction}) to transfer selection, adds it to the popup
* <li>redefines Ctrl+Backspace (delete line) to preserve the cursor column position
* <li>redefines Ctrl+N (find next) to first search for the selected text, if any
* <li>sets Ctrl+Shift+V to do a paste replace
* <li>redefines mouse button 1 double-click to select the current line
* <li>sets the default selection type to character
* <li>defines a <b>detab</b> command (using {@link DetabCommand})
* <li>defines a synonym <b>diff</b> for the <b>compare</b> command
* <li>defines a synonym <b>k</b> for the <b>calc</b> command
* <li>adds an action to the pop-up menu of Java properties documents to
* compare ignoring the mnemonics ('&'s).
* </ul>
*
* <p>The user profile is run during the processing of the <b>updateProfile</b>
* command. The <b>updateProfile</b> command is normally run when a document
* view is created, and it may be issued at any time to allow the document view
* to reflect changes to the profile.</p>
*
* <p>Here is the TestUserProfile <a href="doc-files/TestUserProfile.java.html">source
* code</a>.</p>
*
* <p>To run this sample:
* <ul>
* <li>Register this user profile from an editor preference page, where available, or
* from the editor command line:
* <pre>set [default.]updateProfile.userProfile com.ibm.lpex.samples.TestUserProfile</pre>
* <li>Run the <b>updateProfile</b> command from the editor command line:
* <pre>updateProfile</pre>
* </ul></p>
*
* <p>A user profile is a public Java class that has a method of the form:
* <pre>
* public static void userProfile(LpexView lpexView) </pre>
* See the <b>updateProfile.userProfile</b> parameter.</p>
*
* @see com.ibm.lpex.samples All the samples
*/
public class TestUserProfile
{
// private constructor, not used
private TestUserProfile() {}
/**
* This is the method in a user profile that is called by the
* <b>updateProfile</b> editor command.
*
* @param lpexView the document view for which this profile is being run
*/
public static void userProfile(LpexView lpexView)
{
// if the current editor profile is "vi", don't touch it
String baseProfile = lpexView.query("baseProfile");
if ("vi".equals(baseProfile))
{
lpexView.doDefaultCommand("set messageText Base profile NOT modified by TestUserProfile.");
return;
}
/*--------------------------*/
/* define actions, commands */
/*--------------------------*/
// define an action to select the current line
lpexView.defineAction("myBlockMarkElement", new LpexAction()
{
public void doAction(LpexView view)
{
view.doCommand("block clear");
view.doCommand("block set element");
}
public boolean available(LpexView view) { return true; }
});
// define a deleteLine action that preserves the cursor column position
lpexView.defineAction("myDeleteLine", new LpexAction()
{
public void doAction(LpexView view)
{
int displayPosition = view.queryInt("displayPosition");
if (displayPosition > 0)
{
view.doAction(view.actionId("deleteLine"));
view.doCommand("set displayPosition " + displayPosition);
}
}
public boolean available(LpexView view) { return true; }
});
// define a join action that keeps one and only one space between texts
lpexView.defineAction("myJoin", new LpexAction()
{
public void doAction(LpexView view)
{
LpexDocumentLocation joinLocation = view.documentLocation();
if (joinLocation.element > 0)
{
// save cursor position, may be affected by deleteWhiteSpace / insertText
int displayPosition = view.queryInt("displayPosition");
joinLocation.position = view.queryInt("length") + 1;
view.doAction(view.actionId("join"));
view.doCommand(joinLocation, "action oneSpace");
// restore original cursor position
view.doCommand("set displayPosition " + displayPosition);
}
}
public boolean available(LpexView view) { return true; }
});
// define a find-next action that first searches for the selected text, if any
lpexView.defineAction("myFindNext", new LpexAction()
{
public void doAction(LpexView view)
{
if (view.actionAvailable(view.actionId("findSelection")))
{
view.doAction(view.actionId("findSelection"));
}
else
{
view.doAction(view.actionId("findNext"));
}
}
public boolean available(LpexView view)
{ return view.actionAvailable(view.actionId("findNext")) ||
view.actionAvailable(view.actionId("findSelection")); }
});
// define a compare ignoring mnemonics action for the Java properties document parser
lpexView.defineAction("myPropCompare", new LpexAction()
{
public void doAction(LpexView view)
{ view.doCommand("compare ignoredStyles \"a\" prompt"); }
public boolean available(LpexView view) { return true; }
});
// define a synonym "diff" for the "compare" command
lpexView.defineCommand("diff", new LpexCommand()
{
public boolean doCommand(LpexView view, String parameters)
{ return view.doCommand("compare " + parameters); }
});
// define a synonym "k" for the "calc" command
lpexView.defineCommand("k", new LpexCommand()
{
public boolean doCommand(LpexView view, String parameters)
{ return view.doCommand("calc " + parameters); }
});
/*------------------------------------------*/
/* (re)define keys, mouse events, the popup */
/*------------------------------------------*/
boolean isEmacs = "emacs".equals(baseProfile);
// set "Delete" and "Backspace" keys to keep it inside the current line
lpexView.doDefaultCommand("set keyAction.backSpace backSpaceInLine");
lpexView.doDefaultCommand("set keyAction.delete deleteInLine");
// set "Enter" keys to go to the next line (not split)
lpexView.doDefaultCommand("set keyAction.enter newLine");
lpexView.doDefaultCommand("set keyAction.numpadEnter newLine");
// set smarter "Home" and "End"
lpexView.doDefaultCommand("set keyAction.home contextHome");
lpexView.doDefaultCommand("set keyAction.end contextEnd");
// set "Alt+F1" key to compose special characters - use com.ibm.lpex.samples.ComposeAction
lpexView.defineCommand("compose", ComposeAction.composeCommand);
lpexView.defineAction("compose", ComposeAction.composeAction);
lpexView.doDefaultCommand("set keyAction.a-f1 compose");
// set "Alt+J" to join next line's text with just one space in-between
lpexView.doDefaultCommand("set keyAction.a-j myJoin");
// set "Alt+T" to do a block transfer - use com.ibm.lpex.samples.BlockTransferAction
lpexView.doDefaultCommand("set actionClass.blockTransfer " +
"com.ibm.lpex.samples.BlockTransferAction");
if (!isEmacs)
lpexView.doDefaultCommand("set keyAction.a-t blockTransfer");
// set "Ctrl+Backspace" to delete and preserve the cursor column position
lpexView.doDefaultCommand("set keyAction.c-backSpace.t.p.c myDeleteLine");
// set "Ctrl+N" to first search for the selected text, if any
if (!isEmacs)
lpexView.doDefaultCommand("set keyAction.c-n.t.p.c myFindNext");
// set "Ctrl+Shift+V" to do a paste replace, like "Alt+Z" does a block replace
lpexView.doDefaultCommand("set keyAction.c-s-v.t pasteOverlay");
// set mouse button1 double-click to select the line (not word)
lpexView.doDefaultCommand("set mouseAction.1-pressed.2 myBlockMarkElement");
// set default selection type to character (rather than the default stream)
lpexView.doDefaultCommand("set block.defaultType character");
// define a "detab" command - use com.ibm.lpex.samples.DetabCommand
lpexView.doDefaultCommand("set commandClass.detab com.ibm.lpex.samples.DetabCommand");
// add block-transfer action to the pop-up (context) menu, submenu "Selected"
StringBuffer sb = new StringBuffer(lpexView.query("current.popup"));
String transferSubmenu = " \"Tr&ansfer selection\" blockTransfer ";
int i = sb.indexOf("popup.blockDelete ");
if (i >= 0)
{
sb.insert(i, transferSubmenu);
}
else
{
sb.append(" separator" + transferSubmenu);
}
// if properties file, add option to compare ignoring mnemonics on submenu "Source"
if ("prop".equals(parser(lpexView)))
{
String compareSubmenu = " \"Compare w/o &mnemonics...\" myPropCompare ";
i = sb.indexOf("popup.sourceMenu");
if (i >= 0)
{
sb.insert(i + "popup.sourceMenu".length(), compareSubmenu);
}
else
{
sb.append(" separator beginSubmenu popup.sourceMenu" + compareSubmenu + "endSubmenu");
}
}
lpexView.doDefaultCommand("set popup " + sb.toString());
// indicate this profile has run
lpexView.doDefaultCommand("set messageText TestUserProfile settings in effect.");
}
/**
* Determines the document parser which will run after this user profile completes.
*
* @param lpexView the document view for which this profile is being run
* @return the document parser name, or <code>null</code> if none
*/
public static String parser(LpexView lpexView)
{
String parser = null;
if (!lpexView.queryOn("current.updateProfile.noParser"))
{
parser = lpexView.query("current.updateProfile.parser");
// if "associated", determine the parser via the document name extension
if ("associated".equals(parser))
{
parser = null;
String extension = lpexView.query("name");
if (extension != null)
{
int extensionStart = extension.lastIndexOf('.');
if (extensionStart != -1)
{
extension = extension.substring(extensionStart);
parser = lpexView.query("current.updateProfile.parserAssociation" + extension);
}
}
}
}
return parser;
}
}