//----------------------------------------------------------------------------
// COMPONENT NAME: LPEX Editor
//
// © Copyright IBM Corporation 2006, 2007
// All Rights Reserved.
//
// DESCRIPTION:
// MatchesCommand - sample user-defined command (matches)
//----------------------------------------------------------------------------
package com.ibm.lpex.samples;
import java.util.HashSet;
import java.util.Iterator;
import com.ibm.lpex.core.LpexCommand;
import com.ibm.lpex.core.LpexDocumentLocation;
import com.ibm.lpex.core.LpexView;
/**
* Sample command <b>matches</b> - highlight find-text matches in the document.
* This command extends {@link FindsCommand} to determine, and also highlight, the
* occurrences in the document of either <b>findText.findText</b> or the
* specified text string. It is a "findText all" which highlights the results
* rather than filtering the view.
*
* <p>Here is the MatchesCommand <a href="doc-files/MatchesCommand.java.html">source
* code</a>.</p>
*
* <p>To run this sample:
* <ul>
* <li>Define this user command via an editor preference page, where available,
* or from the editor command line:
* <pre>set commandClass.matches com.ibm.lpex.samples.MatchesCommand</pre></li>
* <li>Run it from the editor command line:
* <pre>matches [<i>text</i>]</pre></li>
* </ul></p>
*
* When called with <code>?</code> as a parameter, the command displays its syntax
* on the message line. It also clears any existing matches.
*
* @see com.ibm.lpex.samples All the samples
*/
public class MatchesCommand extends FindsCommand
{
// choose an unlikely style character for the match marks
// (TODO create parameter to return an unassigned styleAttributes character!?)
private static final char _matchStyleChar = '`';
// use a yellow background to highlight the matches
private static final String _matchStyle = "-1 -1 -1 255 255 0";
// set of match marks
private HashSet<String> _marks = new HashSet<String>();
// "findText" command stuff
private int _foundTextLength;
private LpexCommand _oldFindTextCommand;
private LpexCommand _findTextCommand = new LpexCommand() {
public boolean doCommand(LpexView lpexView, String parameters) {
return doFindTextCommand(lpexView, parameters);
}};
/**
* Runs this command.
* Highlights the find-text matches on the current screen.
*/
public boolean doCommand(LpexView lpexView, String parameters)
{
if (lpexView == null)
{
return true;
}
if ("?".equals(parameters.trim())) // command help
{
lpexView.doCommand("set messageText Syntax: matches [<text>]");
clearMatches(lpexView);
return true;
}
// ensure the mark highlight character style is still defined
lpexView.doCommand("set styleAttributes." + _matchStyleChar + ' ' + _matchStyle);
// in order to get found-text's length for each match (which may differ each time
// in the case of regular expression), temporarily extend the "findText" command
// in this view so we can query the emphasisLength after each find
_oldFindTextCommand = lpexView.defineCommand("findText", _findTextCommand);
// System.out.println(" class="+lpexView.query("commandClass.findText"));
// clear any old matches
clearMatches(lpexView);
// do the searching
doFinds(lpexView, parameters);
// restore the original "findText" command in this view
lpexView.defineCommand("findText", _oldFindTextCommand);
// System.out.println(" class="+lpexView.query("commandClass.findText"));
return true;
}
/**
* Implementation of the temporarily redefined "findText" command.
*/
boolean doFindTextCommand(LpexView lpexView, String parameters)
{
boolean rc;
if (_oldFindTextCommand != null)
{
rc = _oldFindTextCommand.doCommand(lpexView, parameters);
}
else
{
rc = lpexView.doDefaultCommand("findText " + parameters);
}
_foundTextLength = lpexView.queryInt("emphasisLength");
return rc;
}
/**
* Clear all the match marks from a previous run.
*/
void clearMatches(LpexView lpexView)
{
if (!_marks.isEmpty())
{
Iterator<String> iterator = _marks.iterator();
while (iterator.hasNext())
{
String markId = iterator.next();
lpexView.doCommand("set mark.#" + markId + " clear");
}
_marks.clear();
}
}
/**
* Returns the basic parameters for the "findText" command we'll use.
* Overrides FindsCommand's in order to drop the noEmphasis option -
* we need emphasisLength for the match mark.
*/
String basicFindTextParms()
{
return "quiet noBeep noWrap ";
}
/**
* Notification from #doFinds() of a successful find.
* Overrides FindsCommand's in order to set a match mark.
*/
void found(LpexView lpexView, LpexDocumentLocation loc)
{
lpexView.doCommand("set mark. " + loc.element + ' ' + loc.position + ' ' +
loc.element + ' ' + (loc.position + _foundTextLength -1));
String markId = lpexView.query("markId.");
lpexView.doCommand("set markHighlight.#" + markId + " on");
lpexView.doCommand("set markStyle.#" + markId + ' ' + _matchStyleChar);
_marks.add(markId);
}
}