1
0
Fork 0
libreoffice/odk/examples/DevelopersGuide/Forms/ControlLock.java
Daniel Baumann 8e63e14cf6
Adding upstream version 4:25.2.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 16:20:04 +02:00

223 lines
8.4 KiB
Java

/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
*
* The Contents of this file are made available subject to the terms of
* the BSD license.
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Sun Microsystems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*************************************************************************/
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.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 = Boolean.valueOf( bLockIt );
m_nLevel = 0;
}
/* ------------------------------------------------------------------ */
@Override
protected boolean shouldStepInto( XIndexContainer xContainer )
{
if ( !super.shouldStepInto( xContainer ) )
return false; // don't try to be more clever than our base class
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;
}
/* ------------------------------------------------------------------ */
@Override
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
*/
private 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 = 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
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */