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