| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| package complex.toolkit; |
| |
| import com.sun.star.awt.XControl; |
| import com.sun.star.awt.XControlContainer; |
| import com.sun.star.awt.XControlModel; |
| import com.sun.star.awt.XToolkit; |
| import com.sun.star.awt.grid.DefaultGridDataModel; |
| import com.sun.star.awt.grid.XGridColumn; |
| import com.sun.star.awt.grid.XGridColumnModel; |
| import com.sun.star.awt.grid.XGridControl; |
| import com.sun.star.awt.grid.XGridDataModel; |
| import com.sun.star.awt.grid.XMutableGridDataModel; |
| import com.sun.star.awt.grid.XSortableMutableGridDataModel; |
| import com.sun.star.beans.Pair; |
| import com.sun.star.beans.XPropertySet; |
| import com.sun.star.container.ContainerEvent; |
| import com.sun.star.container.XContainerListener; |
| import com.sun.star.container.XNameContainer; |
| import com.sun.star.lang.EventObject; |
| import com.sun.star.lang.IndexOutOfBoundsException; |
| import com.sun.star.lang.XComponent; |
| import com.sun.star.lang.XEventListener; |
| import com.sun.star.lang.XMultiServiceFactory; |
| import com.sun.star.uno.Exception; |
| import com.sun.star.uno.UnoRuntime; |
| import com.sun.star.uno.XComponentContext; |
| import com.sun.star.uno.XInterface; |
| import com.sun.star.util.XCloneable; |
| import complex.toolkit.awtgrid.DummyColumn; |
| import complex.toolkit.awtgrid.TMutableGridDataModel; |
| import java.lang.reflect.Method; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Random; |
| import org.junit.AfterClass; |
| import org.junit.BeforeClass; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import static org.junit.Assert.*; |
| import org.openoffice.test.OfficeConnection; |
| |
| /** is a unit test for the grid control related implementations |
| * @author frank.schoenheit@sun.com |
| */ |
| public class GridControl |
| { |
| // ----------------------------------------------------------------------------------------------------------------- |
| public GridControl() |
| { |
| m_context = m_connection.getComponentContext(); |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| private static void impl_dispose( final Object... i_components ) |
| { |
| for ( int i=0; i<i_components.length; ++i ) |
| { |
| if ( i_components[i] != null ) |
| { |
| final XComponent component = UnoRuntime.queryInterface( XComponent.class, i_components[i] ); |
| component.dispose(); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| private void impl_recreateGridModel() throws Exception |
| { |
| impl_dispose( m_gridControlModel, m_columnModel, m_dataModel ); |
| |
| // create a grid control model, and ensure it has a proper data and column model already |
| m_gridControlModel = UnoRuntime.queryInterface( XPropertySet.class, |
| createInstance( "com.sun.star.awt.grid.UnoControlGridModel" ) ); |
| assertNotNull( "grid control model does not provide XPropertySet interface", m_gridControlModel ); |
| |
| // ensure that the model has default column/data models |
| m_columnModel = UnoRuntime.queryInterface( XGridColumnModel.class, m_gridControlModel.getPropertyValue( "ColumnModel" ) ); |
| assertNotNull( "the control model is expected to have an initial column model", m_columnModel ); |
| final XGridDataModel dataModel = UnoRuntime.queryInterface( XGridDataModel.class, m_gridControlModel.getPropertyValue( "GridDataModel" ) ); |
| assertNotNull( "the control model is expected to have an initial data model", dataModel ); |
| m_dataModel = UnoRuntime.queryInterface( XSortableMutableGridDataModel.class, |
| dataModel ); |
| assertNotNull( "the out-of-the-box data model should be mutable and sortable", m_dataModel ); |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| @Test |
| public void testGridControlCloning() throws Exception |
| { |
| impl_recreateGridModel(); |
| |
| // give the test something to compare, actually |
| XGridColumnModel columnModel = UnoRuntime.queryInterface( XGridColumnModel.class, |
| m_gridControlModel.getPropertyValue( "ColumnModel" ) ); |
| columnModel.setDefaultColumns( 10 ); |
| |
| // clone the grid model |
| final XCloneable cloneable = UnoRuntime.queryInterface( XCloneable.class, m_gridControlModel ); |
| assertNotNull( "all UnoControlModel's are expected to be cloneable", cloneable ); |
| |
| final XInterface clone = cloneable.createClone(); |
| final XPropertySet clonedProps = UnoRuntime.queryInterface( XPropertySet.class, clone ); |
| |
| // TODO: check all those generic properties for equality |
| |
| // the data model and the column model should have been cloned, too |
| // in particular, the clone should not share the sub models with the orignal |
| final XMutableGridDataModel originalDataModel = UnoRuntime.queryInterface( XMutableGridDataModel.class, |
| m_gridControlModel.getPropertyValue( "GridDataModel" ) ); |
| final XMutableGridDataModel clonedDataModel = UnoRuntime.queryInterface( XMutableGridDataModel.class, |
| clonedProps.getPropertyValue( "GridDataModel" ) ); |
| assertFalse( "data model should not be shared after cloning", UnoRuntime.areSame( originalDataModel, clonedDataModel ) ); |
| impl_assertEquality( originalDataModel, clonedDataModel ); |
| |
| final XGridColumnModel originalColumnModel = columnModel; |
| final XGridColumnModel clonedColumnModel = UnoRuntime.queryInterface( XGridColumnModel.class, |
| clonedProps.getPropertyValue( "ColumnModel" ) ); |
| assertFalse( "column model should not be shared after cloning", UnoRuntime.areSame( originalColumnModel, clonedColumnModel ) ); |
| impl_assertEquality( originalColumnModel, clonedColumnModel ); |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| @Test |
| public void testDisposal() throws Exception |
| { |
| impl_recreateGridModel(); |
| |
| final int columnCount = 3; |
| m_columnModel.setDefaultColumns( columnCount ); |
| |
| // add disposal listeners to all columns so far |
| final XGridColumn[] columns = m_columnModel.getColumns(); |
| assertEquals( "creating default columns resulted in unexpected column count", columnCount, columns.length ); |
| final DisposeListener[] columnListeners = new DisposeListener[columnCount]; |
| for ( int i=0; i<columnCount; ++i ) |
| columnListeners[i] = new DisposeListener( columns[i] ); |
| |
| // add another column, and check that upon removal, it is disposed |
| final int newColumnIndex = m_columnModel.addColumn( m_columnModel.createColumn() ); |
| final DisposeListener columnListener = new DisposeListener( m_columnModel.getColumn( newColumnIndex ) ); |
| m_columnModel.removeColumn( newColumnIndex ); |
| assertTrue( "explicit column removal is expected to dispose the column", columnListener.isDisposed() ); |
| |
| // by definition, the grid control model is the owner of both the column and the data model. So, setting |
| // a new column/data model should implicitly dispose the old models |
| final DisposeListener oldDataModelListener = new DisposeListener( m_dataModel ); |
| final DisposeListener oldColumnModelListener = new DisposeListener( m_columnModel ); |
| |
| final Object newDataModel = createInstance( "com.sun.star.awt.grid.DefaultGridDataModel" ); |
| final Object newColumnModel = createInstance( "com.sun.star.awt.grid.DefaultGridColumnModel" ); |
| final DisposeListener newDataModelListener = new DisposeListener( newDataModel ); |
| final DisposeListener newColumnModelListener = new DisposeListener( newColumnModel ); |
| |
| m_gridControlModel.setPropertyValue( "GridDataModel", newDataModel ); |
| assertTrue( "setting a new data model failed", impl_areSameInterface( newDataModel, m_gridControlModel.getPropertyValue( "GridDataModel" ) ) ); |
| m_gridControlModel.setPropertyValue( "ColumnModel", newColumnModel ); |
| assertTrue( "setting a new column model failed", impl_areSameInterface( newColumnModel, m_gridControlModel.getPropertyValue( "ColumnModel" ) ) ); |
| |
| assertTrue( "old data model has not been disposed", oldDataModelListener.isDisposed() ); |
| assertTrue( "old column model has not been disposed", oldColumnModelListener.isDisposed() ); |
| for ( int i=0; i<columnCount; ++i ) |
| assertTrue( "column no. " + i + " has not been disposed", columnListeners[i].isDisposed() ); |
| |
| // the same holds if the grid control model itself is disposed - it should dispose the depending models, too |
| assertFalse( "new data model is already disposed - this is unexpected", newDataModelListener.isDisposed() ); |
| assertFalse( "new column model is already disposed - this is unexpected", newColumnModelListener.isDisposed() ); |
| impl_dispose( m_gridControlModel ); |
| assertTrue( "new data model is not disposed after disposing the grid column model", newDataModelListener.isDisposed() ); |
| assertTrue( "new column model is not disposed after disposing the grid column model", newColumnModelListener.isDisposed() ); |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| /** |
| * tests various aspects of the <code>XMutableGridDataModel</code> interface |
| */ |
| @Test |
| public void testMutableGridDataModel() throws Exception |
| { |
| impl_recreateGridModel(); |
| |
| TMutableGridDataModel test = new TMutableGridDataModel( m_dataModel ); |
| test.testAddRow(); |
| test.testAddRows(); |
| test.testInsertRow(); |
| test.testInsertRows(); |
| test.testRemoveRow(); |
| test.testRemoveAllRows(); |
| test.testUpdateCellData(); |
| test.testUpdateRowData(); |
| test.testUpdateRowHeading(); |
| test.cleanup(); |
| |
| // a somehwat less straight-forward test: the data model is expected to implicitly increase its column count |
| // when you add a row which has more columns than currently known |
| final XMutableGridDataModel dataModel = DefaultGridDataModel.create( m_context ); |
| dataModel.addRow( 0, new Object[] { 1 } ); |
| assertEquals( "unexpected column count after adding the most simple row", 1, dataModel.getColumnCount() ); |
| dataModel.addRow( 1, new Object[] { 1, 2 } ); |
| assertEquals( "implicit extension of the column count doesn't work", 2, dataModel.getColumnCount() ); |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| @Test |
| public void testGridColumnModel() throws Exception |
| { |
| impl_recreateGridModel(); |
| |
| ColumnModelListener listener = new ColumnModelListener(); |
| m_columnModel.addContainerListener( listener ); |
| |
| // insert default columns into the previously empty model, ensure we get the right notifications |
| final int defaultColumnsCount = 3; |
| m_columnModel.setDefaultColumns( defaultColumnsCount ); |
| impl_assertColumnModelConsistency(); |
| List< ContainerEvent > events = listener.assertExclusiveInsertionEvents(); |
| listener.reset(); |
| assertEquals( "wrong number of events fired by setDefaulColumns", defaultColumnsCount, events.size() ); |
| for ( int i=0; i<defaultColumnsCount; ++i ) |
| { |
| final ContainerEvent event = events.get(i); |
| final int index = impl_assertInteger( event.Accessor ); |
| assertEquals( "unexpected Accessor value in insert notification", i, index ); |
| assertTrue( "wrong column object notified in insert notification", |
| impl_areSameInterface( event.Element, m_columnModel.getColumn(i) ) ); |
| } |
| |
| // insert some more default columns, ensure that all previously existing columns are removed |
| final int moreDefaultColumnsCount = 5; |
| m_columnModel.setDefaultColumns( moreDefaultColumnsCount ); |
| impl_assertColumnModelConsistency(); |
| assertEquals( "setting default columns is expected to remove all previously existing columns", |
| moreDefaultColumnsCount, m_columnModel.getColumnCount() ); |
| |
| // in this situation, both removal and insertion events have been notified |
| final List< ContainerEvent > removalEvents = listener.getRemovalEvents(); |
| final List< ContainerEvent > insertionEvents = listener.getInsertionEvents(); |
| listener.reset(); |
| |
| // for the removal events, check the indexes |
| assertEquals( "wrong number of columns removed (or notified) upon setting default columns", |
| defaultColumnsCount, removalEvents.size() ); |
| for ( int i=0; i<removalEvents.size(); ++i ) |
| { |
| final ContainerEvent event = removalEvents.get(i); |
| final int removedIndex = impl_assertInteger( event.Accessor ); |
| |
| // The implementation is allowed to remove the columns from the beginning, in which case the |
| // index of the removed column must always be 0, since e.g. the second column has index 0 |
| // after the first column (which previously had index 0) had been removed. |
| // Alternatively, the implementation is allowed to remove columns from the end, which means |
| // that the column index given in the event is steadily increasing. |
| assertTrue( "unexpected column removal event column index", |
| ( removedIndex == 0 ) || ( removedIndex == removalEvents.size() - 1 - i ) ); |
| } |
| |
| // for the insertion events, check the indexes as well |
| assertEquals( "wrong number of insertion events when setting default columns over existing columns", |
| moreDefaultColumnsCount, insertionEvents.size() ); |
| for ( int i=0; i<insertionEvents.size(); ++i ) |
| { |
| final ContainerEvent event = insertionEvents.get(i); |
| final int index = impl_assertInteger( event.Accessor ); |
| assertEquals( i, index ); |
| } |
| |
| // okay, remove all those columns |
| while ( m_columnModel.getColumnCount() != 0 ) |
| { |
| final int columnCount = m_columnModel.getColumnCount(); |
| final int removeColumnIndex = m_randomGenerator.nextInt( columnCount ); |
| m_columnModel.removeColumn( removeColumnIndex ); |
| events = listener.assertExclusiveRemovalEvents(); |
| listener.reset(); |
| assertEquals( "removing a single column should notify a single event", 1, events.size() ); |
| final ContainerEvent event = events.get(0); |
| final int removalIndex = impl_assertInteger( event.Accessor ); |
| assertEquals( "removing an arbitrary column does not notify the proper accessor", |
| removeColumnIndex, removalIndex ); |
| } |
| |
| // calling addColumn with a column not created by the given model/implementatoion should not succeed |
| boolean caughtExpected = false; |
| try |
| { |
| m_columnModel.addColumn( new DummyColumn() ); |
| } |
| catch( final com.sun.star.lang.IllegalArgumentException e ) |
| { |
| assertTrue( impl_areSameInterface( e.Context, m_columnModel ) ); |
| caughtExpected = true; |
| } |
| assertTrue( "adding a dummy (self-implemented) grid column to the model should not succeed", caughtExpected ); |
| |
| // adding a single column to the end should succeed, properly notify, and still be consistent |
| final XGridColumn newColumn = m_columnModel.createColumn(); |
| m_columnModel.addColumn( newColumn ); |
| impl_assertColumnModelConsistency(); |
| events = listener.assertExclusiveInsertionEvents(); |
| listener.reset(); |
| assertEquals( "addColumn notifies the wrong number of insertion events", 1, events.size() ); |
| final int insertionIndex = impl_assertInteger( events.get(0).Accessor ); |
| assertEquals( insertionIndex, newColumn.getIndex() ); |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| @Test |
| public void testDataModel() throws Exception |
| { |
| impl_recreateGridModel(); |
| |
| // ensure that getCellData and getRowData have the same opinion on the data they deliver |
| final Object[][] data = new Object[][] { |
| new Object[] { 15, 17, 0 }, |
| new Object[] { 9, 8, 14 }, |
| new Object[] { 17, 2, 16 }, |
| new Object[] { 0, 7, 14 }, |
| new Object[] { 10, 16, 16 }, |
| }; |
| m_dataModel.addRows( new Object[ data.length ], data ); |
| |
| for ( int row = 0; row < data.length; ++row ) |
| { |
| assertArrayEquals( "getRowData delivers wrong data in row " + row, data[row], m_dataModel.getRowData( row ) ); |
| for ( int col = 0; col < data[row].length; ++col ) |
| { |
| assertEquals( "getCellData delivers wrong data at position (" + col + ", " + row + ")", |
| data[row][col], m_dataModel.getCellData( col, row ) ); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| @Test |
| public void testSortableDataModel() throws Exception |
| { |
| impl_recreateGridModel(); |
| |
| final int colCount = 3; |
| final int rowCount = 10; |
| // initialize with some data |
| final Object[][] data = new Object[][] { |
| new Object[] { 15, 17, 0 }, |
| new Object[] { 9, 8, 14 }, |
| new Object[] { 17, 2, 16 }, |
| new Object[] { 0, 7, 14 }, |
| new Object[] { 10, 16, 16 }, |
| new Object[] { 2, 8, 10 }, |
| new Object[] { 4, 8, 3 }, |
| new Object[] { 7, 9, 0 }, |
| new Object[] { 15, 6, 19 }, |
| new Object[] { 2, 14, 19 } |
| }; |
| final Object[] rowHeadings = new Object[] { |
| 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 |
| }; |
| // ensure consistency of the test data |
| assertEquals( rowHeadings.length, rowCount ); |
| assertEquals( data.length, rowCount ); |
| for ( Object[] rowData : data ) |
| assertEquals( rowData.length, colCount ); |
| |
| // add the test data |
| m_dataModel.addRows( rowHeadings, data ); |
| assertEquals( rowCount, m_dataModel.getRowCount() ); |
| assertEquals( colCount, m_dataModel.getColumnCount() ); |
| |
| // sort by each column |
| for ( int colIndex = 0; colIndex < colCount; ++colIndex ) |
| { |
| for ( boolean ascending : new boolean[] { true, false } ) |
| { |
| m_dataModel.sortByColumn( colIndex, ascending ); |
| Pair currentSortOrder = m_dataModel.getCurrentSortOrder(); |
| assertEquals( "invalid current sort column (column " + colIndex + ")", ((Integer)currentSortOrder.First).intValue(), colIndex ); |
| assertEquals( "invalid current sort direction", ((Boolean)currentSortOrder.Second).booleanValue(), ascending ); |
| |
| /*for ( int i=0; i<rowCount; ++i ) |
| { |
| for ( int j=0; j<colCount; ++j ) |
| System.out.print( m_dataModel.getCellData( j, i ).toString() + ", " ); |
| System.out.println(); |
| }*/ |
| |
| // verify the data is actually sorted by this column |
| for ( int rowIndex = 0; rowIndex < rowCount - 1; ++rowIndex ) |
| { |
| final Object currentValue = m_dataModel.getCellData( colIndex, rowIndex ); |
| final int currentIntValue = impl_assertInteger( currentValue ); |
| final Object nextValue = m_dataModel.getCellData( colIndex, rowIndex + 1 ); |
| final int nextIntValue = impl_assertInteger( nextValue ); |
| assertTrue( "data in row " + rowIndex + " is actually not sorted " + ( ascending ? "ascending" : "descending" ), |
| ascending ? currentIntValue <= nextIntValue |
| : currentIntValue >= nextIntValue ); |
| |
| // ensure the data in the other columns, and the row headings, are sorted as well |
| final Object rowHeading = m_dataModel.getRowHeading( rowIndex ); |
| final int unsortedRowIndex = impl_assertInteger( rowHeading ); |
| for ( int innerColIndex = 0; innerColIndex < colCount; ++innerColIndex ) |
| { |
| assertEquals( "sorted row " + rowIndex + ", unsorted row " + unsortedRowIndex + ", col " + innerColIndex + |
| ": wrong data", |
| data[unsortedRowIndex][innerColIndex], m_dataModel.getCellData( innerColIndex, rowIndex ) ); |
| } |
| } |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| @Test |
| public void testView() throws Exception |
| { |
| final XControl control = impl_createDialogWithGridControl(); |
| final XPropertySet gridModelProps = |
| UnoRuntime.queryInterface( XPropertySet.class, control.getModel() ); |
| |
| // in the current implementation (not sure this is a good idea at all), the control (more precise: the peer) |
| // ensures that if there are no columns in the column model, but in the data model, then the column model |
| // will implicitly have the needed columns added. |
| // To ensure that clients which rely on this do not break in the future, check this here. |
| final XMutableGridDataModel dataModel = UnoRuntime.queryInterface( XMutableGridDataModel.class, |
| gridModelProps.getPropertyValue( "GridDataModel" ) ); |
| assertNotNull( dataModel ); |
| assertEquals( 0, dataModel.getColumnCount() ); |
| |
| final XGridColumnModel columnModel = UnoRuntime.queryInterface( XGridColumnModel.class, |
| gridModelProps.getPropertyValue( "ColumnModel" ) ); |
| assertNotNull( columnModel ); |
| assertEquals( 0, columnModel.getColumnCount() ); |
| |
| final int columnCount = 3; |
| final int rowCount = 2; |
| dataModel.addRow( null, new Object[] { 1, 2, 3 } ); |
| dataModel.addRow( null, new Object[] { 6, 5, 4 } ); |
| |
| assertEquals( columnCount, dataModel.getColumnCount() ); |
| assertEquals( columnCount, columnModel.getColumnCount() ); |
| |
| // some cursor traveling |
| final XGridControl gridControl = UnoRuntime.queryInterface( XGridControl.class, control ); |
| gridControl.goToCell( 0, 0 ); |
| assertEquals( "wrong 'current column' (1)", 0, gridControl.getCurrentColumn() ); |
| assertEquals( "wrong 'current row' (1)", 0, gridControl.getCurrentRow() ); |
| gridControl.goToCell( columnCount - 1, rowCount - 1 ); |
| assertEquals( "wrong 'current column' (2)", dataModel.getColumnCount() - 1, gridControl.getCurrentColumn() ); |
| assertEquals( "wrong 'current row' (2)", dataModel.getRowCount() - 1, gridControl.getCurrentRow() ); |
| |
| // removing the last column, while the active cell is in this very last column, is expected to adjust |
| // the active cell |
| columnModel.removeColumn( columnCount - 1 ); |
| assertEquals( "removed the last and active column, active column was not adjusted!", |
| columnCount - 2, gridControl.getCurrentColumn() ); |
| // same holds for rows |
| dataModel.removeRow( rowCount - 1 ); |
| assertEquals( "removed the last and active row, active row was not adjusted!", |
| rowCount - 2, gridControl.getCurrentRow() ); |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| private XControl impl_createDialogWithGridControl() throws Exception |
| { |
| // create a simple dialog model/control/peer trinity |
| final XControlModel dialogModel = createInstance( XControlModel.class, "com.sun.star.awt.UnoControlDialogModel" ); |
| m_disposables.add( dialogModel ); |
| final XPropertySet dialogProps = UnoRuntime.queryInterface( XPropertySet.class, dialogModel ); |
| dialogProps.setPropertyValue( "Width", 200 ); |
| dialogProps.setPropertyValue( "Height", 100 ); |
| dialogProps.setPropertyValue( "Title", "Grid Control Unit Test" ); |
| final XControl dialogControl = createInstance( XControl.class, "com.sun.star.awt.UnoControlDialog" ); |
| m_disposables.add( dialogControl ); |
| dialogControl.setModel( dialogModel ); |
| dialogControl.createPeer( createInstance( XToolkit.class, "com.sun.star.awt.Toolkit" ), null ); |
| |
| // insert a grid control model |
| final XMultiServiceFactory controlModelFactory = UnoRuntime.queryInterface( XMultiServiceFactory.class, |
| dialogModel ); |
| final XPropertySet gridModelProps = UnoRuntime.queryInterface( XPropertySet.class, |
| controlModelFactory.createInstance( "com.sun.star.awt.grid.UnoControlGridModel" ) ); |
| m_disposables.add( gridModelProps ); |
| gridModelProps.setPropertyValue( "PositionX", 6 ); |
| gridModelProps.setPropertyValue( "PositionY", 6 ); |
| gridModelProps.setPropertyValue( "Width", 188 ); |
| gridModelProps.setPropertyValue( "Height", 88 ); |
| final XNameContainer modelContainer = UnoRuntime.queryInterface( XNameContainer.class, dialogModel ); |
| modelContainer.insertByName( "grid", gridModelProps ); |
| |
| // check the respective control has been created |
| final XControlContainer controlContainer = UnoRuntime.queryInterface( XControlContainer.class, dialogControl ); |
| final XControl gridControl = controlContainer.getControl( "grid" ); |
| assertNotNull( "no grid control created in the dialog", gridControl ); |
| |
| return gridControl; |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| private int impl_assertInteger( final Object i_object ) |
| { |
| assertTrue( i_object instanceof Integer ); |
| return ((Integer)i_object).intValue(); |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| private void impl_assertColumnModelConsistency() throws IndexOutOfBoundsException |
| { |
| for ( int col = 0; col < m_columnModel.getColumnCount(); ++col ) |
| { |
| final XGridColumn column = m_columnModel.getColumn( col ); |
| assertNotNull( column ); |
| assertEquals( "column/model inconsistency: column " + col + " has a wrong index!", col, column.getIndex() ); |
| } |
| |
| final XGridColumn[] allColumns = m_columnModel.getColumns(); |
| assertEquals( "getColumns returns the wrong number of column objects", |
| m_columnModel.getColumnCount(), allColumns.length ); |
| for ( int col = 0; col < m_columnModel.getColumnCount(); ++col ) |
| { |
| assertTrue( "getColumns inconsistency", impl_areSameInterface( allColumns[col], m_columnModel.getColumn(col) ) ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| private void impl_assertEquality( final XGridDataModel i_reference, final XGridDataModel i_compare ) throws IndexOutOfBoundsException |
| { |
| assertNotNull( i_reference ); |
| assertNotNull( i_compare ); |
| |
| assertEquals( "data model comparison: wrong column counts", i_reference.getColumnCount(), i_compare.getColumnCount() ); |
| assertEquals( "data model comparison: wrong row counts", i_reference.getRowCount(), i_compare.getRowCount() ); |
| |
| for ( int row = 0; row < i_reference.getRowCount(); ++row ) |
| { |
| assertEquals( "data model comparison: wrong row heading content in row " + row, |
| i_reference.getRowHeading( row ) ); |
| for ( int col = 0; col < i_reference.getRowCount(); ++col ) |
| { |
| assertEquals( "data model comparison: wrong cell content in cell (" + col + ", " + row + ")", |
| i_reference.getCellData( col, row ) ); |
| assertEquals( "data model comparison: wrong tooltip content in cell (" + col + ", " + row + ")", |
| i_reference.getCellToolTip( col, row ) ); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| private void impl_assertEquality( final XGridColumnModel i_reference, final XGridColumnModel i_compare ) throws IndexOutOfBoundsException |
| { |
| assertEquals( "column model comparison: wrong column counts", i_reference.getColumnCount(), i_compare.getColumnCount() ); |
| for ( int col = 0; col < i_reference.getColumnCount(); ++col ) |
| { |
| final XGridColumn referenceColumn = i_reference.getColumn( col ); |
| final XGridColumn compareColumn = i_compare.getColumn( col ); |
| impl_assertEquality( referenceColumn, compareColumn ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| private void impl_assertEquality( final XGridColumn i_reference, final XGridColumn i_compare ) |
| { |
| final Method[] methods = XGridColumn.class.getMethods(); |
| for ( int m=0; m<methods.length; ++m ) |
| { |
| if ( !methods[m].getName().startsWith( "get" ) ) |
| continue; |
| try |
| { |
| final Object referenceValue = methods[m].invoke( i_reference ); |
| final Object compareValue = methods[m].invoke( i_compare ); |
| assertEquals( "grid column comparison: column attribute '" + methods[m].getName().substring(3) + "' does not match", |
| referenceValue, compareValue ); |
| } |
| catch ( java.lang.Exception ex ) |
| { |
| fail( " could not retrieve object attributes: " + ex.toString() ); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| private boolean impl_areSameInterface( final Object i_lhs, final Object i_rhs ) |
| { |
| final XInterface lhs = UnoRuntime.queryInterface( XInterface.class, i_lhs ); |
| final XInterface rhs = UnoRuntime.queryInterface( XInterface.class, i_rhs ); |
| return UnoRuntime.areSame( lhs, rhs ); |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| @Before |
| public void initTestCase() |
| { |
| m_disposables.clear(); |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| @After |
| public void cleanupTestCase() |
| { |
| impl_dispose( m_disposables.toArray() ); |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| @BeforeClass |
| public static void setUpConnection() throws java.lang.Exception |
| { |
| System.out.println( "--------------------------------------------------------------------------------" ); |
| System.out.println( "starting class: " + GridControl.class.getName() ); |
| System.out.print( "connecting ... " ); |
| m_connection.setUp(); |
| System.out.println( "done."); |
| |
| final long seed = m_randomGenerator.nextLong(); |
| m_randomGenerator.setSeed( seed ); |
| System.out.println( "seeding random number generator with " + seed ); |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| @AfterClass |
| public static void tearDownConnection() |
| throws InterruptedException, com.sun.star.uno.Exception |
| { |
| System.out.println(); |
| System.out.println( "tearing down connection" ); |
| m_connection.tearDown(); |
| System.out.println( "finished class: " + GridControl.class.getName() ); |
| System.out.println( "--------------------------------------------------------------------------------" ); |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| public <T> T createInstance( Class<T> i_interfaceClass, final String i_serviceIndentifer ) throws Exception |
| { |
| return UnoRuntime.queryInterface( i_interfaceClass, createInstance( i_serviceIndentifer ) ); |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| private Object createInstance( final String i_serviceName ) throws Exception |
| { |
| Object instance = m_context.getServiceManager().createInstanceWithContext( i_serviceName, m_context ); |
| assertNotNull( "could not create an instance of '" + i_serviceName + "'", instance ); |
| return instance; |
| } |
| // ----------------------------------------------------------------------------------------------------------------- |
| private static final class DisposeListener implements XEventListener |
| { |
| DisposeListener( final Object i_component ) |
| { |
| m_component = UnoRuntime.queryInterface( XComponent.class, i_component ); |
| assertNotNull( m_component ); |
| m_component.addEventListener( this ); |
| } |
| |
| public void disposing( EventObject i_event ) |
| { |
| assertTrue( UnoRuntime.areSame( i_event.Source, m_component ) ); |
| m_isDisposed = true; |
| } |
| |
| final boolean isDisposed() { return m_isDisposed; } |
| |
| private final XComponent m_component; |
| private boolean m_isDisposed; |
| }; |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| private static final class ColumnModelListener implements XContainerListener |
| { |
| ColumnModelListener() |
| { |
| } |
| |
| public void elementInserted( ContainerEvent i_event ) |
| { |
| m_insertionEvents.add( i_event ); |
| } |
| |
| public void elementRemoved( ContainerEvent i_event ) |
| { |
| m_removalEvents.add( i_event ); |
| } |
| |
| public void elementReplaced( ContainerEvent i_event ) |
| { |
| m_replacementEvents.add( i_event ); |
| } |
| |
| public void disposing( EventObject eo ) |
| { |
| m_isDisposed = true; |
| } |
| |
| private List< ContainerEvent > assertExclusiveInsertionEvents() |
| { |
| assertFalse( m_insertionEvents.isEmpty() ); |
| assertTrue( m_removalEvents.isEmpty() ); |
| assertTrue( m_replacementEvents.isEmpty() ); |
| return m_insertionEvents; |
| } |
| |
| private List< ContainerEvent > assertExclusiveRemovalEvents() |
| { |
| assertTrue( m_insertionEvents.isEmpty() ); |
| assertFalse( m_removalEvents.isEmpty() ); |
| assertTrue( m_replacementEvents.isEmpty() ); |
| return m_removalEvents; |
| } |
| |
| private void reset() |
| { |
| m_insertionEvents = new ArrayList< ContainerEvent >(); |
| m_removalEvents = new ArrayList< ContainerEvent >(); |
| m_replacementEvents = new ArrayList< ContainerEvent >(); |
| } |
| |
| private List< ContainerEvent > getInsertionEvents() { return m_insertionEvents; } |
| private List< ContainerEvent > getRemovalEvents() { return m_removalEvents; } |
| |
| final boolean isDisposed() { return m_isDisposed; } |
| |
| private List< ContainerEvent > m_insertionEvents = new ArrayList< ContainerEvent >(); |
| private List< ContainerEvent > m_removalEvents = new ArrayList< ContainerEvent >(); |
| private List< ContainerEvent > m_replacementEvents = new ArrayList< ContainerEvent >(); |
| private boolean m_isDisposed = false; |
| }; |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| private static final OfficeConnection m_connection = new OfficeConnection(); |
| private static Random m_randomGenerator = new Random(); |
| private final XComponentContext m_context; |
| |
| private XPropertySet m_gridControlModel; |
| private XGridColumnModel m_columnModel; |
| private XSortableMutableGridDataModel m_dataModel; |
| private final List< Object > m_disposables = new ArrayList< Object >(); |
| } |