1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: documen5.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include <com/sun/star/util/XModifiable.hpp>
35 #include <com/sun/star/chart/ChartDataRowSource.hpp>
36 #include <com/sun/star/chart2/XChartDocument.hpp>
37 #include <com/sun/star/chart2/data/XDataProvider.hpp>
38 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
39 #include <com/sun/star/embed/EmbedStates.hpp>
40 #include <com/sun/star/embed/XEmbeddedObject.hpp>
44 #pragma optimize("",off)
47 // INCLUDE ---------------------------------------------------------------
49 #include <sfx2/objsh.hxx>
50 #include <svx/svditer.hxx>
51 #include <svx/svdoole2.hxx>
52 #include <svx/svdpage.hxx>
54 //REMOVE #ifndef SO2_DECL_SVINPLACEOBJECT_DEFINED
55 //REMOVE #define SO2_DECL_SVINPLACEOBJECT_DEFINED
56 //REMOVE SO2_DECL_REF(SvInPlaceObject)
59 #include "document.hxx"
60 #include "drwlayer.hxx"
61 #include "chartarr.hxx"
62 #include "chartlis.hxx"
63 #include "chartlock.hxx"
64 #include "refupdat.hxx"
65 #include <tools/globname.hxx>
66 #include <sot/exchange.hxx>
68 #include "miscuno.hxx"
69 #include "chart2uno.hxx"
71 using namespace ::com::sun::star
;
73 // -----------------------------------------------------------------------
75 void lcl_GetChartRanges( const uno::Reference
< chart2::XChartDocument
>& xChartDoc
,
76 uno::Sequence
< rtl::OUString
>& rRanges
)
79 uno::Reference
< chart2::data::XDataSource
> xDataSource( xChartDoc
, uno::UNO_QUERY
);
80 if( !xDataSource
.is() )
82 //uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider();
84 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aLabeledDataSequences( xDataSource
->getDataSequences() );
85 rRanges
.realloc(2*aLabeledDataSequences
.getLength());
86 sal_Int32 nRealCount
=0;
87 for( sal_Int32 nN
=0;nN
<aLabeledDataSequences
.getLength();nN
++)
89 uno::Reference
< chart2::data::XLabeledDataSequence
> xLabeledSequence( aLabeledDataSequences
[nN
] );
90 if(!xLabeledSequence
.is())
92 uno::Reference
< chart2::data::XDataSequence
> xLabel( xLabeledSequence
->getLabel());
93 uno::Reference
< chart2::data::XDataSequence
> xValues( xLabeledSequence
->getValues());
96 rRanges
[nRealCount
++] = xLabel
->getSourceRangeRepresentation();
98 rRanges
[nRealCount
++] = xValues
->getSourceRangeRepresentation();
100 rRanges
.realloc(nRealCount
);
103 void lcl_SetChartRanges( const uno::Reference
< chart2::XChartDocument
>& xChartDoc
,
104 const uno::Sequence
< rtl::OUString
>& rRanges
)
106 uno::Reference
< chart2::data::XDataSource
> xDataSource( xChartDoc
, uno::UNO_QUERY
);
107 if( !xDataSource
.is() )
109 uno::Reference
< chart2::data::XDataProvider
> xDataProvider
= xChartDoc
->getDataProvider();
110 if( !xDataProvider
.is() )
113 uno::Reference
< frame::XModel
> xModel( xChartDoc
, uno::UNO_QUERY
);
115 xModel
->lockControllers();
119 rtl::OUString
aPropertyNameRole( ::rtl::OUString::createFromAscii("Role") );
121 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aLabeledDataSequences( xDataSource
->getDataSequences() );
123 for( sal_Int32 nN
=0; (nN
<aLabeledDataSequences
.getLength()) && (nRange
<rRanges
.getLength()); nN
++ )
125 uno::Reference
< chart2::data::XLabeledDataSequence
> xLabeledSequence( aLabeledDataSequences
[nN
] );
126 if(!xLabeledSequence
.is())
128 uno::Reference
< beans::XPropertySet
> xLabel( xLabeledSequence
->getLabel(), uno::UNO_QUERY
);
129 uno::Reference
< beans::XPropertySet
> xValues( xLabeledSequence
->getValues(), uno::UNO_QUERY
);
133 // the range string must be in Calc A1 format.
134 uno::Reference
< chart2::data::XDataSequence
> xNewSeq(
135 xDataProvider
->createDataSequenceByRangeRepresentation( rRanges
[nRange
++] ));
137 uno::Reference
< beans::XPropertySet
> xNewProps( xNewSeq
, uno::UNO_QUERY
);
139 xNewProps
->setPropertyValue( aPropertyNameRole
, xLabel
->getPropertyValue( aPropertyNameRole
) );
141 xLabeledSequence
->setLabel( xNewSeq
);
144 if( !(nRange
<rRanges
.getLength()) )
149 // the range string must be in Calc A1 format.
150 uno::Reference
< chart2::data::XDataSequence
> xNewSeq(
151 xDataProvider
->createDataSequenceByRangeRepresentation( rRanges
[nRange
++] ));
153 uno::Reference
< beans::XPropertySet
> xNewProps( xNewSeq
, uno::UNO_QUERY
);
155 xNewProps
->setPropertyValue( aPropertyNameRole
, xValues
->getPropertyValue( aPropertyNameRole
) );
157 xLabeledSequence
->setValues( xNewSeq
);
161 catch ( uno::Exception
& ex
)
164 DBG_ERROR("Exception in lcl_SetChartRanges - invalid range string?");
168 xModel
->unlockControllers();
171 void lcl_GetChartParameters( const uno::Reference
< chart2::XChartDocument
>& xChartDoc
,
172 rtl::OUString
& rRanges
, chart::ChartDataRowSource
& rDataRowSource
,
173 bool& rHasCategories
, bool& rFirstCellAsLabel
)
175 rHasCategories
= rFirstCellAsLabel
= false; // default if not in sequence
177 uno::Reference
< chart2::data::XDataReceiver
> xReceiver( xChartDoc
, uno::UNO_QUERY
);
179 uno::Reference
< chart2::data::XDataSource
> xDataSource
= xReceiver
->getUsedData();
180 uno::Reference
< chart2::data::XDataProvider
> xProvider
= xChartDoc
->getDataProvider();
182 if ( xProvider
.is() )
184 uno::Sequence
< beans::PropertyValue
> aArgs( xProvider
->detectArguments( xDataSource
) );
186 const beans::PropertyValue
* pPropArray
= aArgs
.getConstArray();
187 long nPropCount
= aArgs
.getLength();
188 for (long i
= 0; i
< nPropCount
; i
++)
190 const beans::PropertyValue
& rProp
= pPropArray
[i
];
191 String
aPropName(rProp
.Name
);
193 if (aPropName
.EqualsAscii( "CellRangeRepresentation" ))
194 rProp
.Value
>>= rRanges
;
195 else if (aPropName
.EqualsAscii( "DataRowSource" ))
196 rDataRowSource
= (chart::ChartDataRowSource
)ScUnoHelpFunctions::GetEnumFromAny( rProp
.Value
);
197 else if (aPropName
.EqualsAscii( "HasCategories" ))
198 rHasCategories
= ScUnoHelpFunctions::GetBoolFromAny( rProp
.Value
);
199 else if (aPropName
.EqualsAscii( "FirstCellAsLabel" ))
200 rFirstCellAsLabel
= ScUnoHelpFunctions::GetBoolFromAny( rProp
.Value
);
205 void lcl_SetChartParameters( const uno::Reference
< chart2::data::XDataReceiver
>& xReceiver
,
206 const rtl::OUString
& rRanges
, chart::ChartDataRowSource eDataRowSource
,
207 bool bHasCategories
, bool bFirstCellAsLabel
)
209 if ( xReceiver
.is() )
211 uno::Sequence
< beans::PropertyValue
> aArgs( 4 );
212 aArgs
[0] = beans::PropertyValue(
213 ::rtl::OUString::createFromAscii("CellRangeRepresentation"), -1,
214 uno::makeAny( rRanges
), beans::PropertyState_DIRECT_VALUE
);
215 aArgs
[1] = beans::PropertyValue(
216 ::rtl::OUString::createFromAscii("HasCategories"), -1,
217 uno::makeAny( bHasCategories
), beans::PropertyState_DIRECT_VALUE
);
218 aArgs
[2] = beans::PropertyValue(
219 ::rtl::OUString::createFromAscii("FirstCellAsLabel"), -1,
220 uno::makeAny( bFirstCellAsLabel
), beans::PropertyState_DIRECT_VALUE
);
221 aArgs
[3] = beans::PropertyValue(
222 ::rtl::OUString::createFromAscii("DataRowSource"), -1,
223 uno::makeAny( eDataRowSource
), beans::PropertyState_DIRECT_VALUE
);
224 xReceiver
->setArguments( aArgs
);
228 // update charts after loading old document
230 void ScDocument::UpdateAllCharts()
232 if ( !pDrawLayer
|| !pShell
)
235 USHORT nDataCount
= pChartCollection
->GetCount();
237 return ; // nothing to do
241 for (SCTAB nTab
=0; nTab
<=MAXTAB
; nTab
++)
245 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
246 DBG_ASSERT(pPage
,"Page ?");
249 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
250 SdrObject
* pObject
= aIter
.Next();
253 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
)
255 uno::Reference
< embed::XEmbeddedObject
> xIPObj
= ((SdrOle2Obj
*)pObject
)->GetObjRef();
258 String aIPName
= ((SdrOle2Obj
*)pObject
)->GetPersistName();
260 for (nPos
=0; nPos
<nDataCount
; nPos
++)
262 ScChartArray
* pChartObj
= (*pChartCollection
)[nPos
];
263 if (pChartObj
->GetName() == aIPName
)
265 ScRangeListRef aRanges
= pChartObj
->GetRangeList();
267 aRanges
->Format( sRangeStr
, SCR_ABS_3D
, this, GetAddressConvention() );
269 chart::ChartDataRowSource eDataRowSource
= chart::ChartDataRowSource_COLUMNS
;
270 bool bHasCategories
= pChartObj
->HasRowHeaders();
271 bool bFirstCellAsLabel
= pChartObj
->HasColHeaders();
273 // Calc -> DataProvider
274 uno::Reference
< chart2::data::XDataProvider
> xDataProvider
=
275 new ScChart2DataProvider( this );
276 // Chart -> DataReceiver
277 uno::Reference
< chart2::data::XDataReceiver
> xReceiver
;
278 uno::Reference
< embed::XComponentSupplier
> xCompSupp( xIPObj
, uno::UNO_QUERY
);
280 xReceiver
.set( xCompSupp
->getComponent(), uno::UNO_QUERY
);
284 xReceiver
->attachDataProvider( xDataProvider
);
285 uno::Reference
< util::XNumberFormatsSupplier
> xNumberFormatsSupplier(
286 pShell
->GetModel(), uno::UNO_QUERY
);
287 xReceiver
->attachNumberFormatsSupplier( xNumberFormatsSupplier
);
289 lcl_SetChartParameters( xReceiver
, sRangeStr
, eDataRowSource
,
290 bHasCategories
, bFirstCellAsLabel
);
293 ScChartListener
* pCL
= new ScChartListener(
294 aIPName
, this, pChartObj
->GetRangeList() );
295 pChartListenerCollection
->Insert( pCL
);
296 pCL
->StartListeningTo();
301 pObject
= aIter
.Next();
306 pChartCollection
->FreeAll();
309 BOOL
ScDocument::HasChartAtPoint( SCTAB nTab
, const Point
& rPos
, String
* pName
)
311 if (pDrawLayer
&& pTab
[nTab
])
313 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
314 DBG_ASSERT(pPage
,"Page ?");
316 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
317 SdrObject
* pObject
= aIter
.Next();
320 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
321 pObject
->GetCurrentBoundRect().IsInside(rPos
) )
323 // auch Chart-Objekte die nicht in der Collection sind
325 if (IsChart(pObject
))
328 *pName
= ((SdrOle2Obj
*)pObject
)->GetPersistName();
332 pObject
= aIter
.Next();
338 return FALSE
; // nix gefunden
341 void ScDocument::UpdateChartArea( const String
& rChartName
,
342 const ScRange
& rNewArea
, BOOL bColHeaders
, BOOL bRowHeaders
,
345 ScRangeListRef
aRLR( new ScRangeList
);
346 aRLR
->Append( rNewArea
);
347 UpdateChartArea( rChartName
, aRLR
, bColHeaders
, bRowHeaders
, bAdd
);
350 uno::Reference
< chart2::XChartDocument
> ScDocument::GetChartByName( const String
& rChartName
)
352 uno::Reference
< chart2::XChartDocument
> xReturn
;
356 sal_uInt16 nCount
= pDrawLayer
->GetPageCount();
357 for (sal_uInt16 nTab
=0; nTab
<nCount
; nTab
++)
359 SdrPage
* pPage
= pDrawLayer
->GetPage(nTab
);
360 DBG_ASSERT(pPage
,"Page ?");
362 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
363 SdrObject
* pObject
= aIter
.Next();
366 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
367 ((SdrOle2Obj
*)pObject
)->GetPersistName() == rChartName
)
369 uno::Reference
< embed::XEmbeddedObject
> xIPObj
= ((SdrOle2Obj
*)pObject
)->GetObjRef();
372 svt::EmbeddedObjectRef::TryRunningState( xIPObj
);
374 uno::Reference
< util::XCloseable
> xComponent
= xIPObj
->getComponent();
375 xReturn
.set( uno::Reference
< chart2::XChartDocument
>( xComponent
, uno::UNO_QUERY
) );
379 pObject
= aIter
.Next();
385 void ScDocument::GetChartRanges( const String
& rChartName
, ::std::vector
< ScRangeList
>& rRangesVector
, ScDocument
* pSheetNameDoc
)
387 rRangesVector
.clear();
388 uno::Reference
< chart2::XChartDocument
> xChartDoc( GetChartByName( rChartName
) );
389 if ( xChartDoc
.is() )
391 uno::Sequence
< rtl::OUString
> aRangeStrings
;
392 lcl_GetChartRanges( xChartDoc
, aRangeStrings
);
393 for( sal_Int32 nN
=0; nN
<aRangeStrings
.getLength(); nN
++ )
396 aRanges
.Parse( aRangeStrings
[nN
], pSheetNameDoc
, SCA_VALID
, pSheetNameDoc
->GetAddressConvention() );
397 rRangesVector
.push_back(aRanges
);
402 void ScDocument::SetChartRanges( const String
& rChartName
, const ::std::vector
< ScRangeList
>& rRangesVector
)
404 uno::Reference
< chart2::XChartDocument
> xChartDoc( GetChartByName( rChartName
) );
405 if ( xChartDoc
.is() )
407 sal_Int32 nCount
= static_cast<sal_Int32
>( rRangesVector
.size() );
408 uno::Sequence
< rtl::OUString
> aRangeStrings(nCount
);
409 for( sal_Int32 nN
=0; nN
<nCount
; nN
++ )
411 ScRangeList
aScRangeList( rRangesVector
[nN
] );
412 String sRangeStr
; // This range must be in Calc A1 format.
413 aScRangeList
.Format( sRangeStr
, SCR_ABS_3D
, this );
414 aRangeStrings
[nN
]=sRangeStr
;
416 lcl_SetChartRanges( xChartDoc
, aRangeStrings
);
420 void ScDocument::GetOldChartParameters( const String
& rName
,
421 ScRangeList
& rRanges
, BOOL
& rColHeaders
, BOOL
& rRowHeaders
)
423 // used for undo of changing chart source area
428 sal_uInt16 nCount
= pDrawLayer
->GetPageCount();
429 for (sal_uInt16 nTab
=0; nTab
<nCount
; nTab
++)
431 SdrPage
* pPage
= pDrawLayer
->GetPage(nTab
);
432 DBG_ASSERT(pPage
,"Page ?");
434 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
435 SdrObject
* pObject
= aIter
.Next();
438 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
439 ((SdrOle2Obj
*)pObject
)->GetPersistName() == rName
)
441 uno::Reference
< embed::XEmbeddedObject
> xIPObj
= ((SdrOle2Obj
*)pObject
)->GetObjRef();
444 svt::EmbeddedObjectRef::TryRunningState( xIPObj
);
446 uno::Reference
< util::XCloseable
> xComponent
= xIPObj
->getComponent();
447 uno::Reference
< chart2::XChartDocument
> xChartDoc( xComponent
, uno::UNO_QUERY
);
448 if ( xChartDoc
.is() )
450 chart::ChartDataRowSource eDataRowSource
= chart::ChartDataRowSource_COLUMNS
;
451 bool bHasCategories
= false;
452 bool bFirstCellAsLabel
= false;
453 rtl::OUString aRangesStr
;
454 lcl_GetChartParameters( xChartDoc
, aRangesStr
, eDataRowSource
, bHasCategories
, bFirstCellAsLabel
);
456 rRanges
.Parse( aRangesStr
, this );
457 if ( eDataRowSource
== chart::ChartDataRowSource_COLUMNS
)
459 rRowHeaders
= bHasCategories
;
460 rColHeaders
= bFirstCellAsLabel
;
464 rColHeaders
= bHasCategories
;
465 rRowHeaders
= bFirstCellAsLabel
;
471 pObject
= aIter
.Next();
476 void ScDocument::UpdateChartArea( const String
& rChartName
,
477 const ScRangeListRef
& rNewList
, BOOL bColHeaders
, BOOL bRowHeaders
,
483 for (SCTAB nTab
=0; nTab
<=MAXTAB
&& pTab
[nTab
]; nTab
++)
485 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
486 DBG_ASSERT(pPage
,"Page ?");
488 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
489 SdrObject
* pObject
= aIter
.Next();
492 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
493 ((SdrOle2Obj
*)pObject
)->GetPersistName() == rChartName
)
495 uno::Reference
< embed::XEmbeddedObject
> xIPObj
= ((SdrOle2Obj
*)pObject
)->GetObjRef();
498 svt::EmbeddedObjectRef::TryRunningState( xIPObj
);
500 uno::Reference
< util::XCloseable
> xComponent
= xIPObj
->getComponent();
501 uno::Reference
< chart2::XChartDocument
> xChartDoc( xComponent
, uno::UNO_QUERY
);
502 uno::Reference
< chart2::data::XDataReceiver
> xReceiver( xComponent
, uno::UNO_QUERY
);
503 if ( xChartDoc
.is() && xReceiver
.is() )
505 ScRangeListRef aNewRanges
;
506 chart::ChartDataRowSource eDataRowSource
= chart::ChartDataRowSource_COLUMNS
;
507 bool bHasCategories
= false;
508 bool bFirstCellAsLabel
= false;
509 rtl::OUString aRangesStr
;
510 lcl_GetChartParameters( xChartDoc
, aRangesStr
, eDataRowSource
, bHasCategories
, bFirstCellAsLabel
);
512 sal_Bool bInternalData
= xChartDoc
->hasInternalDataProvider();
514 if ( bAdd
&& !bInternalData
)
516 // append to old ranges, keep other settings
518 aNewRanges
= new ScRangeList
;
519 aNewRanges
->Parse( aRangesStr
, this );
521 ULONG nAddCount
= rNewList
->Count();
522 for ( ULONG nAdd
=0; nAdd
<nAddCount
; nAdd
++ )
523 aNewRanges
->Append( *rNewList
->GetObject(nAdd
) );
527 // directly use new ranges (only eDataRowSource is used from old settings)
529 if ( eDataRowSource
== chart::ChartDataRowSource_COLUMNS
)
531 bHasCategories
= bRowHeaders
;
532 bFirstCellAsLabel
= bColHeaders
;
536 bHasCategories
= bColHeaders
;
537 bFirstCellAsLabel
= bRowHeaders
;
539 aNewRanges
= rNewList
;
542 if ( bInternalData
&& pShell
)
544 // Calc -> DataProvider
545 uno::Reference
< chart2::data::XDataProvider
> xDataProvider
= new ScChart2DataProvider( this );
546 xReceiver
->attachDataProvider( xDataProvider
);
547 uno::Reference
< util::XNumberFormatsSupplier
> xNumberFormatsSupplier(
548 pShell
->GetModel(), uno::UNO_QUERY
);
549 xReceiver
->attachNumberFormatsSupplier( xNumberFormatsSupplier
);
553 aNewRanges
->Format( sRangeStr
, SCR_ABS_3D
, this, GetAddressConvention() );
555 lcl_SetChartParameters( xReceiver
, sRangeStr
, eDataRowSource
, bHasCategories
, bFirstCellAsLabel
);
557 pChartListenerCollection
->ChangeListening( rChartName
, aNewRanges
);
559 // ((SdrOle2Obj*)pObject)->GetNewReplacement();
560 // pObject->ActionChanged();
562 return; // nicht weitersuchen
566 pObject
= aIter
.Next();
571 void ScDocument::UpdateChart( const String
& rChartName
)
573 if (!pDrawLayer
|| bInDtorClear
)
576 for (SCTAB nTab
=0; nTab
<=MAXTAB
&& pTab
[nTab
]; nTab
++)
578 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
579 DBG_ASSERT(pPage
,"Page ?");
581 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
582 SdrObject
* pObject
= aIter
.Next();
585 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
586 ((SdrOle2Obj
*)pObject
)->GetPersistName() == rChartName
)
588 //@todo?: maybe we need a notification
589 //from the calc to the chart in future
590 //that calc content has changed
591 // ((SdrOle2Obj*)pObject)->GetNewReplacement();
593 // Load the object and set modified
595 uno::Reference
< embed::XEmbeddedObject
> xIPObj
= ((SdrOle2Obj
*)pObject
)->GetObjRef();
598 svt::EmbeddedObjectRef::TryRunningState( xIPObj
);
602 uno::Reference
< util::XModifiable
> xModif( xIPObj
->getComponent(), uno::UNO_QUERY_THROW
);
603 if( apTemporaryChartLock
.get() )
604 apTemporaryChartLock
->AlsoLockThisChart( uno::Reference
< frame::XModel
>( xModif
, uno::UNO_QUERY
) );
605 xModif
->setModified( sal_True
);
607 catch ( uno::Exception
& )
614 pObject
->ActionChanged();
616 // After the update, chart keeps track of its own data source ranges,
617 // the listener doesn't need to listen anymore.
619 pChartListenerCollection
->ChangeListening( rChartName
, new ScRangeList
);
624 uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef();
627 const SchMemChart* pChartData = SchDLL::GetChartData(xIPObj);
630 ScChartArray aArray( this, *pChartData );
632 SchMemChart* pMemChart = aArray.CreateMemChart();
633 ScChartArray::CopySettings( *pMemChart, *pChartData );
635 // #57655# Chart-Update ohne geaenderte Einstellungen (MemChart)
636 // soll das Dokument nicht auf modified setzen (z.B. in frisch
637 // geladenem Dokument durch initiales Recalc)
639 // #72576# disable SetModified for readonly documents only
641 sal_Bool bEnabled = ( (pShell && pShell->IsReadOnly()) || IsImportingXML() );
642 sal_Bool bModified = sal_False;
643 uno::Reference< util::XModifiable > xModif;
650 uno::Reference< util::XModifiable >( xIPObj->getComponent(), uno::UNO_QUERY_THROW );
651 bModified = xModif->isModified();
653 catch( uno::Exception& )
655 bEnabled = sal_False;
659 SchDLL::Update( xIPObj, pMemChart, pWindow );
660 ((SdrOle2Obj*)pObject)->GetNewReplacement();
663 // Dies veranlaesst Chart zum sofortigen Update
665 //aIPObj->SendDataChanged( aEmpty );
667 // the method below did nothing in SO7
668 //REMOVE aIPObj->SendViewChanged();
671 pObject->ActionChanged();
672 // pObject->SendRepaintBroadcast();
674 if ( bEnabled && xModif.is() )
678 if ( xModif->isModified() != bModified )
679 xModif->setModified( bModified );
681 catch ( uno::Exception& )
685 return; // nicht weitersuchen
690 pObject
= aIter
.Next();
695 void ScDocument::RestoreChartListener( const String
& rName
)
697 // Read the data ranges from the chart object, and start listening to those ranges again
698 // (called when a chart is saved, because then it might be swapped out and stop listening itself).
700 uno::Reference
< embed::XEmbeddedObject
> xObject
= FindOleObjectByName( rName
);
703 uno::Reference
< util::XCloseable
> xComponent
= xObject
->getComponent();
704 uno::Reference
< chart2::XChartDocument
> xChartDoc( xComponent
, uno::UNO_QUERY
);
705 uno::Reference
< chart2::data::XDataReceiver
> xReceiver( xComponent
, uno::UNO_QUERY
);
706 if ( xChartDoc
.is() && xReceiver
.is() && !xChartDoc
->hasInternalDataProvider())
708 uno::Sequence
<rtl::OUString
> aRepresentations( xReceiver
->getUsedRangeRepresentations() );
709 ScRangeListRef aRanges
= new ScRangeList
;
710 sal_Int32 nRangeCount
= aRepresentations
.getLength();
711 for ( sal_Int32 i
=0; i
<nRangeCount
; i
++ )
714 ScAddress::Details
aDetails(GetAddressConvention(), 0, 0);
715 if ( aRange
.ParseAny( aRepresentations
[i
], this, aDetails
) & SCA_VALID
)
716 aRanges
->Append( aRange
);
719 pChartListenerCollection
->ChangeListening( rName
, aRanges
);
724 void ScDocument::UpdateChartRef( UpdateRefMode eUpdateRefMode
,
725 SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
726 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
727 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
)
732 USHORT nChartCount
= pChartListenerCollection
->GetCount();
733 for ( USHORT nIndex
= 0; nIndex
< nChartCount
; nIndex
++ )
735 ScChartListener
* pChartListener
=
736 (ScChartListener
*) (pChartListenerCollection
->At(nIndex
));
737 ScRangeListRef
aRLR( pChartListener
->GetRangeList() );
738 ScRangeListRef
aNewRLR( new ScRangeList
);
739 BOOL bChanged
= FALSE
;
740 BOOL bDataChanged
= FALSE
;
741 for ( ScRangePtr pR
= aRLR
->First(); pR
; pR
= aRLR
->Next() )
743 SCCOL theCol1
= pR
->aStart
.Col();
744 SCROW theRow1
= pR
->aStart
.Row();
745 SCTAB theTab1
= pR
->aStart
.Tab();
746 SCCOL theCol2
= pR
->aEnd
.Col();
747 SCROW theRow2
= pR
->aEnd
.Row();
748 SCTAB theTab2
= pR
->aEnd
.Tab();
749 ScRefUpdateRes eRes
= ScRefUpdate::Update(
750 this, eUpdateRefMode
,
751 nCol1
,nRow1
,nTab1
, nCol2
,nRow2
,nTab2
,
753 theCol1
,theRow1
,theTab1
,
754 theCol2
,theRow2
,theTab2
);
755 if ( eRes
!= UR_NOTHING
)
758 aNewRLR
->Append( ScRange(
759 theCol1
, theRow1
, theTab1
,
760 theCol2
, theRow2
, theTab2
));
761 if ( eUpdateRefMode
== URM_INSDEL
763 && (eRes
== UR_INVALID
||
764 ((pR
->aEnd
.Col() - pR
->aStart
.Col()
765 != theCol2
- theCol1
)
766 || (pR
->aEnd
.Row() - pR
->aStart
.Row()
767 != theRow2
- theRow1
)
768 || (pR
->aEnd
.Tab() - pR
->aStart
.Tab()
769 != theTab2
- theTab1
))) )
775 aNewRLR
->Append( *pR
);
781 { // #81844# sheet to be deleted or inserted or moved
782 // => no valid sheet names for references right now
783 pChartListener
->ChangeListening( aNewRLR
, bDataChanged
);
784 pChartListener
->ScheduleSeriesRanges();
789 // SetChartRangeList( pChartListener->GetString(), aNewRLR );
790 // pChartListener->ChangeListening( aNewRLR, bDataChanged );
792 // Force the chart to be loaded now, so it registers itself for UNO events.
793 // UNO broadcasts are done after UpdateChartRef, so the chart will get this
796 uno::Reference
< embed::XEmbeddedObject
> xIPObj
= FindOleObjectByName( pChartListener
->GetString() );
797 svt::EmbeddedObjectRef::TryRunningState( xIPObj
);
799 // After the change, chart keeps track of its own data source ranges,
800 // the listener doesn't need to listen anymore.
802 pChartListener
->ChangeListening( new ScRangeList
, bDataChanged
);
809 void ScDocument::SetChartRangeList( const String
& rChartName
,
810 const ScRangeListRef
& rNewRangeListRef
)
812 // called from ChartListener
817 for (SCTAB nTab
=0; nTab
<=MAXTAB
&& pTab
[nTab
]; nTab
++)
819 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
820 DBG_ASSERT(pPage
,"Page ?");
822 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
823 SdrObject
* pObject
= aIter
.Next();
826 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
827 ((SdrOle2Obj
*)pObject
)->GetPersistName() == rChartName
)
829 uno::Reference
< embed::XEmbeddedObject
> xIPObj
= ((SdrOle2Obj
*)pObject
)->GetObjRef();
832 svt::EmbeddedObjectRef::TryRunningState( xIPObj
);
834 uno::Reference
< util::XCloseable
> xComponent
= xIPObj
->getComponent();
835 uno::Reference
< chart2::XChartDocument
> xChartDoc( xComponent
, uno::UNO_QUERY
);
836 uno::Reference
< chart2::data::XDataReceiver
> xReceiver( xComponent
, uno::UNO_QUERY
);
837 if ( xChartDoc
.is() && xReceiver
.is() )
839 ScRangeListRef aNewRanges
;
840 chart::ChartDataRowSource eDataRowSource
= chart::ChartDataRowSource_COLUMNS
;
841 bool bHasCategories
= false;
842 bool bFirstCellAsLabel
= false;
843 rtl::OUString aRangesStr
;
844 lcl_GetChartParameters( xChartDoc
, aRangesStr
, eDataRowSource
, bHasCategories
, bFirstCellAsLabel
);
847 rNewRangeListRef
->Format( sRangeStr
, SCR_ABS_3D
, this, GetAddressConvention() );
849 lcl_SetChartParameters( xReceiver
, sRangeStr
, eDataRowSource
, bHasCategories
, bFirstCellAsLabel
);
851 // don't modify pChartListenerCollection here, called from there
856 pObject
= aIter
.Next();
862 BOOL
ScDocument::HasData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
865 return pTab
[nTab
]->HasData( nCol
, nRow
);
870 uno::Reference
< embed::XEmbeddedObject
>
871 ScDocument::FindOleObjectByName( const String
& rName
)
874 return uno::Reference
< embed::XEmbeddedObject
>();
876 // die Seiten hier vom Draw-Layer nehmen,
877 // weil sie evtl. nicht mit den Tabellen uebereinstimmen
878 // (z.B. Redo von Tabelle loeschen, Draw-Redo passiert vor DeleteTab).
880 sal_uInt16 nCount
= pDrawLayer
->GetPageCount();
881 for (sal_uInt16 nTab
=0; nTab
<nCount
; nTab
++)
883 SdrPage
* pPage
= pDrawLayer
->GetPage(nTab
);
884 DBG_ASSERT(pPage
,"Page ?");
886 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
887 SdrObject
* pObject
= aIter
.Next();
890 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
)
892 SdrOle2Obj
* pOleObject ( dynamic_cast< SdrOle2Obj
* >( pObject
));
894 pOleObject
->GetPersistName() == rName
)
896 return pOleObject
->GetObjRef();
899 pObject
= aIter
.Next();
903 return uno::Reference
< embed::XEmbeddedObject
>();
906 BOOL
lcl_StringInCollection( const ScStrCollection
* pColl
, const String
& rStr
)
911 StrData
aData( rStr
);
913 return pColl
->Search( &aData
, nDummy
);
916 void ScDocument::UpdateChartListenerCollection()
918 bChartListenerCollectionNeedsUpdate
= FALSE
;
924 // Range fuer Suche unwichtig
925 ScChartListener
aCLSearcher( EMPTY_STRING
, this, aRange
);
926 for (SCTAB nTab
=0; nTab
<=MAXTAB
; nTab
++)
930 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
931 DBG_ASSERT(pPage
,"Page ?");
933 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
934 SdrObject
* pObject
= aIter
.Next();
937 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
)
939 String aObjName
= ((SdrOle2Obj
*)pObject
)->GetPersistName();
940 aCLSearcher
.SetString( aObjName
);
942 if ( pChartListenerCollection
->Search( &aCLSearcher
, nIndex
) )
944 ((ScChartListener
*) (pChartListenerCollection
->
945 At( nIndex
)))->SetUsed( TRUE
);
947 else if ( lcl_StringInCollection( pOtherObjects
, aObjName
) )
949 // non-chart OLE object -> don't touch
953 bool bIsChart
= false;
955 uno::Reference
< embed::XEmbeddedObject
> xIPObj
= ((SdrOle2Obj
*)pObject
)->GetObjRef();
956 DBG_ASSERT( xIPObj
.is(), "No embedded object is given!");
957 uno::Reference
< ::com::sun::star::chart2::data::XDataReceiver
> xReceiver
;
958 uno::Reference
< embed::XComponentSupplier
> xCompSupp( xIPObj
, uno::UNO_QUERY
);
960 xReceiver
.set( xCompSupp
->getComponent(), uno::UNO_QUERY
);
962 // if the object is a chart2::XDataReceiver, we must attach as XDataProvider
963 if( xReceiver
.is() &&
964 !PastingDrawFromOtherDoc())
966 // NOTE: this currently does not work as we are
967 // unable to set the data. So a chart from the
968 // same document is treated like a chart with
969 // own data for the time being.
972 uno::Reference
< chart2::data::XDataProvider
> xDataProvider
= new
973 ScChart2DataProvider( this );
974 xReceiver
->attachDataProvider( xDataProvider
);
975 // number formats supplier
976 uno::Reference
< util::XNumberFormatsSupplier
> xNumberFormatsSupplier( pShell
->GetModel(), uno::UNO_QUERY
);
977 xReceiver
->attachNumberFormatsSupplier( xNumberFormatsSupplier
);
979 // how to set?? Defined in XML-file, which is already loaded!!!
980 // => we have to do this stuff here, BEFORE the chart is actually loaded
988 // put into list of other ole objects, so the object doesn't have to
989 // be swapped in the next time UpdateChartListenerCollection is called
990 //! remove names when objects are no longer there?
991 // (object names aren't used again before reloading the document)
994 pOtherObjects
= new ScStrCollection
;
995 pOtherObjects
->Insert( new StrData( aObjName
) );
999 pObject
= aIter
.Next();
1003 // alle nicht auf SetUsed gesetzten loeschen
1004 pChartListenerCollection
->FreeUnused();
1008 void ScDocument::AddOLEObjectToCollection(const String
& rName
)
1011 pOtherObjects
= new ScStrCollection
;
1012 pOtherObjects
->Insert( new StrData( rName
) );