/*************************************************************************
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: FormControlTest.java,v $
*
* $Revision: 1.8 $
*
* last change: $Author: obo $ $Date: 2006/07/10 14:45:52 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
*
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2005 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
************************************************************************/
package integration.forms;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XNamingService;
import com.sun.star.uno.Any;
import com.sun.star.container.XNameAccess;
import com.sun.star.container.XIndexContainer;
import com.sun.star.container.XIndexAccess;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XComponent;
import com.sun.star.util.XCloseable;
import com.sun.star.util.XRefreshable;
import com.sun.star.util.XURLTransformer;
import com.sun.star.util.URL;
import com.sun.star.sdb.CommandType;
import com.sun.star.sdbc.XDataSource;
import com.sun.star.sdbc.XConnection;
import com.sun.star.sdbc.XResultSet;
import com.sun.star.sdbc.XResultSetUpdate;
import com.sun.star.sdbc.XStatement;
import com.sun.star.sdbcx.XTablesSupplier;
import com.sun.star.form.XImageProducerSupplier;
import com.sun.star.beans.XPropertySet;
import com.sun.star.beans.PropertyValue;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XDispatch;
import com.sun.star.awt.XImageProducer;
import com.sun.star.accessibility.XAccessible;
import com.sun.star.accessibility.XAccessibleEditableText;
import integration.forms.dbfTools;
import integration.forms.DocumentHelper;
import integration.forms.FormLayer;
import connectivity.tools.HsqlDatabase;
import util.utils;
import java.util.*;
import java.io.*;
import java.lang.*;
public class FormControlTest extends complexlib.ComplexTestCase
{
private static String s_tableName = "CTC_form_controls";
private HsqlDatabase m_databaseDocument;
private XDataSource m_dataSource;
private XPropertySet m_dataSourceProps;
private XMultiServiceFactory m_orb;
private DocumentHelper m_document;
private FormLayer m_formLayer;
private XPropertySet m_masterForm;
private String m_sImageURL;
private final String m_dataSourceName = "integration.forms.FormControlTest";
/* ------------------------------------------------------------------ */
public String[] getTestMethodNames()
{
return new String[] {
"checkFirstRow",
"checkInsertRow",
"checkImageControl",
"checkCrossUpdates_checkBox",
"checkCrossUpdates_radioButton",
"checkRowUpdates"
};
}
/* ------------------------------------------------------------------ */
public String getTestObjectName()
{
return "Database Form Controls Test";
}
/* ------------------------------------------------------------------ */
/// pre-test initialization
public void before() throws com.sun.star.uno.Exception, java.lang.Exception
{
// ensure that we have a data source to work with, and the required tables
if ( !ensureDataSource() || !ensureTables() )
{
failed( "could not access the required data source or table therein." );
return;
}
// create the document which we work on
createSampleDocument();
createImageFile();
}
/* ------------------------------------------------------------------ */
public void checkFirstRow() throws com.sun.star.uno.Exception, java.lang.Exception
{
moveToFirst();
// and check the content of the various controls
if ( !checkRadios( (short)1, (short)0, (short)0 )
|| !checkDoubleValue( 1, "ID", "Value" )
|| !checkDoubleValue( 42, "f_integer", "EffectiveValue" )
|| !checkStringValue( "the answer", "f_text", "Text" )
|| !checkDoubleValue( 0.12, "f_decimal", "Value" )
|| !checkIntValue ( 20030922, "f_date", "Date" )
|| !checkIntValue ( 15000000, "f_time", "Time" )
|| !checkIntValue ( 20030923, "f_timestamp_date", "Date" )
|| !checkIntValue ( 17152300, "f_timestamp_time", "Time" )
|| !checkShortValue ( (short)1, "f_tinyint", "State" )
)
{
failed( "checking the content of one or more controls on the first row failed (see the log for details)" );
return;
}
}
/* ------------------------------------------------------------------ */
public void checkInsertRow() throws com.sun.star.uno.Exception, java.lang.Exception
{
// move the cursor to the insert row
moveToInsertRow();
// and check the content of the various controls
if ( !verifyCleanInsertRow() )
{
failed( "checking the content of one or more controls on the insert row failed (see the log for details)" );
return;
}
}
/* ------------------------------------------------------------------ */
/// some tests with the image control
public void checkImageControl() throws com.sun.star.uno.Exception, java.lang.Exception
{
// since we did not yet insert any image, the control should not display one ...
moveToFirst();
if ( !verifyReferenceImage( new byte[0] ) )
{
failed( "image control failed to display empty image" );
return;
}
// check if the image control is able to insert our sample image into the database
// insert an
XPropertySet xImageModel = getControlModel( "f_blob" );
xImageModel.setPropertyValue( "ImageURL", m_sImageURL );
if ( !verifyReferenceImage( getSamplePictureBytes() ) )
{
failed( "image control does not display the sample image as required" );
return;
}
// save the record
saveRecordByUI();
// still needs to be the sample image
if ( !verifyReferenceImage( getSamplePictureBytes() ) )
{
failed( "image control does not, after saving the record, display the sample image as required" );
return;
}
// on the next record, the image should be empty
moveToNext();
if ( !verifyReferenceImage( new byte[0] ) )
{
failed( "image control failed to display empty image, after coming from a non-empty image" );
return;
}
// back to the record where we just inserted the image, it should be our sample image
moveToFirst();
if ( !verifyReferenceImage( getSamplePictureBytes() ) )
{
failed( "image control does not, after coming back to the record, display the sample image as required" );
return;
}
// okay, now remove the image
xImageModel.setPropertyValue( "ImageURL", new String() );
if ( !verifyReferenceImage( new byte[0] ) )
{
failed( "image control failed to remove the image" );
return;
}
nextRecordByUI();
previousRecordByUI();
if ( !verifyReferenceImage( new byte[0] ) )
{
failed( "image still there after coming back, though we just removed it" );
return;
}
}
/* ------------------------------------------------------------------ */
/** This is both a test for controls which are bound to the same column (they must reflect
* each others updates), and for the immediate updates which need to happen for both check
* boxes and radio buttons: They must commit their content to the underlying column as soon
* as the change is made, *not* only upon explicit commit
*/
public void checkCrossUpdates_checkBox() throws com.sun.star.uno.Exception, java.lang.Exception
{
// move to the first record
moveToFirst();
if ( !checkShortValue ( (short)1, "f_tinyint", "State" )
|| !checkDoubleValue( 1, "f_tinyint_format", "EffectiveValue" )
)
{
failed( "huh? inconsistence in the test!" );
// we created the sample data in a way that the f_tinyint field should contain a "1" at the first
// record. We already asserted the proper function of the check box in checkFirstRow, so if this
// fails here, the script became inconsistent
return;
}
XPropertySet checkModel = getControlModel( "f_tinyint" );
checkModel.setPropertyValue( "State", new Short( (short)0 ) );
// setting the state of the check box needs to be reflected in the formatted field immediately
if ( !checkDoubleValue( 0, "f_tinyint_format", "EffectiveValue" ) )
{
failed( "cross-update failed: updating the check box should result in updating the same-bound formatted field (1)!" );
return;
}
// same for the "indetermined" state of the check box
checkModel.setPropertyValue( "State", new Short( (short)2 ) );
if ( !checkNullValue( "f_tinyint_format", "EffectiveValue" ) )
{
failed( "cross-update failed: updating the check box should result in updating the same-bound formatted field (2)!" );
return;
}
// undo the changes done so far
undoRecordByUI();
// and see if this is properly reflected in the controls
if ( !checkShortValue ( (short)1, "f_tinyint", "State" )
|| !checkDoubleValue( 1, "f_tinyint_format", "EffectiveValue" )
)
{
failed( "either the check box or the formatted field failed to recognize the UNDO!" );
return;
}
// the other way round - when changing the formatted field - the change should *not*
// be reflected to the check box, since the formatted field needs an explicit commit
XPropertySet tinyFormattedModel = getControlModel( "f_tinyint_format" );
m_document.getCurrentView().grabControlFocus( tinyFormattedModel );
userTextInput( tinyFormattedModel, "0", false );
if ( !checkShortValue ( (short)1, "f_tinyint", "State" )
)
{
failed( "the check box should not be updated here! (did the formatted model commit immediately?)" );
return;
}
// set the focus to *any* other control (since we just have it at hand, we use the check box control)
// this should result in the formatted control being committed, and thus in the check box updating
m_document.getCurrentView().grabControlFocus( checkModel );
if ( !checkShortValue ( (short)0, "f_tinyint", "State" )
)
{
failed( "formatted field did not commit (or check box did not update)" );
return;
}
// undo the changes done so far, so we leave the document in a clean state for the next test
undoRecordByUI();
}
/* ------------------------------------------------------------------ */
/** very similar to checkCrossUpdates_checkBox - does nearly the same for the radio buttons. See there for more
* explanations.
*/
public void checkCrossUpdates_radioButton() throws com.sun.star.uno.Exception, java.lang.Exception
{
// move to the first record
moveToFirst();
if ( !checkRadios( (short)1, (short)0, (short)0 )
|| !checkStringValue( "none", "f_text_enum_text", "Text" )
)
{
failed( "huh? inconsistence in the test!" );
return;
}
XPropertySet radioModel = getRadioModel( "radio_group", "normal" );
radioModel.setPropertyValue( "State", new Short( (short)1 ) );
// setting the state of the radio button needs to be reflected in the formatted field immediately
if ( !checkStringValue( "normal", "f_text_enum_text", "Text" ) )
{
failed( "cross-update failed: updating the radio button should result in updating the same-bound text field (1)!" );
return;
}
// same for the "indetermined" state of the check box
getRadioModel( "radio_group", "important" ).setPropertyValue( "State", new Short( (short)1 ) );
if ( !checkStringValue( "important", "f_text_enum_text", "Text" ) )
{
failed( "cross-update failed: updating the radio button should result in updating the same-bound text field (2)!" );
return;
}
// undo the changes done so far
undoRecordByUI();
// and see if this is properly reflected in the controls
if ( !checkRadios( (short)1, (short)0, (short)0 )
|| !checkStringValue( "none", "f_text_enum_text", "Text" )
)
{
failed( "either the radio button or the text field failed to recognize the UNDO!" );
return;
}
// the other way round - when changing the formatted field - the change should *not*
// be reflected to the check box, since the formatted field needs an explicit commit
XPropertySet textModel = getControlModel( "f_text_enum_text" );
m_document.getCurrentView().grabControlFocus( textModel );
userTextInput( textModel, "normal", false );
if ( !checkRadios( (short)1, (short)0, (short)0 )
)
{
failed( "the radio buttons should not be updated here! (did the formatted model commit immediately?)" );
return;
}
// set the focus to *any* other control (since we just have it at hand, we use the check box control)
// this should result in the formatted control being committed, and thus in the check box updating
m_document.getCurrentView().grabControlFocus( radioModel );
if ( !checkRadios( (short)0, (short)1, (short)0 )
)
{
failed( "text field did not commit (or radio button did not update)" );
return;
}
// undo the changes done so far, so we leave the document in a clean state for the next test
undoRecordByUI();
}
/* ------------------------------------------------------------------ */
/** some tests with updating the table via our controls
*/
public void checkRowUpdates() throws com.sun.star.uno.Exception, java.lang.Exception
{
// start with inserting a new record
moveToInsertRow();
if ( !verifyCleanInsertRow() )
{
failed( "insert row not in expected clean state" );
return;
}
userTextInput( "ID", "3", true );
userTextInput( "f_integer", "729", true );
userTextInput( "f_text", "test", true );
userTextInput( "f_decimal", "152343", true );
userTextInput( "f_date", "31.12.1999", true );
userTextInput( "f_time", "23:59:59", true );
// move to the next row, this should automatically commit the changes we made
nextRecordByUI();
// and back to the row we just inserted
previousRecordByUI();
if ( !checkDoubleValue( 3, "ID", "Value" )
|| !checkDoubleValue( 729, "f_integer", "EffectiveValue" )
|| !checkStringValue( "test", "f_text", "Text" )
|| !checkDoubleValue( 152343, "f_decimal", "Value" )
|| !checkIntValue ( 19991231, "f_date", "Date" )
|| !checkIntValue ( 23595900, "f_time", "Time" )
)
{
failed( "the changes we made on the insert row have not been committed" );
return;
}
// now change the data, to see if regular updates work, too
userTextInput( "ID", "4", true );
userTextInput( "f_integer", "618", true );
userTextInput( "f_text", "yet another stupid, meaningless text", true );
userTextInput( "f_decimal", "4562", true );
userTextInput( "f_date", "26.03.2004", true );
userTextInput( "f_time", "17:05:00", true );
// move to the next row, this should automatically commit the changes we made
nextRecordByUI();
// and back to the row we just inserted
previousRecordByUI();
if ( !checkDoubleValue( 4, "ID", "Value" )
|| !checkDoubleValue( 618, "f_integer", "EffectiveValue" )
|| !checkStringValue( "yet another stupid, meaningless text", "f_text", "Text" )
|| !checkDoubleValue( 4562, "f_decimal", "Value" )
|| !checkIntValue ( 20040326, "f_date", "Date" )
|| !checkIntValue ( 17050000, "f_time", "Time" )
)
{
failed( "the changes we made on the insert row have not been committed" );
return;
}
m_document.getCurrentView().grabControlFocus( getControlModel( "ID" ) );
}
/* ------------------------------------------------------------------ */
private boolean verifyCleanInsertRow( ) throws com.sun.star.uno.Exception, java.lang.Exception
{
// and check the content of the various controls
return ( checkRadios( (short)0, (short)0, (short)0 )
&& checkShortValue( (short)2, "f_tinyint", "State" )
&& checkStringValue( "", "f_text", "Text" )
&& checkNullValue( "ID", "Value" )
&& checkNullValue( "f_integer", "EffectiveValue" )
&& checkNullValue( "f_decimal", "Value" )
);
}
/* ------------------------------------------------------------------ */
/// post-test cleanup
public void after() throws com.sun.star.uno.Exception, java.lang.Exception
{
// close our document
if ( m_document != null )
{
XCloseable closeDoc = (XCloseable)UnoRuntime.queryInterface( XCloseable.class,
m_document.getDocument() );
closeDoc.close( true );
}
}
//=========================================================================
/* ------------------------------------------------------------------ */
private boolean ensureDataSource() throws Exception
{
m_orb = (XMultiServiceFactory)param.getMSF();
XNameAccess databaseContext = (XNameAccess)UnoRuntime.queryInterface( XNameAccess.class,
m_orb.createInstance( "com.sun.star.sdb.DatabaseContext" ) );
XNamingService namingService = (XNamingService)UnoRuntime.queryInterface( XNamingService.class,
databaseContext );
// revoke the data source, if it previously existed
if ( databaseContext.hasByName( m_dataSourceName ) )
namingService.revokeObject( m_dataSourceName );
// // create a new ODB file, and register it with its URL
m_databaseDocument = new HsqlDatabase( m_orb );
String documentURL = m_databaseDocument.getDocumentURL();
namingService.registerObject( m_dataSourceName, databaseContext.getByName( documentURL ) );
m_dataSource = (XDataSource)UnoRuntime.queryInterface( XDataSource.class,
databaseContext.getByName( m_dataSourceName ) );
m_dataSourceProps = dbfTools.queryPropertySet( m_dataSource );
return m_dataSource != null;
}
/* ------------------------------------------------------------------ */
/** retrives the control model with the given name
*/
private XPropertySet getControlModel( String name ) throws com.sun.star.uno.Exception, java.lang.Exception
{
XNameAccess nameAccess = (XNameAccess)UnoRuntime.queryInterface( XNameAccess.class,
m_masterForm );
return (XPropertySet)UnoRuntime.queryInterface( XPropertySet.class,
nameAccess.getByName( name ) );
}
/* ------------------------------------------------------------------ */
private void createSampleDocument() throws com.sun.star.uno.Exception, java.lang.Exception
{
m_document = DocumentHelper.blankTextDocument( m_orb );
m_formLayer = new FormLayer( m_document );
// insert some controls
XPropertySet xIDField = m_formLayer.insertControlLine( "DatabaseNumericField", "ID", "", 3 );
m_formLayer.insertControlLine( "DatabaseFormattedField","f_integer", "", 11 );
m_formLayer.insertControlLine( "DatabaseTextField", "f_text", "", 19 );
XPropertySet xDecField = m_formLayer.insertControlLine( "DatabaseNumericField", "f_decimal", "", 27 );
m_formLayer.insertControlLine( "DatabaseDateField", "f_date", "", 35 );
XPropertySet xTimeField = m_formLayer.insertControlLine( "DatabaseTimeField", "f_time", "", 43 );
m_formLayer.insertControlLine( "DatabaseDateField", "f_timestamp", "_date", 51 );
m_formLayer.insertControlLine( "DatabaseTimeField", "f_timestamp", "_time", 59 );
XPropertySet xImageField = m_formLayer.insertControlLine( "DatabaseImageControl", "f_blob", "", 2, 67, 40 );
m_formLayer.insertControlLine( "DatabaseTextField", "f_text_enum", "_text", 80, 25, 6 );
XPropertySet xCheckBox = m_formLayer.insertControlLine( "DatabaseCheckBox", "f_tinyint", "", 80, 33, 6 );
m_formLayer.insertControlLine( "DatabaseFormattedField","f_tinyint", "_format",80, 41, 6 );
m_formLayer.insertControlLine( "DatabaseTextField", "dummy", "", 150 );
xIDField.setPropertyValue( "DecimalAccuracy", new Short( (short)0 ) );
xImageField.setPropertyValue( "ScaleImage", new Boolean( (boolean)true) );
xImageField.setPropertyValue( "Tabstop", new Boolean( true) );
xCheckBox.setPropertyValue( "TriState", new Boolean( true ) );
xCheckBox.setPropertyValue( "DefaultState", new Short( (short)2 ) );
xTimeField.setPropertyValue( "TimeFormat", new Short( (short)1 ) );
xTimeField.setPropertyValue( "TimeMax", new Integer( 23595999 ) );
// the logical form
m_masterForm = (XPropertySet)dbfTools.getParent( xIDField, XPropertySet.class );
m_masterForm.setPropertyValue( "DataSourceName", m_dataSourceProps.getPropertyValue( "Name" ) );
m_masterForm.setPropertyValue( "CommandType", new Integer( CommandType.TABLE ) );
m_masterForm.setPropertyValue( "Command", s_tableName );
insertRadio( 3, "none", "none" );
insertRadio( 10, "normal", "normal" );
insertRadio( 17, "important", "important" );
// switch the forms into data entry mode
m_document.getCurrentView( ).toggleFormDesignMode( );
// set the focus to the ID control
m_document.getCurrentView().grabControlFocus( xIDField );
}
/* ------------------------------------------------------------------ */
private void insertRadio( int nYPos, String label, String refValue ) throws com.sun.star.uno.Exception, java.lang.Exception
{
XPropertySet xRadio = m_formLayer.createControlAndShape( "DatabaseRadioButton", 106, nYPos, 25, 6 );
xRadio.setPropertyValue( "Label", label );
xRadio.setPropertyValue( "RefValue", refValue );
xRadio.setPropertyValue( "Name", new String( "radio_group" ) );
xRadio.setPropertyValue( "DataField", new String( "f_text_enum" ) );
}
/* ------------------------------------------------------------------ */
private String getCreateTableStatement( )
{
String sCreateTableStatement = "CREATE TABLE \"" + s_tableName + "\" (";
sCreateTableStatement += "\"ID\" INTEGER NOT NULL PRIMARY KEY,";
sCreateTableStatement += "\"f_integer\" INTEGER default NULL,";
sCreateTableStatement += "\"f_text\" VARCHAR(50) default NULL,";
sCreateTableStatement += "\"f_decimal\" DECIMAL(10,2) default NULL,";
sCreateTableStatement += "\"f_date\" DATE default NULL,";
sCreateTableStatement += "\"f_time\" TIME default NULL,";
sCreateTableStatement += "\"f_timestamp\" DATETIME default NULL,";
sCreateTableStatement += "\"f_blob\" VARBINARY,";
sCreateTableStatement += "\"f_text_enum\" VARCHAR(50) default NULL,";
sCreateTableStatement += "\"f_tinyint\" TINYINT default NULL";
sCreateTableStatement += ");";
return sCreateTableStatement;
}
/* ------------------------------------------------------------------ */
private String[] getSampleDataValueString( ) throws java.lang.Exception
{
String[] aValues = new String[] {
"1,42,'the answer',0.12,'2003-09-22','15:00:00','2003-09-23 17:15:23',NULL,'none',1",
"2,13,'the question',12.43,'2003-09-24','16:18:00','2003-09-24 08:45:12',NULL,'none',0"
};
return aValues;
}
/* ------------------------------------------------------------------ */
private boolean ensureTables() throws com.sun.star.uno.Exception, java.lang.Exception
{
XConnection xConn = m_dataSource.getConnection( "", "" );
assure( "could not connect to the data source", xConn != null );
// drop the table, if it already exists
if ( !implExecuteStatement( xConn, "DROP TABLE \"" + s_tableName + "\" IF EXISTS" )
|| !implExecuteStatement( xConn, getCreateTableStatement() )
)
{
failed( "could not create the required sample table!" );
return false;
}
String sInsertionPrefix = "INSERT INTO \"" + s_tableName + "\" VALUES (";
String[] aValues = getSampleDataValueString();
for ( int i=0; i<aValues.length; ++i )
if ( !implExecuteStatement( xConn, sInsertionPrefix + aValues[ i ] + ")" ) )
{
failed( "could not create the required sample data" );
return false;
}
m_databaseDocument.getDataSource().refreshTables( xConn );
// do not need the connection anymore
dbfTools.disposeComponent( xConn );
return true;
}
/* ------------------------------------------------------------------ */
/// checks the 3 radio buttons for the given states
private boolean checkRadios( short stateNone, short stateNormal, short stateImportant ) throws com.sun.star.uno.Exception, java.lang.Exception
{
if ( ((Short)getRadioModel( "radio_group", "none" ).getPropertyValue( "State" )).shortValue() != stateNone )
{
failed( "wrong value of the 'none' radio button!" );
}
else if ( ((Short)getRadioModel( "radio_group", "normal" ).getPropertyValue( "State" )).shortValue() != stateNormal )
{
failed( "wrong value of the 'normal' radio button!" );
}
else if ( ((Short)getRadioModel( "radio_group", "important" ).getPropertyValue( "State" )).shortValue() != stateImportant )
{
failed( "wrong value of the 'important' radio button!" );
}
else
return true;
return false;
}
/* ------------------------------------------------------------------ */
private boolean checkNullValue( String fieldName, String propertyName ) throws com.sun.star.uno.Exception, java.lang.Exception
{
Object value = getControlModel( fieldName ).getPropertyValue( propertyName );
if ( !util.utils.isVoid( value ) )
{
log.println( "wrong value of the " + fieldName + " field!" );
log.println( " expected: <null/>" );
log.println( " found : " + value.toString() );
}
else
return true;
return false;
}
/* ------------------------------------------------------------------ */
private boolean checkIntValue( int requiredValue, String fieldName, String propertyName ) throws com.sun.star.uno.Exception, java.lang.Exception
{
try
{
if ( fieldName.equals( "f_time" ) )
// http://bugs.mysql.com/bug.php?id=5681
return true;
int currentValue = ((Integer)getControlModel( fieldName ).getPropertyValue( propertyName )).intValue();
if ( currentValue != requiredValue )
{
log.println( "wrong value of the " + fieldName + " field!" );
log.println( " expected: " + String.valueOf( requiredValue ) );
log.println( " found : " + String.valueOf( currentValue ) );
}
else
return true;
}
catch( com.sun.star.uno.Exception e )
{
log.println( "caught an exception while retrieving property value '" + propertyName + "' of control model '" + fieldName + "'" );
throw e;
}
return false;
}
/* ------------------------------------------------------------------ */
private boolean checkShortValue( short requiredValue, String fieldName, String propertyName ) throws com.sun.star.uno.Exception, java.lang.Exception
{
try
{
short currentValue = ((Short)getControlModel( fieldName ).getPropertyValue( propertyName )).shortValue();
if ( currentValue != requiredValue )
{
log.println( "wrong value of the " + fieldName + " field!" );
log.println( " expected: " + String.valueOf( requiredValue ) );
log.println( " found : " + String.valueOf( currentValue ) );
}
else
return true;
}
catch( com.sun.star.uno.Exception e )
{
log.println( "caught an exception while retrieving property value '" + propertyName + "' of control model '" + fieldName + "'" );
throw e;
}
return false;
}
/* ------------------------------------------------------------------ */
private boolean checkDoubleValue( double requiredValue, String fieldName, String propertyName ) throws com.sun.star.uno.Exception, java.lang.Exception
{
double currentValue = ((Double)getControlModel( fieldName ).getPropertyValue( propertyName )).doubleValue();
if ( currentValue != requiredValue )
{
log.println( "wrong value of the " + fieldName + " field!" );
log.println( " expected: " + String.valueOf( requiredValue ) );
log.println( " found : " + String.valueOf( currentValue ) );
}
else
return true;
return false;
}
/* ------------------------------------------------------------------ */
private boolean checkStringValue( String requiredValue, String fieldName, String propertyName ) throws com.sun.star.uno.Exception, java.lang.Exception
{
String currentValue = (String)getControlModel( fieldName ).getPropertyValue( propertyName );
if ( !currentValue.equals( requiredValue ) )
{
log.println( "wrong value of the " + fieldName + " field!" );
log.println( " expected: " + requiredValue );
log.println( " found : " + currentValue );
}
else
return true;
return false;
}
/* ------------------------------------------------------------------ */
private XPropertySet getRadioModel( String name, String refValue ) throws com.sun.star.uno.Exception, java.lang.Exception
{
return m_formLayer.getRadioModelByRefValue( m_masterForm, name, refValue );
}
/* ------------------------------------------------------------------ */
/** executes the given statement on the given connection
*/
protected boolean implExecuteStatement( XConnection xConn, String sStatement ) throws java.lang.Exception
{
try
{
m_databaseDocument.executeSQL( sStatement );
}
catch(com.sun.star.sdbc.SQLException e)
{
System.err.println( e );
return false;
}
return true;
}
/* ------------------------------------------------------------------ */
/** simulates a user's text input into a control given by model name
*/
private void userTextInput( String modelName, String text, boolean withCommit ) throws com.sun.star.uno.Exception, java.lang.Exception
{
userTextInput( getControlModel( modelName ), text, withCommit );
}
/* ------------------------------------------------------------------ */
/** simulates a user's text input into a control given by control model
*/
private void userTextInput( XPropertySet controlModel, String text, boolean withCommit ) throws com.sun.star.uno.Exception, java.lang.Exception
{
// the form runtime environment (namely the form controller) rely on focus events for recognizing
// control content changes ...
if ( withCommit )
m_document.getCurrentView().grabControlFocus( controlModel );
// we will *not* simply set the value property at the model. This is not the same as
// doing a user input, as the latter will trigger a lot of notifications, which the forms runtime environment
// (namely the FormController) relies on to notice that the control changed.
// Instead, we use the Accessibility interfaces of the control to simulate text input
XAccessible formattedAccessible = (XAccessible)UnoRuntime.queryInterface( XAccessible.class,
m_document.getCurrentView().getControl( controlModel )
);
XAccessibleEditableText textAccess = (XAccessibleEditableText)UnoRuntime.queryInterface( XAccessibleEditableText.class,
formattedAccessible.getAccessibleContext() );
textAccess.setText( text );
// focus back to a dummy control model so the content of the model we just changed will
// be committed to the underlying database column
if ( withCommit )
m_document.getCurrentView().grabControlFocus( getControlModel( "dummy" ) );
}
/* ------------------------------------------------------------------ */
private void moveToInsertRow() throws com.sun.star.uno.Exception, java.lang.Exception
{
XResultSetUpdate xResultSet = (XResultSetUpdate)UnoRuntime.queryInterface( XResultSetUpdate.class, m_masterForm );
xResultSet.moveToInsertRow( );
}
/* ------------------------------------------------------------------ */
private void moveToFirst() throws com.sun.star.uno.Exception, java.lang.Exception
{
XResultSet xResultSet = (XResultSet)UnoRuntime.queryInterface( XResultSet.class, m_masterForm );
xResultSet.first( );
}
/* ------------------------------------------------------------------ */
private void moveToNext() throws com.sun.star.uno.Exception, java.lang.Exception
{
XResultSet xResultSet = (XResultSet)UnoRuntime.queryInterface( XResultSet.class, m_masterForm );
xResultSet.next( );
}
/* ------------------------------------------------------------------ */
/** simulates pressing a toolbox button with the given URL
*/
private void executeSlot( String slotURL ) throws java.lang.Exception
{
XDispatch xDispatch = (XDispatch)m_document.getCurrentView().getDispatcher( slotURL );
URL[] url = new URL[] { new URL() };
url[0].Complete = slotURL;
XURLTransformer xTransformer = (XURLTransformer)UnoRuntime.queryInterface(
XURLTransformer.class, m_orb.createInstance( "com.sun.star.util.URLTransformer" ) );
xTransformer.parseStrict( url );
PropertyValue[] aArgs = new PropertyValue[0];
xDispatch.dispatch( url[0], aArgs );
}
/* ------------------------------------------------------------------ */
/** undos the changes on the current record, by simulating pressing of the respective toolbox button
*/
private void undoRecordByUI() throws java.lang.Exception
{
executeSlot( ".uno:RecUndo" );
}
/* ------------------------------------------------------------------ */
/** saves the current record, by simulating pressing of the respective toolbox button
*/
private void saveRecordByUI() throws java.lang.Exception
{
executeSlot( ".uno:RecSave" );
}
/* ------------------------------------------------------------------ */
/** moves to the next record, by simulating pressing of the respective toolbox button
*/
private void nextRecordByUI() throws java.lang.Exception
{
executeSlot( ".uno:NextRecord" );
}
/* ------------------------------------------------------------------ */
/** moves to the previous record, by simulating pressing of the respective toolbox button
*/
private void previousRecordByUI() throws java.lang.Exception
{
executeSlot( ".uno:PrevRecord" );
}
/* ------------------------------------------------------------------ */
private void createImageFile() throws java.io.IOException
{
m_sImageURL = util.utils.getOfficeTempDir( m_orb ) + "image.gif";
FileOutputStream aFile = new FileOutputStream( m_sImageURL );
aFile.write( getSamplePicture() );
aFile.close();
log.println( "created temporary image file: " + m_sImageURL );
// for later setting the url at the imaghe control, we need a real URL, no system path
m_sImageURL = util.utils.getOfficeTemp( m_orb ) + "image.gif";
}
/* ------------------------------------------------------------------ */
private byte[] getSamplePicture()
{
byte[] aBytes = new byte[] {
(byte)0x47, (byte)0x49, (byte)0x46, (byte)0x38, (byte)0x39, (byte)0x61, (byte)0x0A, (byte)0x00, (byte)0x0A, (byte)0x00, (byte)0xB3, (byte)0x00, (byte)0x00, (byte)0xFF, (byte)0x00, (byte)0x00,
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0x00, (byte)0x00, (byte)0xFF, (byte)0xFF, (byte)0x00, (byte)0xFF, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xFF, (byte)0xFF,
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0x2C, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x0A, (byte)0x00, (byte)0x0A, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x20, (byte)0x10, (byte)0xC8, (byte)0x49, (byte)0x41, (byte)0xB9, (byte)0xF8, (byte)0xCA,
(byte)0x12, (byte)0xBA, (byte)0x2F, (byte)0x5B, (byte)0x30, (byte)0x8C, (byte)0x43, (byte)0x00, (byte)0x5A, (byte)0x22, (byte)0x41, (byte)0x94, (byte)0x27, (byte)0x37, (byte)0xA8, (byte)0x6C,
(byte)0x48, (byte)0xC6, (byte)0xA8, (byte)0xD7, (byte)0xB5, (byte)0x19, (byte)0x56, (byte)0xED, (byte)0x11, (byte)0x00, (byte)0x3B
};
return aBytes;
}
private byte[] getSamplePictureBytes()
{
byte[] aBytes = new byte[] {
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte