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 o3tl::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
, "ScAreaLinkObj", "com.sun.star.sheet.CellAreaLink" )
70 SC_SIMPLE_SERVICE_INFO( ScAreaLinksObj
, "ScAreaLinksObj", "com.sun.star.sheet.CellAreaLinks" )
71 SC_SIMPLE_SERVICE_INFO( ScDDELinkObj
, "ScDDELinkObj", "com.sun.star.sheet.DDELink" )
72 SC_SIMPLE_SERVICE_INFO( ScDDELinksObj
, "ScDDELinksObj", "com.sun.star.sheet.DDELinks" )
73 SC_SIMPLE_SERVICE_INFO( ScSheetLinkObj
, "ScSheetLinkObj", "com.sun.star.sheet.SheetLink" )
74 SC_SIMPLE_SERVICE_INFO( ScSheetLinksObj
, "ScSheetLinksObj", "com.sun.star.sheet.SheetLinks" )
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 ( auto pRefreshHint
= dynamic_cast<const ScLinkRefreshedHint
*>(&rHint
) )
99 if ( pRefreshHint
->GetLinkType() == ScLinkRefType::SHEET
&& pRefreshHint
->GetUrl() == aFileName
)
104 if ( rHint
.GetId() == SfxHintId::Dying
)
105 pDocShell
= nullptr; // pointer is invalid
109 ScTableLink
* ScSheetLinkObj::GetLink_Impl() const
113 sfx2::LinkManager
* pLinkManager
= pDocShell
->GetDocument().GetLinkManager();
114 size_t nCount
= pLinkManager
->GetLinks().size();
115 for (size_t i
=0; i
<nCount
; i
++)
117 ::sfx2::SvBaseLink
* pBase
= pLinkManager
->GetLinks()[i
].get();
118 if (auto pTabLink
= dynamic_cast<ScTableLink
*>( pBase
))
120 if ( pTabLink
->GetFileName() == aFileName
)
125 return nullptr; // not found
130 OUString SAL_CALL
ScSheetLinkObj::getName()
132 SolarMutexGuard aGuard
;
133 return getFileName(); // Name is the same as filename (URL)
136 void SAL_CALL
ScSheetLinkObj::setName( const OUString
& aName
)
138 SolarMutexGuard aGuard
;
139 setFileName(aName
); // Name is the same as filename (URL)
144 void SAL_CALL
ScSheetLinkObj::refresh()
146 SolarMutexGuard aGuard
;
147 ScTableLink
* pLink
= GetLink_Impl();
149 pLink
->Refresh( pLink
->GetFileName(), pLink
->GetFilterName(), nullptr, pLink
->GetRefreshDelaySeconds() );
152 void SAL_CALL
ScSheetLinkObj::addRefreshListener(
153 const uno::Reference
<util::XRefreshListener
>& xListener
)
155 SolarMutexGuard aGuard
;
156 aRefreshListeners
.push_back( xListener
);
158 // hold one additional ref to keep this object alive as long as there are listeners
159 if ( aRefreshListeners
.size() == 1 )
163 void SAL_CALL
ScSheetLinkObj::removeRefreshListener(
164 const uno::Reference
<util::XRefreshListener
>& xListener
)
166 SolarMutexGuard aGuard
;
167 size_t nCount
= aRefreshListeners
.size();
168 for ( size_t n
=nCount
; n
--; )
170 uno::Reference
<util::XRefreshListener
>& rObj
= aRefreshListeners
[n
];
171 if ( rObj
== xListener
)
173 aRefreshListeners
.erase( aRefreshListeners
.begin() + n
);
174 if ( aRefreshListeners
.empty() )
175 release(); // release ref for listeners
181 void ScSheetLinkObj::Refreshed_Impl()
183 lang::EventObject aEvent
;
184 aEvent
.Source
.set(static_cast<cppu::OWeakObject
*>(this));
185 for (uno::Reference
<util::XRefreshListener
> & xRefreshListener
: aRefreshListeners
)
186 xRefreshListener
->refreshed( aEvent
);
189 void ScSheetLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh
)
191 ScTableLink
* pLink
= GetLink_Impl();
193 pLink
->SetRefreshDelay( static_cast<sal_uLong
>(nRefresh
) );
198 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
ScSheetLinkObj::getPropertySetInfo()
200 SolarMutexGuard aGuard
;
201 static uno::Reference
<beans::XPropertySetInfo
> aRef(
202 new SfxItemPropertySetInfo( aPropSet
.getPropertyMap() ));
206 void SAL_CALL
ScSheetLinkObj::setPropertyValue(
207 const OUString
& aPropertyName
, const uno::Any
& aValue
)
209 SolarMutexGuard aGuard
;
211 if ( aPropertyName
== SC_UNONAME_LINKURL
)
213 if ( aValue
>>= aValStr
)
214 setFileName( aValStr
);
216 else if ( aPropertyName
== SC_UNONAME_FILTER
)
218 if ( aValue
>>= aValStr
)
219 setFilter( aValStr
);
221 else if ( aPropertyName
== SC_UNONAME_FILTOPT
)
223 if ( aValue
>>= aValStr
)
224 setFilterOptions( aValStr
);
226 else if ( aPropertyName
== SC_UNONAME_REFPERIOD
)
228 sal_Int32 nRefresh
= 0;
229 if ( aValue
>>= nRefresh
)
230 setRefreshDelay( nRefresh
);
232 else if ( aPropertyName
== SC_UNONAME_REFDELAY
)
234 sal_Int32 nRefresh
= 0;
235 if ( aValue
>>= nRefresh
)
236 setRefreshDelay( nRefresh
);
240 uno::Any SAL_CALL
ScSheetLinkObj::getPropertyValue( const OUString
& aPropertyName
)
242 SolarMutexGuard aGuard
;
244 if ( aPropertyName
== SC_UNONAME_LINKURL
)
245 aRet
<<= getFileName();
246 else if ( aPropertyName
== SC_UNONAME_FILTER
)
247 aRet
<<= getFilter();
248 else if ( aPropertyName
== SC_UNONAME_FILTOPT
)
249 aRet
<<= getFilterOptions();
250 else if ( aPropertyName
== SC_UNONAME_REFPERIOD
)
251 aRet
<<= getRefreshDelay();
252 else if ( aPropertyName
== SC_UNONAME_REFDELAY
)
253 aRet
<<= getRefreshDelay();
257 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSheetLinkObj
)
261 OUString
ScSheetLinkObj::getFileName() const
263 SolarMutexGuard aGuard
;
267 void ScSheetLinkObj::setFileName(const OUString
& rNewName
)
269 SolarMutexGuard aGuard
;
270 ScTableLink
* pLink
= GetLink_Impl();
274 // pLink->Refresh with a new file name confuses sfx2::LinkManager
275 // therefore we transplant the sheets manually and create new links with UpdateLinks
277 OUString
aNewStr(ScGlobal::GetAbsDocName( rNewName
, pDocShell
));
279 // first transplant the sheets
281 ScDocument
& rDoc
= pDocShell
->GetDocument();
282 SCTAB nTabCount
= rDoc
.GetTableCount();
283 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
284 if ( rDoc
.IsLinked(nTab
) && rDoc
.GetLinkDoc(nTab
) == aFileName
) // old file
285 rDoc
.SetLink( nTab
, rDoc
.GetLinkMode(nTab
), aNewStr
,
286 rDoc
.GetLinkFlt(nTab
), rDoc
.GetLinkOpt(nTab
),
287 rDoc
.GetLinkTab(nTab
),
288 rDoc
.GetLinkRefreshDelay(nTab
) ); // only change the file
293 pDocShell
->UpdateLinks(); // remove old links, possibly set up new ones
298 pLink
= GetLink_Impl(); // new link with new name
300 pLink
->Update(); // incl. paint & undo for data
303 OUString
ScSheetLinkObj::getFilter() const
305 SolarMutexGuard aGuard
;
307 ScTableLink
* pLink
= GetLink_Impl();
309 aRet
= pLink
->GetFilterName();
313 void ScSheetLinkObj::setFilter(const OUString
& rFilter
)
315 SolarMutexGuard aGuard
;
316 ScTableLink
* pLink
= GetLink_Impl();
319 pLink
->Refresh( aFileName
, rFilter
, nullptr, pLink
->GetRefreshDelaySeconds() );
323 OUString
ScSheetLinkObj::getFilterOptions() const
325 SolarMutexGuard aGuard
;
327 ScTableLink
* pLink
= GetLink_Impl();
329 aRet
= pLink
->GetOptions();
333 void ScSheetLinkObj::setFilterOptions(const OUString
& FilterOptions
)
335 SolarMutexGuard aGuard
;
336 ScTableLink
* pLink
= GetLink_Impl();
339 OUString
aOptStr(FilterOptions
);
340 pLink
->Refresh( aFileName
, pLink
->GetFilterName(), &aOptStr
, pLink
->GetRefreshDelaySeconds() );
344 sal_Int32
ScSheetLinkObj::getRefreshDelay() const
346 SolarMutexGuard aGuard
;
348 ScTableLink
* pLink
= GetLink_Impl();
350 nRet
= pLink
->GetRefreshDelaySeconds();
354 void ScSheetLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay
)
356 SolarMutexGuard aGuard
;
357 ModifyRefreshDelay_Impl( nRefreshDelay
);
360 ScSheetLinksObj::ScSheetLinksObj(ScDocShell
* pDocSh
) :
363 pDocShell
->GetDocument().AddUnoObject(*this);
366 ScSheetLinksObj::~ScSheetLinksObj()
371 pDocShell
->GetDocument().RemoveUnoObject(*this);
374 void ScSheetLinksObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
376 // we don't care about update of references here
378 if ( rHint
.GetId() == SfxHintId::Dying
)
380 pDocShell
= nullptr; // became invalid
386 rtl::Reference
<ScSheetLinkObj
> ScSheetLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex
)
391 typedef std::unordered_set
<OUString
> StrSetType
;
393 ScDocument
& rDoc
= pDocShell
->GetDocument();
394 SCTAB nTabCount
= rDoc
.GetTableCount();
395 sal_Int32 nCount
= 0;
396 for (SCTAB nTab
= 0; nTab
< nTabCount
; ++nTab
)
398 if (!rDoc
.IsLinked(nTab
))
401 OUString aLinkDoc
= rDoc
.GetLinkDoc(nTab
);
402 if (aNames
.insert(aLinkDoc
).second
)
404 // unique document name.
405 if (nCount
== nIndex
)
406 return new ScSheetLinkObj( pDocShell
, aLinkDoc
);
411 return nullptr; // no document or index too large
414 rtl::Reference
<ScSheetLinkObj
> ScSheetLinksObj::GetObjectByName_Impl(const OUString
& aName
)
416 // Name is the same as file name
420 ScDocument
& rDoc
= pDocShell
->GetDocument();
421 SCTAB nTabCount
= rDoc
.GetTableCount();
422 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
423 if (rDoc
.IsLinked(nTab
))
425 //! case-insensitive ???
426 OUString aLinkDoc
= rDoc
.GetLinkDoc( nTab
);
427 if ( aLinkDoc
== aName
)
428 return new ScSheetLinkObj( pDocShell
, aName
);
435 // XEnumerationAccess
436 uno::Reference
<container::XEnumeration
> SAL_CALL
ScSheetLinksObj::createEnumeration()
438 SolarMutexGuard aGuard
;
439 return new ScIndexEnumeration(this, "com.sun.star.sheet.SheetLinksEnumeration");
443 sal_Int32 SAL_CALL
ScSheetLinksObj::getCount()
445 typedef std::unordered_set
<OUString
> StrSetType
;
447 SolarMutexGuard aGuard
;
451 sal_Int32 nCount
= 0;
454 ScDocument
& rDoc
= pDocShell
->GetDocument();
455 SCTAB nTabCount
= rDoc
.GetTableCount();
456 for (SCTAB nTab
= 0; nTab
< nTabCount
; ++nTab
)
458 if (!rDoc
.IsLinked(nTab
))
461 OUString aLinkDoc
= rDoc
.GetLinkDoc(nTab
);
462 if (aNames
.insert(aLinkDoc
).second
)
468 uno::Any SAL_CALL
ScSheetLinksObj::getByIndex( sal_Int32 nIndex
)
470 SolarMutexGuard aGuard
;
471 uno::Reference
<beans::XPropertySet
> xLink(GetObjectByIndex_Impl(nIndex
));
473 throw lang::IndexOutOfBoundsException();
475 return uno::Any(xLink
);
478 uno::Type SAL_CALL
ScSheetLinksObj::getElementType()
480 return cppu::UnoType
<beans::XPropertySet
>::get();
483 sal_Bool SAL_CALL
ScSheetLinksObj::hasElements()
485 SolarMutexGuard aGuard
;
486 return ( getCount() != 0 );
489 uno::Any SAL_CALL
ScSheetLinksObj::getByName( const OUString
& aName
)
491 SolarMutexGuard aGuard
;
492 uno::Reference
<beans::XPropertySet
> xLink(GetObjectByName_Impl(aName
));
494 throw container::NoSuchElementException();
496 return uno::Any(xLink
);
499 sal_Bool SAL_CALL
ScSheetLinksObj::hasByName( const OUString
& aName
)
501 SolarMutexGuard aGuard
;
502 // Name is the same as file name
506 ScDocument
& rDoc
= pDocShell
->GetDocument();
507 SCTAB nTabCount
= rDoc
.GetTableCount();
508 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
509 if (rDoc
.IsLinked(nTab
))
511 //! case-insensitive ???
512 OUString
aLinkDoc(rDoc
.GetLinkDoc( nTab
));
513 if ( aLinkDoc
== aName
)
520 uno::Sequence
<OUString
> SAL_CALL
ScSheetLinksObj::getElementNames()
522 typedef std::unordered_set
<OUString
> StrSetType
;
524 SolarMutexGuard aGuard
;
525 // Name is the same as file name
528 return uno::Sequence
<OUString
>();
531 ScDocument
& rDoc
= pDocShell
->GetDocument();
532 SCTAB nTabCount
= rDoc
.GetTableCount();
534 sal_Int32 nLinkCount
= getCount();
535 uno::Sequence
<OUString
> aSeq(nLinkCount
);
536 OUString
* pAry
= aSeq
.getArray();
538 for (SCTAB nTab
= 0; nTab
< nTabCount
; ++nTab
)
540 if (!rDoc
.IsLinked(nTab
))
543 OUString aLinkDoc
= rDoc
.GetLinkDoc(nTab
);
544 if (aNames
.insert(aLinkDoc
).second
)
545 pAry
[nPos
++] = aLinkDoc
;
547 OSL_ENSURE( nPos
==static_cast<size_t>(nLinkCount
), "verzaehlt" );
551 static ScAreaLink
* lcl_GetAreaLink( ScDocShell
* pDocShell
, size_t nPos
)
555 sfx2::LinkManager
* pLinkManager
= pDocShell
->GetDocument().GetLinkManager();
556 size_t nTotalCount
= pLinkManager
->GetLinks().size();
557 size_t nAreaCount
= 0;
558 for (size_t i
=0; i
<nTotalCount
; i
++)
560 ::sfx2::SvBaseLink
* pBase
= pLinkManager
->GetLinks()[i
].get();
561 if (auto pAreaLink
= dynamic_cast<ScAreaLink
*>( pBase
))
563 if ( nAreaCount
== nPos
)
569 return nullptr; // not found
572 ScAreaLinkObj::ScAreaLinkObj(ScDocShell
* pDocSh
, size_t nP
) :
573 aPropSet( lcl_GetSheetLinkMap() ),
577 pDocShell
->GetDocument().AddUnoObject(*this);
580 ScAreaLinkObj::~ScAreaLinkObj()
585 pDocShell
->GetDocument().RemoveUnoObject(*this);
588 void ScAreaLinkObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
590 //! notify if links in document are changed
591 // UpdateRef is not needed here
593 if ( auto pRefreshedHint
= dynamic_cast<const ScLinkRefreshedHint
*>(&rHint
) )
595 if ( pRefreshedHint
->GetLinkType() == ScLinkRefType::AREA
)
597 // get this link to compare dest position
598 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
599 if ( pLink
&& pLink
->GetDestArea().aStart
== pRefreshedHint
->GetDestPos() )
605 if ( rHint
.GetId() == SfxHintId::Dying
)
606 pDocShell
= nullptr; // pointer is invalid
612 void ScAreaLinkObj::Modify_Impl( const OUString
* pNewFile
, const OUString
* pNewFilter
,
613 const OUString
* pNewOptions
, const OUString
* pNewSource
,
614 const table::CellRangeAddress
* pNewDest
)
616 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
620 OUString
aFile (pLink
->GetFile());
621 OUString
aFilter (pLink
->GetFilter());
622 OUString
aOptions (pLink
->GetOptions());
623 OUString
aSource (pLink
->GetSource());
624 ScRange
aDest (pLink
->GetDestArea());
625 sal_Int32 nRefreshDelaySeconds
= pLink
->GetRefreshDelaySeconds();
630 sfx2::LinkManager
* pLinkManager
= pDocShell
->GetDocument().GetLinkManager();
631 pLinkManager
->Remove( pLink
);
632 pLink
= nullptr; // deleted along with remove
634 bool bFitBlock
= true; // move, if the size changes with update
637 aFile
= ScGlobal::GetAbsDocName( *pNewFile
, pDocShell
); //! in InsertAreaLink?
640 aFilter
= *pNewFilter
;
642 aOptions
= *pNewOptions
;
644 aSource
= *pNewSource
;
647 ScUnoConversion::FillScRange( aDest
, *pNewDest
);
648 bFitBlock
= false; // new range was specified -> do not move the content
650 pDocShell
->GetDocFunc().InsertAreaLink( aFile
, aFilter
, aOptions
, aSource
,
651 aDest
, nRefreshDelaySeconds
, bFitBlock
, true );
654 void ScAreaLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefreshDelaySeconds
)
656 ScAreaLink
* pLink
= lcl_GetAreaLink( pDocShell
, nPos
);
658 pLink
->SetRefreshDelay( nRefreshDelaySeconds
);
663 void SAL_CALL
ScAreaLinkObj::refresh()
665 SolarMutexGuard aGuard
;
666 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
668 pLink
->Refresh( pLink
->GetFile(), pLink
->GetFilter(), pLink
->GetSource(), pLink
->GetRefreshDelaySeconds() );
671 void SAL_CALL
ScAreaLinkObj::addRefreshListener(
672 const uno::Reference
<util::XRefreshListener
>& xListener
)
674 SolarMutexGuard aGuard
;
675 aRefreshListeners
.push_back( xListener
);
677 // hold one additional ref to keep this object alive as long as there are listeners
678 if ( aRefreshListeners
.size() == 1 )
682 void SAL_CALL
ScAreaLinkObj::removeRefreshListener(
683 const uno::Reference
<util::XRefreshListener
>& xListener
)
685 SolarMutexGuard aGuard
;
686 size_t nCount
= aRefreshListeners
.size();
687 for ( size_t n
=nCount
; n
--; )
689 uno::Reference
<util::XRefreshListener
>& rObj
= aRefreshListeners
[n
];
690 if ( rObj
== xListener
)
692 aRefreshListeners
.erase( aRefreshListeners
.begin() + n
);
693 if ( aRefreshListeners
.empty() )
694 release(); // release ref for listeners
703 void ScAreaLinkObj::Refreshed_Impl()
705 lang::EventObject aEvent
;
706 aEvent
.Source
.set(static_cast<cppu::OWeakObject
*>(this));
707 for (uno::Reference
<util::XRefreshListener
> & xRefreshListener
: aRefreshListeners
)
708 xRefreshListener
->refreshed( aEvent
);
713 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
ScAreaLinkObj::getPropertySetInfo()
715 SolarMutexGuard aGuard
;
716 static uno::Reference
<beans::XPropertySetInfo
> aRef(
717 new SfxItemPropertySetInfo( aPropSet
.getPropertyMap() ));
721 void SAL_CALL
ScAreaLinkObj::setPropertyValue(
722 const OUString
& aPropertyName
, const uno::Any
& aValue
)
724 SolarMutexGuard aGuard
;
726 if ( aPropertyName
== SC_UNONAME_LINKURL
)
728 if ( aValue
>>= aValStr
)
729 setFileName( aValStr
);
731 else if ( aPropertyName
== SC_UNONAME_FILTER
)
733 if ( aValue
>>= aValStr
)
734 setFilter( aValStr
);
736 else if ( aPropertyName
== SC_UNONAME_FILTOPT
)
738 if ( aValue
>>= aValStr
)
739 setFilterOptions( aValStr
);
741 else if ( aPropertyName
== SC_UNONAME_REFPERIOD
)
743 sal_Int32 nRefresh
= 0;
744 if ( aValue
>>= nRefresh
)
745 setRefreshDelay( nRefresh
);
747 else if ( aPropertyName
== SC_UNONAME_REFDELAY
)
749 sal_Int32 nRefresh
= 0;
750 if ( aValue
>>= nRefresh
)
751 setRefreshDelay( nRefresh
);
755 uno::Any SAL_CALL
ScAreaLinkObj::getPropertyValue( const OUString
& aPropertyName
)
757 SolarMutexGuard aGuard
;
759 if ( aPropertyName
== SC_UNONAME_LINKURL
)
760 aRet
<<= getFileName();
761 else if ( aPropertyName
== SC_UNONAME_FILTER
)
762 aRet
<<= getFilter();
763 else if ( aPropertyName
== SC_UNONAME_FILTOPT
)
764 aRet
<<= getFilterOptions();
765 else if ( aPropertyName
== SC_UNONAME_REFPERIOD
)
766 aRet
<<= getRefreshDelay();
767 else if ( aPropertyName
== SC_UNONAME_REFDELAY
)
768 aRet
<<= getRefreshDelay();
772 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAreaLinkObj
)
776 OUString
ScAreaLinkObj::getFileName() const
778 SolarMutexGuard aGuard
;
780 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
782 aRet
= pLink
->GetFile();
786 void ScAreaLinkObj::setFileName(const OUString
& rNewName
)
788 SolarMutexGuard aGuard
;
789 Modify_Impl( &rNewName
, nullptr, nullptr, nullptr, nullptr );
792 OUString
ScAreaLinkObj::getFilter() const
794 SolarMutexGuard aGuard
;
796 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
798 aRet
= pLink
->GetFilter();
802 void ScAreaLinkObj::setFilter(const OUString
& Filter
)
804 SolarMutexGuard aGuard
;
805 Modify_Impl( nullptr, &Filter
, nullptr, nullptr, nullptr );
808 OUString
ScAreaLinkObj::getFilterOptions() const
810 SolarMutexGuard aGuard
;
812 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
814 aRet
= pLink
->GetOptions();
818 void ScAreaLinkObj::setFilterOptions(const OUString
& FilterOptions
)
820 SolarMutexGuard aGuard
;
821 Modify_Impl( nullptr, nullptr, &FilterOptions
, nullptr, nullptr );
824 sal_Int32
ScAreaLinkObj::getRefreshDelay() const
826 SolarMutexGuard aGuard
;
828 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
830 nRet
= pLink
->GetRefreshDelaySeconds();
834 void ScAreaLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay
)
836 SolarMutexGuard aGuard
;
837 ModifyRefreshDelay_Impl( nRefreshDelay
);
842 OUString SAL_CALL
ScAreaLinkObj::getSourceArea()
844 SolarMutexGuard aGuard
;
846 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
848 aRet
= pLink
->GetSource();
852 void SAL_CALL
ScAreaLinkObj::setSourceArea( const OUString
& aSourceArea
)
854 SolarMutexGuard aGuard
;
855 Modify_Impl( nullptr, nullptr, nullptr, &aSourceArea
, nullptr );
858 table::CellRangeAddress SAL_CALL
ScAreaLinkObj::getDestArea()
860 SolarMutexGuard aGuard
;
861 table::CellRangeAddress aRet
;
862 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, nPos
);
864 ScUnoConversion::FillApiRange( aRet
, pLink
->GetDestArea() );
868 void SAL_CALL
ScAreaLinkObj::setDestArea( const table::CellRangeAddress
& aDestArea
)
870 SolarMutexGuard aGuard
;
871 Modify_Impl( nullptr, nullptr, nullptr, nullptr, &aDestArea
);
874 ScAreaLinksObj::ScAreaLinksObj(ScDocShell
* pDocSh
) :
877 pDocShell
->GetDocument().AddUnoObject(*this);
880 ScAreaLinksObj::~ScAreaLinksObj()
885 pDocShell
->GetDocument().RemoveUnoObject(*this);
888 void ScAreaLinksObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
890 // we don't care about update of references here
892 if ( rHint
.GetId() == SfxHintId::Dying
)
894 pDocShell
= nullptr; // became invalid
900 rtl::Reference
<ScAreaLinkObj
> ScAreaLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex
)
902 if ( pDocShell
&& nIndex
>= 0 && nIndex
< getCount() )
903 return new ScAreaLinkObj( pDocShell
, static_cast<size_t>(nIndex
) );
905 return nullptr; // not found
908 void SAL_CALL
ScAreaLinksObj::insertAtPosition( const table::CellAddress
& aDestPos
,
909 const OUString
& aFileName
,
910 const OUString
& aSourceArea
,
911 const OUString
& aFilter
,
912 const OUString
& aFilterOptions
)
914 SolarMutexGuard aGuard
;
917 OUString
aFileStr (aFileName
);
918 ScAddress
aDestAddr( static_cast<SCCOL
>(aDestPos
.Column
), static_cast<SCROW
>(aDestPos
.Row
), aDestPos
.Sheet
);
920 aFileStr
= ScGlobal::GetAbsDocName( aFileStr
, pDocShell
); //! in InsertAreaLink ???
921 pDocShell
->GetDocFunc().InsertAreaLink( aFileStr
, aFilter
, aFilterOptions
,
922 aSourceArea
, ScRange(aDestAddr
),
923 /*nRefreshDelaySeconds*/0, false, true ); // don't move contents
927 void SAL_CALL
ScAreaLinksObj::removeByIndex( sal_Int32 nIndex
)
929 SolarMutexGuard aGuard
;
930 ScAreaLink
* pLink
= lcl_GetAreaLink(pDocShell
, static_cast<size_t>(nIndex
));
933 //! SetAddUndo or what
935 sfx2::LinkManager
* pLinkManager
= pDocShell
->GetDocument().GetLinkManager();
936 pLinkManager
->Remove( pLink
);
940 // XEnumerationAccess
942 uno::Reference
<container::XEnumeration
> SAL_CALL
ScAreaLinksObj::createEnumeration()
944 SolarMutexGuard aGuard
;
945 return new ScIndexEnumeration(this, "com.sun.star.sheet.CellAreaLinksEnumeration");
950 sal_Int32 SAL_CALL
ScAreaLinksObj::getCount()
952 SolarMutexGuard aGuard
;
953 sal_Int32 nAreaCount
= 0;
956 sfx2::LinkManager
* pLinkManager
= pDocShell
->GetDocument().GetLinkManager();
957 size_t nTotalCount
= pLinkManager
->GetLinks().size();
958 for (size_t i
=0; i
<nTotalCount
; i
++)
960 ::sfx2::SvBaseLink
* pBase
= pLinkManager
->GetLinks()[i
].get();
961 if (dynamic_cast<const ScAreaLink
*>( pBase
) != nullptr)
968 uno::Any SAL_CALL
ScAreaLinksObj::getByIndex( sal_Int32 nIndex
)
970 SolarMutexGuard aGuard
;
971 uno::Reference
<sheet::XAreaLink
> xLink(GetObjectByIndex_Impl(nIndex
));
973 throw lang::IndexOutOfBoundsException();
975 return uno::Any(xLink
);
979 uno::Type SAL_CALL
ScAreaLinksObj::getElementType()
981 return cppu::UnoType
<sheet::XAreaLink
>::get();
984 sal_Bool SAL_CALL
ScAreaLinksObj::hasElements()
986 SolarMutexGuard aGuard
;
987 return ( getCount() != 0 );
990 ScDDELinkObj::ScDDELinkObj(ScDocShell
* pDocSh
, OUString aA
,
991 OUString aT
, OUString aI
) :
993 aAppl(std::move( aA
)),
994 aTopic(std::move( aT
)),
995 aItem(std::move( aI
))
997 pDocShell
->GetDocument().AddUnoObject(*this);
1000 ScDDELinkObj::~ScDDELinkObj()
1005 pDocShell
->GetDocument().RemoveUnoObject(*this);
1008 void ScDDELinkObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
1010 //! notify if links in document are changed
1011 // UpdateRef is not needed here
1013 if ( auto pRefreshedHint
= dynamic_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
1023 if ( rHint
.GetId() == SfxHintId::Dying
)
1024 pDocShell
= nullptr; // pointer is invalid
1030 static OUString
lcl_BuildDDEName( std::u16string_view rAppl
, std::u16string_view rTopic
, std::u16string_view rItem
)
1032 // Appl|Topic!Item (like Excel)
1033 OUString aRet
= OUString::Concat(rAppl
) + "|" + rTopic
+ "!" + rItem
;
1037 OUString SAL_CALL
ScDDELinkObj::getName()
1039 SolarMutexGuard aGuard
;
1040 return lcl_BuildDDEName( aAppl
, aTopic
, aItem
);
1043 void SAL_CALL
ScDDELinkObj::setName( const OUString
& /* aName */ )
1045 // name can't be changed (formulas wouldn't find the link)
1046 throw uno::RuntimeException();
1051 OUString SAL_CALL
ScDDELinkObj::getApplication()
1053 SolarMutexGuard aGuard
;
1054 //! Test if the link is still in the document?
1059 OUString SAL_CALL
ScDDELinkObj::getTopic()
1061 SolarMutexGuard aGuard
;
1062 //! Test if the link is still in the document?
1067 OUString SAL_CALL
ScDDELinkObj::getItem()
1069 SolarMutexGuard aGuard
;
1070 //! Test if the link is still in the document?
1077 void SAL_CALL
ScDDELinkObj::refresh()
1079 SolarMutexGuard aGuard
;
1082 sc::DocumentLinkManager
& rMgr
= pDocShell
->GetDocument().GetDocLinkManager();
1083 rMgr
.updateDdeLink(aAppl
, aTopic
, aItem
);
1087 void SAL_CALL
ScDDELinkObj::addRefreshListener(
1088 const uno::Reference
<util::XRefreshListener
>& xListener
)
1090 SolarMutexGuard aGuard
;
1091 aRefreshListeners
.push_back( xListener
);
1093 // hold one additional ref to keep this object alive as long as there are listeners
1094 if ( aRefreshListeners
.size() == 1 )
1098 void SAL_CALL
ScDDELinkObj::removeRefreshListener(
1099 const uno::Reference
<util::XRefreshListener
>& xListener
)
1101 SolarMutexGuard aGuard
;
1102 size_t nCount
= aRefreshListeners
.size();
1103 for ( size_t n
=nCount
; n
--; )
1105 uno::Reference
<util::XRefreshListener
>& rObj
= aRefreshListeners
[n
];
1106 if ( rObj
== xListener
)
1108 aRefreshListeners
.erase( aRefreshListeners
.begin() + n
);
1109 if ( aRefreshListeners
.empty() )
1110 release(); // release ref for listeners
1118 uno::Sequence
< uno::Sequence
< uno::Any
> > ScDDELinkObj::getResults( )
1120 SolarMutexGuard aGuard
;
1121 uno::Sequence
< uno::Sequence
< uno::Any
> > aReturn
;
1122 bool bSuccess
= false;
1126 ScDocument
& rDoc
= pDocShell
->GetDocument();
1128 if ( rDoc
.FindDdeLink( aAppl
, aTopic
, aItem
, SC_DDE_IGNOREMODE
, nPos
) )
1130 const ScMatrix
* pMatrix
= rDoc
.GetDdeLinkResultMatrix( nPos
);
1134 if ( ScRangeToSequence::FillMixedArray( aAny
, pMatrix
, true ) )
1145 throw uno::RuntimeException(
1146 "ScDDELinkObj::getResults: failed to get results!" );
1152 void ScDDELinkObj::setResults( const uno::Sequence
< uno::Sequence
< uno::Any
> >& aResults
)
1154 SolarMutexGuard aGuard
;
1155 bool bSuccess
= false;
1159 ScDocument
& rDoc
= pDocShell
->GetDocument();
1161 if ( rDoc
.FindDdeLink( aAppl
, aTopic
, aItem
, SC_DDE_IGNOREMODE
, nPos
) )
1163 ScMatrixRef xMatrix
= ScSequenceToMatrix::CreateMixedMatrix( Any(aResults
) );
1164 bSuccess
= rDoc
.SetDdeLinkResultMatrix( nPos
, xMatrix
);
1170 throw uno::RuntimeException(
1171 "ScDDELinkObj::setResults: failed to set results!" );
1175 void ScDDELinkObj::Refreshed_Impl()
1177 lang::EventObject aEvent
;
1178 aEvent
.Source
.set(static_cast<cppu::OWeakObject
*>(this));
1179 for (uno::Reference
<util::XRefreshListener
> & xRefreshListener
: aRefreshListeners
)
1180 xRefreshListener
->refreshed( aEvent
);
1183 ScDDELinksObj::ScDDELinksObj(ScDocShell
* pDocSh
) :
1186 pDocShell
->GetDocument().AddUnoObject(*this);
1189 ScDDELinksObj::~ScDDELinksObj()
1194 pDocShell
->GetDocument().RemoveUnoObject(*this);
1197 void ScDDELinksObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
1199 // we don't care about update of references here
1201 if ( rHint
.GetId() == SfxHintId::Dying
)
1203 pDocShell
= nullptr; // became invalid
1209 rtl::Reference
<ScDDELinkObj
> ScDDELinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex
)
1213 OUString aAppl
, aTopic
, aItem
;
1214 if ( pDocShell
->GetDocument().GetDdeLinkData( static_cast<size_t>(nIndex
), aAppl
, aTopic
, aItem
) )
1215 return new ScDDELinkObj( pDocShell
, aAppl
, aTopic
, aItem
);
1220 rtl::Reference
<ScDDELinkObj
> ScDDELinksObj::GetObjectByName_Impl(std::u16string_view aName
)
1224 OUString aAppl
, aTopic
, aItem
;
1226 ScDocument
& rDoc
= pDocShell
->GetDocument();
1227 size_t nCount
= rDoc
.GetDocLinkManager().getDdeLinkCount();
1228 for (size_t i
=0; i
<nCount
; i
++)
1230 rDoc
.GetDdeLinkData( i
, aAppl
, aTopic
, aItem
);
1231 if ( lcl_BuildDDEName(aAppl
, aTopic
, aItem
) == aName
)
1232 return new ScDDELinkObj( pDocShell
, aAppl
, aTopic
, aItem
);
1238 // XEnumerationAccess
1240 uno::Reference
<container::XEnumeration
> SAL_CALL
ScDDELinksObj::createEnumeration()
1242 SolarMutexGuard aGuard
;
1243 return new ScIndexEnumeration(this, "com.sun.star.sheet.DDELinksEnumeration");
1248 sal_Int32 SAL_CALL
ScDDELinksObj::getCount()
1250 SolarMutexGuard aGuard
;
1251 sal_Int32 nAreaCount
= 0;
1253 nAreaCount
= pDocShell
->GetDocument().GetDocLinkManager().getDdeLinkCount();
1257 uno::Any SAL_CALL
ScDDELinksObj::getByIndex( sal_Int32 nIndex
)
1259 SolarMutexGuard aGuard
;
1260 uno::Reference
<sheet::XDDELink
> xLink(GetObjectByIndex_Impl(nIndex
));
1262 throw lang::IndexOutOfBoundsException();
1264 return uno::Any(xLink
);
1267 uno::Type SAL_CALL
ScDDELinksObj::getElementType()
1269 return cppu::UnoType
<sheet::XDDELink
>::get();
1272 sal_Bool SAL_CALL
ScDDELinksObj::hasElements()
1274 SolarMutexGuard aGuard
;
1275 return ( getCount() != 0 );
1278 uno::Any SAL_CALL
ScDDELinksObj::getByName( const OUString
& aName
)
1280 SolarMutexGuard aGuard
;
1281 uno::Reference
<sheet::XDDELink
> xLink(GetObjectByName_Impl(aName
));
1283 throw container::NoSuchElementException();
1285 return uno::Any(xLink
);
1288 uno::Sequence
<OUString
> SAL_CALL
ScDDELinksObj::getElementNames()
1290 SolarMutexGuard aGuard
;
1293 OUString aAppl
, aTopic
, aItem
;
1295 ScDocument
& rDoc
= pDocShell
->GetDocument();
1296 size_t nCount
= pDocShell
->GetDocument().GetDocLinkManager().getDdeLinkCount();
1297 uno::Sequence
<OUString
> aSeq(nCount
);
1298 OUString
* pAry
= aSeq
.getArray();
1300 for (size_t i
=0; i
<nCount
; i
++)
1302 rDoc
.GetDdeLinkData( i
, aAppl
, aTopic
, aItem
);
1303 pAry
[i
] = lcl_BuildDDEName(aAppl
, aTopic
, aItem
);
1307 return uno::Sequence
<OUString
>();
1310 sal_Bool SAL_CALL
ScDDELinksObj::hasByName( const OUString
& aName
)
1312 SolarMutexGuard aGuard
;
1315 OUString aAppl
, aTopic
, aItem
;
1317 ScDocument
& rDoc
= pDocShell
->GetDocument();
1318 size_t nCount
= pDocShell
->GetDocument().GetDocLinkManager().getDdeLinkCount();
1319 for (size_t i
=0; i
<nCount
; i
++)
1321 rDoc
.GetDdeLinkData( i
, aAppl
, aTopic
, aItem
);
1322 if ( lcl_BuildDDEName(aAppl
, aTopic
, aItem
) == aName
)
1331 uno::Reference
< sheet::XDDELink
> ScDDELinksObj::addDDELink(
1332 const OUString
& aApplication
, const OUString
& aTopic
,
1333 const OUString
& aItem
, css::sheet::DDELinkMode nMode
)
1335 SolarMutexGuard aGuard
;
1336 uno::Reference
< sheet::XDDELink
> xLink
;
1340 ScDocument
& rDoc
= pDocShell
->GetDocument();
1341 sal_uInt8 nMod
= SC_DDE_DEFAULT
;
1344 case sheet::DDELinkMode_DEFAULT
:
1346 nMod
= SC_DDE_DEFAULT
;
1349 case sheet::DDELinkMode_ENGLISH
:
1351 nMod
= SC_DDE_ENGLISH
;
1354 case sheet::DDELinkMode_TEXT
:
1365 if ( rDoc
.CreateDdeLink( aApplication
, aTopic
, aItem
, nMod
, ScMatrixRef() ) )
1367 const OUString
aName( lcl_BuildDDEName( aApplication
, aTopic
, aItem
) );
1368 xLink
.set( GetObjectByName_Impl( aName
) );
1374 throw uno::RuntimeException(
1375 "ScDDELinksObj::addDDELink: cannot add DDE link!" );
1381 ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScDocShell
* pDocShell
, ScExternalRefCache::TableTypeRef pTable
, size_t nIndex
) :
1382 mpDocShell(pDocShell
),
1383 mpTable(std::move(pTable
)),
1388 ScExternalSheetCacheObj::~ScExternalSheetCacheObj()
1392 void SAL_CALL
ScExternalSheetCacheObj::setCellValue(sal_Int32 nCol
, sal_Int32 nRow
, const Any
& rValue
)
1394 SolarMutexGuard aGuard
;
1395 if (nRow
< 0 || nCol
< 0)
1396 throw IllegalArgumentException();
1398 ScExternalRefCache::TokenRef pToken
;
1401 if (rValue
>>= fVal
)
1402 pToken
.reset(new FormulaDoubleToken(fVal
));
1403 else if (rValue
>>= aVal
)
1405 svl::SharedStringPool
& rPool
= mpDocShell
->GetDocument().GetSharedStringPool();
1406 svl::SharedString aSS
= rPool
.intern(aVal
);
1407 pToken
.reset(new FormulaStringToken(std::move(aSS
)));
1410 // unidentified value type.
1413 mpTable
->setCell(static_cast<SCCOL
>(nCol
), static_cast<SCROW
>(nRow
), pToken
);
1416 Any SAL_CALL
ScExternalSheetCacheObj::getCellValue(sal_Int32 nCol
, sal_Int32 nRow
)
1418 SolarMutexGuard aGuard
;
1419 if (nRow
< 0 || nCol
< 0)
1420 throw IllegalArgumentException();
1422 FormulaToken
* pToken
= mpTable
->getCell(static_cast<SCCOL
>(nCol
), static_cast<SCROW
>(nRow
)).get();
1424 throw IllegalArgumentException();
1427 switch (pToken
->GetType())
1431 double fVal
= pToken
->GetDouble();
1437 OUString aVal
= pToken
->GetString().getString();
1442 throw IllegalArgumentException();
1447 Sequence
< sal_Int32
> SAL_CALL
ScExternalSheetCacheObj::getAllRows()
1449 SolarMutexGuard aGuard
;
1450 vector
<SCROW
> aRows
;
1451 mpTable
->getAllRows(aRows
);
1452 size_t nSize
= aRows
.size();
1453 Sequence
<sal_Int32
> aRowsSeq(nSize
);
1454 auto aRowsSeqRange
= asNonConstRange(aRowsSeq
);
1455 for (size_t i
= 0; i
< nSize
; ++i
)
1456 aRowsSeqRange
[i
] = aRows
[i
];
1461 Sequence
< sal_Int32
> SAL_CALL
ScExternalSheetCacheObj::getAllColumns(sal_Int32 nRow
)
1463 SolarMutexGuard aGuard
;
1465 throw IllegalArgumentException();
1467 vector
<SCCOL
> aCols
;
1468 mpTable
->getAllCols(static_cast<SCROW
>(nRow
), aCols
);
1469 size_t nSize
= aCols
.size();
1470 Sequence
<sal_Int32
> aColsSeq(nSize
);
1471 auto aColsSeqRange
= asNonConstRange(aColsSeq
);
1472 for (size_t i
= 0; i
< nSize
; ++i
)
1473 aColsSeqRange
[i
] = aCols
[i
];
1478 sal_Int32 SAL_CALL
ScExternalSheetCacheObj::getTokenIndex()
1480 return static_cast< sal_Int32
>( mnIndex
);
1483 ScExternalDocLinkObj::ScExternalDocLinkObj(ScDocShell
* pDocShell
, ScExternalRefManager
* pRefMgr
, sal_uInt16 nFileId
) :
1484 mpDocShell(pDocShell
), mpRefMgr(pRefMgr
), mnFileId(nFileId
)
1488 ScExternalDocLinkObj::~ScExternalDocLinkObj()
1492 uno::Reference
< sheet::XExternalSheetCache
> SAL_CALL
ScExternalDocLinkObj::addSheetCache(
1493 const OUString
& aSheetName
, sal_Bool bDynamicCache
)
1495 SolarMutexGuard aGuard
;
1497 ScExternalRefCache::TableTypeRef pTable
= mpRefMgr
->getCacheTable(mnFileId
, aSheetName
, true, &nIndex
);
1499 // Set the whole table cached to prevent access to the source document.
1500 pTable
->setWholeTableCached();
1502 uno::Reference
< sheet::XExternalSheetCache
> aSheetCache(new ScExternalSheetCacheObj(mpDocShell
, pTable
, nIndex
));
1506 Any SAL_CALL
ScExternalDocLinkObj::getByName(const OUString
&aName
)
1508 SolarMutexGuard aGuard
;
1510 ScExternalRefCache::TableTypeRef pTable
= mpRefMgr
->getCacheTable(mnFileId
, aName
, false, &nIndex
);
1512 throw container::NoSuchElementException();
1514 uno::Reference
< sheet::XExternalSheetCache
> aSheetCache(new ScExternalSheetCacheObj(mpDocShell
, pTable
, nIndex
));
1516 return Any(aSheetCache
);
1519 Sequence
< OUString
> SAL_CALL
ScExternalDocLinkObj::getElementNames()
1521 SolarMutexGuard aGuard
;
1522 vector
<OUString
> aTabNames
;
1523 mpRefMgr
->getAllCachedTableNames(mnFileId
, aTabNames
);
1525 // #i116940# be consistent with getByName: include only table names which have a cache already
1526 vector
<OUString
> aValidNames
;
1527 std::copy_if(aTabNames
.begin(), aTabNames
.end(), std::back_inserter(aValidNames
),
1528 [&](const OUString
& rTabName
) { return mpRefMgr
->getCacheTable(mnFileId
, rTabName
, false); });
1530 Sequence
<OUString
> aSeq(comphelper::containerToSequence(aValidNames
));
1534 sal_Bool SAL_CALL
ScExternalDocLinkObj::hasByName(const OUString
&aName
)
1536 SolarMutexGuard aGuard
;
1538 // #i116940# be consistent with getByName: allow only table names which have a cache already
1539 ScExternalRefCache::TableTypeRef pTable
= mpRefMgr
->getCacheTable(mnFileId
, aName
, false);
1540 return bool(pTable
);
1543 sal_Int32 SAL_CALL
ScExternalDocLinkObj::getCount()
1545 SolarMutexGuard aGuard
;
1547 // #i116940# be consistent with getByName: count only table names which have a cache already
1548 return getElementNames().getLength();
1551 Any SAL_CALL
ScExternalDocLinkObj::getByIndex(sal_Int32 nApiIndex
)
1553 SolarMutexGuard aGuard
;
1555 // #i116940# Can't use nApiIndex as index for the ref manager, because the API counts only
1556 // the entries which have a cache already. Quick solution: Use getElementNames.
1557 Sequence
< OUString
> aNames( getElementNames() );
1558 if (nApiIndex
< 0 || nApiIndex
>= aNames
.getLength())
1559 throw lang::IndexOutOfBoundsException();
1562 ScExternalRefCache::TableTypeRef pTable
= mpRefMgr
->getCacheTable(mnFileId
, aNames
[nApiIndex
], false, &nIndex
);
1564 throw lang::IndexOutOfBoundsException();
1566 uno::Reference
< sheet::XExternalSheetCache
> aSheetCache(new ScExternalSheetCacheObj(mpDocShell
, pTable
, nIndex
));
1568 return Any(aSheetCache
);
1571 uno::Reference
< container::XEnumeration
> SAL_CALL
ScExternalDocLinkObj::createEnumeration()
1573 SolarMutexGuard aGuard
;
1574 uno::Reference
< container::XEnumeration
> aRef(
1575 new ScIndexEnumeration(this, "com.sun.star.sheet.ExternalDocLink"));
1579 uno::Type SAL_CALL
ScExternalDocLinkObj::getElementType()
1581 return cppu::UnoType
<sheet::XExternalDocLink
>::get();
1584 sal_Bool SAL_CALL
ScExternalDocLinkObj::hasElements()
1586 SolarMutexGuard aGuard
;
1588 // #i116940# be consistent with getByName: count only table names which have a cache already
1589 return getElementNames().hasElements();
1592 sal_Int32 SAL_CALL
ScExternalDocLinkObj::getTokenIndex()
1594 return static_cast<sal_Int32
>(mnFileId
);
1597 ScExternalDocLinksObj::ScExternalDocLinksObj(ScDocShell
* pDocShell
) :
1598 mpDocShell(pDocShell
),
1599 mpRefMgr(pDocShell
->GetDocument().GetExternalRefManager())
1603 ScExternalDocLinksObj::~ScExternalDocLinksObj()
1607 uno::Reference
< sheet::XExternalDocLink
> SAL_CALL
ScExternalDocLinksObj::addDocLink(
1608 const OUString
& aDocName
)
1610 SolarMutexGuard aGuard
;
1611 OUString
aDocUrl( ScGlobal::GetAbsDocName( aDocName
, mpDocShell
));
1612 sal_uInt16 nFileId
= mpRefMgr
->getExternalFileId(aDocUrl
);
1613 uno::Reference
< sheet::XExternalDocLink
> aDocLink(new ScExternalDocLinkObj(mpDocShell
, mpRefMgr
, nFileId
));
1617 Any SAL_CALL
ScExternalDocLinksObj::getByName(const OUString
&aName
)
1619 SolarMutexGuard aGuard
;
1620 OUString
aDocUrl( ScGlobal::GetAbsDocName( aName
, mpDocShell
));
1621 if (!mpRefMgr
->hasExternalFile(aDocUrl
))
1622 throw container::NoSuchElementException();
1624 sal_uInt16 nFileId
= mpRefMgr
->getExternalFileId(aDocUrl
);
1625 uno::Reference
< sheet::XExternalDocLink
> aDocLink(new ScExternalDocLinkObj(mpDocShell
, mpRefMgr
, nFileId
));
1627 return Any(aDocLink
);
1630 Sequence
< OUString
> SAL_CALL
ScExternalDocLinksObj::getElementNames()
1632 SolarMutexGuard aGuard
;
1633 sal_uInt16 n
= mpRefMgr
->getExternalFileCount();
1634 Sequence
<OUString
> aSeq(n
);
1635 auto aSeqRange
= asNonConstRange(aSeq
);
1636 for (sal_uInt16 i
= 0; i
< n
; ++i
)
1638 const OUString
* pName
= mpRefMgr
->getExternalFileName(i
);
1639 aSeqRange
[i
] = pName
? *pName
: OUString();
1645 sal_Bool SAL_CALL
ScExternalDocLinksObj::hasByName(const OUString
&aName
)
1647 SolarMutexGuard aGuard
;
1648 return mpRefMgr
->hasExternalFile(aName
);
1651 sal_Int32 SAL_CALL
ScExternalDocLinksObj::getCount()
1653 SolarMutexGuard aGuard
;
1654 return mpRefMgr
->getExternalFileCount();
1657 Any SAL_CALL
ScExternalDocLinksObj::getByIndex(sal_Int32 nIndex
)
1659 SolarMutexGuard aGuard
;
1660 if (nIndex
> ::std::numeric_limits
<sal_uInt16
>::max() || nIndex
< ::std::numeric_limits
<sal_uInt16
>::min())
1661 throw lang::IndexOutOfBoundsException();
1663 sal_uInt16 nFileId
= static_cast<sal_uInt16
>(nIndex
);
1665 if (!mpRefMgr
->hasExternalFile(nFileId
))
1666 throw lang::IndexOutOfBoundsException();
1668 uno::Reference
< sheet::XExternalDocLink
> aDocLink(new ScExternalDocLinkObj(mpDocShell
, mpRefMgr
, nFileId
));
1669 return Any(aDocLink
);
1672 uno::Reference
< container::XEnumeration
> SAL_CALL
ScExternalDocLinksObj::createEnumeration()
1674 SolarMutexGuard aGuard
;
1675 uno::Reference
< container::XEnumeration
> aRef(
1676 new ScIndexEnumeration(this, "com.sun.star.sheet.ExternalDocLinks"));
1680 uno::Type SAL_CALL
ScExternalDocLinksObj::getElementType()
1682 return cppu::UnoType
<sheet::XExternalDocLinks
>::get();
1685 sal_Bool SAL_CALL
ScExternalDocLinksObj::hasElements()
1687 SolarMutexGuard aGuard
;
1688 return mpRefMgr
->getExternalFileCount() > 0;
1691 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */