Listing of Source ../source/GOF/GofCheckBoxIdentifier.javapackage se.entra.phantom.server;
import java.util.StringTokenizer;
import java.util.Vector;
/**
* This class identifies check box controls for the Gui-on-the-fly, from unused GofHostFields.
* @author J. Bergström
*/
public class GofCheckBoxIdentifier extends GofControlIdentifierAdapter implements PhantomControlType
{
// ------------------
// INSTANCE VARIABLES
// ------------------
/**
* The start indicator for a list of alternatives.
* <p>
* Defaults to "(".
*/
private String checkListStart = "(";
/**
* The end indicator for a list of alternatives.
* <p>
* Defaults to ")".
*/
private String checkListEnd = ")";
/**
* The separator between the alternatives in the list.
* <p>
* Defaults to "/".
*/
private String checkListSep = "/";
/**
* Flag indicating where to search for the check box indicator, and in what order if multiple search.
* <p>
* The following values are valid:
* <pre>
* 0 Do not search for combo-list.
* 1 Only search the preceding lead text.
* 2 Only search the trailing lead text.
* 3 First search the preceding, then the trailing lead text.
* 4 First search the trailing, then the preceding lead text.
* </pre>
*/
private int checksearch = 0;
/**
* Filler character if there is one. Will be <code>null</code> otherwise.
*/
private String checkFieldFiller;
/**
* A list with acceptable selection strings.
*/
private Vector<String> selList = new Vector<String>( );
/**
* A list with acceptable unselection strings.
*/
private Vector<String> unselList = new Vector<String>( );
/**
* Flag indicating that the check box should get it's text from the indicator.
* Default is false.
*/
private boolean useTextFromIndicator = false;
/**
* Indicates the way the check box's layout will be created.
* Valid values are:
* <pre>
* DEFAULT
* FONT
* COLOR
* FONTANDCOLOR
* </pre>
*/
private String layout;
// ----------------
// INSTANCE METHODS
// ----------------
/**
* Loads setting for the control from the server ini-file.
* <p>
* For the identification of check boxes, the following settings are used:
* <pre>
* checkstart The start indicator for a list of alternatives.
* checkend The end indicator for a list of alternatives.
* checksep The separator between the alternatives in the list.
* </pre>
* <p>
* There are also several possibilities of where the check box can be placed
* relative to the entry field that will be replaced by the check box.
* The check box can either be in the preceding lead text or in the lead text following.
* <p>
* The setting <code>checksearch</code> will tell this class where to look for
* the check box indicator, and in what order to search if multiple places are to be searched.
* <p>
* Valid values are:
* <pre>
* pre Search the preceding leadtext.
* post Search the trailing leadtext.
* </pre>
* <p>
* There is also a setting that specifies if there is a filler character to use, and what
* character this should be. This setting as called checkFieldFiller, and if the filler
* character is the underscore character, it would look like this:
* <pre>
* checkFieldFiller=_
* </pre>
* To make it possible for the GofCheckBoxIdentifier to know which of the two text strings in
* the indicator is the select string, and which is the unselect string, there are two settings
* where all the valid select strings and unselect strings can be listed. These two settings
* look like this:
* <pre>
* checkselect=J Y
* checkunselect=N
* </pre>
* This means that if there are check boxes where there are presumptive checkboxes, where some have
* Yes as checked, and other have No as checked, check boxes can only be used for one of these cases.
* <p>
* It is also possible to either let the lead text where the check box indicator was found be
* created as a separate output text/static text, or to let it be moved to the check box's text.
* <p>
* Which alternative that should be used is specified in the checktextfromindicator setting.
* To move the text to the checkbox, set this setting to 1, otherwise to 0.
* <pre>
* checktextfromindicator=1
* </pre>
* This class also uses a setting that affects the look of the check boxes. This is the checklayout
* setting. Valid values for this setting are:
* <pre>
* checklayout=DEFAULT
* checklayout=FONT
* checklayout=COLOR
* checklayout=FONTANDCOLOR
* </pre>
* DEFAULT means that no settings are taken from the template panel; default values will be used instead.
* <p>
* FONT means that the font is taken from template panel, from an check box with the id=CHK. If this
* control cannot be found, or if it is not an check box control, default values will be used.
* <p>
* COLOR means that the color is taken from template panel, from an check box with the id=CHK. If this
* control cannot be found, or if it is not an check box control, default values will be used.
* <p>
* FONTANDCOLOR means that the font and color are taken from template panel, from an check box with the
* id=CHK. If this control cannot be found, or if it is not an check box control, default values will be
* used.
* <p>
* Any other value will be treated as DEFAULT.
* @param confFile The server ini file.
*/
@Override
public void getControlSettings( IniFile confFile, String subsection )
{
String setting;
setting = confFile.getData( subsection, "checkstart" );
if( setting != null )
checkListStart = setting;
setting = confFile.getData( subsection, "checkend" );
if( setting != null )
checkListEnd = setting;
setting = confFile.getData( subsection, "checksep" );
if( setting != null )
checkListSep = setting;
setting = confFile.getData( subsection, "checksearch" );
checksearch = parsechecksearch( setting );
setting = confFile.getData( subsection, "checkfieldfiller" );
if( setting != null && setting.equals( "" ) == false )
checkFieldFiller = setting;
else
checkFieldFiller = null;
setting = confFile.getData( subsection, "checkselect" );
if( setting != null && setting.equals( "" ) == false )
parseChkString( setting, selList );
setting = confFile.getData( subsection, "checkunselect" );
if( setting != null && setting.equals( "" ) == false )
parseChkString( setting, unselList );
setting = confFile.getData( subsection, "checktextfromindicator" );
if( setting != null && setting.equals( "1" ) == true )
useTextFromIndicator = true;
else
useTextFromIndicator = false;
layout = confFile.getData( subsection, "checklayout" );
if( layout == null )
layout = "DEFAULT";
}
/**
* Identifies all the combination box controls from the <code>GofHostFields</code>.
* <p>
* The identification of combination boxes are done by searching for a lead text that
* indicates an entry field that could be replaced by a combination box. A lead text
* indicating a combination box should have a start indicator, an end indicator and
* two or more values separated by a separator. The start indicator is usually a start
* parenthesis, the end indicator is usually an end parenthesis, and the separator is
* usually a slash. But these are configurable in the configuration file.
* <p>
* After a lead text has been identified to hold a combination box indicator, it checks
* if the next or previous field is an entry field, and that it is on the same line. There
* is a configuration that determines if the lead text should be before the entry field,
* or after, or if both are accepted, and if so, in which order to search.
* @param gofRuntime The GuiOnTheFlyRuntime instance.
* @param areaIdentifier The areaIdentifier in which the controls should be identified.
* @param phantomHostScreen The Phantom host screen corresponding to the host screen.
* @param hostScreen The host screen that we are trying to build a GOF panel for.
* @param newPanel The newly created Gui-on-the-fly runtime panel.
* @param offsetX Offset in columns used for popup windows.
* @param offsetY Offset in lines used for popup windows.
*/
@Override
public void identifyCtrls( GuiOnTheFlyRuntime gofRuntime,
GofHostAreaIdentifier areaIdentifier,
PhantomHostScreen phantomHostScreen,
HostScreen hostScreen,
PhantomPanelData templPanel,
PhantomPanelData newPanel,
int offsetX,
int offsetY )
{
this.templPanel = templPanel;
Vector<GofHostField> gofHostFields = areaIdentifier.getAreasGofHostFields( );
Vector<String> chkList = new Vector<String>( );
for( int i = 0, s = gofHostFields.size( ); i < s; i++ )
{
GofHostField gofHostField = gofHostFields.elementAt( i );
if( gofHostField.hasBeenProcessed == false && gofHostField.isProtected( ) == true && gofHostField.isEmpty( ) == false )
{
String text = gofHostField.getText( );
int sp = text.indexOf( checkListStart );
int ep = text.indexOf( checkListEnd, sp + 1 );
if( sp > -1 && ep > -1 )
{
String chktext = text.substring( sp + 1, ep );
int oldseppos = -1;
int seppos = chktext.indexOf( checkListSep );
while( seppos > -1 )
{
String item = chktext.substring( oldseppos + 1, seppos );
chkList.addElement( item );
oldseppos = seppos;
seppos = chktext.indexOf( checkListSep, oldseppos + 1 );
if( seppos == -1 )
{
item = chktext.substring( oldseppos + 1 );
chkList.addElement( item );
}
}
if( chkList.size( ) == 2 )
{
// Check to se if chkList elements are in select or unselect lists;
boolean isValid = true;
int selitem = -1;
String item0 = chkList.elementAt( 0 );
String item1 = chkList.elementAt( 1 );
if( isStrInList( item0, selList ) == true && isStrInList( item1, unselList ) == true )
selitem = 0;
else if( isStrInList( item1, selList ) == true && isStrInList( item0, unselList ) == true )
selitem = 1;
else
isValid = false;
if( isValid == true )
{
boolean wasFound;
boolean doLoop = true;
int curchecksearch = checksearch;
int j = 0;
while( doLoop )
{
switch( curchecksearch )
{
case 1:
case 3:
j++;
break;
case 2:
case 4:
j--;
break;
default:
doLoop = false;
}
int curElement = i + j;
if( gofHostFields.size( ) > curElement && curElement > 0 )
{
GofHostField nxtGofHostField = gofHostFields.elementAt( curElement );
if( gofHostField.getY( ) == nxtGofHostField.getY( ) )
{
if( nxtGofHostField.isProtected( ) == false && nxtGofHostField.isEmpty( ) == false )
{
wasFound = convertFieldToCheck( chkList,
nxtGofHostField,
areaIdentifier,
phantomHostScreen,
hostScreen,
newPanel,
offsetX,
offsetY,
selitem,
gofHostField );
if( wasFound == true )
doLoop = false;
else
{
switch( curchecksearch )
{
case 3:
j = 0;
curchecksearch = 2;
break;
case 4:
j = 0;
curchecksearch = 1;
break;
default:
doLoop = false;
}
}
}
else
{
switch( curchecksearch )
{
case 3:
j = 0;
curchecksearch = 2;
break;
case 4:
j = 0;
curchecksearch = 1;
break;
}
}
}
else
doLoop = false; // We have switched line, don't continue.
}
else
doLoop = false;
}
}
}
chkList = new Vector<String>( );
}
}
}
}
/**
* Parses the check-search setting, and converts into a flag value.
* @param setting The setting from the server.ini file.
* @return The value for the check-search flag.
*/
private int parsechecksearch( String setting )
{
if( setting == null || setting.equals( "" ) )
return 0;
int flag = 0;
StringTokenizer st = new StringTokenizer( setting, ", " );
while( st.hasMoreTokens( ) )
{
String s = st.nextToken( );
switch( flag )
{
case 1:
if( s.equals( "pre" ) )
flag = 1;
else if( s.equals( "post" ) )
flag = 3;
break;
case 2:
if( s.equals( "pre" ) )
flag = 4;
else if( s.equals( "post" ) )
flag = 2;
break;
default:
if( s.equals( "pre" ) )
flag = 1;
else if( s.equals( "post" ) )
flag = 2;
}
}
return flag;
}
/**
* Tries to convert an entry field to a combination box.
* <p>
* Before the creation of the PhantomCComboBox, a check will be done to se if the text in the host field
* is included in the list.
* @param areaIdentifier The areaIdentifier in which the controls should be identified.
* @param phantomHostScreen The Phantom host screen corresponding to the host screen.
* @param hostScreen The host screen that we are trying to build a GOF panel for.
* @param newPanel The newly created Gui-on-the-fly runtime panel.
* @param offsetX Offset in columns used for popup windows.
* @param offsetY Offset in lines used for popup windows.
* @return <code>true</code> if the GofHostField was converted to a combination box,
* <code>false</code> otherwise.
*/
private boolean convertFieldToCheck( Vector<String> chkList,
GofHostField gofHostField,
GofHostAreaIdentifier areaIdentifier,
PhantomHostScreen phantomHostScreen,
HostScreen hostScreen,
PhantomPanelData newPanel,
int offsetX,
int offsetY,
int selitem,
GofHostField indGofHostField )
{
int x;
int y;
int cx;
String chkText;
// Get the width of the widest string in the list.
int maxWidth = 0;
for( int i = 0, s = chkList.size( ); i < s; i++ )
{
String listElement = chkList.elementAt( i );
if( listElement.length( ) > maxWidth )
maxWidth = listElement.length( );
}
if( gofHostField.hasBeenProcessed == false &&
gofHostField.isProtected( ) == false &&
gofHostField.isEmpty( ) == false &&
gofHostField.getCx( ) >= maxWidth )
{
HostField hf = gofHostField.getHostField( );
if( useTextFromIndicator == true )
{
x = indGofHostField.getX( );
y = indGofHostField.getY( );
cx = indGofHostField.getCx( );
chkText = indGofHostField.getText( );
indGofHostField.hasBeenProcessed = true;
}
else
{
x = gofHostField.getX( );
y = gofHostField.getY( );
cx = gofHostField.getCx( );
chkText = " ";
}
String orgtext = gofHostField.getText( );
int font = -1;
int foregroundColor = -1;
PhantomControl templateControl = templPanel.getControlFromID( "CHK" );
if( layout.equals( "FONT" ) )
{
if( templateControl != null && templateControl.controlBase.type == CTRLTYPE_CHECK )
font = ( ( PhantomCCheckBox )templateControl ).font;
}
else if( layout.equals( "COLOR" ) )
{
if( templateControl != null && templateControl.controlBase.type == CTRLTYPE_CHECK )
foregroundColor = ( ( PhantomCCheckBox )templateControl ).getForegroundColor();
}
else if( layout.equals( "FONTANDCOLOR" ) )
{
if( templateControl != null && templateControl.controlBase.type == CTRLTYPE_CHECK )
{
font = ( ( PhantomCCheckBox )templateControl ).font;
foregroundColor = ( ( PhantomCCheckBox )templateControl ).getForegroundColor();
}
}
// Create the base control.
PhantomControlBase bc = new PhantomControlBase( GOF_MARGINX + ( x - offsetX ) * GOF_STEPX - 1,
GOF_MARGINY + ( y - offsetY ) * GOF_STEPY - 1,
cx * GOF_GUIUNITX + 15,
GOF_GUIUNITY,
CTRLTYPE_CHECK );
// Create the PhantomHostField.
PhantomHostField phf = new PhantomHostField( phantomHostScreen, hostScreen, hf );
if( checkFieldFiller != null )
{
phf.filler = checkFieldFiller.charAt( 0 );
phf.flags = PhantomHostField.FORMAT_STRIPEND;
}
phantomHostScreen.addHostField( phf );
// Create the entry field.
String selStr = "";
String unselStr = "";
if( selitem == 0 )
{
selStr = chkList.elementAt( 0 );
unselStr = chkList.elementAt( 1 );
}
else
{
selStr = chkList.elementAt( 1 );
unselStr = chkList.elementAt( 0 );
}
PhantomCCheckBox cb = new PhantomCCheckBox( newPanel, bc, phf, selStr, unselStr, orgtext.equals( selStr ) );
cb.font = font;
cb.setForegroundColor(foregroundColor);
cb.text = chkText;
// Add the entry field.
newPanel.addControl( cb );
areaIdentifier.addControl( cb );
gofHostField.hasBeenProcessed = true;
return true;
}
return false;
}
/**
* Parses the configuration setting for the pushbutton identifications, and splits
* it up into the identification strings, which are stored in a Vector.
*/
private void parseChkString( String chkStr, Vector<String> chkList )
{
if( chkStr == null )
return;
StringTokenizer st = new StringTokenizer( chkStr, ", " );
while( st.hasMoreTokens( ) )
{
String s = st.nextToken( ).trim( );
if( s.equals( "" ) == false )
chkList.addElement( s );
}
}
/**
* Checks if a String is in a list.
* @param str The String to check.
* @param list The list to search in.
* @return <code>true</code> if the String was found in the list,
* <code>false</code> otherwise.
*/
private boolean isStrInList( String str, Vector<String> list )
{
boolean isInList = false;
for( int i = 0, s = list.size( ); i < s; i++ )
{
String listStr = list.elementAt( i );
if( str.equals( listStr ) == true )
{
isInList = true;
break;
}
}
return isInList;
}
}