1 /************************************************************************* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * Copyright 2000, 2010 Oracle and/or its affiliates. 5 * 6 * OpenOffice.org - a multi-platform office productivity suite 7 * 8 * This file is part of OpenOffice.org. 9 * 10 * OpenOffice.org is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License version 3 12 * only, as published by the Free Software Foundation. 13 * 14 * OpenOffice.org is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public License version 3 for more details 18 * (a copy is included in the LICENSE file that accompanied this code). 19 * 20 * You should have received a copy of the GNU Lesser General Public License 21 * version 3 along with OpenOffice.org. If not, see 22 * <http://www.openoffice.org/license.html> 23 * for a copy of the LGPLv3 License. 24 * 25 ************************************************************************/ 26 27 #include "precompiled_chart2.hxx" 28 29 #include "ChartModelClone.hxx" 30 #include "ChartModelHelper.hxx" 31 #include "ControllerLockGuard.hxx" 32 #include "DataSourceHelper.hxx" 33 34 /** === begin UNO includes === **/ 35 #include <com/sun/star/chart2/XAnyDescriptionAccess.hpp> 36 #include <com/sun/star/util/XCloneable.hpp> 37 #include <com/sun/star/chart2/XChartDocument.hpp> 38 #include <com/sun/star/view/XSelectionSupplier.hpp> 39 #include <com/sun/star/lang/XComponent.hpp> 40 #include <com/sun/star/chart2/XTitled.hpp> 41 #include <com/sun/star/util/XModifiable.hpp> 42 #include <com/sun/star/chart2/data/XDataSource.hpp> 43 #include <com/sun/star/chart2/data/XLabeledDataSequence.hpp> 44 /** === end UNO includes === **/ 45 46 #include <comphelper/property.hxx> 47 #include <tools/diagnose_ex.h> 48 49 //...................................................................................................................... 50 namespace chart 51 { 52 //...................................................................................................................... 53 54 /** === begin UNO using === **/ 55 using ::com::sun::star::uno::Reference; 56 using ::com::sun::star::uno::XInterface; 57 using ::com::sun::star::uno::UNO_QUERY; 58 using ::com::sun::star::uno::UNO_QUERY_THROW; 59 using ::com::sun::star::uno::UNO_SET_THROW; 60 using ::com::sun::star::uno::Exception; 61 using ::com::sun::star::uno::RuntimeException; 62 using ::com::sun::star::uno::Any; 63 using ::com::sun::star::uno::makeAny; 64 using ::com::sun::star::uno::Sequence; 65 using ::com::sun::star::uno::Type; 66 using ::com::sun::star::frame::XModel; 67 using ::com::sun::star::util::XCloneable; 68 using ::com::sun::star::chart2::XChartDocument; 69 using ::com::sun::star::chart2::XInternalDataProvider; 70 using ::com::sun::star::chart2::XAnyDescriptionAccess; 71 using ::com::sun::star::view::XSelectionSupplier; 72 using ::com::sun::star::lang::XComponent; 73 using ::com::sun::star::chart2::XTitled; 74 using ::com::sun::star::util::XModifiable; 75 using ::com::sun::star::chart2::data::XDataSource; 76 using ::com::sun::star::chart2::data::XLabeledDataSequence; 77 /** === end UNO using === **/ 78 79 // ================================================================================================================= 80 // = helper 81 // ================================================================================================================= 82 namespace 83 { 84 Reference< XModel > lcl_cloneModel( const Reference< XModel > & xModel ) 85 { 86 Reference< XModel > xResult; 87 try 88 { 89 const Reference< XCloneable > xCloneable( xModel, UNO_QUERY_THROW ); 90 xResult.set( xCloneable->createClone(), UNO_QUERY_THROW ); 91 } 92 catch( const Exception& ) 93 { 94 DBG_UNHANDLED_EXCEPTION(); 95 } 96 return xResult; 97 } 98 99 } 100 101 // ================================================================================================================= 102 // = ChartModelClone 103 // ================================================================================================================= 104 // ----------------------------------------------------------------------------------------------------------------- 105 ChartModelClone::ChartModelClone( const Reference< XModel >& i_model, const ModelFacet i_facet ) 106 { 107 m_xModelClone.set( lcl_cloneModel( i_model ) ); 108 109 try 110 { 111 if ( i_facet == E_MODEL_WITH_DATA ) 112 { 113 const Reference< XChartDocument > xChartDoc( m_xModelClone, UNO_QUERY_THROW ); 114 ENSURE_OR_THROW( xChartDoc->hasInternalDataProvider(), "invalid chart model" ); 115 116 const Reference< XCloneable > xCloneable( xChartDoc->getDataProvider(), UNO_QUERY_THROW ); 117 m_xDataClone.set( xCloneable->createClone(), UNO_QUERY_THROW ); 118 } 119 120 if ( i_facet == E_MODEL_WITH_SELECTION ) 121 { 122 const Reference< XSelectionSupplier > xSelSupp( m_xModelClone->getCurrentController(), UNO_QUERY_THROW ); 123 m_aSelection = xSelSupp->getSelection(); 124 } 125 } 126 catch( const Exception& ) 127 { 128 DBG_UNHANDLED_EXCEPTION(); 129 } 130 } 131 132 133 // ----------------------------------------------------------------------------------------------------------------- 134 ChartModelClone::~ChartModelClone() 135 { 136 if ( !impl_isDisposed() ) 137 dispose(); 138 } 139 140 // ----------------------------------------------------------------------------------------------------------------- 141 void ChartModelClone::dispose() 142 { 143 if ( impl_isDisposed() ) 144 return; 145 146 try 147 { 148 Reference< XComponent > xComp( m_xModelClone, UNO_QUERY_THROW ); 149 xComp->dispose(); 150 } 151 catch( const Exception& ) 152 { 153 DBG_UNHANDLED_EXCEPTION(); 154 } 155 m_xModelClone.clear(); 156 m_xDataClone.clear(); 157 m_aSelection.clear(); 158 } 159 160 // ----------------------------------------------------------------------------------------------------------------- 161 ModelFacet ChartModelClone::getFacet() const 162 { 163 if ( m_aSelection.hasValue() ) 164 return E_MODEL_WITH_SELECTION; 165 if ( m_xDataClone.is() ) 166 return E_MODEL_WITH_DATA; 167 return E_MODEL; 168 } 169 170 // ----------------------------------------------------------------------------------------------------------------- 171 void ChartModelClone::applyToModel( const Reference< XModel >& i_model ) const 172 { 173 applyModelContentToModel( i_model, m_xModelClone, m_xDataClone ); 174 175 if ( m_aSelection.hasValue() ) 176 { 177 try 178 { 179 Reference< XSelectionSupplier > xCurrentSelectionSuppl( i_model->getCurrentController(), UNO_QUERY_THROW ); 180 xCurrentSelectionSuppl->select( m_aSelection ); 181 } 182 catch( const Exception& ) 183 { 184 DBG_UNHANDLED_EXCEPTION(); 185 } 186 } 187 } 188 189 // ----------------------------------------------------------------------------------------------------------------- 190 namespace 191 { 192 void ImplApplyDataToModel( const Reference< XModel >& i_model, const Reference< XInternalDataProvider > & i_data ) 193 { 194 Reference< XChartDocument > xDoc( i_model, UNO_QUERY ); 195 OSL_ASSERT( xDoc.is() && xDoc->hasInternalDataProvider() ); 196 197 // copy data from stored internal data provider 198 if( xDoc.is() && xDoc->hasInternalDataProvider()) 199 { 200 Reference< XAnyDescriptionAccess > xCurrentData( xDoc->getDataProvider(), UNO_QUERY ); 201 Reference< XAnyDescriptionAccess > xSavedData( i_data, UNO_QUERY ); 202 if ( xCurrentData.is() && xSavedData.is() ) 203 { 204 xCurrentData->setData( xSavedData->getData() ); 205 xCurrentData->setAnyRowDescriptions( xSavedData->getAnyRowDescriptions()); 206 xCurrentData->setAnyColumnDescriptions( xSavedData->getAnyColumnDescriptions()); 207 } 208 } 209 } 210 } 211 212 // ----------------------------------------------------------------------------------------------------------------- 213 void ChartModelClone::applyModelContentToModel( const Reference< XModel >& i_model, 214 const Reference< XModel >& i_modelToCopyFrom, const Reference< XInternalDataProvider >& i_data ) 215 { 216 ENSURE_OR_RETURN_VOID( i_model.is(), "ChartModelElement::applyModelContentToModel: invalid source model!" ); 217 ENSURE_OR_RETURN_VOID( i_modelToCopyFrom.is(), "ChartModelElement::applyModelContentToModel: invalid source model!" ); 218 try 219 { 220 // /-- loccked controllers of destination 221 ControllerLockGuard aLockedControllers( i_model ); 222 Reference< XChartDocument > xSource( i_modelToCopyFrom, UNO_QUERY_THROW ); 223 Reference< XChartDocument > xDestination( i_model, UNO_QUERY_THROW ); 224 225 // propagate the correct flag for plotting of hidden values to the data provider and all used sequences 226 ChartModelHelper::setIncludeHiddenCells( ChartModelHelper::isIncludeHiddenCells( i_modelToCopyFrom ) , i_model ); 227 228 // diagram 229 xDestination->setFirstDiagram( xSource->getFirstDiagram() ); 230 231 // main title 232 Reference< XTitled > xDestinationTitled( xDestination, UNO_QUERY_THROW ); 233 Reference< XTitled > xSourceTitled( xSource, UNO_QUERY_THROW ); 234 xDestinationTitled->setTitleObject( xSourceTitled->getTitleObject() ); 235 236 // page background 237 ::comphelper::copyProperties( 238 xSource->getPageBackground(), 239 xDestination->getPageBackground() ); 240 241 // apply data (not applied in standard Undo) 242 if ( i_data.is() ) 243 ImplApplyDataToModel( i_model, i_data ); 244 245 // register all sequences at the internal data provider to get adapted 246 // indexes when columns are added/removed 247 if ( xDestination->hasInternalDataProvider() ) 248 { 249 Reference< XInternalDataProvider > xNewDataProvider( xDestination->getDataProvider(), UNO_QUERY ); 250 Reference< XDataSource > xUsedData( DataSourceHelper::getUsedData( i_model ) ); 251 if ( xUsedData.is() && xNewDataProvider.is() ) 252 { 253 Sequence< Reference< XLabeledDataSequence > > aData( xUsedData->getDataSequences() ); 254 for( sal_Int32 i=0; i<aData.getLength(); ++i ) 255 { 256 xNewDataProvider->registerDataSequenceForChanges( aData[i]->getValues() ); 257 xNewDataProvider->registerDataSequenceForChanges( aData[i]->getLabel() ); 258 } 259 } 260 } 261 262 // restore modify status 263 Reference< XModifiable > xSourceMod( xSource, UNO_QUERY ); 264 Reference< XModifiable > xDestMod( xDestination, UNO_QUERY ); 265 if ( xSourceMod.is() && xDestMod.is() && !xSourceMod->isModified() ) 266 { 267 xDestMod->setModified( sal_False ); 268 } 269 // \-- loccked controllers of destination 270 } 271 catch( const Exception& ) 272 { 273 DBG_UNHANDLED_EXCEPTION(); 274 } 275 } 276 277 278 //...................................................................................................................... 279 } // namespace chart 280 //...................................................................................................................... 281