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