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 #include "precompiled_chart2.hxx" 25 26 #include "ChartModelClone.hxx" 27 #include "ChartModelHelper.hxx" 28 #include "ControllerLockGuard.hxx" 29 #include "DataSourceHelper.hxx" 30 31 /** === begin UNO includes === **/ 32 #include <com/sun/star/chart2/XAnyDescriptionAccess.hpp> 33 #include <com/sun/star/util/XCloneable.hpp> 34 #include <com/sun/star/chart2/XChartDocument.hpp> 35 #include <com/sun/star/view/XSelectionSupplier.hpp> 36 #include <com/sun/star/lang/XComponent.hpp> 37 #include <com/sun/star/chart2/XTitled.hpp> 38 #include <com/sun/star/util/XModifiable.hpp> 39 #include <com/sun/star/chart2/data/XDataSource.hpp> 40 #include <com/sun/star/chart2/data/XLabeledDataSequence.hpp> 41 /** === end UNO includes === **/ 42 43 #include <comphelper/property.hxx> 44 #include <tools/diagnose_ex.h> 45 46 //...................................................................................................................... 47 namespace chart 48 { 49 //...................................................................................................................... 50 51 /** === begin UNO using === **/ 52 using ::com::sun::star::uno::Reference; 53 using ::com::sun::star::uno::XInterface; 54 using ::com::sun::star::uno::UNO_QUERY; 55 using ::com::sun::star::uno::UNO_QUERY_THROW; 56 using ::com::sun::star::uno::UNO_SET_THROW; 57 using ::com::sun::star::uno::Exception; 58 using ::com::sun::star::uno::RuntimeException; 59 using ::com::sun::star::uno::Any; 60 using ::com::sun::star::uno::makeAny; 61 using ::com::sun::star::uno::Sequence; 62 using ::com::sun::star::uno::Type; 63 using ::com::sun::star::frame::XModel; 64 using ::com::sun::star::util::XCloneable; 65 using ::com::sun::star::chart2::XChartDocument; 66 using ::com::sun::star::chart2::XInternalDataProvider; 67 using ::com::sun::star::chart2::XAnyDescriptionAccess; 68 using ::com::sun::star::view::XSelectionSupplier; 69 using ::com::sun::star::lang::XComponent; 70 using ::com::sun::star::chart2::XTitled; 71 using ::com::sun::star::util::XModifiable; 72 using ::com::sun::star::chart2::data::XDataSource; 73 using ::com::sun::star::chart2::data::XLabeledDataSequence; 74 /** === end UNO using === **/ 75 76 // ================================================================================================================= 77 // = helper 78 // ================================================================================================================= 79 namespace 80 { lcl_cloneModel(const Reference<XModel> & xModel)81 Reference< XModel > lcl_cloneModel( const Reference< XModel > & xModel ) 82 { 83 Reference< XModel > xResult; 84 try 85 { 86 const Reference< XCloneable > xCloneable( xModel, UNO_QUERY_THROW ); 87 xResult.set( xCloneable->createClone(), UNO_QUERY_THROW ); 88 } 89 catch( const Exception& ) 90 { 91 DBG_UNHANDLED_EXCEPTION(); 92 } 93 return xResult; 94 } 95 96 } 97 98 // ================================================================================================================= 99 // = ChartModelClone 100 // ================================================================================================================= 101 // ----------------------------------------------------------------------------------------------------------------- ChartModelClone(const Reference<XModel> & i_model,const ModelFacet i_facet)102 ChartModelClone::ChartModelClone( const Reference< XModel >& i_model, const ModelFacet i_facet ) 103 { 104 m_xModelClone.set( lcl_cloneModel( i_model ) ); 105 106 try 107 { 108 if ( i_facet == E_MODEL_WITH_DATA ) 109 { 110 const Reference< XChartDocument > xChartDoc( m_xModelClone, UNO_QUERY_THROW ); 111 ENSURE_OR_THROW( xChartDoc->hasInternalDataProvider(), "invalid chart model" ); 112 113 const Reference< XCloneable > xCloneable( xChartDoc->getDataProvider(), UNO_QUERY_THROW ); 114 m_xDataClone.set( xCloneable->createClone(), UNO_QUERY_THROW ); 115 } 116 117 if ( i_facet == E_MODEL_WITH_SELECTION ) 118 { 119 const Reference< XSelectionSupplier > xSelSupp( m_xModelClone->getCurrentController(), UNO_QUERY_THROW ); 120 m_aSelection = xSelSupp->getSelection(); 121 } 122 } 123 catch( const Exception& ) 124 { 125 DBG_UNHANDLED_EXCEPTION(); 126 } 127 } 128 129 130 // ----------------------------------------------------------------------------------------------------------------- ~ChartModelClone()131 ChartModelClone::~ChartModelClone() 132 { 133 if ( !impl_isDisposed() ) 134 dispose(); 135 } 136 137 // ----------------------------------------------------------------------------------------------------------------- dispose()138 void ChartModelClone::dispose() 139 { 140 if ( impl_isDisposed() ) 141 return; 142 143 try 144 { 145 Reference< XComponent > xComp( m_xModelClone, UNO_QUERY_THROW ); 146 xComp->dispose(); 147 } 148 catch( const Exception& ) 149 { 150 DBG_UNHANDLED_EXCEPTION(); 151 } 152 m_xModelClone.clear(); 153 m_xDataClone.clear(); 154 m_aSelection.clear(); 155 } 156 157 // ----------------------------------------------------------------------------------------------------------------- getFacet() const158 ModelFacet ChartModelClone::getFacet() const 159 { 160 if ( m_aSelection.hasValue() ) 161 return E_MODEL_WITH_SELECTION; 162 if ( m_xDataClone.is() ) 163 return E_MODEL_WITH_DATA; 164 return E_MODEL; 165 } 166 167 // ----------------------------------------------------------------------------------------------------------------- applyToModel(const Reference<XModel> & i_model) const168 void ChartModelClone::applyToModel( const Reference< XModel >& i_model ) const 169 { 170 applyModelContentToModel( i_model, m_xModelClone, m_xDataClone ); 171 172 if ( m_aSelection.hasValue() ) 173 { 174 try 175 { 176 Reference< XSelectionSupplier > xCurrentSelectionSuppl( i_model->getCurrentController(), UNO_QUERY_THROW ); 177 xCurrentSelectionSuppl->select( m_aSelection ); 178 } 179 catch( const Exception& ) 180 { 181 DBG_UNHANDLED_EXCEPTION(); 182 } 183 } 184 } 185 186 // ----------------------------------------------------------------------------------------------------------------- 187 namespace 188 { ImplApplyDataToModel(const Reference<XModel> & i_model,const Reference<XInternalDataProvider> & i_data)189 void ImplApplyDataToModel( const Reference< XModel >& i_model, const Reference< XInternalDataProvider > & i_data ) 190 { 191 Reference< XChartDocument > xDoc( i_model, UNO_QUERY ); 192 OSL_ASSERT( xDoc.is() && xDoc->hasInternalDataProvider() ); 193 194 // copy data from stored internal data provider 195 if( xDoc.is() && xDoc->hasInternalDataProvider()) 196 { 197 Reference< XAnyDescriptionAccess > xCurrentData( xDoc->getDataProvider(), UNO_QUERY ); 198 Reference< XAnyDescriptionAccess > xSavedData( i_data, UNO_QUERY ); 199 if ( xCurrentData.is() && xSavedData.is() ) 200 { 201 xCurrentData->setData( xSavedData->getData() ); 202 xCurrentData->setAnyRowDescriptions( xSavedData->getAnyRowDescriptions()); 203 xCurrentData->setAnyColumnDescriptions( xSavedData->getAnyColumnDescriptions()); 204 } 205 } 206 } 207 } 208 209 // ----------------------------------------------------------------------------------------------------------------- applyModelContentToModel(const Reference<XModel> & i_model,const Reference<XModel> & i_modelToCopyFrom,const Reference<XInternalDataProvider> & i_data)210 void ChartModelClone::applyModelContentToModel( const Reference< XModel >& i_model, 211 const Reference< XModel >& i_modelToCopyFrom, const Reference< XInternalDataProvider >& i_data ) 212 { 213 ENSURE_OR_RETURN_VOID( i_model.is(), "ChartModelElement::applyModelContentToModel: invalid source model!" ); 214 ENSURE_OR_RETURN_VOID( i_modelToCopyFrom.is(), "ChartModelElement::applyModelContentToModel: invalid source model!" ); 215 try 216 { 217 // /-- loccked controllers of destination 218 ControllerLockGuard aLockedControllers( i_model ); 219 Reference< XChartDocument > xSource( i_modelToCopyFrom, UNO_QUERY_THROW ); 220 Reference< XChartDocument > xDestination( i_model, UNO_QUERY_THROW ); 221 222 // propagate the correct flag for plotting of hidden values to the data provider and all used sequences 223 ChartModelHelper::setIncludeHiddenCells( ChartModelHelper::isIncludeHiddenCells( i_modelToCopyFrom ) , i_model ); 224 225 // diagram 226 xDestination->setFirstDiagram( xSource->getFirstDiagram() ); 227 228 // main title 229 Reference< XTitled > xDestinationTitled( xDestination, UNO_QUERY_THROW ); 230 Reference< XTitled > xSourceTitled( xSource, UNO_QUERY_THROW ); 231 xDestinationTitled->setTitleObject( xSourceTitled->getTitleObject() ); 232 233 // page background 234 ::comphelper::copyProperties( 235 xSource->getPageBackground(), 236 xDestination->getPageBackground() ); 237 238 // apply data (not applied in standard Undo) 239 if ( i_data.is() ) 240 ImplApplyDataToModel( i_model, i_data ); 241 242 // register all sequences at the internal data provider to get adapted 243 // indexes when columns are added/removed 244 if ( xDestination->hasInternalDataProvider() ) 245 { 246 Reference< XInternalDataProvider > xNewDataProvider( xDestination->getDataProvider(), UNO_QUERY ); 247 Reference< XDataSource > xUsedData( DataSourceHelper::getUsedData( i_model ) ); 248 if ( xUsedData.is() && xNewDataProvider.is() ) 249 { 250 Sequence< Reference< XLabeledDataSequence > > aData( xUsedData->getDataSequences() ); 251 for( sal_Int32 i=0; i<aData.getLength(); ++i ) 252 { 253 xNewDataProvider->registerDataSequenceForChanges( aData[i]->getValues() ); 254 xNewDataProvider->registerDataSequenceForChanges( aData[i]->getLabel() ); 255 } 256 } 257 } 258 259 // restore modify status 260 Reference< XModifiable > xSourceMod( xSource, UNO_QUERY ); 261 Reference< XModifiable > xDestMod( xDestination, UNO_QUERY ); 262 if ( xSourceMod.is() && xDestMod.is() && !xSourceMod->isModified() ) 263 { 264 xDestMod->setModified( sal_False ); 265 } 266 // \-- loccked controllers of destination 267 } 268 catch( const Exception& ) 269 { 270 DBG_UNHANDLED_EXCEPTION(); 271 } 272 } 273 274 275 //...................................................................................................................... 276 } // namespace chart 277 //...................................................................................................................... 278