1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 package complex.sfx2.undo; 25 26 import com.sun.star.chart2.XAxis; 27 import com.sun.star.chart2.XCoordinateSystem; 28 import com.sun.star.chart2.XCoordinateSystemContainer; 29 import com.sun.star.awt.Size; 30 import com.sun.star.beans.NamedValue; 31 import com.sun.star.beans.XPropertySet; 32 import com.sun.star.chart2.XChartDocument; 33 import com.sun.star.chart2.XDiagram; 34 import com.sun.star.container.XIndexAccess; 35 import com.sun.star.document.UndoFailedException; 36 import com.sun.star.document.XUndoAction; 37 import com.sun.star.document.XUndoManager; 38 import com.sun.star.document.XUndoManagerSupplier; 39 import com.sun.star.drawing.XShape; 40 import com.sun.star.embed.EmbedStates; 41 import com.sun.star.embed.EmbedVerbs; 42 import com.sun.star.embed.VerbDescriptor; 43 import com.sun.star.embed.WrongStateException; 44 import com.sun.star.embed.XEmbeddedObject; 45 import com.sun.star.embed.XStateChangeBroadcaster; 46 import com.sun.star.embed.XStateChangeListener; 47 import com.sun.star.lang.EventObject; 48 import com.sun.star.lang.IndexOutOfBoundsException; 49 import com.sun.star.lang.WrappedTargetException; 50 import com.sun.star.lang.XMultiServiceFactory; 51 import com.sun.star.text.XTextContent; 52 import com.sun.star.text.XTextRange; 53 import com.sun.star.uno.UnoRuntime; 54 import com.sun.star.view.XSelectionSupplier; 55 import org.openoffice.test.tools.DocumentType; 56 import org.openoffice.test.tools.OfficeDocument; 57 import static org.junit.Assert.*; 58 59 /** 60 * @author frank.schoenheit@oracle.com 61 */ 62 public class ChartDocumentTest implements DocumentTest 63 { ChartDocumentTest( final XMultiServiceFactory i_orb )64 public ChartDocumentTest( final XMultiServiceFactory i_orb ) throws com.sun.star.uno.Exception, InterruptedException 65 { 66 m_textDocument = OfficeDocument.blankDocument( i_orb, DocumentType.WRITER ); 67 68 // create a OLE shape in the document 69 final XMultiServiceFactory factory = UnoRuntime.queryInterface( XMultiServiceFactory.class, m_textDocument.getDocument() ); 70 final String shapeServiceName = "com.sun.star.text.TextEmbeddedObject"; 71 final XPropertySet shapeProps = UnoRuntime.queryInterface( XPropertySet.class, factory.createInstance( shapeServiceName ) ); 72 shapeProps.setPropertyValue("CLSID", "12dcae26-281f-416f-a234-c3086127382e"); 73 74 final XShape shape = UnoRuntime.queryInterface( XShape.class, shapeProps ); 75 shape.setSize( new Size( 16000, 9000 ) ); 76 77 final XTextContent chartTextContent = UnoRuntime.queryInterface( XTextContent.class, shapeProps ); 78 79 final XSelectionSupplier selSupplier = UnoRuntime.queryInterface( XSelectionSupplier.class, 80 m_textDocument.getCurrentView().getController() ); 81 final Object selection = selSupplier.getSelection(); 82 final XTextRange textRange = getAssociatedTextRange( selection ); 83 if ( textRange == null ) 84 throw new RuntimeException( "can't locate a text range" ); 85 86 // insert the chart 87 textRange.getText().insertTextContent(textRange, chartTextContent, false); 88 89 // retrieve the chart model 90 XChartDocument chartDoc = UnoRuntime.queryInterface( XChartDocument.class, shapeProps.getPropertyValue( "Model" ) ); 91 m_chartDocument = new OfficeDocument( i_orb, chartDoc ); 92 93 // actually activate the object 94 final XEmbeddedObject embeddedChart = UnoRuntime.queryInterface( XEmbeddedObject.class, 95 shapeProps.getPropertyValue( "EmbeddedObject" ) ); 96 embeddedChart.doVerb( EmbedVerbs.MS_OLEVERB_SHOW ); 97 98 final int state = embeddedChart.getCurrentState(); 99 if ( state != EmbedStates.UI_ACTIVE ) 100 fail( "unable to activate the embedded chart" ); 101 } 102 getDocumentDescription()103 public String getDocumentDescription() 104 { 105 return "chart document"; 106 } 107 initializeDocument()108 public void initializeDocument() throws com.sun.star.uno.Exception 109 { 110 final XPropertySet wallProperties = impl_getWallProperties(); 111 wallProperties.setPropertyValue( "FillStyle", com.sun.star.drawing.FillStyle.SOLID ); 112 wallProperties.setPropertyValue( "FillColor", 0x00FFFFFF ); 113 } 114 closeDocument()115 public void closeDocument() 116 { 117 m_textDocument.close(); 118 } 119 impl_getWallProperties()120 private XPropertySet impl_getWallProperties() 121 { 122 final XChartDocument chartDoc = UnoRuntime.queryInterface( XChartDocument.class, m_chartDocument.getDocument() ); 123 final XDiagram diagram = chartDoc.getFirstDiagram(); 124 final XPropertySet wallProperties = diagram.getWall(); 125 return wallProperties; 126 } 127 impl_getYAxisProperties()128 private XPropertySet impl_getYAxisProperties() 129 { 130 XPropertySet axisProperties = null; 131 try 132 { 133 final XChartDocument chartDoc = UnoRuntime.queryInterface( XChartDocument.class, m_chartDocument.getDocument() ); 134 final XDiagram diagram = chartDoc.getFirstDiagram(); 135 final XCoordinateSystemContainer coordContainer = UnoRuntime.queryInterface( XCoordinateSystemContainer.class, diagram ); 136 final XCoordinateSystem[] coordSystems = coordContainer.getCoordinateSystems(); 137 final XCoordinateSystem coordSystem = coordSystems[0]; 138 final XAxis primaryYAxis = coordSystem.getAxisByDimension( 1, 0 ); 139 axisProperties = UnoRuntime.queryInterface( XPropertySet.class, primaryYAxis ); 140 } 141 catch ( Exception ex ) 142 { 143 fail( "internal error: could not retrieve primary Y axis properties" ); 144 } 145 return axisProperties; 146 } 147 impl_getUndoManager()148 private XUndoManager impl_getUndoManager() 149 { 150 final XUndoManagerSupplier undoManagerSupp = UnoRuntime.queryInterface( XUndoManagerSupplier.class, m_chartDocument.getDocument() ); 151 final XUndoManager undoManager = undoManagerSupp.getUndoManager(); 152 return undoManager; 153 } 154 doSingleModification()155 public void doSingleModification() throws com.sun.star.uno.Exception 156 { 157 final XPropertySet wallProperties = impl_getWallProperties(); 158 159 // simulate an Undo action, as long as the chart implementation doesn't add Undo actions itself 160 final XUndoManager undoManager = impl_getUndoManager(); 161 undoManager.addUndoAction( new PropertyUndoAction( wallProperties, "FillColor", 0xCCFF44 ) ); 162 // (the UndoAction will actually set the property value) 163 } 164 verifyInitialDocumentState()165 public void verifyInitialDocumentState() throws com.sun.star.uno.Exception 166 { 167 final XPropertySet wallProperties = impl_getWallProperties(); 168 assertEquals( 0x00FFFFFF, ((Integer)wallProperties.getPropertyValue( "FillColor" )).intValue() ); 169 } 170 verifySingleModificationDocumentState()171 public void verifySingleModificationDocumentState() throws com.sun.star.uno.Exception 172 { 173 final XPropertySet wallProperties = impl_getWallProperties(); 174 assertEquals( 0xCCFF44, ((Integer)wallProperties.getPropertyValue( "FillColor" )).intValue() ); 175 } 176 doMultipleModifications()177 public int doMultipleModifications() throws com.sun.star.uno.Exception 178 { 179 final XPropertySet axisProperties = impl_getYAxisProperties(); 180 181 final XUndoManager undoManager = impl_getUndoManager(); 182 undoManager.addUndoAction( new PropertyUndoAction( axisProperties, "LineWidth", 300 ) ); 183 undoManager.addUndoAction( new PropertyUndoAction( axisProperties, "LineColor", 0x000000 ) ); 184 185 return 2; 186 } 187 getDocument()188 public OfficeDocument getDocument() 189 { 190 return m_chartDocument; 191 } 192 getAssociatedTextRange( final Object i_object )193 private XTextRange getAssociatedTextRange( final Object i_object ) throws WrappedTargetException, IndexOutOfBoundsException 194 { 195 // possible cases: 196 // 1. a container of other objects - e.g. selection of 0 to n text portions, or 1 to n drawing objects 197 final XIndexAccess indexer = UnoRuntime.queryInterface( XIndexAccess.class, i_object ); 198 if ((indexer != null) && indexer.getCount() > 0) { 199 final int count = indexer.getCount(); 200 for (int i = 0; i < count; ++i) { 201 final XTextRange range = getAssociatedTextRange( indexer.getByIndex(i) ); 202 if (range != null) { 203 return range; 204 } 205 } 206 } 207 // 2. another TextContent, having an anchor we can use 208 final XTextContent textContent = UnoRuntime.queryInterface(XTextContent.class, i_object); 209 if (textContent != null) { 210 final XTextRange range = textContent.getAnchor(); 211 if (range != null) { 212 return range; 213 } 214 } 215 216 // an object which supports XTextRange directly 217 final XTextRange range = UnoRuntime.queryInterface(XTextRange.class, i_object); 218 if (range != null) { 219 return range; 220 } 221 222 return null; 223 } 224 225 private static class PropertyUndoAction implements XUndoAction 226 { PropertyUndoAction( final XPropertySet i_component, final String i_propertyName, final Object i_newValue )227 PropertyUndoAction( final XPropertySet i_component, final String i_propertyName, final Object i_newValue ) throws com.sun.star.uno.Exception 228 { 229 m_component = i_component; 230 m_propertyName = i_propertyName; 231 m_newValue = i_newValue; 232 233 m_oldValue = i_component.getPropertyValue( m_propertyName ); 234 i_component.setPropertyValue( m_propertyName, m_newValue ); 235 } 236 getTitle()237 public String getTitle() 238 { 239 return "some dummy Undo Action"; 240 } 241 undo()242 public void undo() throws UndoFailedException 243 { 244 try 245 { 246 m_component.setPropertyValue( m_propertyName, m_oldValue ); 247 } 248 catch ( com.sun.star.uno.Exception ex ) 249 { 250 throw new UndoFailedException( "", this, ex ); 251 } 252 } 253 redo()254 public void redo() throws UndoFailedException 255 { 256 try 257 { 258 m_component.setPropertyValue( m_propertyName, m_newValue ); 259 } 260 catch ( com.sun.star.uno.Exception ex ) 261 { 262 throw new UndoFailedException( "", this, ex ); 263 } 264 } 265 266 private final XPropertySet m_component; 267 private final String m_propertyName; 268 private final Object m_oldValue; 269 private final Object m_newValue; 270 } 271 272 private final OfficeDocument m_textDocument; 273 private final OfficeDocument m_chartDocument; 274 } 275