xref: /AOO41X/main/odk/examples/DevelopersGuide/Forms/ControlLock.java (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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