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 <sal/config.h>
22 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
23 #include <comphelper/sequence.hxx>
24 #include <formula/token.hxx>
25 #include <svl/hint.hxx>
26 #include <sfx2/linkmgr.hxx>
28 #include <vcl/svapp.hxx>
29 #include <svl/sharedstringpool.hxx>
31 #include <linkuno.hxx>
32 #include <miscuno.hxx>
33 #include <convuno.hxx>
35 #include <docfunc.hxx>
36 #include <tablink.hxx>
37 #include <arealink.hxx>
39 #include <unonames.hxx>
40 #include <rangeseq.hxx>
41 #include <scmatrix.hxx>
42 #include <documentlinkmgr.hxx>
44 #include <string_view>
47 using namespace com::sun::star
;
48 using namespace formula
;
49 using ::com::sun::star::uno::Any
;
50 using ::com::sun::star::uno::Sequence
;
51 using ::com::sun::star::lang::IllegalArgumentException
;
52 using ::com::sun::star::uno::RuntimeException
;
55 // used for sheet- and area link:
56 static std::span
<const SfxItemPropertyMapEntry
> lcl_GetSheetLinkMap()
58 static const SfxItemPropertyMapEntry aSheetLinkMap_Impl
[] =
60 { SC_UNONAME_FILTER
, 0, cppu::UnoType
<OUString
>::get(), 0, 0 },
61 { SC_UNONAME_FILTOPT
, 0, cppu::UnoType
<OUString
>::get(), 0, 0 },
62 { SC_UNONAME_LINKURL
, 0, cppu::UnoType
<OUString
>::get(), 0, 0 },
63 { SC_UNONAME_REFDELAY
, 0, cppu::UnoType
<sal_Int32
>::get(), 0, 0 },
64 { SC_UNONAME_REFPERIOD
, 0, cppu::UnoType
<sal_Int32
>::get(), 0, 0 },
66 return aSheetLinkMap_Impl
;
69 SC_SIMPLE_SERVICE_INFO( ScAreaLinkObj
, u
"ScAreaLinkObj"_ustr
, u
"com.sun.star.sheet.CellAreaLink"_ustr
)
70 SC_SIMPLE_SERVICE_INFO( ScAreaLinksObj
, u
"ScAreaLinksObj"_ustr
, u
"com.sun.star.sheet.CellAreaLinks"_ustr
)
71 SC_SIMPLE_SERVICE_INFO( ScDDELinkObj
, u
"ScDDELinkObj"_ustr
, u
"com.sun.star.sheet.DDELink"_ustr
)
72 SC_SIMPLE_SERVICE_INFO( ScDDELinksObj
, u
"ScDDELinksObj"_ustr
, u
"com.sun.star.sheet.DDELinks"_ustr
)
73 SC_SIMPLE_SERVICE_INFO( ScSheetLinkObj
, u
"ScSheetLinkObj"_ustr
, u
"com.sun.star.sheet.SheetLink"_ustr
)
74 SC_SIMPLE_SERVICE_INFO( ScSheetLinksObj
, u
"ScSheetLinksObj"_ustr
, u
"com.sun.star.sheet.SheetLinks"_ustr
)
76 ScSheetLinkObj::ScSheetLinkObj(ScDocShell
* pDocSh
, OUString aName
) :
77 aPropSet( lcl_GetSheetLinkMap() ),
79 aFileName(std::move( aName
))
81 pDocShell
->GetDocument().AddUnoObject(*this);
84 ScSheetLinkObj::~ScSheetLinkObj()
89 pDocShell
->GetDocument().RemoveUnoObject(*this);
92 void ScSheetLinkObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
94 //! notify if links in document are changed
95 // UpdateRef is not needed here
97 if ( rHint
.GetId() == SfxHintId::ScLinkRefreshed
)
99 auto pRefreshHint
= static_cast<const ScLinkRefreshedHint
*>(&rHint
);
100 if ( pRefreshHint
->GetLinkType() == ScLinkRefType::SHEET
&& pRefreshHint
->GetUrl() == aFileName
)
105 if ( rHint
.GetId() == SfxHintId::Dying
)
106 pDocShell
= nullptr; // pointer is invalid
110 ScTableLink
* ScSheetLinkObj::GetLink_Impl() const
114 sfx2::LinkManager
* pLinkManager
= pDocShell
->GetDocument().GetLinkManager();
115 size_t nCount
= pLinkManager
->GetLinks().size();
116 for (size_t i
=0; i
<nCount
; i
++)
118 ::sfx2::SvBaseLink
* pBase
= pLinkManager
->GetLinks()[i
].get();
119 if (auto pTabLink
= dynamic_cast<ScTableLink
*>( pBase
))
121 if ( pTabLink
->GetFileName() == aFileName
)
126 return nullptr; // not found
131 OUString SAL_CALL
ScSheetLinkObj::getName()
133 SolarMutexGuard aGuard
;
134 return getFileName(); // Name is the same as filename (URL)
137 void SAL_CALL
ScSheetLinkObj::setName( const OUString
& aName
)
139 SolarMutexGuard aGuard
;
140 setFileName(aName
); // Name is the same as filename (URL)
145 void SAL_CALL
ScSheetLinkObj::refresh()
147 SolarMutexGuard aGuard
;
148 ScTableLink
* pLink
= GetLink_Impl();
150 pLink
->Refresh( pLink
->GetFileName(), pLink
->GetFilterName(), nullptr, pLink
->GetRefreshDelaySeconds() );
153 void SAL_CALL
ScSheetLinkObj::addRefreshListener(
154 const uno::Reference
<util::XRefreshListener
>& xListener
)
156 SolarMutexGuard aGuard
;
157 aRefreshListeners
.push_back( xListener
);
159 // hold one additional ref to keep this object alive as long as there are listeners
160 if ( aRefreshListeners
.size() == 1 )
164 void SAL_CALL
ScSheetLinkObj::removeRefreshListener(
165 const uno::Reference
<util::XRefreshListener
>& xListener
)
167 SolarMutexGuard aGuard
;
168 size_t nCount
= aRefreshListeners
.size();
169 for ( size_t n
=nCount
; n
--; )
171 uno::Reference
<util::XRefreshListener
>& rObj
= aRefreshListeners
[n
];
172 if ( rObj
== xListener
)
174 aRefreshListeners
.erase( aRefreshListeners
.begin() + n
);
175 if ( aRefreshListeners
.empty() )
176 release(); // release ref for listeners
182 void ScSheetLinkObj::Refreshed_Impl()
184 lang::EventObject aEvent
;
185 aEvent
.Source
.set(getXWeak());
186 for (uno::Reference
<util::XRefreshListener
> & xRefreshListener
: aRefreshListeners
)
187 xRefreshListener
->refreshed( aEvent
);
190 void ScSheetLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh
)
192 ScTableLink
* pLink
= GetLink_Impl();
194 pLink
->SetRefreshDelay( static_cast<sal_uLong
>(nRefresh
) );
199 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
ScSheetLinkObj::getPropertySetInfo()
201 SolarMutexGuard aGuard
;
202 static uno::Reference
<beans::XPropertySetInfo
> aRef(
203 new SfxItemPropertySetInfo( aPropSet
.getPropertyMap() ));
207 void SAL_CALL
ScSheetLinkObj::setPropertyValue(
208 const OUString
& aPropertyName
, const uno::Any
& aValue
)
210 SolarMutexGuard aGuard
;
212 if ( aPropertyName
== SC_UNONAME_LINKURL
)
214 if ( aValue
>>= aValStr
)
215 setFileName( aValStr
);
217 else if ( aPropertyName
== SC_UNONAME_FILTER
)
219 if ( aValue
>>= aValStr
)
220 setFilter( aValStr
);
222 else if ( aPropertyName
== SC_UNONAME_FILTOPT
)
224 if ( aValue
>>= aValStr
)
225 setFilterOptions( aValStr
);
227 else if ( aPropertyName
== SC_UNONAME_REFPERIOD
)
229 sal_Int32 nRefresh
= 0;
230 if ( aValue
>>= nRefresh
)
231 setRefreshDelay( nRefresh
);
233 else if ( aPropertyName
== SC_UNONAME_REFDELAY
)
235 sal_Int32 nRefresh
= 0;
236 if ( aValue
>>= nRefresh
)
237 setRefreshDelay( nRefresh
);
241 uno::Any SAL_CALL
ScSheetLinkObj::getPropertyValue( const OUString
& aPropertyName
)
243 SolarMutexGuard aGuard
;
245 if ( aPropertyName
== SC_UNONAME_LINKURL
)
246 aRet
<<= getFileName();
247 else if ( aPropertyName
== SC_UNONAME_FILTER
)
248 aRet
<<= getFilter();
249 else if ( aPropertyName
== SC_UNONAME_FILTOPT
)
250 aRet
<<= getFilterOptions();
251 else if ( aPropertyName
== SC_UNONAME_REFPERIOD
)
252 aRet
<<= getRefreshDelay();
253 else if ( aPropertyName
== SC_UNONAME_REFDELAY
)
254 aRet
<<= getRefreshDelay();
258 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSheetLinkObj
)
262 OUString
ScSheetLinkObj::getFileName() const
264 SolarMutexGuard aGuard
;
268 void ScSheetLinkObj::setFileName(const OUString
& rNewName
)
270 SolarMutexGuard aGuard
;
271 ScTableLink
* pLink
= GetLink_Impl();
275 // pLink->Refresh with a new file name confuses sfx2::LinkManager
276 // therefore we transplant the sheets manually and create new links with UpdateLinks
278 OUString
aNewStr(ScGlobal::GetAbsDocName( rNewName
, pDocShell
));
280 // first transplant the sheets
282 ScDocument
& rDoc
= pDocShell
->GetDocument();
283 SCTAB nTabCount
= rDoc
.GetTableCount();
284 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
285 if ( rDoc
.IsLinked(nTab
) && rDoc
.GetLinkDoc(nTab
) == aFileName
) // old file
286 rDoc
.SetLink( nTab
, rDoc
.GetLinkMode(nTab
), aNewStr
,
287 rDoc
.GetLinkFlt(nTab
), rDoc
.GetLinkOpt(nTab
),
288 rDoc
.GetLinkTab(nTab
),
289 rDoc
.GetLinkRefreshDelay(nTab
) ); // only change the file
294 pDocShell
->UpdateLinks(); // remove old links, possibly set up new ones
299 pLink
= GetLink_Impl(); // new link with new name
301 pLink
->Update(); // incl. paint & undo for data
304 OUString
ScSheetLinkObj::getFilter() const
306 SolarMutexGuard aGuard
;
308 ScTableLink
* pLink
= GetLink_Impl();
310 aRet
= pLink
->GetFilterName();
314 void ScSheetLinkObj::setFilter(const OUString
& rFilter
)
316 SolarMutexGuard aGuard
;
317 ScTableLink
* pLink
= GetLink_Impl();
320 pLink
->Refresh( aFileName
, rFilter
, nullptr, pLink
->GetRefreshDelaySeconds() );
324 OUString
ScSheetLinkObj::getFilterOptions() const
326 SolarMutexGuard aGuard
;
328 ScTableLink
* pLink
= GetLink_Impl();
330 aRet
= pLink
->GetOptions();
334 void ScSheetLinkObj::setFilterOptions(const OUString
& FilterOptions
)
336 SolarMutexGuard aGuard
;
337 ScTableLink
* pLink
= GetLink_Impl();
340 OUString
aOptStr(FilterOptions
);
341 pLink
->Refresh( aFileName
, pLink
->GetFilterName(), &aOptStr
, pLink
->GetRefreshDelaySeconds() );
345 sal_Int32
ScSheetLinkObj::getRefreshDelay() const
347 SolarMutexGuard aGuard
;
349 ScTableLink
* pLink
= GetLink_Impl();
351 nRet
= pLink
->GetRefreshDelaySeconds();
355 void ScSheetLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay
)
357 SolarMutexGuard aGuard
;
358 ModifyRefreshDelay_Impl( nRefreshDelay
);
361 ScSheetLinksObj::ScSheetLinksObj(ScDocShell
* pDocSh
) :
364 pDocShell
->GetDocument().AddUnoObject(*this);
367 ScSheetLinksObj::~ScSheetLinksObj()
372 pDocShell
->GetDocument().RemoveUnoObject(*this);
375 void ScSheetLinksObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
377 // we don't care about update of references here
379 if ( rHint
.GetId() == SfxHintId::Dying
)
381 pDocShell
= nullptr; // became invalid
387 rtl::Reference
<ScSheetLinkObj
> ScSheetLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex
)
392 typedef std::unordered_set
<OUString
> StrSetType
;
394 ScDocument
& rDoc
= pDocShell
->GetDocument();
395 SCTAB nTabCount
= rDoc
.GetTableCount();
396 sal_Int32 nCount
= 0;
397 for (SCTAB nTab
= 0; nTab
< nTabCount
; ++nTab
)
399 if (!rDoc
.IsLinked(nTab
))
402 OUString aLinkDoc
= rDoc
.GetLinkDoc(nTab
);
403 if (aNames
.insert(aLinkDoc
).second
)
405 // unique document name.
406 if (nCount
== nIndex
)
407 return new ScSheetLinkObj( pDocShell
, aLinkDoc
);
412 return nullptr; // no document or index too large
415 rtl::Reference
<ScSheetLinkObj
> ScSheetLinksObj::GetObjectByName_Impl(const OUString
& aName
)
417 // Name is the same as file name
421 ScDocument
& rDoc
= pDocShell
->GetDocument();
422 SCTAB nTabCount
= rDoc
.GetTableCount();
423 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
424 if (rDoc
.IsLinked(nTab
))
426 //! case-insensitive ???
427 OUString aLinkDoc
= rDoc
.GetLinkDoc( nTab
);
428 if ( aLinkDoc
== aName
)
429 return new ScSheetLinkObj( pDocShell
, aName
);
436 // XEnumerationAccess
437 uno::Reference
<container::XEnumeration
> SAL_CALL
ScSheetLinksObj::createEnumeration()
439 SolarMutexGuard aGuard
;
440 return new ScIndexEnumeration(this, u
"com.sun.star.sheet.SheetLinksEnumeration"_ustr
);
444 sal_Int32 SAL_CALL
ScSheetLinksObj::getCount()
446 typedef std::unordered_set
<OUString
> StrSetType
;
448 SolarMutexGuard aGuard
;
452 sal_Int32 nCount
= 0;
455 ScDocument
& rDoc
= pDocShell
->GetDocument();
456 SCTAB nTabCount
= rDoc
.GetTableCount();
457 for (SCTAB nTab
= 0; nTab
< nTabCount
; ++nTab
)
459 if (!rDoc
.IsLinked(nTab
))
462 OUString aLinkDoc
= rDoc
.GetLinkDoc(nTab
);
463 if (aNames
.insert(aLinkDoc
).second
)
469 uno::Any SAL_CALL
ScSheetLinksObj::getByIndex( sal_Int32 nIndex
)
471 SolarMutexGuard aGuard
;
472 uno::Reference
<beans::XPropertySet
> xLink(GetObjectByIndex_Impl(nIndex
));
474 throw lang::IndexOutOfBoundsException();
476 return uno::Any(xLink
);
479 uno::Type SAL_CALL
ScSheetLinksObj::getElementType()
481 return cppu::UnoType
<beans::XPropertySet
>::get();
484 sal_Bool SAL_CALL
ScSheetLinksObj::hasElements()
486 SolarMutexGuard aGuard
;
487 return ( getCount() != 0 );
490 uno::Any SAL_CALL
ScSheetLinksObj::getByName( const OUString
& aName
)
492 SolarMutexGuard aGuard
;
493 uno::Reference
<beans::XPropertySet
> xLink(GetObjectByName_Impl(aName
));
495 throw container::NoSuchElementException();
497 return uno::Any(xLink
);
500 sal_Bool SAL_CALL
ScSheetLinksObj::hasByName( const OUString
& aName
)
502 SolarMutexGuard aGuard
;
503 // Name is the same as file name
507 ScDocument
& rDoc
= pDocShell
->GetDocument();
508 SCTAB nTabCount
= rDoc
.GetTableCount();
509 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
510 if (rDoc
.IsLinked(nTab
))
512 //! case-insensitive ???
513 OUString
aLinkDoc(rDoc
.GetLinkDoc( nTab
));
514 if ( aLinkDoc
== aName
)
521 uno::Sequence
<OUString
> SAL_CALL
ScSheetLinksObj::getElementNames()
523 typedef std::unordered_set
<OUString
> StrSetType
;
525 SolarMutexGuard aGuard
;
526 // Name is the same as file name
529 return uno::Sequence
<OUString
>();
532 ScDocument
& rDoc
= pDocShell
->GetDocument();
533 SCTAB nTabCount
= rDoc
.GetTableCount();
535 sal_Int32 nLinkCount
= getCount();
536 uno::Sequence
<OUString
> aSeq(nLinkCount
);
537 OUString
* pAry
= aSeq
.getArray();
539 for (SCTAB nTab
= 0; nTab
< nTabCount
; ++nTab
)
541 if (!rDoc
.IsLinked(nTab
))
544 OUString aLinkDoc
= rDoc
.GetLinkDoc(nTab
);
545 if (aNames
.insert(aLinkDoc
).second
)
546 pAry
[nPos
++] = aLinkDoc
;
548 OSL_ENSURE( nPos
==static_cast<size_t>(nLinkCount
), "verzaehlt" );
552 static ScAreaLink
* lcl_GetAreaLink( ScDocShell
* pDocShell
, size_t nPos
)
556 sfx2::LinkManager
* pLinkManager
= pDocShell
->GetDocument().GetLinkManager();
557 size_t nTotalCount
= pLinkManager
->GetLinks().size();
558 size_t nAreaCount
= 0;
559 for (size_t i
=0; i
<nTotalCount
; i
++)
561 ::sfx2::SvBaseLink
* pBase
= pLinkManager
->GetLinks()[i
].get();
562 if (auto pAreaLink
= dynamic_cast<ScAreaLink
*>( pBase
))
564 if ( nAreaCount
== nPos
)
570 return nullptr; // not found
573 ScAreaLinkObj::ScAreaLinkObj(ScDocShell
* pDocSh
, size_t nP
) :
574 aPropSet( lcl_GetSheetLinkMap() ),
578 pDocShell
->GetDocument().AddUnoObject(*this);
581 ScAreaLinkObj::~ScAreaLinkObj()
586 pDocShell
->GetDocument().RemoveUnoObject(*this);
589 void ScAreaLinkObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
591 //! notify if links in document are changed
592 // UpdateRef is not needed here
594 if ( rHint
.GetId() == SfxHintId::ScLinkRefreshed
)
596 auto pRefreshedHint
= static_cast<const ScLinkRefreshedHint
*>(&rHint
);
597 if ( pRefreshedHint
->GetLinkType() == ScLinkRefType::AREA
)
599 // get this link to compare dest position
600 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
601 if ( pLink
&& pLink
->GetDestArea().aStart
== pRefreshedHint
->GetDestPos() )
605 else if ( rHint
.GetId() == SfxHintId::Dying
)
606 pDocShell
= nullptr; // pointer is invalid
611 void ScAreaLinkObj::Modify_Impl( const OUString
* pNewFile
, const OUString
* pNewFilter
,
612 const OUString
* pNewOptions
, const OUString
* pNewSource
,
613 const table::CellRangeAddress
* pNewDest
)
615 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
619 OUString
aFile (pLink
->GetFile());
620 OUString
aFilter (pLink
->GetFilter());
621 OUString
aOptions (pLink
->GetOptions());
622 OUString
aSource (pLink
->GetSource());
623 ScRange
aDest (pLink
->GetDestArea());
624 sal_Int32 nRefreshDelaySeconds
= pLink
->GetRefreshDelaySeconds();
629 sfx2::LinkManager
* pLinkManager
= pDocShell
->GetDocument().GetLinkManager();
630 pLinkManager
->Remove( pLink
);
631 pLink
= nullptr; // deleted along with remove
633 bool bFitBlock
= true; // move, if the size changes with update
636 aFile
= ScGlobal::GetAbsDocName( *pNewFile
, pDocShell
); //! in InsertAreaLink?
639 aFilter
= *pNewFilter
;
641 aOptions
= *pNewOptions
;
643 aSource
= *pNewSource
;
646 ScUnoConversion::FillScRange( aDest
, *pNewDest
);
647 bFitBlock
= false; // new range was specified -> do not move the content
649 pDocShell
->GetDocFunc().InsertAreaLink( aFile
, aFilter
, aOptions
, aSource
,
650 aDest
, nRefreshDelaySeconds
, bFitBlock
, true );
653 void ScAreaLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefreshDelaySeconds
)
655 ScAreaLink
* pLink
= lcl_GetAreaLink( pDocShell
, nPos
);
657 pLink
->SetRefreshDelay( nRefreshDelaySeconds
);
662 void SAL_CALL
ScAreaLinkObj::refresh()
664 SolarMutexGuard aGuard
;
665 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
667 pLink
->Refresh( pLink
->GetFile(), pLink
->GetFilter(), pLink
->GetSource(), pLink
->GetRefreshDelaySeconds() );
670 void SAL_CALL
ScAreaLinkObj::addRefreshListener(
671 const uno::Reference
<util::XRefreshListener
>& xListener
)
673 SolarMutexGuard aGuard
;
674 aRefreshListeners
.push_back( xListener
);
676 // hold one additional ref to keep this object alive as long as there are listeners
677 if ( aRefreshListeners
.size() == 1 )
681 void SAL_CALL
ScAreaLinkObj::removeRefreshListener(
682 const uno::Reference
<util::XRefreshListener
>& xListener
)
684 SolarMutexGuard aGuard
;
685 size_t nCount
= aRefreshListeners
.size();
686 for ( size_t n
=nCount
; n
--; )
688 uno::Reference
<util::XRefreshListener
>& rObj
= aRefreshListeners
[n
];
689 if ( rObj
== xListener
)
691 aRefreshListeners
.erase( aRefreshListeners
.begin() + n
);
692 if ( aRefreshListeners
.empty() )
693 release(); // release ref for listeners
702 void ScAreaLinkObj::Refreshed_Impl()
704 lang::EventObject aEvent
;
705 aEvent
.Source
.set(getXWeak());
706 for (uno::Reference
<util::XRefreshListener
> & xRefreshListener
: aRefreshListeners
)
707 xRefreshListener
->refreshed( aEvent
);
712 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
ScAreaLinkObj::getPropertySetInfo()
714 SolarMutexGuard aGuard
;
715 static uno::Reference
<beans::XPropertySetInfo
> aRef(
716 new SfxItemPropertySetInfo( aPropSet
.getPropertyMap() ));
720 void SAL_CALL
ScAreaLinkObj::setPropertyValue(
721 const OUString
& aPropertyName
, const uno::Any
& aValue
)
723 SolarMutexGuard aGuard
;
725 if ( aPropertyName
== SC_UNONAME_LINKURL
)
727 if ( aValue
>>= aValStr
)
728 setFileName( aValStr
);
730 else if ( aPropertyName
== SC_UNONAME_FILTER
)
732 if ( aValue
>>= aValStr
)
733 setFilter( aValStr
);
735 else if ( aPropertyName
== SC_UNONAME_FILTOPT
)
737 if ( aValue
>>= aValStr
)
738 setFilterOptions( aValStr
);
740 else if ( aPropertyName
== SC_UNONAME_REFPERIOD
)
742 sal_Int32 nRefresh
= 0;
743 if ( aValue
>>= nRefresh
)
744 setRefreshDelay( nRefresh
);
746 else if ( aPropertyName
== SC_UNONAME_REFDELAY
)
748 sal_Int32 nRefresh
= 0;
749 if ( aValue
>>= nRefresh
)
750 setRefreshDelay( nRefresh
);
754 uno::Any SAL_CALL
ScAreaLinkObj::getPropertyValue( const OUString
& aPropertyName
)
756 SolarMutexGuard aGuard
;
758 if ( aPropertyName
== SC_UNONAME_LINKURL
)
759 aRet
<<= getFileName();
760 else if ( aPropertyName
== SC_UNONAME_FILTER
)
761 aRet
<<= getFilter();
762 else if ( aPropertyName
== SC_UNONAME_FILTOPT
)
763 aRet
<<= getFilterOptions();
764 else if ( aPropertyName
== SC_UNONAME_REFPERIOD
)
765 aRet
<<= getRefreshDelay();
766 else if ( aPropertyName
== SC_UNONAME_REFDELAY
)
767 aRet
<<= getRefreshDelay();
771 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAreaLinkObj
)
775 OUString
ScAreaLinkObj::getFileName() const
777 SolarMutexGuard aGuard
;
779 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
781 aRet
= pLink
->GetFile();
785 void ScAreaLinkObj::setFileName(const OUString
& rNewName
)
787 SolarMutexGuard aGuard
;
788 Modify_Impl( &rNewName
, nullptr, nullptr, nullptr, nullptr );
791 OUString
ScAreaLinkObj::getFilter() const
793 SolarMutexGuard aGuard
;
795 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
797 aRet
= pLink
->GetFilter();
801 void ScAreaLinkObj::setFilter(const OUString
& Filter
)
803 SolarMutexGuard aGuard
;
804 Modify_Impl( nullptr, &Filter
, nullptr, nullptr, nullptr );
807 OUString
ScAreaLinkObj::getFilterOptions() const
809 SolarMutexGuard aGuard
;
811 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
813 aRet
= pLink
->GetOptions();
817 void ScAreaLinkObj::setFilterOptions(const OUString
& FilterOptions
)
819 SolarMutexGuard aGuard
;
820 Modify_Impl( nullptr, nullptr, &FilterOptions
, nullptr, nullptr );
823 sal_Int32
ScAreaLinkObj::getRefreshDelay() const
825 SolarMutexGuard aGuard
;
827 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
829 nRet
= pLink
->GetRefreshDelaySeconds();
833 void ScAreaLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay
)
835 SolarMutexGuard aGuard
;
836 ModifyRefreshDelay_Impl( nRefreshDelay
);
841 OUString SAL_CALL
ScAreaLinkObj::getSourceArea()
843 SolarMutexGuard aGuard
;
845 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
847 aRet
= pLink
->GetSource();
851 void SAL_CALL
ScAreaLinkObj::setSourceArea( const OUString
& aSourceArea
)
853 SolarMutexGuard aGuard
;
854 Modify_Impl( nullptr, nullptr, nullptr, &aSourceArea
, nullptr );
857 table::CellRangeAddress SAL_CALL
ScAreaLinkObj::getDestArea()
859 SolarMutexGuard aGuard
;
860 table::CellRangeAddress aRet
;
861 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
863 ScUnoConversion::FillApiRange( aRet
, pLink
->GetDestArea() );
867 void SAL_CALL
ScAreaLinkObj::setDestArea( const table::CellRangeAddress
& aDestArea
)
869 SolarMutexGuard aGuard
;
870 Modify_Impl( nullptr, nullptr, nullptr, nullptr, &aDestArea
);
873 ScAreaLinksObj::ScAreaLinksObj(ScDocShell
* pDocSh
) :
876 pDocShell
->GetDocument().AddUnoObject(*this);
879 ScAreaLinksObj::~ScAreaLinksObj()
884 pDocShell
->GetDocument().RemoveUnoObject(*this);
887 void ScAreaLinksObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
889 // we don't care about update of references here
891 if ( rHint
.GetId() == SfxHintId::Dying
)
893 pDocShell
= nullptr; // became invalid
899 rtl::Reference
<ScAreaLinkObj
> ScAreaLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex
)
901 if ( pDocShell
&& nIndex
>= 0 && nIndex
< getCount() )
902 return new ScAreaLinkObj( pDocShell
, static_cast<size_t>(nIndex
) );
904 return nullptr; // not found
907 void SAL_CALL
ScAreaLinksObj::insertAtPosition( const table::CellAddress
& aDestPos
,
908 const OUString
& aFileName
,
909 const OUString
& aSourceArea
,
910 const OUString
& aFilter
,
911 const OUString
& aFilterOptions
)
913 SolarMutexGuard aGuard
;
916 OUString
aFileStr (aFileName
);
917 ScAddress
aDestAddr( static_cast<SCCOL
>(aDestPos
.Column
), static_cast<SCROW
>(aDestPos
.Row
), aDestPos
.Sheet
);
919 aFileStr
= ScGlobal::GetAbsDocName( aFileStr
, pDocShell
); //! in InsertAreaLink ???
920 pDocShell
->GetDocFunc().InsertAreaLink( aFileStr
, aFilter
, aFilterOptions
,
921 aSourceArea
, ScRange(aDestAddr
),
922 /*nRefreshDelaySeconds*/0, false, true ); // don't move contents
926 void SAL_CALL
ScAreaLinksObj::removeByIndex( sal_Int32 nIndex
)
928 SolarMutexGuard aGuard
;
929 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, static_cast<size_t>(nIndex
));
932 //! SetAddUndo or what
934 sfx2::LinkManager
* pLinkManager
= pDocShell
->GetDocument().GetLinkManager();
935 pLinkManager
->Remove( pLink
);
939 // XEnumerationAccess
941 uno::Reference
<container::XEnumeration
> SAL_CALL
ScAreaLinksObj::createEnumeration()
943 SolarMutexGuard aGuard
;
944 return new ScIndexEnumeration(this, u
"com.sun.star.sheet.CellAreaLinksEnumeration"_ustr
);
949 sal_Int32 SAL_CALL
ScAreaLinksObj::getCount()
951 SolarMutexGuard aGuard
;
952 sal_Int32 nAreaCount
= 0;
955 sfx2::LinkManager
* pLinkManager
= pDocShell
->GetDocument().GetLinkManager();
956 size_t nTotalCount
= pLinkManager
->GetLinks().size();
957 for (size_t i
=0; i
<nTotalCount
; i
++)
959 ::sfx2::SvBaseLink
* pBase
= pLinkManager
->GetLinks()[i
].get();
960 if (dynamic_cast<const ScAreaLink
*>( pBase
) != nullptr)
967 uno::Any SAL_CALL
ScAreaLinksObj::getByIndex( sal_Int32 nIndex
)
969 SolarMutexGuard aGuard
;
970 uno::Reference
<sheet::XAreaLink
> xLink(GetObjectByIndex_Impl(nIndex
));
972 throw lang::IndexOutOfBoundsException();
974 return uno::Any(xLink
);
978 uno::Type SAL_CALL
ScAreaLinksObj::getElementType()
980 return cppu::UnoType
<sheet::XAreaLink
>::get();
983 sal_Bool SAL_CALL
ScAreaLinksObj::hasElements()
985 SolarMutexGuard aGuard
;
986 return ( getCount() != 0 );
989 ScDDELinkObj::ScDDELinkObj(ScDocShell
* pDocSh
, OUString aA
,
990 OUString aT
, OUString aI
) :
992 aAppl(std::move( aA
)),
993 aTopic(std::move( aT
)),
994 aItem(std::move( aI
))
996 pDocShell
->GetDocument().AddUnoObject(*this);
999 ScDDELinkObj::~ScDDELinkObj()
1004 pDocShell
->GetDocument().RemoveUnoObject(*this);
1007 void ScDDELinkObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
1009 //! notify if links in document are changed
1010 // UpdateRef is not needed here
1012 if ( rHint
.GetId() == SfxHintId::ScLinkRefreshed
)
1014 auto pRefreshedHint
= static_cast<const ScLinkRefreshedHint
*>(&rHint
);
1015 if ( pRefreshedHint
->GetLinkType() == ScLinkRefType::DDE
&&
1016 pRefreshedHint
->GetDdeAppl() == aAppl
&&
1017 pRefreshedHint
->GetDdeTopic() == aTopic
&&
1018 pRefreshedHint
->GetDdeItem() == aItem
) //! mode is ignored
1021 else if ( rHint
.GetId() == SfxHintId::Dying
)
1022 pDocShell
= nullptr; // pointer is invalid
1027 static OUString
lcl_BuildDDEName( std::u16string_view rAppl
, std::u16string_view rTopic
, std::u16string_view rItem
)
1029 // Appl|Topic!Item (like Excel)
1030 OUString aRet
= OUString::Concat(rAppl
) + "|" + rTopic
+ "!" + rItem
;
1034 OUString SAL_CALL
ScDDELinkObj::getName()
1036 SolarMutexGuard aGuard
;
1037 return lcl_BuildDDEName( aAppl
, aTopic
, aItem
);
1040 void SAL_CALL
ScDDELinkObj::setName( const OUString
& /* aName */ )
1042 // name can't be changed (formulas wouldn't find the link)
1043 throw uno::RuntimeException();
1048 OUString SAL_CALL
ScDDELinkObj::getApplication()
1050 //! Test if the link is still in the document?
1055 OUString SAL_CALL
ScDDELinkObj::getTopic()
1057 //! Test if the link is still in the document?
1062 OUString SAL_CALL
ScDDELinkObj::getItem()
1064 //! Test if the link is still in the document?
1071 void SAL_CALL
ScDDELinkObj::refresh()
1073 SolarMutexGuard aGuard
;
1076 sc::DocumentLinkManager
& rMgr
= pDocShell
->GetDocument().GetDocLinkManager();
1077 rMgr
.updateDdeLink(aAppl
, aTopic
, aItem
);
1081 void SAL_CALL
ScDDELinkObj::addRefreshListener(
1082 const uno::Reference
<util::XRefreshListener
>& xListener
)
1084 SolarMutexGuard aGuard
;
1085 aRefreshListeners
.push_back( xListener
);
1087 // hold one additional ref to keep this object alive as long as there are listeners
1088 if ( aRefreshListeners
.size() == 1 )
1092 void SAL_CALL
ScDDELinkObj::removeRefreshListener(
1093 const uno::Reference
<util::XRefreshListener
>& xListener
)
1095 SolarMutexGuard aGuard
;
1096 size_t nCount
= aRefreshListeners
.size();
1097 for ( size_t n
=nCount
; n
--; )
1099 uno::Reference
<util::XRefreshListener
>& rObj
= aRefreshListeners
[n
];
1100 if ( rObj
== xListener
)
1102 aRefreshListeners
.erase( aRefreshListeners
.begin() + n
);
1103 if ( aRefreshListeners
.empty() )
1104 release(); // release ref for listeners
1112 uno::Sequence
< uno::Sequence
< uno::Any
> > ScDDELinkObj::getResults( )
1114 SolarMutexGuard aGuard
;
1115 uno::Sequence
< uno::Sequence
< uno::Any
> > aReturn
;
1116 bool bSuccess
= false;
1120 ScDocument
& rDoc
= pDocShell
->GetDocument();
1122 if ( rDoc
.FindDdeLink( aAppl
, aTopic
, aItem
, SC_DDE_IGNOREMODE
, nPos
) )
1124 const ScMatrix
* pMatrix
= rDoc
.GetDdeLinkResultMatrix( nPos
);
1128 if ( ScRangeToSequence::FillMixedArray( aAny
, pMatrix
, true ) )
1139 throw uno::RuntimeException(
1140 u
"ScDDELinkObj::getResults: failed to get results!"_ustr
);
1146 void ScDDELinkObj::setResults( const uno::Sequence
< uno::Sequence
< uno::Any
> >& aResults
)
1148 SolarMutexGuard aGuard
;
1149 bool bSuccess
= false;
1153 ScDocument
& rDoc
= pDocShell
->GetDocument();
1155 if ( rDoc
.FindDdeLink( aAppl
, aTopic
, aItem
, SC_DDE_IGNOREMODE
, nPos
) )
1157 ScMatrixRef xMatrix
= ScSequenceToMatrix::CreateMixedMatrix( Any(aResults
) );
1158 bSuccess
= rDoc
.SetDdeLinkResultMatrix( nPos
, xMatrix
);
1164 throw uno::RuntimeException(
1165 u
"ScDDELinkObj::setResults: failed to set results!"_ustr
);
1169 void ScDDELinkObj::Refreshed_Impl()
1171 lang::EventObject aEvent
;
1172 aEvent
.Source
.set(getXWeak());
1173 for (uno::Reference
<util::XRefreshListener
> & xRefreshListener
: aRefreshListeners
)
1174 xRefreshListener
->refreshed( aEvent
);
1177 ScDDELinksObj::ScDDELinksObj(ScDocShell
* pDocSh
) :
1180 pDocShell
->GetDocument().AddUnoObject(*this);
1183 ScDDELinksObj::~ScDDELinksObj()
1188 pDocShell
->GetDocument().RemoveUnoObject(*this);
1191 void ScDDELinksObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
1193 // we don't care about update of references here
1195 if ( rHint
.GetId() == SfxHintId::Dying
)
1197 pDocShell
= nullptr; // became invalid
1203 rtl::Reference
<ScDDELinkObj
> ScDDELinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex
)
1207 OUString aAppl
, aTopic
, aItem
;
1208 if ( pDocShell
->GetDocument().GetDdeLinkData( static_cast<size_t>(nIndex
), aAppl
, aTopic
, aItem
) )
1209 return new ScDDELinkObj( pDocShell
, aAppl
, aTopic
, aItem
);
1214 rtl::Reference
<ScDDELinkObj
> ScDDELinksObj::GetObjectByName_Impl(std::u16string_view aName
)
1218 OUString aAppl
, aTopic
, aItem
;
1220 ScDocument
& rDoc
= pDocShell
->GetDocument();
1221 size_t nCount
= rDoc
.GetDocLinkManager().getDdeLinkCount();
1222 for (size_t i
=0; i
<nCount
; i
++)
1224 rDoc
.GetDdeLinkData( i
, aAppl
, aTopic
, aItem
);
1225 if ( lcl_BuildDDEName(aAppl
, aTopic
, aItem
) == aName
)
1226 return new ScDDELinkObj( pDocShell
, aAppl
, aTopic
, aItem
);
1232 // XEnumerationAccess
1234 uno::Reference
<container::XEnumeration
> SAL_CALL
ScDDELinksObj::createEnumeration()
1236 SolarMutexGuard aGuard
;
1237 return new ScIndexEnumeration(this, u
"com.sun.star.sheet.DDELinksEnumeration"_ustr
);
1242 sal_Int32 SAL_CALL
ScDDELinksObj::getCount()
1244 SolarMutexGuard aGuard
;
1245 sal_Int32 nAreaCount
= 0;
1247 nAreaCount
= pDocShell
->GetDocument().GetDocLinkManager().getDdeLinkCount();
1251 uno::Any SAL_CALL
ScDDELinksObj::getByIndex( sal_Int32 nIndex
)
1253 SolarMutexGuard aGuard
;
1254 uno::Reference
<sheet::XDDELink
> xLink(GetObjectByIndex_Impl(nIndex
));
1256 throw lang::IndexOutOfBoundsException();
1258 return uno::Any(xLink
);
1261 uno::Type SAL_CALL
ScDDELinksObj::getElementType()
1263 return cppu::UnoType
<sheet::XDDELink
>::get();
1266 sal_Bool SAL_CALL
ScDDELinksObj::hasElements()
1268 SolarMutexGuard aGuard
;
1269 return ( getCount() != 0 );
1272 uno::Any SAL_CALL
ScDDELinksObj::getByName( const OUString
& aName
)
1274 SolarMutexGuard aGuard
;
1275 uno::Reference
<sheet::XDDELink
> xLink(GetObjectByName_Impl(aName
));
1277 throw container::NoSuchElementException();
1279 return uno::Any(xLink
);
1282 uno::Sequence
<OUString
> SAL_CALL
ScDDELinksObj::getElementNames()
1284 SolarMutexGuard aGuard
;
1287 OUString aAppl
, aTopic
, aItem
;
1289 ScDocument
& rDoc
= pDocShell
->GetDocument();
1290 size_t nCount
= pDocShell
->GetDocument().GetDocLinkManager().getDdeLinkCount();
1291 uno::Sequence
<OUString
> aSeq(nCount
);
1292 OUString
* pAry
= aSeq
.getArray();
1294 for (size_t i
=0; i
<nCount
; i
++)
1296 rDoc
.GetDdeLinkData( i
, aAppl
, aTopic
, aItem
);
1297 pAry
[i
] = lcl_BuildDDEName(aAppl
, aTopic
, aItem
);
1301 return uno::Sequence
<OUString
>();
1304 sal_Bool SAL_CALL
ScDDELinksObj::hasByName( const OUString
& aName
)
1306 SolarMutexGuard aGuard
;
1309 OUString aAppl
, aTopic
, aItem
;
1311 ScDocument
& rDoc
= pDocShell
->GetDocument();
1312 size_t nCount
= pDocShell
->GetDocument().GetDocLinkManager().getDdeLinkCount();
1313 for (size_t i
=0; i
<nCount
; i
++)
1315 rDoc
.GetDdeLinkData( i
, aAppl
, aTopic
, aItem
);
1316 if ( lcl_BuildDDEName(aAppl
, aTopic
, aItem
) == aName
)
1325 uno::Reference
< sheet::XDDELink
> ScDDELinksObj::addDDELink(
1326 const OUString
& aApplication
, const OUString
& aTopic
,
1327 const OUString
& aItem
, css::sheet::DDELinkMode nMode
)
1329 SolarMutexGuard aGuard
;
1330 uno::Reference
< sheet::XDDELink
> xLink
;
1334 ScDocument
& rDoc
= pDocShell
->GetDocument();
1335 sal_uInt8 nMod
= SC_DDE_DEFAULT
;
1338 case sheet::DDELinkMode_DEFAULT
:
1340 nMod
= SC_DDE_DEFAULT
;
1343 case sheet::DDELinkMode_ENGLISH
:
1345 nMod
= SC_DDE_ENGLISH
;
1348 case sheet::DDELinkMode_TEXT
:
1359 if ( rDoc
.CreateDdeLink( aApplication
, aTopic
, aItem
, nMod
, ScMatrixRef() ) )
1361 const OUString
aName( lcl_BuildDDEName( aApplication
, aTopic
, aItem
) );
1362 xLink
.set( GetObjectByName_Impl( aName
) );
1368 throw uno::RuntimeException(
1369 u
"ScDDELinksObj::addDDELink: cannot add DDE link!"_ustr
);
1375 ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScDocShell
* pDocShell
, ScExternalRefCache::TableTypeRef pTable
, size_t nIndex
) :
1376 mpDocShell(pDocShell
),
1377 mpTable(std::move(pTable
)),
1382 ScExternalSheetCacheObj::~ScExternalSheetCacheObj()
1386 void SAL_CALL
ScExternalSheetCacheObj::setCellValue(sal_Int32 nCol
, sal_Int32 nRow
, const Any
& rValue
)
1388 SolarMutexGuard aGuard
;
1389 if (nRow
< 0 || nCol
< 0)
1390 throw IllegalArgumentException();
1392 ScExternalRefCache::TokenRef pToken
;
1395 if (rValue
>>= fVal
)
1396 pToken
.reset(new FormulaDoubleToken(fVal
));
1397 else if (rValue
>>= aVal
)
1399 svl::SharedStringPool
& rPool
= mpDocShell
->GetDocument().GetSharedStringPool();
1400 svl::SharedString aSS
= rPool
.intern(aVal
);
1401 pToken
.reset(new FormulaStringToken(std::move(aSS
)));
1404 // unidentified value type.
1407 mpTable
->setCell(static_cast<SCCOL
>(nCol
), static_cast<SCROW
>(nRow
), pToken
);
1410 Any SAL_CALL
ScExternalSheetCacheObj::getCellValue(sal_Int32 nCol
, sal_Int32 nRow
)
1412 SolarMutexGuard aGuard
;
1413 if (nRow
< 0 || nCol
< 0)
1414 throw IllegalArgumentException();
1416 FormulaToken
* pToken
= mpTable
->getCell(static_cast<SCCOL
>(nCol
), static_cast<SCROW
>(nRow
)).get();
1418 throw IllegalArgumentException();
1421 switch (pToken
->GetType())
1425 double fVal
= pToken
->GetDouble();
1431 OUString aVal
= pToken
->GetString().getString();
1436 throw IllegalArgumentException();
1441 Sequence
< sal_Int32
> SAL_CALL
ScExternalSheetCacheObj::getAllRows()
1443 SolarMutexGuard aGuard
;
1444 vector
<SCROW
> aRows
;
1445 mpTable
->getAllRows(aRows
);
1446 size_t nSize
= aRows
.size();
1447 Sequence
<sal_Int32
> aRowsSeq(nSize
);
1448 auto aRowsSeqRange
= asNonConstRange(aRowsSeq
);
1449 for (size_t i
= 0; i
< nSize
; ++i
)
1450 aRowsSeqRange
[i
] = aRows
[i
];
1455 Sequence
< sal_Int32
> SAL_CALL
ScExternalSheetCacheObj::getAllColumns(sal_Int32 nRow
)
1457 SolarMutexGuard aGuard
;
1459 throw IllegalArgumentException();
1461 vector
<SCCOL
> aCols
;
1462 mpTable
->getAllCols(static_cast<SCROW
>(nRow
), aCols
);
1463 size_t nSize
= aCols
.size();
1464 Sequence
<sal_Int32
> aColsSeq(nSize
);
1465 auto aColsSeqRange
= asNonConstRange(aColsSeq
);
1466 for (size_t i
= 0; i
< nSize
; ++i
)
1467 aColsSeqRange
[i
] = aCols
[i
];
1472 sal_Int32 SAL_CALL
ScExternalSheetCacheObj::getTokenIndex()
1474 return static_cast< sal_Int32
>( mnIndex
);
1477 ScExternalDocLinkObj::ScExternalDocLinkObj(ScDocShell
* pDocShell
, ScExternalRefManager
* pRefMgr
, sal_uInt16 nFileId
) :
1478 mpDocShell(pDocShell
), mpRefMgr(pRefMgr
), mnFileId(nFileId
)
1482 ScExternalDocLinkObj::~ScExternalDocLinkObj()
1486 uno::Reference
< sheet::XExternalSheetCache
> SAL_CALL
ScExternalDocLinkObj::addSheetCache(
1487 const OUString
& aSheetName
, sal_Bool bDynamicCache
)
1489 SolarMutexGuard aGuard
;
1491 ScExternalRefCache::TableTypeRef xTable
= mpRefMgr
->getCacheTable(mnFileId
, aSheetName
, true, &nIndex
);
1494 // Set the whole table cached to prevent access to the source document.
1495 xTable
->setWholeTableCached();
1498 uno::Reference
< sheet::XExternalSheetCache
> aSheetCache(new ScExternalSheetCacheObj(
1499 mpDocShell
, std::move(xTable
), nIndex
));
1503 Any SAL_CALL
ScExternalDocLinkObj::getByName(const OUString
&aName
)
1505 SolarMutexGuard aGuard
;
1507 ScExternalRefCache::TableTypeRef xTable
= mpRefMgr
->getCacheTable(mnFileId
, aName
, false, &nIndex
);
1509 throw container::NoSuchElementException();
1511 uno::Reference
< sheet::XExternalSheetCache
> aSheetCache(new ScExternalSheetCacheObj(
1512 mpDocShell
, std::move(xTable
), nIndex
));
1514 return Any(aSheetCache
);
1517 Sequence
< OUString
> SAL_CALL
ScExternalDocLinkObj::getElementNames()
1519 SolarMutexGuard aGuard
;
1520 vector
<OUString
> aTabNames
;
1521 mpRefMgr
->getAllCachedTableNames(mnFileId
, aTabNames
);
1523 // #i116940# be consistent with getByName: include only table names which have a cache already
1524 vector
<OUString
> aValidNames
;
1525 std::copy_if(aTabNames
.begin(), aTabNames
.end(), std::back_inserter(aValidNames
),
1526 [&](const OUString
& rTabName
) { return mpRefMgr
->getCacheTable(mnFileId
, rTabName
, false); });
1528 Sequence
<OUString
> aSeq(comphelper::containerToSequence(aValidNames
));
1532 sal_Bool SAL_CALL
ScExternalDocLinkObj::hasByName(const OUString
&aName
)
1534 SolarMutexGuard aGuard
;
1536 // #i116940# be consistent with getByName: allow only table names which have a cache already
1537 ScExternalRefCache::TableTypeRef pTable
= mpRefMgr
->getCacheTable(mnFileId
, aName
, false);
1538 return bool(pTable
);
1541 sal_Int32 SAL_CALL
ScExternalDocLinkObj::getCount()
1543 SolarMutexGuard aGuard
;
1545 // #i116940# be consistent with getByName: count only table names which have a cache already
1546 return getElementNames().getLength();
1549 Any SAL_CALL
ScExternalDocLinkObj::getByIndex(sal_Int32 nApiIndex
)
1551 SolarMutexGuard aGuard
;
1553 // #i116940# Can't use nApiIndex as index for the ref manager, because the API counts only
1554 // the entries which have a cache already. Quick solution: Use getElementNames.
1555 Sequence
< OUString
> aNames( getElementNames() );
1556 if (nApiIndex
< 0 || nApiIndex
>= aNames
.getLength())
1557 throw lang::IndexOutOfBoundsException();
1560 ScExternalRefCache::TableTypeRef pTable
= mpRefMgr
->getCacheTable(mnFileId
, aNames
[nApiIndex
], false, &nIndex
);
1562 throw lang::IndexOutOfBoundsException();
1564 uno::Reference
< sheet::XExternalSheetCache
> aSheetCache(new ScExternalSheetCacheObj(mpDocShell
, std::move(pTable
), nIndex
));
1566 return Any(aSheetCache
);
1569 uno::Reference
< container::XEnumeration
> SAL_CALL
ScExternalDocLinkObj::createEnumeration()
1571 SolarMutexGuard aGuard
;
1572 uno::Reference
< container::XEnumeration
> aRef(
1573 new ScIndexEnumeration(this, u
"com.sun.star.sheet.ExternalDocLink"_ustr
));
1577 uno::Type SAL_CALL
ScExternalDocLinkObj::getElementType()
1579 return cppu::UnoType
<sheet::XExternalDocLink
>::get();
1582 sal_Bool SAL_CALL
ScExternalDocLinkObj::hasElements()
1584 SolarMutexGuard aGuard
;
1586 // #i116940# be consistent with getByName: count only table names which have a cache already
1587 return getElementNames().hasElements();
1590 sal_Int32 SAL_CALL
ScExternalDocLinkObj::getTokenIndex()
1592 return static_cast<sal_Int32
>(mnFileId
);
1595 ScExternalDocLinksObj::ScExternalDocLinksObj(ScDocShell
* pDocShell
) :
1596 mpDocShell(pDocShell
),
1597 mpRefMgr(pDocShell
->GetDocument().GetExternalRefManager())
1601 ScExternalDocLinksObj::~ScExternalDocLinksObj()
1605 uno::Reference
< sheet::XExternalDocLink
> SAL_CALL
ScExternalDocLinksObj::addDocLink(
1606 const OUString
& aDocName
)
1608 SolarMutexGuard aGuard
;
1609 OUString
aDocUrl( ScGlobal::GetAbsDocName( aDocName
, mpDocShell
));
1610 sal_uInt16 nFileId
= mpRefMgr
->getExternalFileId(aDocUrl
);
1611 uno::Reference
< sheet::XExternalDocLink
> aDocLink(new ScExternalDocLinkObj(mpDocShell
, mpRefMgr
, nFileId
));
1615 Any SAL_CALL
ScExternalDocLinksObj::getByName(const OUString
&aName
)
1617 SolarMutexGuard aGuard
;
1618 OUString
aDocUrl( ScGlobal::GetAbsDocName( aName
, mpDocShell
));
1619 if (!mpRefMgr
->hasExternalFile(aDocUrl
))
1620 throw container::NoSuchElementException();
1622 sal_uInt16 nFileId
= mpRefMgr
->getExternalFileId(aDocUrl
);
1623 uno::Reference
< sheet::XExternalDocLink
> aDocLink(new ScExternalDocLinkObj(mpDocShell
, mpRefMgr
, nFileId
));
1625 return Any(aDocLink
);
1628 Sequence
< OUString
> SAL_CALL
ScExternalDocLinksObj::getElementNames()
1630 SolarMutexGuard aGuard
;
1631 sal_uInt16 n
= mpRefMgr
->getExternalFileCount();
1632 Sequence
<OUString
> aSeq(n
);
1633 auto aSeqRange
= asNonConstRange(aSeq
);
1634 for (sal_uInt16 i
= 0; i
< n
; ++i
)
1636 const OUString
* pName
= mpRefMgr
->getExternalFileName(i
);
1637 aSeqRange
[i
] = pName
? *pName
: OUString();
1643 sal_Bool SAL_CALL
ScExternalDocLinksObj::hasByName(const OUString
&aName
)
1645 SolarMutexGuard aGuard
;
1646 return mpRefMgr
->hasExternalFile(aName
);
1649 sal_Int32 SAL_CALL
ScExternalDocLinksObj::getCount()
1651 SolarMutexGuard aGuard
;
1652 return mpRefMgr
->getExternalFileCount();
1655 Any SAL_CALL
ScExternalDocLinksObj::getByIndex(sal_Int32 nIndex
)
1657 SolarMutexGuard aGuard
;
1658 if (nIndex
> ::std::numeric_limits
<sal_uInt16
>::max() || nIndex
< ::std::numeric_limits
<sal_uInt16
>::min())
1659 throw lang::IndexOutOfBoundsException();
1661 sal_uInt16 nFileId
= static_cast<sal_uInt16
>(nIndex
);
1663 if (!mpRefMgr
->hasExternalFile(nFileId
))
1664 throw lang::IndexOutOfBoundsException();
1666 uno::Reference
< sheet::XExternalDocLink
> aDocLink(new ScExternalDocLinkObj(mpDocShell
, mpRefMgr
, nFileId
));
1667 return Any(aDocLink
);
1670 uno::Reference
< container::XEnumeration
> SAL_CALL
ScExternalDocLinksObj::createEnumeration()
1672 SolarMutexGuard aGuard
;
1673 uno::Reference
< container::XEnumeration
> aRef(
1674 new ScIndexEnumeration(this, u
"com.sun.star.sheet.ExternalDocLinks"_ustr
));
1678 uno::Type SAL_CALL
ScExternalDocLinksObj::getElementType()
1680 return cppu::UnoType
<sheet::XExternalDocLinks
>::get();
1683 sal_Bool SAL_CALL
ScExternalDocLinksObj::hasElements()
1685 SolarMutexGuard aGuard
;
1686 return mpRefMgr
->getExternalFileCount() > 0;
1689 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */