1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 import com.sun.star.uno.*; 25 import com.sun.star.lang.*; 26 import com.sun.star.container.*; 27 import com.sun.star.beans.*; 28 import com.sun.star.form.*; 29 import com.sun.star.util.*; 30 import com.sun.star.sdbc.*; 31 32 33 /**************************************************************************/ 34 /** A helper class for recursively locking control models which are bound 35 to a specific field 36 */ 37 38 class LockControlModels extends ComponentTreeTraversal 39 { 40 private String m_sDataField; 41 private Boolean m_aLockIt; 42 private int m_nLevel; // nesting level relative to the form we started with 43 44 /* ------------------------------------------------------------------ */ LockControlModels( String sDataField, boolean bLockIt )45 public LockControlModels( String sDataField, boolean bLockIt ) 46 { 47 m_sDataField = sDataField; 48 m_aLockIt = new Boolean( bLockIt ); 49 m_nLevel = 0; 50 } 51 52 /* ------------------------------------------------------------------ */ shouldStepInto( XIndexContainer xContainer )53 protected boolean shouldStepInto( XIndexContainer xContainer ) throws com.sun.star.uno.Exception 54 { 55 if ( !super.shouldStepInto( xContainer ) ) 56 return false; // don't try to be more clever than our base class 57 58 XForm xForm = (XForm)UnoRuntime.queryInterface( XForm.class, xContainer ); 59 if ( ( null != xForm ) && ( m_nLevel > 1 ) ) 60 // don't step into sub forms - we only handle the form we were originally 61 // applied to 62 return false; 63 64 return true; 65 } 66 67 /* ------------------------------------------------------------------ */ handle( Object aFormComponent )68 public void handle( Object aFormComponent ) throws com.sun.star.uno.Exception 69 { 70 // entering this nesting level 71 ++m_nLevel; 72 73 // check if the component has a DataField property 74 XPropertySet xCompProps = UNO.queryPropertySet( aFormComponent ); 75 XPropertySetInfo xPSI = null; 76 if ( null != xCompProps ) 77 xPSI = xCompProps.getPropertySetInfo(); 78 79 if ( ( null != xPSI ) && xPSI.hasPropertyByName( "DataField" ) ) 80 { // indeed it has .... 81 String sDataField = (String)xCompProps.getPropertyValue( "DataField" ); 82 if ( sDataField.equals( m_sDataField ) ) 83 { // we found a control model which is bound to what we're looking for 84 xCompProps.setPropertyValue( "ReadOnly", m_aLockIt ); 85 } 86 } 87 88 // allow the super class to step down, if possible 89 super.handle( aFormComponent ); 90 91 // leaving this nesting level 92 --m_nLevel; 93 } 94 }; 95 96 /**************************************************************************/ 97 /** a class which automatically handles control locking. 98 <p>The class has to be bound to a form. Upon every movement of the form, 99 all controls which are bound to a (to be specified) field are locked 100 on existing and unlocked on new records.</p> 101 */ 102 class ControlLock implements XRowSetListener 103 { 104 private XPropertySet m_xForm; 105 private String m_sDataField; 106 private boolean m_bLockingEnabled; 107 private boolean m_bPreviousRoundLock; 108 109 /* ------------------------------------------------------------------ */ ControlLock( XPropertySet xForm, String sBoundDataField )110 ControlLock( XPropertySet xForm, String sBoundDataField ) 111 { 112 m_xForm = xForm; 113 m_sDataField = sBoundDataField; 114 m_bLockingEnabled = false; 115 m_bPreviousRoundLock = false; 116 } 117 118 /* ------------------------------------------------------------------ */ 119 /** updates the locks on the affected controls 120 */ updateLocks( )121 protected void updateLocks( ) 122 { 123 try 124 { 125 // first determine if we need to lock 126 Boolean aIsNewRecord = (Boolean)m_xForm.getPropertyValue( "IsNew" ); 127 128 boolean bNeedLock = m_bLockingEnabled && !aIsNewRecord.booleanValue(); 129 130 if ( m_bPreviousRoundLock != bNeedLock ) 131 { 132 LockControlModels aLocker = new LockControlModels( m_sDataField, bNeedLock ); 133 aLocker.handle( m_xForm ); 134 m_bPreviousRoundLock = bNeedLock; 135 } 136 137 // please note that we choose the expensive way here: We always loop through 138 // _all_ control models belonging to the form. This clearly slows down the 139 // whole process. 140 // A better solution would be to cache the affected control models. Then we 141 // could either rely on the fact that the model hierarchy is static, or we 142 // could add ourself as container listener to the form. 143 } 144 catch(com.sun.star.uno.Exception e) 145 { 146 System.out.println(e); 147 e.printStackTrace(); 148 } 149 } 150 151 /* ------------------------------------------------------------------ */ 152 /** enables the locking in general 153 <p>If the control models are really locked depends on the current 154 record of the form: on the insert row, controls are never locked.</p> 155 */ enableLock( boolean bLock )156 public void enableLock( boolean bLock ) 157 { 158 // remember this new setting 159 m_bLockingEnabled = bLock; 160 161 // add or remove ourself as listener to get notified of cursor moves 162 XRowSet xRowSet = (XRowSet)UnoRuntime.queryInterface( 163 XRowSet.class, m_xForm ); 164 if ( m_bLockingEnabled ) 165 { 166 xRowSet.addRowSetListener( this ); 167 } 168 else 169 { 170 xRowSet.removeRowSetListener( this ); 171 } 172 173 // update the locks 174 updateLocks(); 175 } 176 177 /* ================================================================== 178 = UNO callbacks 179 ================================================================== */ 180 181 /* ------------------------------------------------------------------ */ 182 // XResetListener overridables 183 /* ------------------------------------------------------------------ */ cursorMoved( EventObject aEvent )184 public void cursorMoved( EventObject aEvent ) throws com.sun.star.uno.RuntimeException 185 { 186 updateLocks( ); 187 } 188 189 /* ------------------------------------------------------------------ */ rowChanged( EventObject aEvent )190 public void rowChanged( EventObject aEvent ) throws com.sun.star.uno.RuntimeException 191 { 192 // not interested in 193 } 194 195 /* ------------------------------------------------------------------ */ rowSetChanged( EventObject aEvent )196 public void rowSetChanged( EventObject aEvent ) throws com.sun.star.uno.RuntimeException 197 { 198 // not interested in 199 } 200 201 /* ------------------------------------------------------------------ */ 202 // XEventListener overridables 203 /* ------------------------------------------------------------------ */ disposing( EventObject aEvent )204 public void disposing( EventObject aEvent ) 205 { 206 // not interested in 207 } 208 } 209