1*1b0aaa91SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*1b0aaa91SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*1b0aaa91SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*1b0aaa91SAndrew Rist  * distributed with this work for additional information
6*1b0aaa91SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*1b0aaa91SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*1b0aaa91SAndrew Rist  * "License"); you may not use this file except in compliance
9*1b0aaa91SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*1b0aaa91SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*1b0aaa91SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*1b0aaa91SAndrew Rist  * software distributed under the License is distributed on an
15*1b0aaa91SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*1b0aaa91SAndrew Rist  * KIND, either express or implied.  See the License for the
17*1b0aaa91SAndrew Rist  * specific language governing permissions and limitations
18*1b0aaa91SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*1b0aaa91SAndrew Rist  *************************************************************/
21*1b0aaa91SAndrew Rist 
22*1b0aaa91SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir package complex.toolkit;
25cdf0e10cSrcweir 
26cdf0e10cSrcweir import com.sun.star.awt.XControl;
27cdf0e10cSrcweir import com.sun.star.awt.XControlContainer;
28cdf0e10cSrcweir import com.sun.star.awt.XControlModel;
29cdf0e10cSrcweir import com.sun.star.awt.XToolkit;
30cdf0e10cSrcweir import com.sun.star.awt.grid.DefaultGridDataModel;
31cdf0e10cSrcweir import com.sun.star.awt.grid.XGridColumn;
32cdf0e10cSrcweir import com.sun.star.awt.grid.XGridColumnModel;
33cdf0e10cSrcweir import com.sun.star.awt.grid.XGridControl;
34cdf0e10cSrcweir import com.sun.star.awt.grid.XGridDataModel;
35cdf0e10cSrcweir import com.sun.star.awt.grid.XMutableGridDataModel;
36cdf0e10cSrcweir import com.sun.star.awt.grid.XSortableMutableGridDataModel;
37cdf0e10cSrcweir import com.sun.star.beans.Pair;
38cdf0e10cSrcweir import com.sun.star.beans.XPropertySet;
39cdf0e10cSrcweir import com.sun.star.container.ContainerEvent;
40cdf0e10cSrcweir import com.sun.star.container.XContainerListener;
41cdf0e10cSrcweir import com.sun.star.container.XNameContainer;
42cdf0e10cSrcweir import com.sun.star.lang.EventObject;
43cdf0e10cSrcweir import com.sun.star.lang.IndexOutOfBoundsException;
44cdf0e10cSrcweir import com.sun.star.lang.XComponent;
45cdf0e10cSrcweir import com.sun.star.lang.XEventListener;
46cdf0e10cSrcweir import com.sun.star.lang.XMultiServiceFactory;
47cdf0e10cSrcweir import com.sun.star.uno.Exception;
48cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
49cdf0e10cSrcweir import com.sun.star.uno.XComponentContext;
50cdf0e10cSrcweir import com.sun.star.uno.XInterface;
51cdf0e10cSrcweir import com.sun.star.util.XCloneable;
52cdf0e10cSrcweir import complex.toolkit.awtgrid.DummyColumn;
53cdf0e10cSrcweir import complex.toolkit.awtgrid.TMutableGridDataModel;
54cdf0e10cSrcweir import java.lang.reflect.Method;
55cdf0e10cSrcweir import java.util.ArrayList;
56cdf0e10cSrcweir import java.util.List;
57cdf0e10cSrcweir import java.util.Random;
58cdf0e10cSrcweir import org.junit.AfterClass;
59cdf0e10cSrcweir import org.junit.BeforeClass;
60cdf0e10cSrcweir import org.junit.After;
61cdf0e10cSrcweir import org.junit.Before;
62cdf0e10cSrcweir import org.junit.Test;
63cdf0e10cSrcweir import static org.junit.Assert.*;
64cdf0e10cSrcweir import org.openoffice.test.OfficeConnection;
65cdf0e10cSrcweir 
66cdf0e10cSrcweir /** is a unit test for the grid control related implementations
67cdf0e10cSrcweir  * @author frank.schoenheit@sun.com
68cdf0e10cSrcweir  */
69cdf0e10cSrcweir public class GridControl
70cdf0e10cSrcweir {
71cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
GridControl()72cdf0e10cSrcweir     public GridControl()
73cdf0e10cSrcweir     {
74cdf0e10cSrcweir         m_context = m_connection.getComponentContext();
75cdf0e10cSrcweir     }
76cdf0e10cSrcweir 
77cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
impl_dispose( final Object... i_components )78cdf0e10cSrcweir     private static void impl_dispose( final Object... i_components )
79cdf0e10cSrcweir     {
80cdf0e10cSrcweir         for ( int i=0; i<i_components.length; ++i )
81cdf0e10cSrcweir         {
82cdf0e10cSrcweir             if ( i_components[i] != null )
83cdf0e10cSrcweir             {
84cdf0e10cSrcweir                 final XComponent component = UnoRuntime.queryInterface( XComponent.class, i_components[i] );
85cdf0e10cSrcweir                 component.dispose();
86cdf0e10cSrcweir             }
87cdf0e10cSrcweir         }
88cdf0e10cSrcweir     }
89cdf0e10cSrcweir 
90cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
impl_recreateGridModel()91cdf0e10cSrcweir     private void impl_recreateGridModel() throws Exception
92cdf0e10cSrcweir     {
93cdf0e10cSrcweir         impl_dispose( m_gridControlModel, m_columnModel, m_dataModel );
94cdf0e10cSrcweir 
95cdf0e10cSrcweir         // create a grid control model, and ensure it has a proper data and column model already
96cdf0e10cSrcweir         m_gridControlModel = UnoRuntime.queryInterface( XPropertySet.class,
97cdf0e10cSrcweir             createInstance( "com.sun.star.awt.grid.UnoControlGridModel" ) );
98cdf0e10cSrcweir         assertNotNull( "grid control model does not provide XPropertySet interface", m_gridControlModel );
99cdf0e10cSrcweir 
100cdf0e10cSrcweir         // ensure that the model has default column/data models
101cdf0e10cSrcweir         m_columnModel = UnoRuntime.queryInterface( XGridColumnModel.class, m_gridControlModel.getPropertyValue( "ColumnModel" ) );
102cdf0e10cSrcweir         assertNotNull( "the control model is expected to have an initial column model", m_columnModel );
103cdf0e10cSrcweir         final XGridDataModel dataModel = UnoRuntime.queryInterface( XGridDataModel.class, m_gridControlModel.getPropertyValue( "GridDataModel" ) );
104cdf0e10cSrcweir         assertNotNull( "the control model is expected to have an initial data model", dataModel );
105cdf0e10cSrcweir         m_dataModel = UnoRuntime.queryInterface( XSortableMutableGridDataModel.class,
106cdf0e10cSrcweir             dataModel );
107cdf0e10cSrcweir         assertNotNull( "the out-of-the-box data model should be mutable and sortable", m_dataModel );
108cdf0e10cSrcweir     }
109cdf0e10cSrcweir 
110cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
111cdf0e10cSrcweir     @Test
testGridControlCloning()112cdf0e10cSrcweir     public void testGridControlCloning() throws Exception
113cdf0e10cSrcweir     {
114cdf0e10cSrcweir         impl_recreateGridModel();
115cdf0e10cSrcweir 
116cdf0e10cSrcweir         // give the test something to compare, actually
117cdf0e10cSrcweir         XGridColumnModel columnModel = UnoRuntime.queryInterface( XGridColumnModel.class,
118cdf0e10cSrcweir             m_gridControlModel.getPropertyValue( "ColumnModel" ) );
119cdf0e10cSrcweir         columnModel.setDefaultColumns( 10 );
120cdf0e10cSrcweir 
121cdf0e10cSrcweir         // clone the grid model
122cdf0e10cSrcweir         final XCloneable cloneable = UnoRuntime.queryInterface( XCloneable.class, m_gridControlModel );
123cdf0e10cSrcweir         assertNotNull( "all UnoControlModel's are expected to be cloneable", cloneable );
124cdf0e10cSrcweir 
125cdf0e10cSrcweir         final XInterface clone = cloneable.createClone();
126cdf0e10cSrcweir         final XPropertySet clonedProps = UnoRuntime.queryInterface( XPropertySet.class, clone );
127cdf0e10cSrcweir 
128cdf0e10cSrcweir         // TODO: check all those generic properties for equality
129cdf0e10cSrcweir 
130cdf0e10cSrcweir         // the data model and the column model should have been cloned, too
131cdf0e10cSrcweir         // in particular, the clone should not share the sub models with the orignal
132cdf0e10cSrcweir         final XMutableGridDataModel originalDataModel = UnoRuntime.queryInterface( XMutableGridDataModel.class,
133cdf0e10cSrcweir             m_gridControlModel.getPropertyValue( "GridDataModel" ) );
134cdf0e10cSrcweir         final XMutableGridDataModel clonedDataModel = UnoRuntime.queryInterface( XMutableGridDataModel.class,
135cdf0e10cSrcweir             clonedProps.getPropertyValue( "GridDataModel" ) );
136cdf0e10cSrcweir         assertFalse( "data model should not be shared after cloning", UnoRuntime.areSame( originalDataModel, clonedDataModel ) );
137cdf0e10cSrcweir         impl_assertEquality( originalDataModel, clonedDataModel );
138cdf0e10cSrcweir 
139cdf0e10cSrcweir         final XGridColumnModel originalColumnModel = columnModel;
140cdf0e10cSrcweir         final XGridColumnModel clonedColumnModel = UnoRuntime.queryInterface( XGridColumnModel.class,
141cdf0e10cSrcweir             clonedProps.getPropertyValue( "ColumnModel" ) );
142cdf0e10cSrcweir         assertFalse( "column model should not be shared after cloning", UnoRuntime.areSame( originalColumnModel, clonedColumnModel ) );
143cdf0e10cSrcweir         impl_assertEquality( originalColumnModel, clonedColumnModel );
144cdf0e10cSrcweir     }
145cdf0e10cSrcweir 
146cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
147cdf0e10cSrcweir     @Test
testDisposal()148cdf0e10cSrcweir     public void testDisposal() throws Exception
149cdf0e10cSrcweir     {
150cdf0e10cSrcweir         impl_recreateGridModel();
151cdf0e10cSrcweir 
152cdf0e10cSrcweir         final int columnCount = 3;
153cdf0e10cSrcweir         m_columnModel.setDefaultColumns( columnCount );
154cdf0e10cSrcweir 
155cdf0e10cSrcweir         // add disposal listeners to all columns so far
156cdf0e10cSrcweir         final XGridColumn[] columns = m_columnModel.getColumns();
157cdf0e10cSrcweir         assertEquals( "creating default columns resulted in unexpected column count", columnCount, columns.length );
158cdf0e10cSrcweir         final DisposeListener[] columnListeners = new DisposeListener[columnCount];
159cdf0e10cSrcweir         for ( int i=0; i<columnCount; ++i )
160cdf0e10cSrcweir             columnListeners[i] = new DisposeListener( columns[i] );
161cdf0e10cSrcweir 
162cdf0e10cSrcweir         // add another column, and check that upon removal, it is disposed
163cdf0e10cSrcweir         final int newColumnIndex = m_columnModel.addColumn( m_columnModel.createColumn() );
164cdf0e10cSrcweir         final DisposeListener columnListener = new DisposeListener( m_columnModel.getColumn( newColumnIndex ) );
165cdf0e10cSrcweir         m_columnModel.removeColumn( newColumnIndex );
166cdf0e10cSrcweir         assertTrue( "explicit column removal is expected to dispose the column", columnListener.isDisposed() );
167cdf0e10cSrcweir 
168cdf0e10cSrcweir         // by definition, the grid control model is the owner of both the column and the data model. So, setting
169cdf0e10cSrcweir         // a new column/data model should implicitly dispose the old models
170cdf0e10cSrcweir         final DisposeListener oldDataModelListener = new DisposeListener( m_dataModel );
171cdf0e10cSrcweir         final DisposeListener oldColumnModelListener = new DisposeListener( m_columnModel );
172cdf0e10cSrcweir 
173cdf0e10cSrcweir         final Object newDataModel = createInstance( "com.sun.star.awt.grid.DefaultGridDataModel" );
174cdf0e10cSrcweir         final Object newColumnModel = createInstance( "com.sun.star.awt.grid.DefaultGridColumnModel" );
175cdf0e10cSrcweir         final DisposeListener newDataModelListener = new DisposeListener( newDataModel );
176cdf0e10cSrcweir         final DisposeListener newColumnModelListener = new DisposeListener( newColumnModel );
177cdf0e10cSrcweir 
178cdf0e10cSrcweir         m_gridControlModel.setPropertyValue( "GridDataModel", newDataModel );
179cdf0e10cSrcweir         assertTrue( "setting a new data model failed", impl_areSameInterface( newDataModel, m_gridControlModel.getPropertyValue( "GridDataModel" ) ) );
180cdf0e10cSrcweir         m_gridControlModel.setPropertyValue( "ColumnModel", newColumnModel );
181cdf0e10cSrcweir         assertTrue( "setting a new column model failed", impl_areSameInterface( newColumnModel, m_gridControlModel.getPropertyValue( "ColumnModel" ) ) );
182cdf0e10cSrcweir 
183cdf0e10cSrcweir         assertTrue( "old data model has not been disposed", oldDataModelListener.isDisposed() );
184cdf0e10cSrcweir         assertTrue( "old column model has not been disposed", oldColumnModelListener.isDisposed() );
185cdf0e10cSrcweir         for ( int i=0; i<columnCount; ++i )
186cdf0e10cSrcweir             assertTrue( "column no. " + i + " has not been disposed", columnListeners[i].isDisposed() );
187cdf0e10cSrcweir 
188cdf0e10cSrcweir         // the same holds if the grid control model itself is disposed - it should dispose the depending models, too
189cdf0e10cSrcweir         assertFalse( "new data model is already disposed - this is unexpected", newDataModelListener.isDisposed() );
190cdf0e10cSrcweir         assertFalse( "new column model is already disposed - this is unexpected", newColumnModelListener.isDisposed() );
191cdf0e10cSrcweir         impl_dispose( m_gridControlModel );
192cdf0e10cSrcweir         assertTrue( "new data model is not disposed after disposing the grid column model", newDataModelListener.isDisposed() );
193cdf0e10cSrcweir         assertTrue( "new column model is not disposed after disposing the grid column model", newColumnModelListener.isDisposed() );
194cdf0e10cSrcweir     }
195cdf0e10cSrcweir 
196cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
197cdf0e10cSrcweir     /**
198cdf0e10cSrcweir      * tests various aspects of the <code>XMutableGridDataModel</code> interface
199cdf0e10cSrcweir      */
200cdf0e10cSrcweir     @Test
testMutableGridDataModel()201cdf0e10cSrcweir     public void testMutableGridDataModel() throws Exception
202cdf0e10cSrcweir     {
203cdf0e10cSrcweir         impl_recreateGridModel();
204cdf0e10cSrcweir 
205cdf0e10cSrcweir         TMutableGridDataModel test = new TMutableGridDataModel( m_dataModel );
206cdf0e10cSrcweir         test.testAddRow();
207cdf0e10cSrcweir         test.testAddRows();
208cdf0e10cSrcweir         test.testInsertRow();
209cdf0e10cSrcweir         test.testInsertRows();
210cdf0e10cSrcweir         test.testRemoveRow();
211cdf0e10cSrcweir         test.testRemoveAllRows();
212cdf0e10cSrcweir         test.testUpdateCellData();
213cdf0e10cSrcweir         test.testUpdateRowData();
214cdf0e10cSrcweir         test.testUpdateRowHeading();
215cdf0e10cSrcweir         test.cleanup();
216cdf0e10cSrcweir 
217cdf0e10cSrcweir         // a somehwat less straight-forward test: the data model is expected to implicitly increase its column count
218cdf0e10cSrcweir         // when you add a row which has more columns than currently known
219cdf0e10cSrcweir         final XMutableGridDataModel dataModel = DefaultGridDataModel.create( m_context );
220cdf0e10cSrcweir         dataModel.addRow( 0, new Object[] { 1 } );
221cdf0e10cSrcweir         assertEquals( "unexpected column count after adding the most simple row", 1, dataModel.getColumnCount() );
222cdf0e10cSrcweir         dataModel.addRow( 1, new Object[] { 1, 2 } );
223cdf0e10cSrcweir         assertEquals( "implicit extension of the column count doesn't work", 2, dataModel.getColumnCount() );
224cdf0e10cSrcweir     }
225cdf0e10cSrcweir 
226cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
227cdf0e10cSrcweir     @Test
testGridColumnModel()228cdf0e10cSrcweir     public void testGridColumnModel() throws Exception
229cdf0e10cSrcweir     {
230cdf0e10cSrcweir         impl_recreateGridModel();
231cdf0e10cSrcweir 
232cdf0e10cSrcweir         ColumnModelListener listener = new ColumnModelListener();
233cdf0e10cSrcweir         m_columnModel.addContainerListener( listener );
234cdf0e10cSrcweir 
235cdf0e10cSrcweir         // insert default columns into the previously empty model, ensure we get the right notifications
236cdf0e10cSrcweir         final int defaultColumnsCount = 3;
237cdf0e10cSrcweir         m_columnModel.setDefaultColumns( defaultColumnsCount );
238cdf0e10cSrcweir         impl_assertColumnModelConsistency();
239cdf0e10cSrcweir         List< ContainerEvent > events = listener.assertExclusiveInsertionEvents();
240cdf0e10cSrcweir         listener.reset();
241cdf0e10cSrcweir         assertEquals( "wrong number of events fired by setDefaulColumns", defaultColumnsCount, events.size() );
242cdf0e10cSrcweir         for ( int i=0; i<defaultColumnsCount; ++i )
243cdf0e10cSrcweir         {
244cdf0e10cSrcweir             final ContainerEvent event = events.get(i);
245cdf0e10cSrcweir             final int index = impl_assertInteger( event.Accessor );
246cdf0e10cSrcweir             assertEquals( "unexpected Accessor value in insert notification", i, index );
247cdf0e10cSrcweir             assertTrue( "wrong column object notified in insert notification",
248cdf0e10cSrcweir                 impl_areSameInterface( event.Element, m_columnModel.getColumn(i) ) );
249cdf0e10cSrcweir         }
250cdf0e10cSrcweir 
251cdf0e10cSrcweir         // insert some more default columns, ensure that all previously existing columns are removed
252cdf0e10cSrcweir         final int moreDefaultColumnsCount = 5;
253cdf0e10cSrcweir         m_columnModel.setDefaultColumns( moreDefaultColumnsCount );
254cdf0e10cSrcweir         impl_assertColumnModelConsistency();
255cdf0e10cSrcweir         assertEquals( "setting default columns is expected to remove all previously existing columns",
256cdf0e10cSrcweir             moreDefaultColumnsCount, m_columnModel.getColumnCount() );
257cdf0e10cSrcweir 
258cdf0e10cSrcweir         // in this situation, both removal and insertion events have been notified
259cdf0e10cSrcweir         final List< ContainerEvent > removalEvents = listener.getRemovalEvents();
260cdf0e10cSrcweir         final List< ContainerEvent > insertionEvents = listener.getInsertionEvents();
261cdf0e10cSrcweir         listener.reset();
262cdf0e10cSrcweir 
263cdf0e10cSrcweir         // for the removal events, check the indexes
264cdf0e10cSrcweir         assertEquals( "wrong number of columns removed (or notified) upon setting default columns",
265cdf0e10cSrcweir             defaultColumnsCount, removalEvents.size() );
266cdf0e10cSrcweir         for ( int i=0; i<removalEvents.size(); ++i )
267cdf0e10cSrcweir         {
268cdf0e10cSrcweir             final ContainerEvent event = removalEvents.get(i);
269cdf0e10cSrcweir             final int removedIndex = impl_assertInteger( event.Accessor );
270cdf0e10cSrcweir 
271cdf0e10cSrcweir             // The implementation is allowed to remove the columns from the beginning, in which case the
272cdf0e10cSrcweir             // index of the removed column must always be 0, since e.g. the second column has index 0
273cdf0e10cSrcweir             // after the first column (which previously had index 0) had been removed.
274cdf0e10cSrcweir             // Alternatively, the implementation is allowed to remove columns from the end, which means
275cdf0e10cSrcweir             // that the column index given in the event is steadily increasing.
276cdf0e10cSrcweir             assertTrue( "unexpected column removal event column index",
277cdf0e10cSrcweir                 ( removedIndex == 0 ) || ( removedIndex == removalEvents.size() - 1 - i ) );
278cdf0e10cSrcweir         }
279cdf0e10cSrcweir 
280cdf0e10cSrcweir         // for the insertion events, check the indexes as well
281cdf0e10cSrcweir         assertEquals( "wrong number of insertion events when setting default columns over existing columns",
282cdf0e10cSrcweir             moreDefaultColumnsCount, insertionEvents.size() );
283cdf0e10cSrcweir         for ( int i=0; i<insertionEvents.size(); ++i )
284cdf0e10cSrcweir         {
285cdf0e10cSrcweir             final ContainerEvent event = insertionEvents.get(i);
286cdf0e10cSrcweir             final int index = impl_assertInteger( event.Accessor );
287cdf0e10cSrcweir             assertEquals( i, index );
288cdf0e10cSrcweir         }
289cdf0e10cSrcweir 
290cdf0e10cSrcweir         // okay, remove all those columns
291cdf0e10cSrcweir         while ( m_columnModel.getColumnCount() != 0 )
292cdf0e10cSrcweir         {
293cdf0e10cSrcweir             final int columnCount = m_columnModel.getColumnCount();
294cdf0e10cSrcweir             final int removeColumnIndex = m_randomGenerator.nextInt( columnCount );
295cdf0e10cSrcweir             m_columnModel.removeColumn( removeColumnIndex );
296cdf0e10cSrcweir             events = listener.assertExclusiveRemovalEvents();
297cdf0e10cSrcweir             listener.reset();
298cdf0e10cSrcweir             assertEquals( "removing a single column should notify a single event", 1, events.size() );
299cdf0e10cSrcweir             final ContainerEvent event = events.get(0);
300cdf0e10cSrcweir             final int removalIndex = impl_assertInteger( event.Accessor );
301cdf0e10cSrcweir             assertEquals( "removing an arbitrary column does not notify the proper accessor",
302cdf0e10cSrcweir                 removeColumnIndex, removalIndex );
303cdf0e10cSrcweir         }
304cdf0e10cSrcweir 
305cdf0e10cSrcweir         // calling addColumn with a column not created by the given model/implementatoion should not succeed
306cdf0e10cSrcweir         boolean caughtExpected = false;
307cdf0e10cSrcweir         try
308cdf0e10cSrcweir         {
309cdf0e10cSrcweir             m_columnModel.addColumn( new DummyColumn() );
310cdf0e10cSrcweir         }
311cdf0e10cSrcweir         catch( final com.sun.star.lang.IllegalArgumentException e )
312cdf0e10cSrcweir         {
313cdf0e10cSrcweir             assertTrue( impl_areSameInterface( e.Context, m_columnModel ) );
314cdf0e10cSrcweir             caughtExpected = true;
315cdf0e10cSrcweir         }
316cdf0e10cSrcweir         assertTrue( "adding a dummy (self-implemented) grid column to the model should not succeed", caughtExpected );
317cdf0e10cSrcweir 
318cdf0e10cSrcweir         // adding a single column to the end should succeed, properly notify, and still be consistent
319cdf0e10cSrcweir         final XGridColumn newColumn = m_columnModel.createColumn();
320cdf0e10cSrcweir         m_columnModel.addColumn( newColumn );
321cdf0e10cSrcweir         impl_assertColumnModelConsistency();
322cdf0e10cSrcweir         events = listener.assertExclusiveInsertionEvents();
323cdf0e10cSrcweir         listener.reset();
324cdf0e10cSrcweir         assertEquals( "addColumn notifies the wrong number of insertion events", 1, events.size() );
325cdf0e10cSrcweir         final int insertionIndex = impl_assertInteger( events.get(0).Accessor );
326cdf0e10cSrcweir         assertEquals( insertionIndex, newColumn.getIndex() );
327cdf0e10cSrcweir     }
328cdf0e10cSrcweir 
329cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
330cdf0e10cSrcweir     @Test
testDataModel()331cdf0e10cSrcweir     public void testDataModel() throws Exception
332cdf0e10cSrcweir     {
333cdf0e10cSrcweir         impl_recreateGridModel();
334cdf0e10cSrcweir 
335cdf0e10cSrcweir         // ensure that getCellData and getRowData have the same opinion on the data they deliver
336cdf0e10cSrcweir         final Object[][] data = new Object[][] {
337cdf0e10cSrcweir             new Object[] { 15, 17, 0 },
338cdf0e10cSrcweir             new Object[] { 9, 8, 14 },
339cdf0e10cSrcweir             new Object[] { 17, 2, 16 },
340cdf0e10cSrcweir             new Object[] { 0, 7, 14 },
341cdf0e10cSrcweir             new Object[] { 10, 16, 16 },
342cdf0e10cSrcweir         };
343cdf0e10cSrcweir         m_dataModel.addRows( new Object[ data.length ], data );
344cdf0e10cSrcweir 
345cdf0e10cSrcweir         for ( int row = 0; row < data.length; ++row )
346cdf0e10cSrcweir         {
347cdf0e10cSrcweir             assertArrayEquals( "getRowData delivers wrong data in row " + row, data[row], m_dataModel.getRowData( row ) );
348cdf0e10cSrcweir             for ( int col = 0; col < data[row].length; ++col )
349cdf0e10cSrcweir             {
350cdf0e10cSrcweir                 assertEquals( "getCellData delivers wrong data at position (" + col + ", " + row + ")",
351cdf0e10cSrcweir                         data[row][col], m_dataModel.getCellData( col, row ) );
352cdf0e10cSrcweir             }
353cdf0e10cSrcweir         }
354cdf0e10cSrcweir     }
355cdf0e10cSrcweir 
356cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
357cdf0e10cSrcweir     @Test
testSortableDataModel()358cdf0e10cSrcweir     public void testSortableDataModel() throws Exception
359cdf0e10cSrcweir     {
360cdf0e10cSrcweir         impl_recreateGridModel();
361cdf0e10cSrcweir 
362cdf0e10cSrcweir         final int colCount = 3;
363cdf0e10cSrcweir         final int rowCount = 10;
364cdf0e10cSrcweir         // initialize with some data
365cdf0e10cSrcweir         final Object[][] data = new Object[][] {
366cdf0e10cSrcweir             new Object[] { 15, 17, 0 },
367cdf0e10cSrcweir             new Object[] { 9, 8, 14 },
368cdf0e10cSrcweir             new Object[] { 17, 2, 16 },
369cdf0e10cSrcweir             new Object[] { 0, 7, 14 },
370cdf0e10cSrcweir             new Object[] { 10, 16, 16 },
371cdf0e10cSrcweir             new Object[] { 2, 8, 10 },
372cdf0e10cSrcweir             new Object[] { 4, 8, 3 },
373cdf0e10cSrcweir             new Object[] { 7, 9, 0 },
374cdf0e10cSrcweir             new Object[] { 15, 6, 19 },
375cdf0e10cSrcweir             new Object[] { 2, 14, 19 }
376cdf0e10cSrcweir         };
377cdf0e10cSrcweir         final Object[] rowHeadings = new Object[] {
378cdf0e10cSrcweir             0, 1, 2, 3, 4, 5, 6, 7, 8, 9
379cdf0e10cSrcweir         };
380cdf0e10cSrcweir         // ensure consistency of the test data
381cdf0e10cSrcweir         assertEquals( rowHeadings.length, rowCount );
382cdf0e10cSrcweir         assertEquals( data.length, rowCount );
383cdf0e10cSrcweir         for ( Object[] rowData : data )
384cdf0e10cSrcweir             assertEquals( rowData.length, colCount );
385cdf0e10cSrcweir 
386cdf0e10cSrcweir         // add the test data
387cdf0e10cSrcweir         m_dataModel.addRows( rowHeadings, data );
388cdf0e10cSrcweir         assertEquals( rowCount, m_dataModel.getRowCount() );
389cdf0e10cSrcweir         assertEquals( colCount, m_dataModel.getColumnCount() );
390cdf0e10cSrcweir 
391cdf0e10cSrcweir         // sort by each column
392cdf0e10cSrcweir         for ( int colIndex = 0; colIndex < colCount; ++colIndex )
393cdf0e10cSrcweir         {
394cdf0e10cSrcweir             for ( boolean ascending : new boolean[] { true, false } )
395cdf0e10cSrcweir             {
396cdf0e10cSrcweir                 m_dataModel.sortByColumn( colIndex, ascending );
397cdf0e10cSrcweir                 Pair currentSortOrder = m_dataModel.getCurrentSortOrder();
398cdf0e10cSrcweir                 assertEquals( "invalid current sort column (column " + colIndex + ")", ((Integer)currentSortOrder.First).intValue(), colIndex );
399cdf0e10cSrcweir                 assertEquals( "invalid current sort direction", ((Boolean)currentSortOrder.Second).booleanValue(), ascending );
400cdf0e10cSrcweir 
401cdf0e10cSrcweir                 /*for ( int i=0; i<rowCount; ++i )
402cdf0e10cSrcweir                 {
403cdf0e10cSrcweir                     for ( int j=0; j<colCount; ++j )
404cdf0e10cSrcweir                         System.out.print( m_dataModel.getCellData( j, i ).toString() + ", " );
405cdf0e10cSrcweir                     System.out.println();
406cdf0e10cSrcweir                 }*/
407cdf0e10cSrcweir 
408cdf0e10cSrcweir                 // verify the data is actually sorted by this column
409cdf0e10cSrcweir                 for ( int rowIndex = 0; rowIndex < rowCount - 1; ++rowIndex )
410cdf0e10cSrcweir                 {
411cdf0e10cSrcweir                     final Object currentValue = m_dataModel.getCellData( colIndex, rowIndex );
412cdf0e10cSrcweir                     final int currentIntValue = impl_assertInteger( currentValue );
413cdf0e10cSrcweir                     final Object nextValue = m_dataModel.getCellData( colIndex, rowIndex + 1 );
414cdf0e10cSrcweir                     final int nextIntValue = impl_assertInteger( nextValue );
415cdf0e10cSrcweir                     assertTrue( "data in row " + rowIndex + " is actually not sorted " + ( ascending ? "ascending" : "descending" ),
416cdf0e10cSrcweir                         ascending   ? currentIntValue <= nextIntValue
417cdf0e10cSrcweir                                     : currentIntValue >= nextIntValue );
418cdf0e10cSrcweir 
419cdf0e10cSrcweir                     // ensure the data in the other columns, and the row headings, are sorted as well
420cdf0e10cSrcweir                     final Object rowHeading = m_dataModel.getRowHeading( rowIndex );
421cdf0e10cSrcweir                     final int unsortedRowIndex = impl_assertInteger( rowHeading );
422cdf0e10cSrcweir                     for ( int innerColIndex = 0; innerColIndex < colCount; ++innerColIndex )
423cdf0e10cSrcweir                     {
424cdf0e10cSrcweir                         assertEquals( "sorted row " + rowIndex + ", unsorted row " + unsortedRowIndex + ", col " + innerColIndex +
425cdf0e10cSrcweir                             ": wrong data",
426cdf0e10cSrcweir                             data[unsortedRowIndex][innerColIndex], m_dataModel.getCellData( innerColIndex, rowIndex ) );
427cdf0e10cSrcweir                     }
428cdf0e10cSrcweir                 }
429cdf0e10cSrcweir             }
430cdf0e10cSrcweir         }
431cdf0e10cSrcweir     }
432cdf0e10cSrcweir 
433cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
434cdf0e10cSrcweir     @Test
testView()435cdf0e10cSrcweir     public void testView() throws Exception
436cdf0e10cSrcweir     {
437cdf0e10cSrcweir         final XControl control = impl_createDialogWithGridControl();
438cdf0e10cSrcweir         final XPropertySet gridModelProps =
439cdf0e10cSrcweir             UnoRuntime.queryInterface( XPropertySet.class, control.getModel() );
440cdf0e10cSrcweir 
441cdf0e10cSrcweir         // in the current implementation (not sure this is a good idea at all), the control (more precise: the peer)
442cdf0e10cSrcweir         // ensures that if there are no columns in the column model, but in the data model, then the column model
443cdf0e10cSrcweir         // will implicitly have the needed columns added.
444cdf0e10cSrcweir         // To ensure that clients which rely on this do not break in the future, check this here.
445cdf0e10cSrcweir         final XMutableGridDataModel dataModel = UnoRuntime.queryInterface( XMutableGridDataModel.class,
446cdf0e10cSrcweir             gridModelProps.getPropertyValue( "GridDataModel" ) );
447cdf0e10cSrcweir         assertNotNull( dataModel );
448cdf0e10cSrcweir         assertEquals( 0, dataModel.getColumnCount() );
449cdf0e10cSrcweir 
450cdf0e10cSrcweir         final XGridColumnModel columnModel = UnoRuntime.queryInterface( XGridColumnModel.class,
451cdf0e10cSrcweir             gridModelProps.getPropertyValue( "ColumnModel" ) );
452cdf0e10cSrcweir         assertNotNull( columnModel );
453cdf0e10cSrcweir         assertEquals( 0, columnModel.getColumnCount() );
454cdf0e10cSrcweir 
455cdf0e10cSrcweir         final int columnCount = 3;
456cdf0e10cSrcweir         final int rowCount = 2;
457cdf0e10cSrcweir         dataModel.addRow( null, new Object[] { 1, 2, 3 } );
458cdf0e10cSrcweir         dataModel.addRow( null, new Object[] { 6, 5, 4 } );
459cdf0e10cSrcweir 
460cdf0e10cSrcweir         assertEquals( columnCount, dataModel.getColumnCount() );
461cdf0e10cSrcweir         assertEquals( columnCount, columnModel.getColumnCount() );
462cdf0e10cSrcweir 
463cdf0e10cSrcweir         // some cursor traveling
464cdf0e10cSrcweir         final XGridControl gridControl = UnoRuntime.queryInterface( XGridControl.class, control );
465cdf0e10cSrcweir         gridControl.goToCell( 0, 0 );
466cdf0e10cSrcweir         assertEquals( "wrong 'current column' (1)", 0, gridControl.getCurrentColumn() );
467cdf0e10cSrcweir         assertEquals( "wrong 'current row' (1)", 0, gridControl.getCurrentRow() );
468cdf0e10cSrcweir         gridControl.goToCell( columnCount - 1, rowCount - 1 );
469cdf0e10cSrcweir         assertEquals( "wrong 'current column' (2)", dataModel.getColumnCount() - 1, gridControl.getCurrentColumn() );
470cdf0e10cSrcweir         assertEquals( "wrong 'current row' (2)", dataModel.getRowCount() - 1, gridControl.getCurrentRow() );
471cdf0e10cSrcweir 
472cdf0e10cSrcweir         // removing the last column, while the active cell is in this very last column, is expected to adjust
473cdf0e10cSrcweir         // the active cell
474cdf0e10cSrcweir         columnModel.removeColumn( columnCount - 1 );
475cdf0e10cSrcweir         assertEquals( "removed the last and active column, active column was not adjusted!",
476cdf0e10cSrcweir             columnCount - 2, gridControl.getCurrentColumn() );
477cdf0e10cSrcweir         // same holds for rows
478cdf0e10cSrcweir         dataModel.removeRow( rowCount - 1 );
479cdf0e10cSrcweir         assertEquals( "removed the last and active row, active row was not adjusted!",
480cdf0e10cSrcweir             rowCount - 2, gridControl.getCurrentRow() );
481cdf0e10cSrcweir     }
482cdf0e10cSrcweir 
483cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
impl_createDialogWithGridControl()484cdf0e10cSrcweir     private XControl impl_createDialogWithGridControl() throws Exception
485cdf0e10cSrcweir     {
486cdf0e10cSrcweir         // create a simple dialog model/control/peer trinity
487cdf0e10cSrcweir         final XControlModel dialogModel = createInstance( XControlModel.class, "com.sun.star.awt.UnoControlDialogModel" );
488cdf0e10cSrcweir         m_disposables.add( dialogModel );
489cdf0e10cSrcweir         final XPropertySet dialogProps = UnoRuntime.queryInterface( XPropertySet.class, dialogModel );
490cdf0e10cSrcweir         dialogProps.setPropertyValue( "Width", 200 );
491cdf0e10cSrcweir         dialogProps.setPropertyValue( "Height", 100 );
492cdf0e10cSrcweir         dialogProps.setPropertyValue( "Title", "Grid Control Unit Test" );
493cdf0e10cSrcweir         final XControl dialogControl = createInstance( XControl.class, "com.sun.star.awt.UnoControlDialog" );
494cdf0e10cSrcweir         m_disposables.add( dialogControl );
495cdf0e10cSrcweir         dialogControl.setModel( dialogModel );
496cdf0e10cSrcweir         dialogControl.createPeer( createInstance( XToolkit.class, "com.sun.star.awt.Toolkit" ), null );
497cdf0e10cSrcweir 
498cdf0e10cSrcweir         // insert a grid control model
499cdf0e10cSrcweir         final XMultiServiceFactory controlModelFactory = UnoRuntime.queryInterface( XMultiServiceFactory.class,
500cdf0e10cSrcweir             dialogModel );
501cdf0e10cSrcweir         final XPropertySet gridModelProps = UnoRuntime.queryInterface( XPropertySet.class,
502cdf0e10cSrcweir             controlModelFactory.createInstance( "com.sun.star.awt.grid.UnoControlGridModel" ) );
503cdf0e10cSrcweir         m_disposables.add( gridModelProps );
504cdf0e10cSrcweir         gridModelProps.setPropertyValue( "PositionX", 6 );
505cdf0e10cSrcweir         gridModelProps.setPropertyValue( "PositionY", 6 );
506cdf0e10cSrcweir         gridModelProps.setPropertyValue( "Width", 188 );
507cdf0e10cSrcweir         gridModelProps.setPropertyValue( "Height", 88 );
508cdf0e10cSrcweir         final XNameContainer modelContainer = UnoRuntime.queryInterface( XNameContainer.class, dialogModel );
509cdf0e10cSrcweir         modelContainer.insertByName( "grid", gridModelProps );
510cdf0e10cSrcweir 
511cdf0e10cSrcweir         // check the respective control has been created
512cdf0e10cSrcweir         final XControlContainer controlContainer = UnoRuntime.queryInterface( XControlContainer.class, dialogControl );
513cdf0e10cSrcweir         final XControl gridControl = controlContainer.getControl( "grid" );
514cdf0e10cSrcweir         assertNotNull( "no grid control created in the dialog", gridControl );
515cdf0e10cSrcweir 
516cdf0e10cSrcweir         return gridControl;
517cdf0e10cSrcweir     }
518cdf0e10cSrcweir 
519cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
impl_assertInteger( final Object i_object )520cdf0e10cSrcweir     private int impl_assertInteger( final Object i_object )
521cdf0e10cSrcweir     {
522cdf0e10cSrcweir         assertTrue( i_object instanceof Integer );
523cdf0e10cSrcweir         return ((Integer)i_object).intValue();
524cdf0e10cSrcweir     }
525cdf0e10cSrcweir 
526cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
impl_assertColumnModelConsistency()527cdf0e10cSrcweir     private void impl_assertColumnModelConsistency() throws IndexOutOfBoundsException
528cdf0e10cSrcweir     {
529cdf0e10cSrcweir         for ( int col = 0; col < m_columnModel.getColumnCount(); ++col )
530cdf0e10cSrcweir         {
531cdf0e10cSrcweir             final XGridColumn column = m_columnModel.getColumn( col );
532cdf0e10cSrcweir             assertNotNull( column );
533cdf0e10cSrcweir             assertEquals( "column/model inconsistency: column " + col + " has a wrong index!", col, column.getIndex() );
534cdf0e10cSrcweir         }
535cdf0e10cSrcweir 
536cdf0e10cSrcweir         final XGridColumn[] allColumns = m_columnModel.getColumns();
537cdf0e10cSrcweir         assertEquals( "getColumns returns the wrong number of column objects",
538cdf0e10cSrcweir             m_columnModel.getColumnCount(), allColumns.length );
539cdf0e10cSrcweir         for ( int col = 0; col < m_columnModel.getColumnCount(); ++col )
540cdf0e10cSrcweir         {
541cdf0e10cSrcweir             assertTrue( "getColumns inconsistency", impl_areSameInterface( allColumns[col], m_columnModel.getColumn(col) ) );
542cdf0e10cSrcweir         }
543cdf0e10cSrcweir     }
544cdf0e10cSrcweir 
545cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
impl_assertEquality( final XGridDataModel i_reference, final XGridDataModel i_compare )546cdf0e10cSrcweir     private void impl_assertEquality( final XGridDataModel i_reference, final XGridDataModel i_compare ) throws IndexOutOfBoundsException
547cdf0e10cSrcweir     {
548cdf0e10cSrcweir         assertNotNull( i_reference );
549cdf0e10cSrcweir         assertNotNull( i_compare );
550cdf0e10cSrcweir 
551cdf0e10cSrcweir         assertEquals( "data model comparison: wrong column counts", i_reference.getColumnCount(), i_compare.getColumnCount() );
552cdf0e10cSrcweir         assertEquals( "data model comparison: wrong row counts", i_reference.getRowCount(), i_compare.getRowCount() );
553cdf0e10cSrcweir 
554cdf0e10cSrcweir         for ( int row = 0; row < i_reference.getRowCount(); ++row )
555cdf0e10cSrcweir         {
556cdf0e10cSrcweir             assertEquals( "data model comparison: wrong row heading content in row " + row,
557cdf0e10cSrcweir                     i_reference.getRowHeading( row ) );
558cdf0e10cSrcweir             for ( int col = 0; col < i_reference.getRowCount(); ++col )
559cdf0e10cSrcweir             {
560cdf0e10cSrcweir                 assertEquals( "data model comparison: wrong cell content in cell (" + col + ", " + row + ")",
561cdf0e10cSrcweir                     i_reference.getCellData( col, row ) );
562cdf0e10cSrcweir                 assertEquals( "data model comparison: wrong tooltip content in cell (" + col + ", " + row + ")",
563cdf0e10cSrcweir                     i_reference.getCellToolTip( col, row ) );
564cdf0e10cSrcweir             }
565cdf0e10cSrcweir         }
566cdf0e10cSrcweir     }
567cdf0e10cSrcweir 
568cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
impl_assertEquality( final XGridColumnModel i_reference, final XGridColumnModel i_compare )569cdf0e10cSrcweir     private void impl_assertEquality( final XGridColumnModel i_reference, final XGridColumnModel i_compare ) throws IndexOutOfBoundsException
570cdf0e10cSrcweir     {
571cdf0e10cSrcweir         assertEquals( "column model comparison: wrong column counts", i_reference.getColumnCount(), i_compare.getColumnCount() );
572cdf0e10cSrcweir         for ( int col = 0; col < i_reference.getColumnCount(); ++col )
573cdf0e10cSrcweir         {
574cdf0e10cSrcweir             final XGridColumn referenceColumn = i_reference.getColumn( col );
575cdf0e10cSrcweir             final XGridColumn compareColumn = i_compare.getColumn( col );
576cdf0e10cSrcweir             impl_assertEquality( referenceColumn, compareColumn );
577cdf0e10cSrcweir         }
578cdf0e10cSrcweir     }
579cdf0e10cSrcweir 
580cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
impl_assertEquality( final XGridColumn i_reference, final XGridColumn i_compare )581cdf0e10cSrcweir     private void impl_assertEquality( final XGridColumn i_reference, final XGridColumn i_compare )
582cdf0e10cSrcweir     {
583cdf0e10cSrcweir         final Method[] methods = XGridColumn.class.getMethods();
584cdf0e10cSrcweir         for ( int m=0; m<methods.length; ++m )
585cdf0e10cSrcweir         {
586cdf0e10cSrcweir             if ( !methods[m].getName().startsWith( "get" ) )
587cdf0e10cSrcweir                 continue;
588cdf0e10cSrcweir             try
589cdf0e10cSrcweir             {
590cdf0e10cSrcweir                 final Object referenceValue = methods[m].invoke( i_reference );
591cdf0e10cSrcweir                 final Object compareValue = methods[m].invoke( i_compare );
592cdf0e10cSrcweir                 assertEquals( "grid column comparison: column attribute '" + methods[m].getName().substring(3) + "' does not match",
593cdf0e10cSrcweir                     referenceValue, compareValue );
594cdf0e10cSrcweir             }
595cdf0e10cSrcweir             catch ( java.lang.Exception ex )
596cdf0e10cSrcweir             {
597cdf0e10cSrcweir                 fail( " could not retrieve object attributes: " + ex.toString() );
598cdf0e10cSrcweir             }
599cdf0e10cSrcweir         }
600cdf0e10cSrcweir     }
601cdf0e10cSrcweir 
602cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
impl_areSameInterface( final Object i_lhs, final Object i_rhs )603cdf0e10cSrcweir     private boolean impl_areSameInterface( final Object i_lhs, final Object i_rhs )
604cdf0e10cSrcweir     {
605cdf0e10cSrcweir         final XInterface lhs = UnoRuntime.queryInterface( XInterface.class, i_lhs );
606cdf0e10cSrcweir         final XInterface rhs = UnoRuntime.queryInterface( XInterface.class, i_rhs );
607cdf0e10cSrcweir         return UnoRuntime.areSame( lhs, rhs );
608cdf0e10cSrcweir     }
609cdf0e10cSrcweir 
610cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
611cdf0e10cSrcweir     @Before
initTestCase()612cdf0e10cSrcweir     public void initTestCase()
613cdf0e10cSrcweir     {
614cdf0e10cSrcweir         m_disposables.clear();
615cdf0e10cSrcweir     }
616cdf0e10cSrcweir 
617cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
618cdf0e10cSrcweir     @After
cleanupTestCase()619cdf0e10cSrcweir     public void cleanupTestCase()
620cdf0e10cSrcweir     {
621cdf0e10cSrcweir         impl_dispose( m_disposables.toArray() );
622cdf0e10cSrcweir     }
623cdf0e10cSrcweir 
624cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
625cdf0e10cSrcweir     @BeforeClass
setUpConnection()626cdf0e10cSrcweir     public static void setUpConnection() throws java.lang.Exception
627cdf0e10cSrcweir     {
628cdf0e10cSrcweir         System.out.println( "--------------------------------------------------------------------------------" );
629cdf0e10cSrcweir         System.out.println( "starting class: " + GridControl.class.getName() );
630cdf0e10cSrcweir         System.out.print( "connecting ... " );
631cdf0e10cSrcweir         m_connection.setUp();
632cdf0e10cSrcweir         System.out.println( "done.");
633cdf0e10cSrcweir 
634cdf0e10cSrcweir         final long seed = m_randomGenerator.nextLong();
635cdf0e10cSrcweir         m_randomGenerator.setSeed( seed );
636cdf0e10cSrcweir         System.out.println( "seeding random number generator with " + seed );
637cdf0e10cSrcweir     }
638cdf0e10cSrcweir 
639cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
640cdf0e10cSrcweir     @AfterClass
tearDownConnection()641cdf0e10cSrcweir     public static void tearDownConnection()
642cdf0e10cSrcweir         throws InterruptedException, com.sun.star.uno.Exception
643cdf0e10cSrcweir     {
644cdf0e10cSrcweir         System.out.println();
645cdf0e10cSrcweir         System.out.println( "tearing down connection" );
646cdf0e10cSrcweir         m_connection.tearDown();
647cdf0e10cSrcweir         System.out.println( "finished class: " + GridControl.class.getName() );
648cdf0e10cSrcweir         System.out.println( "--------------------------------------------------------------------------------" );
649cdf0e10cSrcweir     }
650cdf0e10cSrcweir 
651cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
createInstance( Class<T> i_interfaceClass, final String i_serviceIndentifer )652cdf0e10cSrcweir     public <T> T createInstance( Class<T> i_interfaceClass, final String i_serviceIndentifer ) throws Exception
653cdf0e10cSrcweir     {
654cdf0e10cSrcweir         return UnoRuntime.queryInterface( i_interfaceClass, createInstance( i_serviceIndentifer ) );
655cdf0e10cSrcweir     }
656cdf0e10cSrcweir 
657cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
createInstance( final String i_serviceName )658cdf0e10cSrcweir     private Object createInstance( final String i_serviceName ) throws Exception
659cdf0e10cSrcweir     {
660cdf0e10cSrcweir         Object instance = m_context.getServiceManager().createInstanceWithContext( i_serviceName, m_context );
661cdf0e10cSrcweir         assertNotNull( "could not create an instance of '" + i_serviceName + "'", instance );
662cdf0e10cSrcweir         return instance;
663cdf0e10cSrcweir     }
664cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
665cdf0e10cSrcweir     private static final class DisposeListener implements XEventListener
666cdf0e10cSrcweir     {
DisposeListener( final Object i_component )667cdf0e10cSrcweir         DisposeListener( final Object i_component )
668cdf0e10cSrcweir         {
669cdf0e10cSrcweir             m_component = UnoRuntime.queryInterface( XComponent.class, i_component );
670cdf0e10cSrcweir             assertNotNull( m_component );
671cdf0e10cSrcweir             m_component.addEventListener( this );
672cdf0e10cSrcweir         }
673cdf0e10cSrcweir 
disposing( EventObject i_event )674cdf0e10cSrcweir         public void disposing( EventObject i_event )
675cdf0e10cSrcweir         {
676cdf0e10cSrcweir             assertTrue( UnoRuntime.areSame( i_event.Source, m_component ) );
677cdf0e10cSrcweir             m_isDisposed = true;
678cdf0e10cSrcweir         }
679cdf0e10cSrcweir 
isDisposed()680cdf0e10cSrcweir         final boolean isDisposed() { return m_isDisposed; }
681cdf0e10cSrcweir 
682cdf0e10cSrcweir         private final XComponent    m_component;
683cdf0e10cSrcweir         private boolean             m_isDisposed;
684cdf0e10cSrcweir     };
685cdf0e10cSrcweir 
686cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
687cdf0e10cSrcweir     private static final class ColumnModelListener implements XContainerListener
688cdf0e10cSrcweir     {
ColumnModelListener()689cdf0e10cSrcweir         ColumnModelListener()
690cdf0e10cSrcweir         {
691cdf0e10cSrcweir         }
692cdf0e10cSrcweir 
elementInserted( ContainerEvent i_event )693cdf0e10cSrcweir         public void elementInserted( ContainerEvent i_event )
694cdf0e10cSrcweir         {
695cdf0e10cSrcweir             m_insertionEvents.add( i_event );
696cdf0e10cSrcweir         }
697cdf0e10cSrcweir 
elementRemoved( ContainerEvent i_event )698cdf0e10cSrcweir         public void elementRemoved( ContainerEvent i_event )
699cdf0e10cSrcweir         {
700cdf0e10cSrcweir             m_removalEvents.add( i_event );
701cdf0e10cSrcweir         }
702cdf0e10cSrcweir 
elementReplaced( ContainerEvent i_event )703cdf0e10cSrcweir         public void elementReplaced( ContainerEvent i_event )
704cdf0e10cSrcweir         {
705cdf0e10cSrcweir             m_replacementEvents.add( i_event );
706cdf0e10cSrcweir         }
707cdf0e10cSrcweir 
disposing( EventObject eo )708cdf0e10cSrcweir         public void disposing( EventObject eo )
709cdf0e10cSrcweir         {
710cdf0e10cSrcweir             m_isDisposed = true;
711cdf0e10cSrcweir         }
712cdf0e10cSrcweir 
assertExclusiveInsertionEvents()713cdf0e10cSrcweir         private List< ContainerEvent > assertExclusiveInsertionEvents()
714cdf0e10cSrcweir         {
715cdf0e10cSrcweir             assertFalse( m_insertionEvents.isEmpty() );
716cdf0e10cSrcweir             assertTrue( m_removalEvents.isEmpty() );
717cdf0e10cSrcweir             assertTrue( m_replacementEvents.isEmpty() );
718cdf0e10cSrcweir             return m_insertionEvents;
719cdf0e10cSrcweir         }
720cdf0e10cSrcweir 
assertExclusiveRemovalEvents()721cdf0e10cSrcweir         private List< ContainerEvent > assertExclusiveRemovalEvents()
722cdf0e10cSrcweir         {
723cdf0e10cSrcweir             assertTrue( m_insertionEvents.isEmpty() );
724cdf0e10cSrcweir             assertFalse( m_removalEvents.isEmpty() );
725cdf0e10cSrcweir             assertTrue( m_replacementEvents.isEmpty() );
726cdf0e10cSrcweir             return m_removalEvents;
727cdf0e10cSrcweir         }
728cdf0e10cSrcweir 
reset()729cdf0e10cSrcweir         private void reset()
730cdf0e10cSrcweir         {
731cdf0e10cSrcweir             m_insertionEvents = new ArrayList< ContainerEvent >();
732cdf0e10cSrcweir             m_removalEvents = new ArrayList< ContainerEvent >();
733cdf0e10cSrcweir             m_replacementEvents = new ArrayList< ContainerEvent >();
734cdf0e10cSrcweir         }
735cdf0e10cSrcweir 
getInsertionEvents()736cdf0e10cSrcweir         private List< ContainerEvent > getInsertionEvents() { return m_insertionEvents; }
getRemovalEvents()737cdf0e10cSrcweir         private List< ContainerEvent > getRemovalEvents() { return m_removalEvents; }
738cdf0e10cSrcweir 
isDisposed()739cdf0e10cSrcweir         final boolean isDisposed() { return m_isDisposed; }
740cdf0e10cSrcweir 
741cdf0e10cSrcweir         private List< ContainerEvent > m_insertionEvents = new ArrayList< ContainerEvent >();
742cdf0e10cSrcweir         private List< ContainerEvent > m_removalEvents = new ArrayList< ContainerEvent >();
743cdf0e10cSrcweir         private List< ContainerEvent > m_replacementEvents = new ArrayList< ContainerEvent >();
744cdf0e10cSrcweir         private boolean m_isDisposed = false;
745cdf0e10cSrcweir     };
746cdf0e10cSrcweir 
747cdf0e10cSrcweir     // -----------------------------------------------------------------------------------------------------------------
748cdf0e10cSrcweir     private static final OfficeConnection m_connection = new OfficeConnection();
749cdf0e10cSrcweir     private static Random m_randomGenerator = new Random();
750cdf0e10cSrcweir     private final XComponentContext m_context;
751cdf0e10cSrcweir 
752cdf0e10cSrcweir     private XPropertySet                    m_gridControlModel;
753cdf0e10cSrcweir     private XGridColumnModel                m_columnModel;
754cdf0e10cSrcweir     private XSortableMutableGridDataModel   m_dataModel;
755cdf0e10cSrcweir     private final List< Object >            m_disposables = new ArrayList< Object >();
756cdf0e10cSrcweir }
757