//----------------------------------------------------------------------------
// COMPONENT NAME: LPEX Editor
//
// © Copyright IBM Corporation 2004, 2007
// All Rights Reserved.
//
// DESCRIPTION:
// FindsCommand - sample user-defined command (finds)
//----------------------------------------------------------------------------
package com.ibm.lpex.samples;
import com.ibm.lpex.core.LpexCommand;
import com.ibm.lpex.core.LpexDocumentLocation;
import com.ibm.lpex.core.LpexStringTokenizer;
import com.ibm.lpex.core.LpexView;
/**
* Sample command <b>finds</b> - count find-text matches in the document.
* This command uses the current <b>findText.</b> settings to determine the
* number of occurrences in the document of either <b>findText.findText</b>
* or the specified text string. It is a purely-informational "findText all".
*
* <p>Here is the FindsCommand <a href="doc-files/FindsCommand.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.finds com.ibm.lpex.samples.FindsCommand</pre></li>
* <li>Run it from the editor command line:
* <pre>finds [<i>text</i>]</pre></li>
* </ul></p>
*
* When called with <code>?</code> as a parameter, the command displays its syntax
* on the message line.
*
* @see MatchesCommand
* @see com.ibm.lpex.samples All the samples
*/
public class FindsCommand implements LpexCommand
{
/**
* Runs this command.
* Displays the number of find-text matches in the view.
*/
public boolean doCommand(LpexView lpexView, String parameters)
{
if (lpexView == null)
{
return true;
}
if ("?".equals(parameters.trim())) // command help
{
lpexView.doCommand("set messageText Syntax: finds [<text>]");
return true;
}
// do the searching
doFinds(lpexView, parameters);
return true;
}
/**
* Searches the document.
*/
void doFinds(LpexView lpexView, String parameters)
{
// build the "findText" command parameters, the options-used result message
StringBuilder findTextParms = new StringBuilder(64);
StringBuilder options = new StringBuilder(64);
findTextParms.append(basicFindTextParms());
if (lpexView.queryOn("current.findText.columns"))
{
String startColumn = lpexView.query("current.findText.startColumn");
String endColumn = lpexView.query("current.findText.endColumn");
findTextParms.append("columns ")
.append(startColumn).append(' ').append(endColumn).append(' ');
setOption(options, "in columns " + startColumn + ".." + endColumn);
}
if (lpexView.queryOn("current.findText.block"))
{
findTextParms.append("block ");
setOption(options, "in selection");
}
if (lpexView.queryOn("current.findText.wholeWord"))
{
findTextParms.append("wholeWord ");
setOption(options, "whole word");
}
if (lpexView.queryOn("current.findText.asis"))
{
findTextParms.append("asis ");
setOption(options, "case sensitive");
}
// the text to find - explicitly specified / view's
String text;
if (parameters.length() != 0)
{
// as ? is used for help, \? is for finding ? (who'd try to find \?...)
if ("\\?".equals(parameters.trim()))
{
int i = parameters.indexOf('\\');
parameters = parameters.substring(0, i) + parameters.substring(i+1);
}
text = parameters;
findTextParms.append(LpexStringTokenizer.addQuotes(parameters));
}
else
{
if (lpexView.queryOn("current.findText.regularExpression"))
{
findTextParms.append("regularExpression ");
setOption(options, "regular expression");
}
text = lpexView.query("current.findText.findText");
findTextParms.append(text);
text = LpexStringTokenizer.removeQuotes(text); // for result
}
setOption(options, null); // close it up
// walk-through document with any redefined "findText" command extras disabled
String oldFindTextContext = lpexView.query("userParameter.view.findTextContext");
/**/ lpexView.doCommand("set userParameter.view.findTextContext off");
String findTextParmsString = findTextParms.toString();
String cmd0 = "findText checkStart " + findTextParmsString;
String cmd = "findText " + findTextParmsString;
int count = 0;
// NB LpexView#doCommand(LpexDocumentLocation,String) forces all elements visible
// while running the specified command - therefore, if we'd want to count only hits
// in the visible elements we would have to check visibility ourselves in here...
for (LpexDocumentLocation loc = new LpexDocumentLocation(1, 1); ; count++)
{
lpexView.doCommand(loc, ((count == 0)? cmd0 : cmd));
if (lpexView.query("status") != null)
{
break;
}
found(lpexView, loc);
}
/**/ lpexView.doCommand("set userParameter.view.findTextContext " +
((oldFindTextContext == null)? "" : oldFindTextContext));
// clear status
lpexView.doCommand("set status");
// display result - text: occurrences (options used).
String countText;
switch (count)
{
case 0: countText = "not found"; break;
case 1: countText = "1 occurrence"; break;
default: countText = count + " occurrences";
}
lpexView.doCommand("set messageText " + text + ": " +
countText + options.toString() + ".");
}
/**
* Returns the basic parameters for the "findText" command we'll use.
*/
String basicFindTextParms()
{
return "quiet noBeep noWrap noEmphasis ";
}
/**
* Notification from #doFinds() of a successful find.
*/
void found(LpexView lpexView, LpexDocumentLocation loc) {}
/**
* Adds a setting to the 'options used' for the result message.
*/
private static void setOption(StringBuilder sb, String option)
{
if (sb.length() == 0)
{
if (option != null)
{
sb.append(option);
}
}
else
{
if (option != null)
{
sb.append(", ").append(option);
}
else
{
sb.insert(0, " (").append(')');
}
}
}
}