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