1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * The Contents of this file are made available subject to the terms of 4*cdf0e10cSrcweir * the BSD license. 5*cdf0e10cSrcweir * 6*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 7*cdf0e10cSrcweir * All rights reserved. 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * Redistribution and use in source and binary forms, with or without 10*cdf0e10cSrcweir * modification, are permitted provided that the following conditions 11*cdf0e10cSrcweir * are met: 12*cdf0e10cSrcweir * 1. Redistributions of source code must retain the above copyright 13*cdf0e10cSrcweir * notice, this list of conditions and the following disclaimer. 14*cdf0e10cSrcweir * 2. Redistributions in binary form must reproduce the above copyright 15*cdf0e10cSrcweir * notice, this list of conditions and the following disclaimer in the 16*cdf0e10cSrcweir * documentation and/or other materials provided with the distribution. 17*cdf0e10cSrcweir * 3. Neither the name of Sun Microsystems, Inc. nor the names of its 18*cdf0e10cSrcweir * contributors may be used to endorse or promote products derived 19*cdf0e10cSrcweir * from this software without specific prior written permission. 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22*cdf0e10cSrcweir * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23*cdf0e10cSrcweir * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24*cdf0e10cSrcweir * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25*cdf0e10cSrcweir * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26*cdf0e10cSrcweir * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27*cdf0e10cSrcweir * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 28*cdf0e10cSrcweir * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29*cdf0e10cSrcweir * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 30*cdf0e10cSrcweir * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 31*cdf0e10cSrcweir * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32*cdf0e10cSrcweir * 33*cdf0e10cSrcweir *************************************************************************/ 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir import com.sun.star.uno.*; 36*cdf0e10cSrcweir import com.sun.star.lang.*; 37*cdf0e10cSrcweir import com.sun.star.container.*; 38*cdf0e10cSrcweir import com.sun.star.beans.*; 39*cdf0e10cSrcweir import com.sun.star.form.*; 40*cdf0e10cSrcweir import com.sun.star.util.*; 41*cdf0e10cSrcweir import com.sun.star.sdbc.*; 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir /**************************************************************************/ 45*cdf0e10cSrcweir /** A helper class for recursively locking control models which are bound 46*cdf0e10cSrcweir to a specific field 47*cdf0e10cSrcweir */ 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir class LockControlModels extends ComponentTreeTraversal 50*cdf0e10cSrcweir { 51*cdf0e10cSrcweir private String m_sDataField; 52*cdf0e10cSrcweir private Boolean m_aLockIt; 53*cdf0e10cSrcweir private int m_nLevel; // nesting level relative to the form we started with 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir /* ------------------------------------------------------------------ */ 56*cdf0e10cSrcweir public LockControlModels( String sDataField, boolean bLockIt ) 57*cdf0e10cSrcweir { 58*cdf0e10cSrcweir m_sDataField = sDataField; 59*cdf0e10cSrcweir m_aLockIt = new Boolean( bLockIt ); 60*cdf0e10cSrcweir m_nLevel = 0; 61*cdf0e10cSrcweir } 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir /* ------------------------------------------------------------------ */ 64*cdf0e10cSrcweir protected boolean shouldStepInto( XIndexContainer xContainer ) throws com.sun.star.uno.Exception 65*cdf0e10cSrcweir { 66*cdf0e10cSrcweir if ( !super.shouldStepInto( xContainer ) ) 67*cdf0e10cSrcweir return false; // don't try to be more clever than our base class 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir XForm xForm = (XForm)UnoRuntime.queryInterface( XForm.class, xContainer ); 70*cdf0e10cSrcweir if ( ( null != xForm ) && ( m_nLevel > 1 ) ) 71*cdf0e10cSrcweir // don't step into sub forms - we only handle the form we were originally 72*cdf0e10cSrcweir // applied to 73*cdf0e10cSrcweir return false; 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir return true; 76*cdf0e10cSrcweir } 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir /* ------------------------------------------------------------------ */ 79*cdf0e10cSrcweir public void handle( Object aFormComponent ) throws com.sun.star.uno.Exception 80*cdf0e10cSrcweir { 81*cdf0e10cSrcweir // entering this nesting level 82*cdf0e10cSrcweir ++m_nLevel; 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir // check if the component has a DataField property 85*cdf0e10cSrcweir XPropertySet xCompProps = UNO.queryPropertySet( aFormComponent ); 86*cdf0e10cSrcweir XPropertySetInfo xPSI = null; 87*cdf0e10cSrcweir if ( null != xCompProps ) 88*cdf0e10cSrcweir xPSI = xCompProps.getPropertySetInfo(); 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir if ( ( null != xPSI ) && xPSI.hasPropertyByName( "DataField" ) ) 91*cdf0e10cSrcweir { // indeed it has .... 92*cdf0e10cSrcweir String sDataField = (String)xCompProps.getPropertyValue( "DataField" ); 93*cdf0e10cSrcweir if ( sDataField.equals( m_sDataField ) ) 94*cdf0e10cSrcweir { // we found a control model which is bound to what we're looking for 95*cdf0e10cSrcweir xCompProps.setPropertyValue( "ReadOnly", m_aLockIt ); 96*cdf0e10cSrcweir } 97*cdf0e10cSrcweir } 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir // allow the super class to step down, if possible 100*cdf0e10cSrcweir super.handle( aFormComponent ); 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir // leaving this nesting level 103*cdf0e10cSrcweir --m_nLevel; 104*cdf0e10cSrcweir } 105*cdf0e10cSrcweir }; 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir /**************************************************************************/ 108*cdf0e10cSrcweir /** a class which automatically handles control locking. 109*cdf0e10cSrcweir <p>The class has to be bound to a form. Upon every movement of the form, 110*cdf0e10cSrcweir all controls which are bound to a (to be specified) field are locked 111*cdf0e10cSrcweir on existing and unlocked on new records.</p> 112*cdf0e10cSrcweir */ 113*cdf0e10cSrcweir class ControlLock implements XRowSetListener 114*cdf0e10cSrcweir { 115*cdf0e10cSrcweir private XPropertySet m_xForm; 116*cdf0e10cSrcweir private String m_sDataField; 117*cdf0e10cSrcweir private boolean m_bLockingEnabled; 118*cdf0e10cSrcweir private boolean m_bPreviousRoundLock; 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir /* ------------------------------------------------------------------ */ 121*cdf0e10cSrcweir ControlLock( XPropertySet xForm, String sBoundDataField ) 122*cdf0e10cSrcweir { 123*cdf0e10cSrcweir m_xForm = xForm; 124*cdf0e10cSrcweir m_sDataField = sBoundDataField; 125*cdf0e10cSrcweir m_bLockingEnabled = false; 126*cdf0e10cSrcweir m_bPreviousRoundLock = false; 127*cdf0e10cSrcweir } 128*cdf0e10cSrcweir 129*cdf0e10cSrcweir /* ------------------------------------------------------------------ */ 130*cdf0e10cSrcweir /** updates the locks on the affected controls 131*cdf0e10cSrcweir */ 132*cdf0e10cSrcweir protected void updateLocks( ) 133*cdf0e10cSrcweir { 134*cdf0e10cSrcweir try 135*cdf0e10cSrcweir { 136*cdf0e10cSrcweir // first determine if we need to lock 137*cdf0e10cSrcweir Boolean aIsNewRecord = (Boolean)m_xForm.getPropertyValue( "IsNew" ); 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir boolean bNeedLock = m_bLockingEnabled && !aIsNewRecord.booleanValue(); 140*cdf0e10cSrcweir 141*cdf0e10cSrcweir if ( m_bPreviousRoundLock != bNeedLock ) 142*cdf0e10cSrcweir { 143*cdf0e10cSrcweir LockControlModels aLocker = new LockControlModels( m_sDataField, bNeedLock ); 144*cdf0e10cSrcweir aLocker.handle( m_xForm ); 145*cdf0e10cSrcweir m_bPreviousRoundLock = bNeedLock; 146*cdf0e10cSrcweir } 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir // please note that we choose the expensive way here: We always loop through 149*cdf0e10cSrcweir // _all_ control models belonging to the form. This clearly slows down the 150*cdf0e10cSrcweir // whole process. 151*cdf0e10cSrcweir // A better solution would be to cache the affected control models. Then we 152*cdf0e10cSrcweir // could either rely on the fact that the model hierarchy is static, or we 153*cdf0e10cSrcweir // could add ourself as container listener to the form. 154*cdf0e10cSrcweir } 155*cdf0e10cSrcweir catch(com.sun.star.uno.Exception e) 156*cdf0e10cSrcweir { 157*cdf0e10cSrcweir System.out.println(e); 158*cdf0e10cSrcweir e.printStackTrace(); 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir } 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir /* ------------------------------------------------------------------ */ 163*cdf0e10cSrcweir /** enables the locking in general 164*cdf0e10cSrcweir <p>If the control models are really locked depends on the current 165*cdf0e10cSrcweir record of the form: on the insert row, controls are never locked.</p> 166*cdf0e10cSrcweir */ 167*cdf0e10cSrcweir public void enableLock( boolean bLock ) 168*cdf0e10cSrcweir { 169*cdf0e10cSrcweir // remember this new setting 170*cdf0e10cSrcweir m_bLockingEnabled = bLock; 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir // add or remove ourself as listener to get notified of cursor moves 173*cdf0e10cSrcweir XRowSet xRowSet = (XRowSet)UnoRuntime.queryInterface( 174*cdf0e10cSrcweir XRowSet.class, m_xForm ); 175*cdf0e10cSrcweir if ( m_bLockingEnabled ) 176*cdf0e10cSrcweir { 177*cdf0e10cSrcweir xRowSet.addRowSetListener( this ); 178*cdf0e10cSrcweir } 179*cdf0e10cSrcweir else 180*cdf0e10cSrcweir { 181*cdf0e10cSrcweir xRowSet.removeRowSetListener( this ); 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir // update the locks 185*cdf0e10cSrcweir updateLocks(); 186*cdf0e10cSrcweir } 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir /* ================================================================== 189*cdf0e10cSrcweir = UNO callbacks 190*cdf0e10cSrcweir ================================================================== */ 191*cdf0e10cSrcweir 192*cdf0e10cSrcweir /* ------------------------------------------------------------------ */ 193*cdf0e10cSrcweir // XResetListener overridables 194*cdf0e10cSrcweir /* ------------------------------------------------------------------ */ 195*cdf0e10cSrcweir public void cursorMoved( EventObject aEvent ) throws com.sun.star.uno.RuntimeException 196*cdf0e10cSrcweir { 197*cdf0e10cSrcweir updateLocks( ); 198*cdf0e10cSrcweir } 199*cdf0e10cSrcweir 200*cdf0e10cSrcweir /* ------------------------------------------------------------------ */ 201*cdf0e10cSrcweir public void rowChanged( EventObject aEvent ) throws com.sun.star.uno.RuntimeException 202*cdf0e10cSrcweir { 203*cdf0e10cSrcweir // not interested in 204*cdf0e10cSrcweir } 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir /* ------------------------------------------------------------------ */ 207*cdf0e10cSrcweir public void rowSetChanged( EventObject aEvent ) throws com.sun.star.uno.RuntimeException 208*cdf0e10cSrcweir { 209*cdf0e10cSrcweir // not interested in 210*cdf0e10cSrcweir } 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir /* ------------------------------------------------------------------ */ 213*cdf0e10cSrcweir // XEventListener overridables 214*cdf0e10cSrcweir /* ------------------------------------------------------------------ */ 215*cdf0e10cSrcweir public void disposing( EventObject aEvent ) 216*cdf0e10cSrcweir { 217*cdf0e10cSrcweir // not interested in 218*cdf0e10cSrcweir } 219*cdf0e10cSrcweir } 220