1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "charthelper.hxx"
21 #include "document.hxx"
22 #include "drwlayer.hxx"
23 #include "rangelst.hxx"
24 #include "chartlis.hxx"
27 #include <svx/svditer.hxx>
28 #include <svx/svdoole2.hxx>
29 #include <svx/svdpage.hxx>
30 #include <svtools/embedhlp.hxx>
32 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
33 #include <com/sun/star/util/XModifiable.hpp>
35 using namespace com::sun::star
;
36 using ::com::sun::star::uno::Reference
;
41 sal_uInt16
lcl_DoUpdateCharts( const ScAddress
& rPos
, ScDocument
* pDoc
, bool bAllCharts
)
43 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
47 sal_uInt16 nFound
= 0;
49 sal_uInt16 nPageCount
= pModel
->GetPageCount();
50 for (sal_uInt16 nPageNo
=0; nPageNo
<nPageCount
; nPageNo
++)
52 SdrPage
* pPage
= pModel
->GetPage(nPageNo
);
53 OSL_ENSURE(pPage
,"Page ?");
55 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
56 SdrObject
* pObject
= aIter
.Next();
59 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&& ScDocument::IsChart( pObject
) )
61 OUString aName
= static_cast<SdrOle2Obj
*>(pObject
)->GetPersistName();
66 bool bColHeaders
= false;
67 bool bRowHeaders
= false;
68 pDoc
->GetOldChartParameters( aName
, aRanges
, bColHeaders
, bRowHeaders
);
69 bHit
= aRanges
.In( rPos
);
73 pDoc
->UpdateChart( aName
);
77 pObject
= aIter
.Next();
83 bool lcl_AdjustRanges( ScRangeList
& rRanges
, SCTAB nSourceTab
, SCTAB nDestTab
, SCTAB nTabCount
)
85 //TODO: if multiple sheets are copied, update references into the other copied sheets?
87 bool bChanged
= false;
89 for ( size_t i
=0, nCount
= rRanges
.size(); i
< nCount
; i
++ )
91 ScRange
* pRange
= rRanges
[ i
];
92 if ( pRange
->aStart
.Tab() == nSourceTab
&& pRange
->aEnd
.Tab() == nSourceTab
)
94 pRange
->aStart
.SetTab( nDestTab
);
95 pRange
->aEnd
.SetTab( nDestTab
);
98 if ( pRange
->aStart
.Tab() >= nTabCount
)
100 pRange
->aStart
.SetTab( nTabCount
> 0 ? ( nTabCount
- 1 ) : 0 );
103 if ( pRange
->aEnd
.Tab() >= nTabCount
)
105 pRange
->aEnd
.SetTab( nTabCount
> 0 ? ( nTabCount
- 1 ) : 0 );
113 }//end anonymous namespace
117 sal_uInt16
ScChartHelper::DoUpdateAllCharts( ScDocument
* pDoc
)
119 return lcl_DoUpdateCharts( ScAddress(), pDoc
, true );
122 void ScChartHelper::AdjustRangesOfChartsOnDestinationPage( ScDocument
* pSrcDoc
, ScDocument
* pDestDoc
, const SCTAB nSrcTab
, const SCTAB nDestTab
)
124 if( !pSrcDoc
|| !pDestDoc
)
126 ScDrawLayer
* pDrawLayer
= pDestDoc
->GetDrawLayer();
130 SdrPage
* pDestPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nDestTab
));
133 SdrObjListIter
aIter( *pDestPage
, IM_FLAT
);
134 SdrObject
* pObject
= aIter
.Next();
137 if( pObject
->GetObjIdentifier() == OBJ_OLE2
&& static_cast<SdrOle2Obj
*>(pObject
)->IsChart() )
139 OUString aChartName
= static_cast<SdrOle2Obj
*>(pObject
)->GetPersistName();
141 Reference
< chart2::XChartDocument
> xChartDoc( pDestDoc
->GetChartByName( aChartName
) );
142 Reference
< chart2::data::XDataReceiver
> xReceiver( xChartDoc
, uno::UNO_QUERY
);
143 if( xChartDoc
.is() && xReceiver
.is() && !xChartDoc
->hasInternalDataProvider() )
145 ::std::vector
< ScRangeList
> aRangesVector
;
146 pDestDoc
->GetChartRanges( aChartName
, aRangesVector
, pSrcDoc
);
148 ::std::vector
< ScRangeList
>::iterator
aIt( aRangesVector
.begin() );
149 for( ; aIt
!=aRangesVector
.end(); ++aIt
)
151 ScRangeList
& rScRangeList( *aIt
);
152 lcl_AdjustRanges( rScRangeList
, nSrcTab
, nDestTab
, pDestDoc
->GetTableCount() );
154 pDestDoc
->SetChartRanges( aChartName
, aRangesVector
);
157 pObject
= aIter
.Next();
162 void ScChartHelper::UpdateChartsOnDestinationPage( ScDocument
* pDestDoc
, const SCTAB nDestTab
)
166 ScDrawLayer
* pDrawLayer
= pDestDoc
->GetDrawLayer();
170 SdrPage
* pDestPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nDestTab
));
173 SdrObjListIter
aIter( *pDestPage
, IM_FLAT
);
174 SdrObject
* pObject
= aIter
.Next();
177 if( pObject
->GetObjIdentifier() == OBJ_OLE2
&& static_cast<SdrOle2Obj
*>(pObject
)->IsChart() )
179 OUString aChartName
= static_cast<SdrOle2Obj
*>(pObject
)->GetPersistName();
180 Reference
< chart2::XChartDocument
> xChartDoc( pDestDoc
->GetChartByName( aChartName
) );
181 Reference
< util::XModifiable
> xModif(xChartDoc
, uno::UNO_QUERY_THROW
);
182 xModif
->setModified( sal_True
);
184 pObject
= aIter
.Next();
189 uno::Reference
< chart2::XChartDocument
> ScChartHelper::GetChartFromSdrObject( SdrObject
* pObject
)
191 uno::Reference
< chart2::XChartDocument
> xReturn
;
194 if( pObject
->GetObjIdentifier() == OBJ_OLE2
&& static_cast<SdrOle2Obj
*>(pObject
)->IsChart() )
196 uno::Reference
< embed::XEmbeddedObject
> xIPObj
= static_cast<SdrOle2Obj
*>(pObject
)->GetObjRef();
199 svt::EmbeddedObjectRef::TryRunningState( xIPObj
);
200 uno::Reference
< util::XCloseable
> xComponent
= xIPObj
->getComponent();
201 xReturn
.set( uno::Reference
< chart2::XChartDocument
>( xComponent
, uno::UNO_QUERY
) );
208 void ScChartHelper::GetChartRanges( const uno::Reference
< chart2::XChartDocument
>& xChartDoc
,
209 uno::Sequence
< OUString
>& rRanges
)
212 uno::Reference
< chart2::data::XDataSource
> xDataSource( xChartDoc
, uno::UNO_QUERY
);
213 if( !xDataSource
.is() )
216 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aLabeledDataSequences( xDataSource
->getDataSequences() );
217 rRanges
.realloc(2*aLabeledDataSequences
.getLength());
218 sal_Int32 nRealCount
=0;
219 for( sal_Int32 nN
=0;nN
<aLabeledDataSequences
.getLength();nN
++)
221 uno::Reference
< chart2::data::XLabeledDataSequence
> xLabeledSequence( aLabeledDataSequences
[nN
] );
222 if(!xLabeledSequence
.is())
224 uno::Reference
< chart2::data::XDataSequence
> xLabel( xLabeledSequence
->getLabel());
225 uno::Reference
< chart2::data::XDataSequence
> xValues( xLabeledSequence
->getValues());
228 rRanges
[nRealCount
++] = xLabel
->getSourceRangeRepresentation();
230 rRanges
[nRealCount
++] = xValues
->getSourceRangeRepresentation();
232 rRanges
.realloc(nRealCount
);
235 void ScChartHelper::SetChartRanges( const uno::Reference
< chart2::XChartDocument
>& xChartDoc
,
236 const uno::Sequence
< OUString
>& rRanges
)
238 uno::Reference
< chart2::data::XDataSource
> xDataSource( xChartDoc
, uno::UNO_QUERY
);
239 if( !xDataSource
.is() )
241 uno::Reference
< chart2::data::XDataProvider
> xDataProvider
= xChartDoc
->getDataProvider();
242 if( !xDataProvider
.is() )
245 uno::Reference
< frame::XModel
> xModel( xChartDoc
, uno::UNO_QUERY
);
247 xModel
->lockControllers();
251 OUString
aPropertyNameRole( "Role" );
253 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aLabeledDataSequences( xDataSource
->getDataSequences() );
255 for( sal_Int32 nN
=0; (nN
<aLabeledDataSequences
.getLength()) && (nRange
<rRanges
.getLength()); nN
++ )
257 uno::Reference
< chart2::data::XLabeledDataSequence
> xLabeledSequence( aLabeledDataSequences
[nN
] );
258 if(!xLabeledSequence
.is())
260 uno::Reference
< beans::XPropertySet
> xLabel( xLabeledSequence
->getLabel(), uno::UNO_QUERY
);
261 uno::Reference
< beans::XPropertySet
> xValues( xLabeledSequence
->getValues(), uno::UNO_QUERY
);
265 uno::Reference
< chart2::data::XDataSequence
> xNewSeq(
266 xDataProvider
->createDataSequenceByRangeRepresentation( rRanges
[nRange
++] ));
268 uno::Reference
< beans::XPropertySet
> xNewProps( xNewSeq
, uno::UNO_QUERY
);
270 xNewProps
->setPropertyValue( aPropertyNameRole
, xLabel
->getPropertyValue( aPropertyNameRole
) );
272 xLabeledSequence
->setLabel( xNewSeq
);
275 if( !(nRange
<rRanges
.getLength()) )
280 uno::Reference
< chart2::data::XDataSequence
> xNewSeq(
281 xDataProvider
->createDataSequenceByRangeRepresentation( rRanges
[nRange
++] ));
283 uno::Reference
< beans::XPropertySet
> xNewProps( xNewSeq
, uno::UNO_QUERY
);
285 xNewProps
->setPropertyValue( aPropertyNameRole
, xValues
->getPropertyValue( aPropertyNameRole
) );
287 xLabeledSequence
->setValues( xNewSeq
);
291 catch (const uno::Exception
&)
293 OSL_FAIL("Exception in ScChartHelper::SetChartRanges - invalid range string?");
297 xModel
->unlockControllers();
300 void ScChartHelper::AddRangesIfProtectedChart( ScRangeListVector
& rRangesVector
, ScDocument
* pDocument
, SdrObject
* pObject
)
302 if ( pDocument
&& pObject
&& ( pObject
->GetObjIdentifier() == OBJ_OLE2
) )
304 SdrOle2Obj
* pSdrOle2Obj
= dynamic_cast< SdrOle2Obj
* >( pObject
);
305 if ( pSdrOle2Obj
&& pSdrOle2Obj
->IsChart() )
307 uno::Reference
< embed::XEmbeddedObject
> xEmbeddedObj
= pSdrOle2Obj
->GetObjRef();
308 if ( xEmbeddedObj
.is() )
310 bool bDisableDataTableDialog
= false;
311 sal_Int32 nOldState
= xEmbeddedObj
->getCurrentState();
312 svt::EmbeddedObjectRef::TryRunningState( xEmbeddedObj
);
313 uno::Reference
< beans::XPropertySet
> xProps( xEmbeddedObj
->getComponent(), uno::UNO_QUERY
);
315 ( xProps
->getPropertyValue("DisableDataTableDialog") >>= bDisableDataTableDialog
) &&
316 bDisableDataTableDialog
)
318 ScChartListenerCollection
* pCollection
= pDocument
->GetChartListenerCollection();
321 OUString aChartName
= pSdrOle2Obj
->GetPersistName();
322 const ScChartListener
* pListener
= pCollection
->findByName(aChartName
);
325 const ScRangeListRef
& rRangeList
= pListener
->GetRangeList();
326 if ( rRangeList
.Is() )
328 rRangesVector
.push_back( *rRangeList
);
333 if ( xEmbeddedObj
->getCurrentState() != nOldState
)
335 xEmbeddedObj
->changeState( nOldState
);
342 void ScChartHelper::FillProtectedChartRangesVector( ScRangeListVector
& rRangesVector
, ScDocument
* pDocument
, SdrPage
* pPage
)
344 if ( pDocument
&& pPage
)
346 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
347 SdrObject
* pObject
= aIter
.Next();
350 AddRangesIfProtectedChart( rRangesVector
, pDocument
, pObject
);
351 pObject
= aIter
.Next();
356 void ScChartHelper::GetChartNames( ::std::vector
< OUString
>& rChartNames
, SdrPage
* pPage
)
360 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
361 SdrObject
* pObject
= aIter
.Next();
364 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
)
366 SdrOle2Obj
* pSdrOle2Obj
= dynamic_cast< SdrOle2Obj
* >( pObject
);
367 if ( pSdrOle2Obj
&& pSdrOle2Obj
->IsChart() )
369 rChartNames
.push_back( pSdrOle2Obj
->GetPersistName() );
372 pObject
= aIter
.Next();
377 void ScChartHelper::CreateProtectedChartListenersAndNotify( ScDocument
* pDoc
, SdrPage
* pPage
, ScModelObj
* pModelObj
, SCTAB nTab
,
378 const ScRangeListVector
& rRangesVector
, const ::std::vector
< OUString
>& rExcludedChartNames
, bool bSameDoc
)
380 if ( pDoc
&& pPage
&& pModelObj
)
382 size_t nRangeListCount
= rRangesVector
.size();
383 size_t nRangeList
= 0;
384 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
385 SdrObject
* pObject
= aIter
.Next();
388 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
)
390 SdrOle2Obj
* pSdrOle2Obj
= dynamic_cast< SdrOle2Obj
* >( pObject
);
391 if ( pSdrOle2Obj
&& pSdrOle2Obj
->IsChart() )
393 OUString aChartName
= pSdrOle2Obj
->GetPersistName();
394 ::std::vector
< OUString
>::const_iterator aEnd
= rExcludedChartNames
.end();
395 ::std::vector
< OUString
>::const_iterator aFound
= ::std::find( rExcludedChartNames
.begin(), aEnd
, aChartName
);
396 if ( aFound
== aEnd
)
398 uno::Reference
< embed::XEmbeddedObject
> xEmbeddedObj
= pSdrOle2Obj
->GetObjRef();
399 if ( xEmbeddedObj
.is() && ( nRangeList
< nRangeListCount
) )
401 bool bDisableDataTableDialog
= false;
402 svt::EmbeddedObjectRef::TryRunningState( xEmbeddedObj
);
403 uno::Reference
< beans::XPropertySet
> xProps( xEmbeddedObj
->getComponent(), uno::UNO_QUERY
);
405 ( xProps
->getPropertyValue("DisableDataTableDialog") >>= bDisableDataTableDialog
) &&
406 bDisableDataTableDialog
)
410 ScChartListenerCollection
* pCollection
= pDoc
->GetChartListenerCollection();
411 if (pCollection
&& !pCollection
->findByName(aChartName
))
413 ScRangeList
aRangeList( rRangesVector
[ nRangeList
++ ] );
414 ScRangeListRef
rRangeList( new ScRangeList( aRangeList
) );
415 ScChartListener
* pChartListener
= new ScChartListener( aChartName
, pDoc
, rRangeList
);
416 pCollection
->insert( pChartListener
);
417 pChartListener
->StartListeningTo();
422 xProps
->setPropertyValue("DisableDataTableDialog",
423 uno::makeAny( sal_False
) );
424 xProps
->setPropertyValue("DisableComplexChartTypes",
425 uno::makeAny( sal_False
) );
430 if ( pModelObj
&& pModelObj
->HasChangesListeners() )
432 Rectangle aRectangle
= pSdrOle2Obj
->GetSnapRect();
433 ScRange
aRange( pDoc
->GetRange( nTab
, aRectangle
) );
434 ScRangeList aChangeRanges
;
435 aChangeRanges
.Append( aRange
);
437 uno::Sequence
< beans::PropertyValue
> aProperties( 1 );
438 aProperties
[ 0 ].Name
= "Name";
439 aProperties
[ 0 ].Value
<<= aChartName
;
441 pModelObj
->NotifyChanges( OUString( "insert-chart" ), aChangeRanges
, aProperties
);
446 pObject
= aIter
.Next();
451 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */