blob: e7ece3e800bb568d4a39dd00b60ecd5479d1057f [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
import com.sun.star.uno.*;
import com.sun.star.lang.*;
import com.sun.star.container.*;
import com.sun.star.beans.*;
import com.sun.star.form.*;
import com.sun.star.util.*;
import com.sun.star.sdbc.*;
/**************************************************************************/
/** A helper class for recursively locking control models which are bound
to a specific field
*/
class LockControlModels extends ComponentTreeTraversal
{
private String m_sDataField;
private Boolean m_aLockIt;
private int m_nLevel; // nesting level relative to the form we started with
/* ------------------------------------------------------------------ */
public LockControlModels( String sDataField, boolean bLockIt )
{
m_sDataField = sDataField;
m_aLockIt = new Boolean( bLockIt );
m_nLevel = 0;
}
/* ------------------------------------------------------------------ */
protected boolean shouldStepInto( XIndexContainer xContainer ) throws com.sun.star.uno.Exception
{
if ( !super.shouldStepInto( xContainer ) )
return false; // don't try to be more clever than our base class
XForm xForm = (XForm)UnoRuntime.queryInterface( XForm.class, xContainer );
if ( ( null != xForm ) && ( m_nLevel > 1 ) )
// don't step into sub forms - we only handle the form we were originally
// applied to
return false;
return true;
}
/* ------------------------------------------------------------------ */
public void handle( Object aFormComponent ) throws com.sun.star.uno.Exception
{
// entering this nesting level
++m_nLevel;
// check if the component has a DataField property
XPropertySet xCompProps = UNO.queryPropertySet( aFormComponent );
XPropertySetInfo xPSI = null;
if ( null != xCompProps )
xPSI = xCompProps.getPropertySetInfo();
if ( ( null != xPSI ) && xPSI.hasPropertyByName( "DataField" ) )
{ // indeed it has ....
String sDataField = (String)xCompProps.getPropertyValue( "DataField" );
if ( sDataField.equals( m_sDataField ) )
{ // we found a control model which is bound to what we're looking for
xCompProps.setPropertyValue( "ReadOnly", m_aLockIt );
}
}
// allow the super class to step down, if possible
super.handle( aFormComponent );
// leaving this nesting level
--m_nLevel;
}
};
/**************************************************************************/
/** a class which automatically handles control locking.
<p>The class has to be bound to a form. Upon every movement of the form,
all controls which are bound to a (to be specified) field are locked
on existing and unlocked on new records.</p>
*/
class ControlLock implements XRowSetListener
{
private XPropertySet m_xForm;
private String m_sDataField;
private boolean m_bLockingEnabled;
private boolean m_bPreviousRoundLock;
/* ------------------------------------------------------------------ */
ControlLock( XPropertySet xForm, String sBoundDataField )
{
m_xForm = xForm;
m_sDataField = sBoundDataField;
m_bLockingEnabled = false;
m_bPreviousRoundLock = false;
}
/* ------------------------------------------------------------------ */
/** updates the locks on the affected controls
*/
protected void updateLocks( )
{
try
{
// first determine if we need to lock
Boolean aIsNewRecord = (Boolean)m_xForm.getPropertyValue( "IsNew" );
boolean bNeedLock = m_bLockingEnabled && !aIsNewRecord.booleanValue();
if ( m_bPreviousRoundLock != bNeedLock )
{
LockControlModels aLocker = new LockControlModels( m_sDataField, bNeedLock );
aLocker.handle( m_xForm );
m_bPreviousRoundLock = bNeedLock;
}
// please note that we choose the expensive way here: We always loop through
// _all_ control models belonging to the form. This clearly slows down the
// whole process.
// A better solution would be to cache the affected control models. Then we
// could either rely on the fact that the model hierarchy is static, or we
// could add ourself as container listener to the form.
}
catch(com.sun.star.uno.Exception e)
{
System.out.println(e);
e.printStackTrace();
}
}
/* ------------------------------------------------------------------ */
/** enables the locking in general
<p>If the control models are really locked depends on the current
record of the form: on the insert row, controls are never locked.</p>
*/
public void enableLock( boolean bLock )
{
// remember this new setting
m_bLockingEnabled = bLock;
// add or remove ourself as listener to get notified of cursor moves
XRowSet xRowSet = (XRowSet)UnoRuntime.queryInterface(
XRowSet.class, m_xForm );
if ( m_bLockingEnabled )
{
xRowSet.addRowSetListener( this );
}
else
{
xRowSet.removeRowSetListener( this );
}
// update the locks
updateLocks();
}
/* ==================================================================
= UNO callbacks
================================================================== */
/* ------------------------------------------------------------------ */
// XResetListener overridables
/* ------------------------------------------------------------------ */
public void cursorMoved( EventObject aEvent ) throws com.sun.star.uno.RuntimeException
{
updateLocks( );
}
/* ------------------------------------------------------------------ */
public void rowChanged( EventObject aEvent ) throws com.sun.star.uno.RuntimeException
{
// not interested in
}
/* ------------------------------------------------------------------ */
public void rowSetChanged( EventObject aEvent ) throws com.sun.star.uno.RuntimeException
{
// not interested in
}
/* ------------------------------------------------------------------ */
// XEventListener overridables
/* ------------------------------------------------------------------ */
public void disposing( EventObject aEvent )
{
// not interested in
}
}