1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 package integration.forms;
28 
29 import com.sun.star.uno.*;
30 import com.sun.star.util.*;
31 import com.sun.star.lang.*;
32 import com.sun.star.container.*;
33 import com.sun.star.beans.*;
34 import com.sun.star.awt.XRadioButton;
35 
36 import integration.forms.dbfTools;
37 import integration.forms.DocumentHelper;
38 import integration.forms.SpreadsheetDocument;
39 
40 import util.utils;
41 import java.util.*;
42 import java.io.*;
43 import java.lang.*;
44 
45 /**
46  *
47  * @author  fs@openoffice.org
48  */
49 public class RadioButtons extends complexlib.ComplexTestCase
50 {
51     private DocumentHelper          m_document;         /// our current test document
52     private FormLayer               m_formLayer;        /// quick access to the form layer
53     private XMultiServiceFactory    m_orb;              /// our service factory
54     private XPropertySet            m_primaryForm;      /// the primary form, to be used in text documents and in the first page of spreadsheets
55     private XPropertySet            m_secondaryForm;    /// the secondary form, to be used in the second page of spreadsheets
56 
57     /* ------------------------------------------------------------------ */
58     public RadioButtons()
59     {
60     }
61 
62     /* ------------------------------------------------------------------ */
63     public String[] getTestMethodNames()
64     {
65         return new String[] {
66             "checkSingleButtons",
67             "checkThreeGroups",
68             "checkMultipleForms",
69             "checkCalcPageSwitch"
70         };
71     }
72 
73     /* ------------------------------------------------------------------ */
74     public String getTestObjectName()
75     {
76         return "Form Radio Buttons Test";
77     }
78 
79     /* ------------------------------------------------------------------ */
80     public void before() throws com.sun.star.uno.Exception, java.lang.Exception
81     {
82         m_orb = (XMultiServiceFactory)param.getMSF();
83     }
84 
85     /* ------------------------------------------------------------------ */
86     private XPropertySet insertRadio( int nXPos, int nYPos, String label, String name, String refValue ) throws com.sun.star.uno.Exception, java.lang.Exception
87     {
88         return insertRadio( nXPos, nYPos, label, name, refValue, null );
89     }
90 
91     /* ------------------------------------------------------------------ */
92     private XPropertySet insertRadio( int nXPos, int nYPos, String label, String name, String refValue, XPropertySet parentForm ) throws com.sun.star.uno.Exception, java.lang.Exception
93     {
94         XIndexContainer parentContainer = dbfTools.queryIndexContainer( parentForm );
95         XPropertySet xRadio = m_formLayer.createControlAndShape( "DatabaseRadioButton", nXPos, nYPos, 25, 6, parentContainer );
96         xRadio.setPropertyValue( "Label", label );
97         xRadio.setPropertyValue( "RefValue", refValue );
98         xRadio.setPropertyValue( "Name", name );
99 
100         if ( null == m_primaryForm )
101             m_primaryForm = (XPropertySet)dbfTools.getParent( xRadio, XPropertySet.class );
102 
103         return xRadio;
104     }
105 
106     /* ------------------------------------------------------------------ */
107     /** this checks whether n groups of radio buttons, consisting of only one button each,
108      *  behave properly
109      */
110     public void checkSingleButtons() throws com.sun.star.uno.Exception, java.lang.Exception
111     {
112         prepareTestStep( false );
113 
114         insertRadio( 20, 30,  "group 1", "group 1", "" );
115         insertRadio( 20, 38,  "group 2", "group 2", "" );
116         insertRadio( 20, 46,  "group 3", "group 3", "" );
117         insertRadio( 20, 54,  "group 4", "group 4", "" );
118 
119         // switch to alive mode
120         m_document.getCurrentView( ).toggleFormDesignMode( );
121 
122         checkRadio( "group 1", "" );
123         verifySingleRadios( 1, 0, 0, 0 );
124 
125         checkRadio( "group 4", "" );
126         verifySingleRadios( 1, 0, 0, 1 );
127 
128         checkRadio( "group 2", "" );
129         verifySingleRadios( 1, 1, 0, 1 );
130 
131         checkRadio( "group 3", "" );
132         verifySingleRadios( 1, 1, 1, 1 );
133 
134         cleanupTestStep();
135     }
136 
137     /* ------------------------------------------------------------------ */
138     /** creates three groups of radio buttons in a sample document, and checks whether they're working
139      */
140     public void checkThreeGroups( ) throws com.sun.star.uno.Exception, java.lang.Exception
141     {
142         prepareTestStep( false );
143 
144         insertRadio( 20, 30,  "group 1 (a)", "group 1", "a" );
145         insertRadio( 20, 38,  "group 1 (b)", "group 1", "b" );
146 
147         insertRadio( 20, 50,  "group 2 (a)", "group 2", "a" );
148         insertRadio( 20, 58,  "group 2 (b)", "group 2", "b" );
149 
150         insertRadio( 20, 70,  "group 3 (a)", "group 3", "a" );
151         insertRadio( 20, 78,  "group 3 (b)", "group 3", "b" );
152 
153         // switch to alive mode
154         m_document.getCurrentView( ).toggleFormDesignMode( );
155 
156         // initially, after switching to alive mode, all buttons should be unchecked
157         verifySixPack( 0, 0, 0, 0, 0, 0 );
158 
159         // check one button in every group
160         checkRadio( "group 1", "a" );
161         checkRadio( "group 2", "b" );
162         checkRadio( "group 3", "a" );
163         // and verify that this worked
164         verifySixPack( 1, 0, 0, 1, 1, 0 );
165 
166         // check all buttons which are currently unchecked
167         checkRadio( "group 1", "b" );
168         checkRadio( "group 2", "a" );
169         checkRadio( "group 3", "b" );
170         // this should have reset the previous checks in the respective groups
171         verifySixPack( 0, 1, 1, 0, 0, 1 );
172 
173         // and back to the previous check state
174         checkRadio( "group 1", "a" );
175         checkRadio( "group 2", "b" );
176         checkRadio( "group 3", "a" );
177         verifySixPack( 1, 0, 0, 1, 1, 0 );
178 
179         cleanupTestStep();
180     }
181 
182     /* ------------------------------------------------------------------ */
183     /** tests whether radio buttons which belong to different forms behave properly
184      */
185     public void checkMultipleForms( ) throws com.sun.star.uno.Exception, java.lang.Exception
186     {
187         prepareTestStep( false );
188 
189         insertRadio( 20, 30,  "group 1 (a)", "group 1", "a" );
190         insertRadio( 20, 38,  "group 1 (b)", "group 1", "b" );
191         insertRadio( 20, 46,  "group 1 (c)", "group 1", "c" );
192 
193         m_secondaryForm = dbfTools.queryPropertySet( m_document.createSiblingForm( m_primaryForm, "secondary" ) );
194 
195         insertRadio( 70, 30,  "group 2 (a)", "group 2", "a", m_secondaryForm );
196         insertRadio( 70, 38,  "group 2 (b)", "group 2", "b", m_secondaryForm );
197         insertRadio( 70, 46,  "group 2 (c)", "group 2", "c", m_secondaryForm );
198 
199         // switch to alive mode
200         m_document.getCurrentView( ).toggleFormDesignMode( );
201 
202         // play around with different check states
203         checkRadio( "group 1", "b", m_primaryForm );
204         checkRadio( "group 2", "c", m_secondaryForm );
205         verifyTwoFormRadios( 0, 1, 0, 0, 0, 1 );
206 
207         checkRadio( "group 1", "c", m_primaryForm );
208         verifyTwoFormRadios( 0, 0, 1, 0, 0, 1 );
209 
210         checkRadio( "group 2", "a", m_secondaryForm );
211         verifyTwoFormRadios( 0, 0, 1, 1, 0, 0 );
212 
213         checkRadio( "group 1", "a", m_primaryForm );
214         verifyTwoFormRadios( 1, 0, 0, 1, 0, 0 );
215 
216         checkRadio( "group 2", "b", m_secondaryForm );
217         verifyTwoFormRadios( 1, 0, 0, 0, 1, 0 );
218 
219         cleanupTestStep();
220     }
221 
222     /* ------------------------------------------------------------------ */
223     /** tests for a special bug which we once had, where radio buttons lost their state after
224      *  switching spreadsheet pages
225      */
226     public void checkCalcPageSwitch( ) throws com.sun.star.uno.Exception, java.lang.Exception
227     {
228         prepareTestStep( true );
229 
230         m_formLayer.setInsertPage( 0 );
231         insertRadio( 15, 20,  "group 1 (a)", "group 1", "a" );
232         insertRadio( 15, 26,  "group 1 (b)", "group 1", "b" );
233 
234         m_formLayer.setInsertPage( 1 );
235         XPropertySet xRadio = insertRadio( 15, 20,  "group 2 (a)", "group 2", "a" );
236                               insertRadio( 15, 26,  "group 2 (b)", "group 2", "b" );
237         m_secondaryForm = (XPropertySet)dbfTools.getParent( xRadio, XPropertySet.class );
238 
239         // switch to alive mode
240         SpreadsheetView view = (SpreadsheetView)m_document.getCurrentView( );
241         view.toggleFormDesignMode( );
242         // and do initial checking
243         checkRadio( "group 1", "a", m_primaryForm );
244         view.activateSheet( 1 );
245         checkRadio( "group 2", "b", m_secondaryForm );
246 
247         // see whether the check states on the first page survived the page switch
248         verifySheetRadios( 1, 0, 0, 1 );
249         // switch back to the first sheet, and see whether the check states survived
250         view.activateSheet( 0 );
251         verifySheetRadios( 1, 0, 0, 1 );
252         // and for completely, check again after switching to third sheet and back to the first
253         view.activateSheet( 2 );
254         view.activateSheet( 1 );
255         verifySheetRadios( 1, 0, 0, 1 );
256 
257         cleanupTestStep();
258     }
259 
260     /* ------------------------------------------------------------------ */
261     public void after()
262     {
263         closeDocument();
264     }
265 
266     /* ------------------------------------------------------------------ */
267     /** closes our document, if we have an open one
268      */
269     private void closeDocument()
270     {
271         try
272         {
273             // close our document
274             if ( m_document != null )
275             {
276                 XCloseable closeDoc = (XCloseable)UnoRuntime.queryInterface( XCloseable.class,
277                     m_document.getDocument() );
278                 closeDoc.close( true );
279             }
280         }
281         catch ( com.sun.star.uno.Exception e )
282         {
283         }
284     }
285 
286     /* ------------------------------------------------------------------ */
287     private void prepareTestStep( boolean useSpreadsheetDocument ) throws com.sun.star.uno.Exception, java.lang.Exception
288     {
289         m_primaryForm = null;
290 
291         m_document = useSpreadsheetDocument ? new SpreadsheetDocument( m_orb ) : DocumentHelper.blankTextDocument( m_orb );
292         m_formLayer = new FormLayer( m_document );
293     }
294 
295     /* ------------------------------------------------------------------ */
296     private void cleanupTestStep( )
297     {
298         closeDocument();
299     }
300 
301     /* ------------------------------------------------------------------ */
302     /** checks or unchecks the radio button (in our primary form) with the given name and the given ref value
303      */
304     private void checkRadio( String groupName, String refValue ) throws com.sun.star.uno.Exception, java.lang.Exception
305     {
306         checkRadio( groupName, refValue, m_primaryForm );
307     }
308 
309     /* ------------------------------------------------------------------ */
310     /** checks or unchecks the radio button with the given name and the given ref value
311      */
312     private void checkRadio( String groupName, String refValue, XPropertySet form ) throws com.sun.star.uno.Exception, java.lang.Exception
313     {
314         XPropertySet xRadio = getRadioModel( groupName, refValue, form );
315 
316 		XRadioButton radioButton = (XRadioButton)UnoRuntime.queryInterface(
317 			XRadioButton.class, m_document.getCurrentView().getControl( xRadio ) );
318 		radioButton.setState( true );
319     }
320 
321     /* ------------------------------------------------------------------ */
322     private XPropertySet getRadioModel( String name, String refValue ) throws com.sun.star.uno.Exception, java.lang.Exception
323     {
324         return getRadioModel( name, refValue, m_primaryForm );
325     }
326 
327     /* ------------------------------------------------------------------ */
328     private XPropertySet getRadioModel( String name, String refValue, XPropertySet form ) throws com.sun.star.uno.Exception, java.lang.Exception
329     {
330         return m_formLayer.getRadioModelByRefValue( form, name, refValue );
331     }
332 
333     /* ------------------------------------------------------------------ */
334     private String stateString( short[] states )
335     {
336 		StringBuffer buf = new StringBuffer();
337 		for ( int i=0; i<states.length; ++i )
338 			buf.append( states[i] );
339 		return buf.toString();
340 	}
341 
342     /* ------------------------------------------------------------------ */
343     /** verifies a number of radio buttons for their states
344      */
345     private boolean verifyRadios( XPropertySet[] radios, short[] expectedStates, String errorMessage ) throws com.sun.star.uno.Exception
346     {
347 		short[] actualStates = new short[radios.length];
348 
349 		// collect all current states. This is just to be able to emit them, in case of a failure
350         for ( int i = 0; i<radios.length; ++i )
351         {
352 			actualStates[i] = ((Short)radios[i].getPropertyValue( "State" )).shortValue();
353         }
354 
355 		// now actually check the states
356         for ( int i = 0; i<radios.length; ++i )
357         {
358 			if ( actualStates[i] != expectedStates[i] )
359 			{
360 				failed( errorMessage + " (expected: " + stateString( expectedStates ) + ", found: " + stateString( actualStates ) + ")" );
361 				return false;
362 			}
363 		}
364 
365         return true;
366     }
367 
368     /* ------------------------------------------------------------------ */
369     /** verifies the states of the 4 radio buttons from the checkSingleButtons test
370      */
371     private boolean verifySingleRadios( int state1, int state2, int state3, int state4 ) throws com.sun.star.uno.Exception, java.lang.Exception
372     {
373         XPropertySet[] radios = new XPropertySet[4];
374         radios[0] = getRadioModel( "group 1", "" );
375         radios[1] = getRadioModel( "group 2", "" );
376         radios[2] = getRadioModel( "group 3", "" );
377         radios[3] = getRadioModel( "group 4", "" );
378 
379         short[] states = new short[4];
380         states[0] = (short)state1;
381         states[1] = (short)state2;
382         states[2] = (short)state3;
383         states[3] = (short)state4;
384 
385         return verifyRadios( radios, states, "single-group radio buttons do not work!" );
386     }
387 
388     /* ------------------------------------------------------------------ */
389     /** verifies the states of 6 radio buttons form the checkThreeGroups test
390      */
391     private boolean verifySixPack( XPropertySet[] radios, String errorMessage,
392         int state1, int state2, int state3, int state4, int state5, int state6 ) throws com.sun.star.uno.Exception, java.lang.Exception
393     {
394         short[] states = new short[6];
395         states[0] = (short)state1;
396         states[1] = (short)state2;
397         states[2] = (short)state3;
398         states[3] = (short)state4;
399         states[4] = (short)state5;
400         states[5] = (short)state6;
401 
402         return verifyRadios( radios, states, errorMessage );
403     }
404 
405     /* ------------------------------------------------------------------ */
406     /** verifies the states of 6 radio buttons
407      */
408     private boolean verifySixPack( int state1, int state2, int state3, int state4, int state5, int state6 ) throws com.sun.star.uno.Exception, java.lang.Exception
409     {
410         XPropertySet[] radios = new XPropertySet[6];
411         radios[0] = getRadioModel( "group 1", "a" );
412         radios[1] = getRadioModel( "group 1", "b" );
413         radios[2] = getRadioModel( "group 2", "a" );
414         radios[3] = getRadioModel( "group 2", "b" );
415         radios[4] = getRadioModel( "group 3", "a" );
416         radios[5] = getRadioModel( "group 3", "b" );
417 
418         return verifySixPack( radios, "six radio buttons, forming three different groups, do not properly work!",
419             state1, state2, state3, state4, state5, state6 );
420     }
421 
422     /* ------------------------------------------------------------------ */
423     /** verifies the states of the 6 radio buttons in our checkMultipleForms test
424      */
425     private boolean verifyTwoFormRadios( int state1, int state2, int state3, int state4, int state5, int state6 ) throws com.sun.star.uno.Exception, java.lang.Exception
426     {
427         XPropertySet[] radios = new XPropertySet[6];
428         radios[0] = getRadioModel( "group 1", "a", m_primaryForm );
429         radios[1] = getRadioModel( "group 1", "b", m_primaryForm );
430         radios[2] = getRadioModel( "group 1", "c", m_primaryForm );
431         radios[3] = getRadioModel( "group 2", "a", m_secondaryForm );
432         radios[4] = getRadioModel( "group 2", "b", m_secondaryForm );
433         radios[5] = getRadioModel( "group 2", "c", m_secondaryForm );
434 
435         return verifySixPack( radios, "radio buttons on different forms do not work properly!",
436             state1, state2, state3, state4, state5, state6 );
437     }
438 
439     /* ------------------------------------------------------------------ */
440     /** verifies the states of the 4 radio buttons in our spreadsheet document (checkCalcPageSwitch)
441      */
442     private boolean verifySheetRadios( int state1, int state2, int state3, int state4 ) throws com.sun.star.uno.Exception, java.lang.Exception
443     {
444         XPropertySet[] radios = new XPropertySet[4];
445         radios[0] = getRadioModel( "group 1", "a", m_primaryForm );
446         radios[1] = getRadioModel( "group 1", "b", m_primaryForm );
447         radios[2] = getRadioModel( "group 2", "a", m_secondaryForm );
448         radios[3] = getRadioModel( "group 2", "b", m_secondaryForm );
449 
450         short[] states = new short[4];
451         states[0] = (short)state1;
452         states[1] = (short)state2;
453         states[2] = (short)state3;
454         states[3] = (short)state4;
455 
456         return verifyRadios( radios, states, "seems some of the radio button check states didn't survive the page activation(s)!" );
457     }
458 }
459 
460