/src/libreoffice/sc/source/ui/unoobj/linkuno.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
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 . |
18 | | */ |
19 | | |
20 | | #include <sal/config.h> |
21 | | |
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> |
27 | | #include <utility> |
28 | | #include <vcl/svapp.hxx> |
29 | | #include <svl/sharedstringpool.hxx> |
30 | | |
31 | | #include <linkuno.hxx> |
32 | | #include <miscuno.hxx> |
33 | | #include <convuno.hxx> |
34 | | #include <docsh.hxx> |
35 | | #include <docfunc.hxx> |
36 | | #include <tablink.hxx> |
37 | | #include <arealink.hxx> |
38 | | #include <hints.hxx> |
39 | | #include <unonames.hxx> |
40 | | #include <rangeseq.hxx> |
41 | | #include <scmatrix.hxx> |
42 | | #include <documentlinkmgr.hxx> |
43 | | |
44 | | #include <string_view> |
45 | | #include <vector> |
46 | | |
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; |
53 | | |
54 | | // used for sheet- and area link: |
55 | | static std::span<const SfxItemPropertyMapEntry> lcl_GetSheetLinkMap() |
56 | 0 | { |
57 | 0 | static const SfxItemPropertyMapEntry aSheetLinkMap_Impl[] = |
58 | 0 | { |
59 | 0 | { SC_UNONAME_FILTER, 0, cppu::UnoType<OUString>::get(), 0, 0 }, |
60 | 0 | { SC_UNONAME_FILTOPT, 0, cppu::UnoType<OUString>::get(), 0, 0 }, |
61 | 0 | { SC_UNONAME_LINKURL, 0, cppu::UnoType<OUString>::get(), 0, 0 }, |
62 | 0 | { SC_UNONAME_REFDELAY, 0, cppu::UnoType<sal_Int32>::get(), 0, 0 }, |
63 | 0 | { SC_UNONAME_REFPERIOD, 0, cppu::UnoType<sal_Int32>::get(), 0, 0 }, |
64 | 0 | }; |
65 | 0 | return aSheetLinkMap_Impl; |
66 | 0 | } |
67 | | |
68 | | SC_SIMPLE_SERVICE_INFO( ScAreaLinkObj, u"ScAreaLinkObj"_ustr, u"com.sun.star.sheet.CellAreaLink"_ustr ) |
69 | | SC_SIMPLE_SERVICE_INFO( ScAreaLinksObj, u"ScAreaLinksObj"_ustr, u"com.sun.star.sheet.CellAreaLinks"_ustr ) |
70 | | SC_SIMPLE_SERVICE_INFO( ScDDELinkObj, u"ScDDELinkObj"_ustr, u"com.sun.star.sheet.DDELink"_ustr ) |
71 | | SC_SIMPLE_SERVICE_INFO( ScDDELinksObj, u"ScDDELinksObj"_ustr, u"com.sun.star.sheet.DDELinks"_ustr ) |
72 | | SC_SIMPLE_SERVICE_INFO( ScSheetLinkObj, u"ScSheetLinkObj"_ustr, u"com.sun.star.sheet.SheetLink"_ustr ) |
73 | | SC_SIMPLE_SERVICE_INFO( ScSheetLinksObj, u"ScSheetLinksObj"_ustr, u"com.sun.star.sheet.SheetLinks"_ustr ) |
74 | | |
75 | | ScSheetLinkObj::ScSheetLinkObj(ScDocShell* pDocSh, OUString aName) : |
76 | 0 | aPropSet( lcl_GetSheetLinkMap() ), |
77 | 0 | pDocShell( pDocSh ), |
78 | 0 | aFileName(std::move( aName )) |
79 | 0 | { |
80 | 0 | pDocShell->GetDocument().AddUnoObject(*this); |
81 | 0 | } |
82 | | |
83 | | ScSheetLinkObj::~ScSheetLinkObj() |
84 | 0 | { |
85 | 0 | SolarMutexGuard g; |
86 | |
|
87 | 0 | if (pDocShell) |
88 | 0 | pDocShell->GetDocument().RemoveUnoObject(*this); |
89 | 0 | } |
90 | | |
91 | | void ScSheetLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) |
92 | 0 | { |
93 | | //! notify if links in document are changed |
94 | | // UpdateRef is not needed here |
95 | |
|
96 | 0 | if ( rHint.GetId() == SfxHintId::ScLinkRefreshed ) |
97 | 0 | { |
98 | 0 | auto pRefreshHint = static_cast<const ScLinkRefreshedHint*>(&rHint); |
99 | 0 | if ( pRefreshHint->GetLinkType() == ScLinkRefType::SHEET && pRefreshHint->GetUrl() == aFileName ) |
100 | 0 | Refreshed_Impl(); |
101 | 0 | } |
102 | 0 | else |
103 | 0 | { |
104 | 0 | if ( rHint.GetId() == SfxHintId::Dying ) |
105 | 0 | pDocShell = nullptr; // pointer is invalid |
106 | 0 | } |
107 | 0 | } |
108 | | |
109 | | ScTableLink* ScSheetLinkObj::GetLink_Impl() const |
110 | 0 | { |
111 | 0 | if (pDocShell) |
112 | 0 | { |
113 | 0 | sfx2::LinkManager* pLinkManager = pDocShell->GetDocument().GetLinkManager(); |
114 | 0 | size_t nCount = pLinkManager->GetLinks().size(); |
115 | 0 | for (size_t i=0; i<nCount; i++) |
116 | 0 | { |
117 | 0 | ::sfx2::SvBaseLink* pBase = pLinkManager->GetLinks()[i].get(); |
118 | 0 | if (auto pTabLink = dynamic_cast<ScTableLink*>( pBase)) |
119 | 0 | { |
120 | 0 | if ( pTabLink->GetFileName() == aFileName ) |
121 | 0 | return pTabLink; |
122 | 0 | } |
123 | 0 | } |
124 | 0 | } |
125 | 0 | return nullptr; // not found |
126 | 0 | } |
127 | | |
128 | | // XNamed |
129 | | |
130 | | OUString SAL_CALL ScSheetLinkObj::getName() |
131 | 0 | { |
132 | 0 | SolarMutexGuard aGuard; |
133 | 0 | return getFileName(); // Name is the same as filename (URL) |
134 | 0 | } |
135 | | |
136 | | void SAL_CALL ScSheetLinkObj::setName( const OUString& aName ) |
137 | 0 | { |
138 | 0 | SolarMutexGuard aGuard; |
139 | 0 | setFileName(aName); // Name is the same as filename (URL) |
140 | 0 | } |
141 | | |
142 | | // XRefreshable |
143 | | |
144 | | void SAL_CALL ScSheetLinkObj::refresh() |
145 | 0 | { |
146 | 0 | SolarMutexGuard aGuard; |
147 | 0 | ScTableLink* pLink = GetLink_Impl(); |
148 | 0 | if (pLink) |
149 | 0 | pLink->Refresh( pLink->GetFileName(), pLink->GetFilterName(), nullptr, pLink->GetRefreshDelaySeconds() ); |
150 | 0 | } |
151 | | |
152 | | void SAL_CALL ScSheetLinkObj::addRefreshListener( |
153 | | const uno::Reference<util::XRefreshListener >& xListener ) |
154 | 0 | { |
155 | 0 | SolarMutexGuard aGuard; |
156 | 0 | aRefreshListeners.push_back( xListener ); |
157 | | |
158 | | // hold one additional ref to keep this object alive as long as there are listeners |
159 | 0 | if ( aRefreshListeners.size() == 1 ) |
160 | 0 | acquire(); |
161 | 0 | } |
162 | | |
163 | | void SAL_CALL ScSheetLinkObj::removeRefreshListener( |
164 | | const uno::Reference<util::XRefreshListener >& xListener ) |
165 | 0 | { |
166 | 0 | SolarMutexGuard aGuard; |
167 | 0 | size_t nCount = aRefreshListeners.size(); |
168 | 0 | for ( size_t n=nCount; n--; ) |
169 | 0 | { |
170 | 0 | uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n]; |
171 | 0 | if ( rObj == xListener ) |
172 | 0 | { |
173 | 0 | aRefreshListeners.erase( aRefreshListeners.begin() + n ); |
174 | 0 | if ( aRefreshListeners.empty() ) |
175 | 0 | release(); // release ref for listeners |
176 | 0 | break; |
177 | 0 | } |
178 | 0 | } |
179 | 0 | } |
180 | | |
181 | | void ScSheetLinkObj::Refreshed_Impl() |
182 | 0 | { |
183 | 0 | lang::EventObject aEvent; |
184 | 0 | aEvent.Source.set(getXWeak()); |
185 | 0 | for (uno::Reference<util::XRefreshListener> & xRefreshListener : aRefreshListeners) |
186 | 0 | xRefreshListener->refreshed( aEvent ); |
187 | 0 | } |
188 | | |
189 | | void ScSheetLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh ) |
190 | 0 | { |
191 | 0 | ScTableLink* pLink = GetLink_Impl(); |
192 | 0 | if( pLink ) |
193 | 0 | pLink->SetRefreshDelay( static_cast<sal_uLong>(nRefresh) ); |
194 | 0 | } |
195 | | |
196 | | // XPropertySet |
197 | | |
198 | | uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSheetLinkObj::getPropertySetInfo() |
199 | 0 | { |
200 | 0 | SolarMutexGuard aGuard; |
201 | 0 | static uno::Reference<beans::XPropertySetInfo> aRef( |
202 | 0 | new SfxItemPropertySetInfo( aPropSet.getPropertyMap() )); |
203 | 0 | return aRef; |
204 | 0 | } |
205 | | |
206 | | void SAL_CALL ScSheetLinkObj::setPropertyValue( |
207 | | const OUString& aPropertyName, const uno::Any& aValue ) |
208 | 0 | { |
209 | 0 | SolarMutexGuard aGuard; |
210 | 0 | OUString aValStr; |
211 | 0 | if ( aPropertyName == SC_UNONAME_LINKURL ) |
212 | 0 | { |
213 | 0 | if ( aValue >>= aValStr ) |
214 | 0 | setFileName( aValStr ); |
215 | 0 | } |
216 | 0 | else if ( aPropertyName == SC_UNONAME_FILTER ) |
217 | 0 | { |
218 | 0 | if ( aValue >>= aValStr ) |
219 | 0 | setFilter( aValStr ); |
220 | 0 | } |
221 | 0 | else if ( aPropertyName == SC_UNONAME_FILTOPT ) |
222 | 0 | { |
223 | 0 | if ( aValue >>= aValStr ) |
224 | 0 | setFilterOptions( aValStr ); |
225 | 0 | } |
226 | 0 | else if ( aPropertyName == SC_UNONAME_REFPERIOD ) |
227 | 0 | { |
228 | 0 | sal_Int32 nRefresh = 0; |
229 | 0 | if ( aValue >>= nRefresh ) |
230 | 0 | setRefreshDelay( nRefresh ); |
231 | 0 | } |
232 | 0 | else if ( aPropertyName == SC_UNONAME_REFDELAY ) |
233 | 0 | { |
234 | 0 | sal_Int32 nRefresh = 0; |
235 | 0 | if ( aValue >>= nRefresh ) |
236 | 0 | setRefreshDelay( nRefresh ); |
237 | 0 | } |
238 | 0 | } |
239 | | |
240 | | uno::Any SAL_CALL ScSheetLinkObj::getPropertyValue( const OUString& aPropertyName ) |
241 | 0 | { |
242 | 0 | SolarMutexGuard aGuard; |
243 | 0 | uno::Any aRet; |
244 | 0 | if ( aPropertyName == SC_UNONAME_LINKURL ) |
245 | 0 | aRet <<= getFileName(); |
246 | 0 | else if ( aPropertyName == SC_UNONAME_FILTER ) |
247 | 0 | aRet <<= getFilter(); |
248 | 0 | else if ( aPropertyName == SC_UNONAME_FILTOPT ) |
249 | 0 | aRet <<= getFilterOptions(); |
250 | 0 | else if ( aPropertyName == SC_UNONAME_REFPERIOD ) |
251 | 0 | aRet <<= getRefreshDelay(); |
252 | 0 | else if ( aPropertyName == SC_UNONAME_REFDELAY ) |
253 | 0 | aRet <<= getRefreshDelay(); |
254 | 0 | return aRet; |
255 | 0 | } |
256 | | |
257 | | SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSheetLinkObj ) |
258 | | |
259 | | // internal: |
260 | | |
261 | | OUString ScSheetLinkObj::getFileName() const |
262 | 0 | { |
263 | 0 | SolarMutexGuard aGuard; |
264 | 0 | return aFileName; |
265 | 0 | } |
266 | | |
267 | | void ScSheetLinkObj::setFileName(const OUString& rNewName) |
268 | 0 | { |
269 | 0 | SolarMutexGuard aGuard; |
270 | 0 | ScTableLink* pLink = GetLink_Impl(); |
271 | 0 | if (!pLink) |
272 | 0 | return; |
273 | | |
274 | | // pLink->Refresh with a new file name confuses sfx2::LinkManager |
275 | | // therefore we transplant the sheets manually and create new links with UpdateLinks |
276 | | |
277 | 0 | OUString aNewStr(ScGlobal::GetAbsDocName( rNewName, pDocShell )); |
278 | | |
279 | | // first transplant the sheets |
280 | |
|
281 | 0 | ScDocument& rDoc = pDocShell->GetDocument(); |
282 | 0 | SCTAB nTabCount = rDoc.GetTableCount(); |
283 | 0 | for (SCTAB nTab=0; nTab<nTabCount; nTab++) |
284 | 0 | if ( rDoc.IsLinked(nTab) && rDoc.GetLinkDoc(nTab) == aFileName ) // old file |
285 | 0 | rDoc.SetLink( nTab, rDoc.GetLinkMode(nTab), aNewStr, |
286 | 0 | rDoc.GetLinkFlt(nTab), rDoc.GetLinkOpt(nTab), |
287 | 0 | rDoc.GetLinkTab(nTab), |
288 | 0 | rDoc.GetLinkRefreshDelay(nTab) ); // only change the file |
289 | | |
290 | | // update links |
291 | | //! Undo !!! |
292 | |
|
293 | 0 | pDocShell->UpdateLinks(); // remove old links, possibly set up new ones |
294 | | |
295 | | // copy data |
296 | |
|
297 | 0 | aFileName = aNewStr; |
298 | 0 | pLink = GetLink_Impl(); // new link with new name |
299 | 0 | if (pLink) |
300 | 0 | pLink->Update(); // incl. paint & undo for data |
301 | 0 | } |
302 | | |
303 | | OUString ScSheetLinkObj::getFilter() const |
304 | 0 | { |
305 | 0 | SolarMutexGuard aGuard; |
306 | 0 | OUString aRet; |
307 | 0 | ScTableLink* pLink = GetLink_Impl(); |
308 | 0 | if (pLink) |
309 | 0 | aRet = pLink->GetFilterName(); |
310 | 0 | return aRet; |
311 | 0 | } |
312 | | |
313 | | void ScSheetLinkObj::setFilter(const OUString& rFilter) |
314 | 0 | { |
315 | 0 | SolarMutexGuard aGuard; |
316 | 0 | ScTableLink* pLink = GetLink_Impl(); |
317 | 0 | if (pLink) |
318 | 0 | { |
319 | 0 | pLink->Refresh( aFileName, rFilter, nullptr, pLink->GetRefreshDelaySeconds() ); |
320 | 0 | } |
321 | 0 | } |
322 | | |
323 | | OUString ScSheetLinkObj::getFilterOptions() const |
324 | 0 | { |
325 | 0 | SolarMutexGuard aGuard; |
326 | 0 | OUString aRet; |
327 | 0 | ScTableLink* pLink = GetLink_Impl(); |
328 | 0 | if (pLink) |
329 | 0 | aRet = pLink->GetOptions(); |
330 | 0 | return aRet; |
331 | 0 | } |
332 | | |
333 | | void ScSheetLinkObj::setFilterOptions(const OUString& FilterOptions) |
334 | 0 | { |
335 | 0 | SolarMutexGuard aGuard; |
336 | 0 | ScTableLink* pLink = GetLink_Impl(); |
337 | 0 | if (pLink) |
338 | 0 | { |
339 | 0 | OUString aOptStr(FilterOptions); |
340 | 0 | pLink->Refresh( aFileName, pLink->GetFilterName(), &aOptStr, pLink->GetRefreshDelaySeconds() ); |
341 | 0 | } |
342 | 0 | } |
343 | | |
344 | | sal_Int32 ScSheetLinkObj::getRefreshDelay() const |
345 | 0 | { |
346 | 0 | SolarMutexGuard aGuard; |
347 | 0 | sal_Int32 nRet = 0; |
348 | 0 | ScTableLink* pLink = GetLink_Impl(); |
349 | 0 | if (pLink) |
350 | 0 | nRet = pLink->GetRefreshDelaySeconds(); |
351 | 0 | return nRet; |
352 | 0 | } |
353 | | |
354 | | void ScSheetLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay) |
355 | 0 | { |
356 | 0 | SolarMutexGuard aGuard; |
357 | 0 | ModifyRefreshDelay_Impl( nRefreshDelay ); |
358 | 0 | } |
359 | | |
360 | | ScSheetLinksObj::ScSheetLinksObj(ScDocShell* pDocSh) : |
361 | 0 | pDocShell( pDocSh ) |
362 | 0 | { |
363 | 0 | pDocShell->GetDocument().AddUnoObject(*this); |
364 | 0 | } |
365 | | |
366 | | ScSheetLinksObj::~ScSheetLinksObj() |
367 | 0 | { |
368 | 0 | SolarMutexGuard g; |
369 | |
|
370 | 0 | if (pDocShell) |
371 | 0 | pDocShell->GetDocument().RemoveUnoObject(*this); |
372 | 0 | } |
373 | | |
374 | | void ScSheetLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) |
375 | 0 | { |
376 | | // we don't care about update of references here |
377 | |
|
378 | 0 | if ( rHint.GetId() == SfxHintId::Dying ) |
379 | 0 | { |
380 | 0 | pDocShell = nullptr; // became invalid |
381 | 0 | } |
382 | 0 | } |
383 | | |
384 | | // XSheetLinks |
385 | | |
386 | | rtl::Reference<ScSheetLinkObj> ScSheetLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex) |
387 | 0 | { |
388 | 0 | if (!pDocShell) |
389 | 0 | return nullptr; |
390 | | |
391 | 0 | typedef std::unordered_set<OUString> StrSetType; |
392 | 0 | StrSetType aNames; |
393 | 0 | ScDocument& rDoc = pDocShell->GetDocument(); |
394 | 0 | SCTAB nTabCount = rDoc.GetTableCount(); |
395 | 0 | sal_Int32 nCount = 0; |
396 | 0 | for (SCTAB nTab = 0; nTab < nTabCount; ++nTab) |
397 | 0 | { |
398 | 0 | if (!rDoc.IsLinked(nTab)) |
399 | 0 | continue; |
400 | | |
401 | 0 | OUString aLinkDoc = rDoc.GetLinkDoc(nTab); |
402 | 0 | if (aNames.insert(aLinkDoc).second) |
403 | 0 | { |
404 | | // unique document name. |
405 | 0 | if (nCount == nIndex) |
406 | 0 | return new ScSheetLinkObj( pDocShell, aLinkDoc ); |
407 | 0 | ++nCount; |
408 | 0 | } |
409 | 0 | } |
410 | | |
411 | 0 | return nullptr; // no document or index too large |
412 | 0 | } |
413 | | |
414 | | rtl::Reference<ScSheetLinkObj> ScSheetLinksObj::GetObjectByName_Impl(const OUString& aName) |
415 | 0 | { |
416 | | // Name is the same as file name |
417 | |
|
418 | 0 | if (pDocShell) |
419 | 0 | { |
420 | 0 | ScDocument& rDoc = pDocShell->GetDocument(); |
421 | 0 | SCTAB nTabCount = rDoc.GetTableCount(); |
422 | 0 | for (SCTAB nTab=0; nTab<nTabCount; nTab++) |
423 | 0 | if (rDoc.IsLinked(nTab)) |
424 | 0 | { |
425 | | //! case-insensitive ??? |
426 | 0 | OUString aLinkDoc = rDoc.GetLinkDoc( nTab ); |
427 | 0 | if ( aLinkDoc == aName ) |
428 | 0 | return new ScSheetLinkObj( pDocShell, aName ); |
429 | 0 | } |
430 | 0 | } |
431 | | |
432 | 0 | return nullptr; |
433 | 0 | } |
434 | | |
435 | | // XEnumerationAccess |
436 | | uno::Reference<container::XEnumeration> SAL_CALL ScSheetLinksObj::createEnumeration() |
437 | 0 | { |
438 | 0 | SolarMutexGuard aGuard; |
439 | 0 | return new ScIndexEnumeration(this, u"com.sun.star.sheet.SheetLinksEnumeration"_ustr); |
440 | 0 | } |
441 | | |
442 | | // XIndexAccess |
443 | | sal_Int32 SAL_CALL ScSheetLinksObj::getCount() |
444 | 0 | { |
445 | 0 | typedef std::unordered_set<OUString> StrSetType; |
446 | |
|
447 | 0 | SolarMutexGuard aGuard; |
448 | 0 | if (!pDocShell) |
449 | 0 | return 0; |
450 | | |
451 | 0 | sal_Int32 nCount = 0; |
452 | |
|
453 | 0 | StrSetType aNames; |
454 | 0 | ScDocument& rDoc = pDocShell->GetDocument(); |
455 | 0 | SCTAB nTabCount = rDoc.GetTableCount(); |
456 | 0 | for (SCTAB nTab = 0; nTab < nTabCount; ++nTab) |
457 | 0 | { |
458 | 0 | if (!rDoc.IsLinked(nTab)) |
459 | 0 | continue; |
460 | | |
461 | 0 | OUString aLinkDoc = rDoc.GetLinkDoc(nTab); |
462 | 0 | if (aNames.insert(aLinkDoc).second) |
463 | 0 | ++nCount; |
464 | 0 | } |
465 | 0 | return nCount; |
466 | 0 | } |
467 | | |
468 | | uno::Any SAL_CALL ScSheetLinksObj::getByIndex( sal_Int32 nIndex ) |
469 | 0 | { |
470 | 0 | SolarMutexGuard aGuard; |
471 | 0 | rtl::Reference<ScSheetLinkObj> xLink(GetObjectByIndex_Impl(nIndex)); |
472 | 0 | if (!xLink.is()) |
473 | 0 | throw lang::IndexOutOfBoundsException(); |
474 | | |
475 | 0 | return uno::Any(uno::Reference<beans::XPropertySet>(xLink)); |
476 | 0 | } |
477 | | |
478 | | uno::Type SAL_CALL ScSheetLinksObj::getElementType() |
479 | 0 | { |
480 | 0 | return cppu::UnoType<beans::XPropertySet>::get(); |
481 | 0 | } |
482 | | |
483 | | sal_Bool SAL_CALL ScSheetLinksObj::hasElements() |
484 | 0 | { |
485 | 0 | SolarMutexGuard aGuard; |
486 | 0 | return ( getCount() != 0 ); |
487 | 0 | } |
488 | | |
489 | | uno::Any SAL_CALL ScSheetLinksObj::getByName( const OUString& aName ) |
490 | 0 | { |
491 | 0 | SolarMutexGuard aGuard; |
492 | 0 | rtl::Reference<ScSheetLinkObj> xLink(GetObjectByName_Impl(aName)); |
493 | 0 | if (!xLink.is()) |
494 | 0 | throw container::NoSuchElementException(); |
495 | | |
496 | 0 | return uno::Any(uno::Reference<beans::XPropertySet>(xLink)); |
497 | 0 | } |
498 | | |
499 | | sal_Bool SAL_CALL ScSheetLinksObj::hasByName( const OUString& aName ) |
500 | 0 | { |
501 | 0 | SolarMutexGuard aGuard; |
502 | | // Name is the same as file name |
503 | |
|
504 | 0 | if (pDocShell) |
505 | 0 | { |
506 | 0 | ScDocument& rDoc = pDocShell->GetDocument(); |
507 | 0 | SCTAB nTabCount = rDoc.GetTableCount(); |
508 | 0 | for (SCTAB nTab=0; nTab<nTabCount; nTab++) |
509 | 0 | if (rDoc.IsLinked(nTab)) |
510 | 0 | { |
511 | | //! case-insensitive ??? |
512 | 0 | OUString aLinkDoc(rDoc.GetLinkDoc( nTab )); |
513 | 0 | if ( aLinkDoc == aName ) |
514 | 0 | return true; |
515 | 0 | } |
516 | 0 | } |
517 | 0 | return false; |
518 | 0 | } |
519 | | |
520 | | uno::Sequence<OUString> SAL_CALL ScSheetLinksObj::getElementNames() |
521 | 0 | { |
522 | 0 | typedef std::unordered_set<OUString> StrSetType; |
523 | |
|
524 | 0 | SolarMutexGuard aGuard; |
525 | | // Name is the same as file name |
526 | |
|
527 | 0 | if (!pDocShell) |
528 | 0 | return uno::Sequence<OUString>(); |
529 | | |
530 | 0 | StrSetType aNames; |
531 | 0 | ScDocument& rDoc = pDocShell->GetDocument(); |
532 | 0 | SCTAB nTabCount = rDoc.GetTableCount(); |
533 | |
|
534 | 0 | sal_Int32 nLinkCount = getCount(); |
535 | 0 | uno::Sequence<OUString> aSeq(nLinkCount); |
536 | 0 | OUString* pAry = aSeq.getArray(); |
537 | 0 | size_t nPos = 0; |
538 | 0 | for (SCTAB nTab = 0; nTab < nTabCount; ++nTab) |
539 | 0 | { |
540 | 0 | if (!rDoc.IsLinked(nTab)) |
541 | 0 | continue; |
542 | | |
543 | 0 | OUString aLinkDoc = rDoc.GetLinkDoc(nTab); |
544 | 0 | if (aNames.insert(aLinkDoc).second) |
545 | 0 | pAry[nPos++] = aLinkDoc; |
546 | 0 | } |
547 | 0 | OSL_ENSURE( nPos==static_cast<size_t>(nLinkCount), "verzaehlt" ); |
548 | 0 | return aSeq; |
549 | 0 | } |
550 | | |
551 | | static ScAreaLink* lcl_GetAreaLink( ScDocShell* pDocShell, size_t nPos ) |
552 | 0 | { |
553 | 0 | if (pDocShell) |
554 | 0 | { |
555 | 0 | sfx2::LinkManager* pLinkManager = pDocShell->GetDocument().GetLinkManager(); |
556 | 0 | size_t nTotalCount = pLinkManager->GetLinks().size(); |
557 | 0 | size_t nAreaCount = 0; |
558 | 0 | for (size_t i=0; i<nTotalCount; i++) |
559 | 0 | { |
560 | 0 | ::sfx2::SvBaseLink* pBase = pLinkManager->GetLinks()[i].get(); |
561 | 0 | if (auto pAreaLink = dynamic_cast<ScAreaLink*>( pBase)) |
562 | 0 | { |
563 | 0 | if ( nAreaCount == nPos ) |
564 | 0 | return pAreaLink; |
565 | 0 | ++nAreaCount; |
566 | 0 | } |
567 | 0 | } |
568 | 0 | } |
569 | 0 | return nullptr; // not found |
570 | 0 | } |
571 | | |
572 | | ScAreaLinkObj::ScAreaLinkObj(ScDocShell* pDocSh, size_t nP) : |
573 | 0 | aPropSet( lcl_GetSheetLinkMap() ), |
574 | 0 | pDocShell( pDocSh ), |
575 | 0 | nPos( nP ) |
576 | 0 | { |
577 | 0 | pDocShell->GetDocument().AddUnoObject(*this); |
578 | 0 | } |
579 | | |
580 | | ScAreaLinkObj::~ScAreaLinkObj() |
581 | 0 | { |
582 | 0 | SolarMutexGuard g; |
583 | |
|
584 | 0 | if (pDocShell) |
585 | 0 | pDocShell->GetDocument().RemoveUnoObject(*this); |
586 | 0 | } |
587 | | |
588 | | void ScAreaLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) |
589 | 0 | { |
590 | | //! notify if links in document are changed |
591 | | // UpdateRef is not needed here |
592 | |
|
593 | 0 | if ( rHint.GetId() == SfxHintId::ScLinkRefreshed ) |
594 | 0 | { |
595 | 0 | auto pRefreshedHint = static_cast<const ScLinkRefreshedHint*>(&rHint); |
596 | 0 | if ( pRefreshedHint->GetLinkType() == ScLinkRefType::AREA ) |
597 | 0 | { |
598 | | // get this link to compare dest position |
599 | 0 | ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); |
600 | 0 | if ( pLink && pLink->GetDestArea().aStart == pRefreshedHint->GetDestPos() ) |
601 | 0 | Refreshed_Impl(); |
602 | 0 | } |
603 | 0 | } |
604 | 0 | else if ( rHint.GetId() == SfxHintId::Dying ) |
605 | 0 | pDocShell = nullptr; // pointer is invalid |
606 | 0 | } |
607 | | |
608 | | // XFileLink |
609 | | |
610 | | void ScAreaLinkObj::Modify_Impl( const OUString* pNewFile, const OUString* pNewFilter, |
611 | | const OUString* pNewOptions, const OUString* pNewSource, |
612 | | const table::CellRangeAddress* pNewDest ) |
613 | 0 | { |
614 | 0 | ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); |
615 | 0 | if (!pLink) |
616 | 0 | return; |
617 | | |
618 | 0 | OUString aFile (pLink->GetFile()); |
619 | 0 | OUString aFilter (pLink->GetFilter()); |
620 | 0 | OUString aOptions (pLink->GetOptions()); |
621 | 0 | OUString aSource (pLink->GetSource()); |
622 | 0 | ScRange aDest (pLink->GetDestArea()); |
623 | 0 | sal_Int32 nRefreshDelaySeconds = pLink->GetRefreshDelaySeconds(); |
624 | | |
625 | | //! Undo delete |
626 | | //! Undo merge |
627 | |
|
628 | 0 | sfx2::LinkManager* pLinkManager = pDocShell->GetDocument().GetLinkManager(); |
629 | 0 | pLinkManager->Remove( pLink ); |
630 | 0 | pLink = nullptr; // deleted along with remove |
631 | |
|
632 | 0 | bool bFitBlock = true; // move, if the size changes with update |
633 | 0 | if (pNewFile) |
634 | 0 | { |
635 | 0 | aFile = ScGlobal::GetAbsDocName( *pNewFile, pDocShell ); //! in InsertAreaLink? |
636 | 0 | } |
637 | 0 | if (pNewFilter) |
638 | 0 | aFilter = *pNewFilter; |
639 | 0 | if (pNewOptions) |
640 | 0 | aOptions = *pNewOptions; |
641 | 0 | if (pNewSource) |
642 | 0 | aSource = *pNewSource; |
643 | 0 | if (pNewDest) |
644 | 0 | { |
645 | 0 | ScUnoConversion::FillScRange( aDest, *pNewDest ); |
646 | 0 | bFitBlock = false; // new range was specified -> do not move the content |
647 | 0 | } |
648 | 0 | pDocShell->GetDocFunc().InsertAreaLink( aFile, aFilter, aOptions, aSource, |
649 | 0 | aDest, nRefreshDelaySeconds, bFitBlock, true ); |
650 | 0 | } |
651 | | |
652 | | void ScAreaLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefreshDelaySeconds ) |
653 | 0 | { |
654 | 0 | ScAreaLink* pLink = lcl_GetAreaLink( pDocShell, nPos ); |
655 | 0 | if( pLink ) |
656 | 0 | pLink->SetRefreshDelay( nRefreshDelaySeconds ); |
657 | 0 | } |
658 | | |
659 | | // XRefreshable |
660 | | |
661 | | void SAL_CALL ScAreaLinkObj::refresh() |
662 | 0 | { |
663 | 0 | SolarMutexGuard aGuard; |
664 | 0 | ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); |
665 | 0 | if (pLink) |
666 | 0 | pLink->Refresh( pLink->GetFile(), pLink->GetFilter(), pLink->GetSource(), pLink->GetRefreshDelaySeconds() ); |
667 | 0 | } |
668 | | |
669 | | void SAL_CALL ScAreaLinkObj::addRefreshListener( |
670 | | const uno::Reference<util::XRefreshListener >& xListener ) |
671 | 0 | { |
672 | 0 | SolarMutexGuard aGuard; |
673 | 0 | aRefreshListeners.push_back( xListener ); |
674 | | |
675 | | // hold one additional ref to keep this object alive as long as there are listeners |
676 | 0 | if ( aRefreshListeners.size() == 1 ) |
677 | 0 | acquire(); |
678 | 0 | } |
679 | | |
680 | | void SAL_CALL ScAreaLinkObj::removeRefreshListener( |
681 | | const uno::Reference<util::XRefreshListener >& xListener ) |
682 | 0 | { |
683 | 0 | SolarMutexGuard aGuard; |
684 | 0 | size_t nCount = aRefreshListeners.size(); |
685 | 0 | for ( size_t n=nCount; n--; ) |
686 | 0 | { |
687 | 0 | uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n]; |
688 | 0 | if ( rObj == xListener ) |
689 | 0 | { |
690 | 0 | aRefreshListeners.erase( aRefreshListeners.begin() + n ); |
691 | 0 | if ( aRefreshListeners.empty() ) |
692 | 0 | release(); // release ref for listeners |
693 | 0 | break; |
694 | 0 | } |
695 | | |
696 | 0 | if(n == 0) |
697 | 0 | break; |
698 | 0 | } |
699 | 0 | } |
700 | | |
701 | | void ScAreaLinkObj::Refreshed_Impl() |
702 | 0 | { |
703 | 0 | lang::EventObject aEvent; |
704 | 0 | aEvent.Source.set(getXWeak()); |
705 | 0 | for (uno::Reference<util::XRefreshListener> & xRefreshListener : aRefreshListeners) |
706 | 0 | xRefreshListener->refreshed( aEvent ); |
707 | 0 | } |
708 | | |
709 | | // XPropertySet |
710 | | |
711 | | uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAreaLinkObj::getPropertySetInfo() |
712 | 0 | { |
713 | 0 | SolarMutexGuard aGuard; |
714 | 0 | static uno::Reference<beans::XPropertySetInfo> aRef( |
715 | 0 | new SfxItemPropertySetInfo( aPropSet.getPropertyMap() )); |
716 | 0 | return aRef; |
717 | 0 | } |
718 | | |
719 | | void SAL_CALL ScAreaLinkObj::setPropertyValue( |
720 | | const OUString& aPropertyName, const uno::Any& aValue ) |
721 | 0 | { |
722 | 0 | SolarMutexGuard aGuard; |
723 | 0 | OUString aValStr; |
724 | 0 | if ( aPropertyName == SC_UNONAME_LINKURL ) |
725 | 0 | { |
726 | 0 | if ( aValue >>= aValStr ) |
727 | 0 | setFileName( aValStr ); |
728 | 0 | } |
729 | 0 | else if ( aPropertyName == SC_UNONAME_FILTER ) |
730 | 0 | { |
731 | 0 | if ( aValue >>= aValStr ) |
732 | 0 | setFilter( aValStr ); |
733 | 0 | } |
734 | 0 | else if ( aPropertyName == SC_UNONAME_FILTOPT ) |
735 | 0 | { |
736 | 0 | if ( aValue >>= aValStr ) |
737 | 0 | setFilterOptions( aValStr ); |
738 | 0 | } |
739 | 0 | else if ( aPropertyName == SC_UNONAME_REFPERIOD ) |
740 | 0 | { |
741 | 0 | sal_Int32 nRefresh = 0; |
742 | 0 | if ( aValue >>= nRefresh ) |
743 | 0 | setRefreshDelay( nRefresh ); |
744 | 0 | } |
745 | 0 | else if ( aPropertyName == SC_UNONAME_REFDELAY ) |
746 | 0 | { |
747 | 0 | sal_Int32 nRefresh = 0; |
748 | 0 | if ( aValue >>= nRefresh ) |
749 | 0 | setRefreshDelay( nRefresh ); |
750 | 0 | } |
751 | 0 | } |
752 | | |
753 | | uno::Any SAL_CALL ScAreaLinkObj::getPropertyValue( const OUString& aPropertyName ) |
754 | 0 | { |
755 | 0 | SolarMutexGuard aGuard; |
756 | 0 | uno::Any aRet; |
757 | 0 | if ( aPropertyName == SC_UNONAME_LINKURL ) |
758 | 0 | aRet <<= getFileName(); |
759 | 0 | else if ( aPropertyName == SC_UNONAME_FILTER ) |
760 | 0 | aRet <<= getFilter(); |
761 | 0 | else if ( aPropertyName == SC_UNONAME_FILTOPT ) |
762 | 0 | aRet <<= getFilterOptions(); |
763 | 0 | else if ( aPropertyName == SC_UNONAME_REFPERIOD ) |
764 | 0 | aRet <<= getRefreshDelay(); |
765 | 0 | else if ( aPropertyName == SC_UNONAME_REFDELAY ) |
766 | 0 | aRet <<= getRefreshDelay(); |
767 | 0 | return aRet; |
768 | 0 | } |
769 | | |
770 | | SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAreaLinkObj ) |
771 | | |
772 | | // internal: |
773 | | |
774 | | OUString ScAreaLinkObj::getFileName() const |
775 | 0 | { |
776 | 0 | SolarMutexGuard aGuard; |
777 | 0 | OUString aRet; |
778 | 0 | ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); |
779 | 0 | if (pLink) |
780 | 0 | aRet = pLink->GetFile(); |
781 | 0 | return aRet; |
782 | 0 | } |
783 | | |
784 | | void ScAreaLinkObj::setFileName(const OUString& rNewName) |
785 | 0 | { |
786 | 0 | SolarMutexGuard aGuard; |
787 | 0 | Modify_Impl( &rNewName, nullptr, nullptr, nullptr, nullptr ); |
788 | 0 | } |
789 | | |
790 | | OUString ScAreaLinkObj::getFilter() const |
791 | 0 | { |
792 | 0 | SolarMutexGuard aGuard; |
793 | 0 | OUString aRet; |
794 | 0 | ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); |
795 | 0 | if (pLink) |
796 | 0 | aRet = pLink->GetFilter(); |
797 | 0 | return aRet; |
798 | 0 | } |
799 | | |
800 | | void ScAreaLinkObj::setFilter(const OUString& Filter) |
801 | 0 | { |
802 | 0 | SolarMutexGuard aGuard; |
803 | 0 | Modify_Impl( nullptr, &Filter, nullptr, nullptr, nullptr ); |
804 | 0 | } |
805 | | |
806 | | OUString ScAreaLinkObj::getFilterOptions() const |
807 | 0 | { |
808 | 0 | SolarMutexGuard aGuard; |
809 | 0 | OUString aRet; |
810 | 0 | ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); |
811 | 0 | if (pLink) |
812 | 0 | aRet = pLink->GetOptions(); |
813 | 0 | return aRet; |
814 | 0 | } |
815 | | |
816 | | void ScAreaLinkObj::setFilterOptions(const OUString& FilterOptions) |
817 | 0 | { |
818 | 0 | SolarMutexGuard aGuard; |
819 | 0 | Modify_Impl( nullptr, nullptr, &FilterOptions, nullptr, nullptr ); |
820 | 0 | } |
821 | | |
822 | | sal_Int32 ScAreaLinkObj::getRefreshDelay() const |
823 | 0 | { |
824 | 0 | SolarMutexGuard aGuard; |
825 | 0 | sal_Int32 nRet = 0; |
826 | 0 | ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); |
827 | 0 | if (pLink) |
828 | 0 | nRet = pLink->GetRefreshDelaySeconds(); |
829 | 0 | return nRet; |
830 | 0 | } |
831 | | |
832 | | void ScAreaLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay) |
833 | 0 | { |
834 | 0 | SolarMutexGuard aGuard; |
835 | 0 | ModifyRefreshDelay_Impl( nRefreshDelay ); |
836 | 0 | } |
837 | | |
838 | | // XAreaLink |
839 | | |
840 | | OUString SAL_CALL ScAreaLinkObj::getSourceArea() |
841 | 0 | { |
842 | 0 | SolarMutexGuard aGuard; |
843 | 0 | OUString aRet; |
844 | 0 | ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); |
845 | 0 | if (pLink) |
846 | 0 | aRet = pLink->GetSource(); |
847 | 0 | return aRet; |
848 | 0 | } |
849 | | |
850 | | void SAL_CALL ScAreaLinkObj::setSourceArea( const OUString& aSourceArea ) |
851 | 0 | { |
852 | 0 | SolarMutexGuard aGuard; |
853 | 0 | Modify_Impl( nullptr, nullptr, nullptr, &aSourceArea, nullptr ); |
854 | 0 | } |
855 | | |
856 | | table::CellRangeAddress SAL_CALL ScAreaLinkObj::getDestArea() |
857 | 0 | { |
858 | 0 | SolarMutexGuard aGuard; |
859 | 0 | table::CellRangeAddress aRet; |
860 | 0 | ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos); |
861 | 0 | if (pLink) |
862 | 0 | ScUnoConversion::FillApiRange( aRet, pLink->GetDestArea() ); |
863 | 0 | return aRet; |
864 | 0 | } |
865 | | |
866 | | void SAL_CALL ScAreaLinkObj::setDestArea( const table::CellRangeAddress& aDestArea ) |
867 | 0 | { |
868 | 0 | SolarMutexGuard aGuard; |
869 | 0 | Modify_Impl( nullptr, nullptr, nullptr, nullptr, &aDestArea ); |
870 | 0 | } |
871 | | |
872 | | ScAreaLinksObj::ScAreaLinksObj(ScDocShell* pDocSh) : |
873 | 0 | pDocShell( pDocSh ) |
874 | 0 | { |
875 | 0 | pDocShell->GetDocument().AddUnoObject(*this); |
876 | 0 | } |
877 | | |
878 | | ScAreaLinksObj::~ScAreaLinksObj() |
879 | 0 | { |
880 | 0 | SolarMutexGuard g; |
881 | |
|
882 | 0 | if (pDocShell) |
883 | 0 | pDocShell->GetDocument().RemoveUnoObject(*this); |
884 | 0 | } |
885 | | |
886 | | void ScAreaLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) |
887 | 0 | { |
888 | | // we don't care about update of references here |
889 | |
|
890 | 0 | if ( rHint.GetId() == SfxHintId::Dying ) |
891 | 0 | { |
892 | 0 | pDocShell = nullptr; // became invalid |
893 | 0 | } |
894 | 0 | } |
895 | | |
896 | | // XAreaLinks |
897 | | |
898 | | rtl::Reference<ScAreaLinkObj> ScAreaLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex) |
899 | 0 | { |
900 | 0 | if ( pDocShell && nIndex >= 0 && nIndex < getCount() ) |
901 | 0 | return new ScAreaLinkObj( pDocShell, static_cast<size_t>(nIndex) ); |
902 | | |
903 | 0 | return nullptr; // not found |
904 | 0 | } |
905 | | |
906 | | void SAL_CALL ScAreaLinksObj::insertAtPosition( const table::CellAddress& aDestPos, |
907 | | const OUString& aFileName, |
908 | | const OUString& aSourceArea, |
909 | | const OUString& aFilter, |
910 | | const OUString& aFilterOptions ) |
911 | 0 | { |
912 | 0 | SolarMutexGuard aGuard; |
913 | 0 | if (pDocShell) |
914 | 0 | { |
915 | 0 | OUString aFileStr (aFileName); |
916 | 0 | ScAddress aDestAddr( static_cast<SCCOL>(aDestPos.Column), static_cast<SCROW>(aDestPos.Row), aDestPos.Sheet ); |
917 | |
|
918 | 0 | aFileStr = ScGlobal::GetAbsDocName( aFileStr, pDocShell ); //! in InsertAreaLink ??? |
919 | 0 | pDocShell->GetDocFunc().InsertAreaLink( aFileStr, aFilter, aFilterOptions, |
920 | 0 | aSourceArea, ScRange(aDestAddr), |
921 | 0 | /*nRefreshDelaySeconds*/0, false, true ); // don't move contents |
922 | 0 | } |
923 | 0 | } |
924 | | |
925 | | void SAL_CALL ScAreaLinksObj::removeByIndex( sal_Int32 nIndex ) |
926 | 0 | { |
927 | 0 | SolarMutexGuard aGuard; |
928 | 0 | ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, static_cast<size_t>(nIndex)); |
929 | 0 | if (pLink) |
930 | 0 | { |
931 | | //! SetAddUndo or what |
932 | |
|
933 | 0 | sfx2::LinkManager* pLinkManager = pDocShell->GetDocument().GetLinkManager(); |
934 | 0 | pLinkManager->Remove( pLink ); |
935 | 0 | } |
936 | 0 | } |
937 | | |
938 | | // XEnumerationAccess |
939 | | |
940 | | uno::Reference<container::XEnumeration> SAL_CALL ScAreaLinksObj::createEnumeration() |
941 | 0 | { |
942 | 0 | SolarMutexGuard aGuard; |
943 | 0 | return new ScIndexEnumeration(this, u"com.sun.star.sheet.CellAreaLinksEnumeration"_ustr); |
944 | 0 | } |
945 | | |
946 | | // XIndexAccess |
947 | | |
948 | | sal_Int32 SAL_CALL ScAreaLinksObj::getCount() |
949 | 0 | { |
950 | 0 | SolarMutexGuard aGuard; |
951 | 0 | sal_Int32 nAreaCount = 0; |
952 | 0 | if (pDocShell) |
953 | 0 | { |
954 | 0 | sfx2::LinkManager* pLinkManager = pDocShell->GetDocument().GetLinkManager(); |
955 | 0 | size_t nTotalCount = pLinkManager->GetLinks().size(); |
956 | 0 | for (size_t i=0; i<nTotalCount; i++) |
957 | 0 | { |
958 | 0 | ::sfx2::SvBaseLink* pBase = pLinkManager->GetLinks()[i].get(); |
959 | 0 | if (dynamic_cast<const ScAreaLink*>( pBase) != nullptr) |
960 | 0 | ++nAreaCount; |
961 | 0 | } |
962 | 0 | } |
963 | 0 | return nAreaCount; |
964 | 0 | } |
965 | | |
966 | | uno::Any SAL_CALL ScAreaLinksObj::getByIndex( sal_Int32 nIndex ) |
967 | 0 | { |
968 | 0 | SolarMutexGuard aGuard; |
969 | 0 | rtl::Reference<ScAreaLinkObj> xLink(GetObjectByIndex_Impl(nIndex)); |
970 | 0 | if (!xLink.is()) |
971 | 0 | throw lang::IndexOutOfBoundsException(); |
972 | | |
973 | 0 | return uno::Any(uno::Reference<sheet::XAreaLink>(xLink)); |
974 | |
|
975 | 0 | } |
976 | | |
977 | | uno::Type SAL_CALL ScAreaLinksObj::getElementType() |
978 | 0 | { |
979 | 0 | return cppu::UnoType<sheet::XAreaLink>::get(); |
980 | 0 | } |
981 | | |
982 | | sal_Bool SAL_CALL ScAreaLinksObj::hasElements() |
983 | 0 | { |
984 | 0 | SolarMutexGuard aGuard; |
985 | 0 | return ( getCount() != 0 ); |
986 | 0 | } |
987 | | |
988 | | ScDDELinkObj::ScDDELinkObj(ScDocShell* pDocSh, OUString aA, |
989 | | OUString aT, OUString aI) : |
990 | 0 | pDocShell( pDocSh ), |
991 | 0 | aAppl(std::move( aA )), |
992 | 0 | aTopic(std::move( aT )), |
993 | 0 | aItem(std::move( aI )) |
994 | 0 | { |
995 | 0 | pDocShell->GetDocument().AddUnoObject(*this); |
996 | 0 | } |
997 | | |
998 | | ScDDELinkObj::~ScDDELinkObj() |
999 | 0 | { |
1000 | 0 | SolarMutexGuard g; |
1001 | |
|
1002 | 0 | if (pDocShell) |
1003 | 0 | pDocShell->GetDocument().RemoveUnoObject(*this); |
1004 | 0 | } |
1005 | | |
1006 | | void ScDDELinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) |
1007 | 0 | { |
1008 | | //! notify if links in document are changed |
1009 | | // UpdateRef is not needed here |
1010 | |
|
1011 | 0 | if ( rHint.GetId() == SfxHintId::ScLinkRefreshed ) |
1012 | 0 | { |
1013 | 0 | auto pRefreshedHint = static_cast<const ScLinkRefreshedHint*>(&rHint); |
1014 | 0 | if ( pRefreshedHint->GetLinkType() == ScLinkRefType::DDE && |
1015 | 0 | pRefreshedHint->GetDdeAppl() == aAppl && |
1016 | 0 | pRefreshedHint->GetDdeTopic() == aTopic && |
1017 | 0 | pRefreshedHint->GetDdeItem() == aItem ) //! mode is ignored |
1018 | 0 | Refreshed_Impl(); |
1019 | 0 | } |
1020 | 0 | else if ( rHint.GetId() == SfxHintId::Dying ) |
1021 | 0 | pDocShell = nullptr; // pointer is invalid |
1022 | 0 | } |
1023 | | |
1024 | | // XNamed |
1025 | | |
1026 | | static OUString lcl_BuildDDEName( std::u16string_view rAppl, std::u16string_view rTopic, std::u16string_view rItem ) |
1027 | 0 | { |
1028 | | // Appl|Topic!Item (like Excel) |
1029 | 0 | OUString aRet = OUString::Concat(rAppl) + "|" + rTopic + "!" + rItem; |
1030 | 0 | return aRet; |
1031 | 0 | } |
1032 | | |
1033 | | OUString SAL_CALL ScDDELinkObj::getName() |
1034 | 0 | { |
1035 | 0 | SolarMutexGuard aGuard; |
1036 | 0 | return lcl_BuildDDEName( aAppl, aTopic, aItem ); |
1037 | 0 | } |
1038 | | |
1039 | | void SAL_CALL ScDDELinkObj::setName( const OUString& /* aName */ ) |
1040 | 0 | { |
1041 | | // name can't be changed (formulas wouldn't find the link) |
1042 | 0 | throw uno::RuntimeException(); |
1043 | 0 | } |
1044 | | |
1045 | | // XDDELink |
1046 | | |
1047 | | OUString SAL_CALL ScDDELinkObj::getApplication() |
1048 | 0 | { |
1049 | | //! Test if the link is still in the document? |
1050 | |
|
1051 | 0 | return aAppl; |
1052 | 0 | } |
1053 | | |
1054 | | OUString SAL_CALL ScDDELinkObj::getTopic() |
1055 | 0 | { |
1056 | | //! Test if the link is still in the document? |
1057 | |
|
1058 | 0 | return aTopic; |
1059 | 0 | } |
1060 | | |
1061 | | OUString SAL_CALL ScDDELinkObj::getItem() |
1062 | 0 | { |
1063 | | //! Test if the link is still in the document? |
1064 | |
|
1065 | 0 | return aItem; |
1066 | 0 | } |
1067 | | |
1068 | | // XRefreshable |
1069 | | |
1070 | | void SAL_CALL ScDDELinkObj::refresh() |
1071 | 0 | { |
1072 | 0 | SolarMutexGuard aGuard; |
1073 | 0 | if (pDocShell) |
1074 | 0 | { |
1075 | 0 | sc::DocumentLinkManager& rMgr = pDocShell->GetDocument().GetDocLinkManager(); |
1076 | 0 | rMgr.updateDdeLink(aAppl, aTopic, aItem); |
1077 | 0 | } |
1078 | 0 | } |
1079 | | |
1080 | | void SAL_CALL ScDDELinkObj::addRefreshListener( |
1081 | | const uno::Reference<util::XRefreshListener >& xListener ) |
1082 | 0 | { |
1083 | 0 | SolarMutexGuard aGuard; |
1084 | 0 | aRefreshListeners.push_back( xListener ); |
1085 | | |
1086 | | // hold one additional ref to keep this object alive as long as there are listeners |
1087 | 0 | if ( aRefreshListeners.size() == 1 ) |
1088 | 0 | acquire(); |
1089 | 0 | } |
1090 | | |
1091 | | void SAL_CALL ScDDELinkObj::removeRefreshListener( |
1092 | | const uno::Reference<util::XRefreshListener >& xListener ) |
1093 | 0 | { |
1094 | 0 | SolarMutexGuard aGuard; |
1095 | 0 | size_t nCount = aRefreshListeners.size(); |
1096 | 0 | for ( size_t n=nCount; n--; ) |
1097 | 0 | { |
1098 | 0 | uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n]; |
1099 | 0 | if ( rObj == xListener ) |
1100 | 0 | { |
1101 | 0 | aRefreshListeners.erase( aRefreshListeners.begin() + n ); |
1102 | 0 | if ( aRefreshListeners.empty() ) |
1103 | 0 | release(); // release ref for listeners |
1104 | 0 | break; |
1105 | 0 | } |
1106 | 0 | } |
1107 | 0 | } |
1108 | | |
1109 | | // XDDELinkResults |
1110 | | |
1111 | | uno::Sequence< uno::Sequence< uno::Any > > ScDDELinkObj::getResults( ) |
1112 | 0 | { |
1113 | 0 | SolarMutexGuard aGuard; |
1114 | 0 | uno::Sequence< uno::Sequence< uno::Any > > aReturn; |
1115 | 0 | bool bSuccess = false; |
1116 | |
|
1117 | 0 | if ( pDocShell ) |
1118 | 0 | { |
1119 | 0 | ScDocument& rDoc = pDocShell->GetDocument(); |
1120 | 0 | size_t nPos = 0; |
1121 | 0 | if ( rDoc.FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) ) |
1122 | 0 | { |
1123 | 0 | const ScMatrix* pMatrix = rDoc.GetDdeLinkResultMatrix( nPos ); |
1124 | 0 | if ( pMatrix ) |
1125 | 0 | { |
1126 | 0 | uno::Any aAny; |
1127 | 0 | if ( ScRangeToSequence::FillMixedArray( aAny, pMatrix, true ) ) |
1128 | 0 | { |
1129 | 0 | aAny >>= aReturn; |
1130 | 0 | } |
1131 | 0 | } |
1132 | 0 | bSuccess = true; |
1133 | 0 | } |
1134 | 0 | } |
1135 | |
|
1136 | 0 | if ( !bSuccess ) |
1137 | 0 | { |
1138 | 0 | throw uno::RuntimeException( |
1139 | 0 | u"ScDDELinkObj::getResults: failed to get results!"_ustr ); |
1140 | 0 | } |
1141 | | |
1142 | 0 | return aReturn; |
1143 | 0 | } |
1144 | | |
1145 | | void ScDDELinkObj::setResults( const uno::Sequence< uno::Sequence< uno::Any > >& aResults ) |
1146 | 0 | { |
1147 | 0 | SolarMutexGuard aGuard; |
1148 | 0 | bool bSuccess = false; |
1149 | |
|
1150 | 0 | if ( pDocShell ) |
1151 | 0 | { |
1152 | 0 | ScDocument& rDoc = pDocShell->GetDocument(); |
1153 | 0 | size_t nPos = 0; |
1154 | 0 | if ( rDoc.FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) ) |
1155 | 0 | { |
1156 | 0 | ScMatrixRef xMatrix = ScSequenceToMatrix::CreateMixedMatrix( Any(aResults) ); |
1157 | 0 | bSuccess = rDoc.SetDdeLinkResultMatrix( nPos, xMatrix ); |
1158 | 0 | } |
1159 | 0 | } |
1160 | |
|
1161 | 0 | if ( !bSuccess ) |
1162 | 0 | { |
1163 | 0 | throw uno::RuntimeException( |
1164 | 0 | u"ScDDELinkObj::setResults: failed to set results!"_ustr ); |
1165 | 0 | } |
1166 | 0 | } |
1167 | | |
1168 | | void ScDDELinkObj::Refreshed_Impl() |
1169 | 0 | { |
1170 | 0 | lang::EventObject aEvent; |
1171 | 0 | aEvent.Source.set(getXWeak()); |
1172 | 0 | for (uno::Reference<util::XRefreshListener> & xRefreshListener : aRefreshListeners) |
1173 | 0 | xRefreshListener->refreshed( aEvent ); |
1174 | 0 | } |
1175 | | |
1176 | | ScDDELinksObj::ScDDELinksObj(ScDocShell* pDocSh) : |
1177 | 0 | pDocShell( pDocSh ) |
1178 | 0 | { |
1179 | 0 | pDocShell->GetDocument().AddUnoObject(*this); |
1180 | 0 | } |
1181 | | |
1182 | | ScDDELinksObj::~ScDDELinksObj() |
1183 | 0 | { |
1184 | 0 | SolarMutexGuard g; |
1185 | |
|
1186 | 0 | if (pDocShell) |
1187 | 0 | pDocShell->GetDocument().RemoveUnoObject(*this); |
1188 | 0 | } |
1189 | | |
1190 | | void ScDDELinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) |
1191 | 0 | { |
1192 | | // we don't care about update of references here |
1193 | |
|
1194 | 0 | if ( rHint.GetId() == SfxHintId::Dying ) |
1195 | 0 | { |
1196 | 0 | pDocShell = nullptr; // became invalid |
1197 | 0 | } |
1198 | 0 | } |
1199 | | |
1200 | | // XDDELinks |
1201 | | |
1202 | | rtl::Reference<ScDDELinkObj> ScDDELinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex) |
1203 | 0 | { |
1204 | 0 | if (pDocShell) |
1205 | 0 | { |
1206 | 0 | OUString aAppl, aTopic, aItem; |
1207 | 0 | if ( pDocShell->GetDocument().GetDdeLinkData( static_cast<size_t>(nIndex), aAppl, aTopic, aItem ) ) |
1208 | 0 | return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem ); |
1209 | 0 | } |
1210 | 0 | return nullptr; |
1211 | 0 | } |
1212 | | |
1213 | | rtl::Reference<ScDDELinkObj> ScDDELinksObj::GetObjectByName_Impl(std::u16string_view aName) |
1214 | 0 | { |
1215 | 0 | if (pDocShell) |
1216 | 0 | { |
1217 | 0 | OUString aAppl, aTopic, aItem; |
1218 | |
|
1219 | 0 | ScDocument& rDoc = pDocShell->GetDocument(); |
1220 | 0 | size_t nCount = rDoc.GetDocLinkManager().getDdeLinkCount(); |
1221 | 0 | for (size_t i=0; i<nCount; i++) |
1222 | 0 | { |
1223 | 0 | rDoc.GetDdeLinkData( i, aAppl, aTopic, aItem ); |
1224 | 0 | if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aName ) |
1225 | 0 | return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem ); |
1226 | 0 | } |
1227 | 0 | } |
1228 | 0 | return nullptr; |
1229 | 0 | } |
1230 | | |
1231 | | // XEnumerationAccess |
1232 | | |
1233 | | uno::Reference<container::XEnumeration> SAL_CALL ScDDELinksObj::createEnumeration() |
1234 | 0 | { |
1235 | 0 | SolarMutexGuard aGuard; |
1236 | 0 | return new ScIndexEnumeration(this, u"com.sun.star.sheet.DDELinksEnumeration"_ustr); |
1237 | 0 | } |
1238 | | |
1239 | | // XIndexAccess |
1240 | | |
1241 | | sal_Int32 SAL_CALL ScDDELinksObj::getCount() |
1242 | 0 | { |
1243 | 0 | SolarMutexGuard aGuard; |
1244 | 0 | sal_Int32 nAreaCount = 0; |
1245 | 0 | if (pDocShell) |
1246 | 0 | nAreaCount = pDocShell->GetDocument().GetDocLinkManager().getDdeLinkCount(); |
1247 | 0 | return nAreaCount; |
1248 | 0 | } |
1249 | | |
1250 | | uno::Any SAL_CALL ScDDELinksObj::getByIndex( sal_Int32 nIndex ) |
1251 | 0 | { |
1252 | 0 | SolarMutexGuard aGuard; |
1253 | 0 | rtl::Reference<ScDDELinkObj> xLink(GetObjectByIndex_Impl(nIndex)); |
1254 | 0 | if (!xLink.is()) |
1255 | 0 | throw lang::IndexOutOfBoundsException(); |
1256 | | |
1257 | 0 | return uno::Any(uno::Reference<sheet::XDDELink>(xLink)); |
1258 | 0 | } |
1259 | | |
1260 | | uno::Type SAL_CALL ScDDELinksObj::getElementType() |
1261 | 0 | { |
1262 | 0 | return cppu::UnoType<sheet::XDDELink>::get(); |
1263 | 0 | } |
1264 | | |
1265 | | sal_Bool SAL_CALL ScDDELinksObj::hasElements() |
1266 | 0 | { |
1267 | 0 | SolarMutexGuard aGuard; |
1268 | 0 | return ( getCount() != 0 ); |
1269 | 0 | } |
1270 | | |
1271 | | uno::Any SAL_CALL ScDDELinksObj::getByName( const OUString& aName ) |
1272 | 0 | { |
1273 | 0 | SolarMutexGuard aGuard; |
1274 | 0 | rtl::Reference<ScDDELinkObj> xLink(GetObjectByName_Impl(aName)); |
1275 | 0 | if (!xLink.is()) |
1276 | 0 | throw container::NoSuchElementException(); |
1277 | | |
1278 | 0 | return uno::Any(uno::Reference<sheet::XDDELink>(xLink)); |
1279 | 0 | } |
1280 | | |
1281 | | uno::Sequence<OUString> SAL_CALL ScDDELinksObj::getElementNames() |
1282 | 0 | { |
1283 | 0 | SolarMutexGuard aGuard; |
1284 | 0 | if (pDocShell) |
1285 | 0 | { |
1286 | 0 | OUString aAppl, aTopic, aItem; |
1287 | |
|
1288 | 0 | ScDocument& rDoc = pDocShell->GetDocument(); |
1289 | 0 | size_t nCount = pDocShell->GetDocument().GetDocLinkManager().getDdeLinkCount(); |
1290 | 0 | uno::Sequence<OUString> aSeq(nCount); |
1291 | 0 | OUString* pAry = aSeq.getArray(); |
1292 | |
|
1293 | 0 | for (size_t i=0; i<nCount; i++) |
1294 | 0 | { |
1295 | 0 | rDoc.GetDdeLinkData( i, aAppl, aTopic, aItem ); |
1296 | 0 | pAry[i] = lcl_BuildDDEName(aAppl, aTopic, aItem); |
1297 | 0 | } |
1298 | 0 | return aSeq; |
1299 | 0 | } |
1300 | 0 | return uno::Sequence<OUString>(); |
1301 | 0 | } |
1302 | | |
1303 | | sal_Bool SAL_CALL ScDDELinksObj::hasByName( const OUString& aName ) |
1304 | 0 | { |
1305 | 0 | SolarMutexGuard aGuard; |
1306 | 0 | if (pDocShell) |
1307 | 0 | { |
1308 | 0 | OUString aAppl, aTopic, aItem; |
1309 | |
|
1310 | 0 | ScDocument& rDoc = pDocShell->GetDocument(); |
1311 | 0 | size_t nCount = pDocShell->GetDocument().GetDocLinkManager().getDdeLinkCount(); |
1312 | 0 | for (size_t i=0; i<nCount; i++) |
1313 | 0 | { |
1314 | 0 | rDoc.GetDdeLinkData( i, aAppl, aTopic, aItem ); |
1315 | 0 | if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aName ) |
1316 | 0 | return true; |
1317 | 0 | } |
1318 | 0 | } |
1319 | 0 | return false; |
1320 | 0 | } |
1321 | | |
1322 | | // XDDELinks |
1323 | | |
1324 | | uno::Reference< sheet::XDDELink > ScDDELinksObj::addDDELink( |
1325 | | const OUString& aApplication, const OUString& aTopic, |
1326 | | const OUString& aItem, css::sheet::DDELinkMode nMode ) |
1327 | 0 | { |
1328 | 0 | SolarMutexGuard aGuard; |
1329 | 0 | uno::Reference< sheet::XDDELink > xLink; |
1330 | |
|
1331 | 0 | if ( pDocShell ) |
1332 | 0 | { |
1333 | 0 | ScDocument& rDoc = pDocShell->GetDocument(); |
1334 | 0 | sal_uInt8 nMod = SC_DDE_DEFAULT; |
1335 | 0 | switch ( nMode ) |
1336 | 0 | { |
1337 | 0 | case sheet::DDELinkMode_DEFAULT: |
1338 | 0 | { |
1339 | 0 | nMod = SC_DDE_DEFAULT; |
1340 | 0 | } |
1341 | 0 | break; |
1342 | 0 | case sheet::DDELinkMode_ENGLISH: |
1343 | 0 | { |
1344 | 0 | nMod = SC_DDE_ENGLISH; |
1345 | 0 | } |
1346 | 0 | break; |
1347 | 0 | case sheet::DDELinkMode_TEXT: |
1348 | 0 | { |
1349 | 0 | nMod = SC_DDE_TEXT; |
1350 | 0 | } |
1351 | 0 | break; |
1352 | 0 | default: |
1353 | 0 | { |
1354 | 0 | } |
1355 | 0 | break; |
1356 | 0 | } |
1357 | | |
1358 | 0 | if ( rDoc.CreateDdeLink( aApplication, aTopic, aItem, nMod, ScMatrixRef() ) ) |
1359 | 0 | { |
1360 | 0 | const OUString aName( lcl_BuildDDEName( aApplication, aTopic, aItem ) ); |
1361 | 0 | xLink.set( GetObjectByName_Impl( aName ) ); |
1362 | 0 | } |
1363 | 0 | } |
1364 | | |
1365 | 0 | if ( !xLink.is() ) |
1366 | 0 | { |
1367 | 0 | throw uno::RuntimeException( |
1368 | 0 | u"ScDDELinksObj::addDDELink: cannot add DDE link!"_ustr ); |
1369 | 0 | } |
1370 | | |
1371 | 0 | return xLink; |
1372 | 0 | } |
1373 | | |
1374 | | ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScDocShell* pDocShell, ScExternalRefCache::TableTypeRef pTable, size_t nIndex) : |
1375 | 205 | mpDocShell(pDocShell), |
1376 | 205 | mpTable(std::move(pTable)), |
1377 | 205 | mnIndex(nIndex) |
1378 | 205 | { |
1379 | 205 | } |
1380 | | |
1381 | | ScExternalSheetCacheObj::~ScExternalSheetCacheObj() |
1382 | 205 | { |
1383 | 205 | } |
1384 | | |
1385 | | void SAL_CALL ScExternalSheetCacheObj::setCellValue(sal_Int32 nCol, sal_Int32 nRow, const Any& rValue) |
1386 | 2.07k | { |
1387 | 2.07k | SolarMutexGuard aGuard; |
1388 | 2.07k | if (nRow < 0 || nCol < 0) |
1389 | 0 | throw IllegalArgumentException(); |
1390 | | |
1391 | 2.07k | ScExternalRefCache::TokenRef pToken; |
1392 | 2.07k | double fVal = 0.0; |
1393 | 2.07k | OUString aVal; |
1394 | 2.07k | if (rValue >>= fVal) |
1395 | 1.60k | pToken.reset(new FormulaDoubleToken(fVal)); |
1396 | 466 | else if (rValue >>= aVal) |
1397 | 466 | { |
1398 | 466 | svl::SharedStringPool& rPool = mpDocShell->GetDocument().GetSharedStringPool(); |
1399 | 466 | svl::SharedString aSS = rPool.intern(aVal); |
1400 | 466 | pToken.reset(new FormulaStringToken(std::move(aSS))); |
1401 | 466 | } |
1402 | 0 | else |
1403 | | // unidentified value type. |
1404 | 0 | return; |
1405 | | |
1406 | 2.07k | mpTable->setCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), pToken); |
1407 | 2.07k | } |
1408 | | |
1409 | | Any SAL_CALL ScExternalSheetCacheObj::getCellValue(sal_Int32 nCol, sal_Int32 nRow) |
1410 | 0 | { |
1411 | 0 | SolarMutexGuard aGuard; |
1412 | 0 | if (nRow < 0 || nCol < 0) |
1413 | 0 | throw IllegalArgumentException(); |
1414 | | |
1415 | 0 | FormulaToken* pToken = mpTable->getCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow)).get(); |
1416 | 0 | if (!pToken) |
1417 | 0 | throw IllegalArgumentException(); |
1418 | | |
1419 | 0 | Any aValue; |
1420 | 0 | switch (pToken->GetType()) |
1421 | 0 | { |
1422 | 0 | case svDouble: |
1423 | 0 | { |
1424 | 0 | double fVal = pToken->GetDouble(); |
1425 | 0 | aValue <<= fVal; |
1426 | 0 | } |
1427 | 0 | break; |
1428 | 0 | case svString: |
1429 | 0 | { |
1430 | 0 | OUString aVal = pToken->GetString().getString(); |
1431 | 0 | aValue <<= aVal; |
1432 | 0 | } |
1433 | 0 | break; |
1434 | 0 | default: |
1435 | 0 | throw IllegalArgumentException(); |
1436 | 0 | } |
1437 | 0 | return aValue; |
1438 | 0 | } |
1439 | | |
1440 | | Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllRows() |
1441 | 0 | { |
1442 | 0 | SolarMutexGuard aGuard; |
1443 | 0 | std::vector<SCROW> aRows; |
1444 | 0 | mpTable->getAllRows(aRows); |
1445 | 0 | size_t nSize = aRows.size(); |
1446 | 0 | Sequence<sal_Int32> aRowsSeq(nSize); |
1447 | 0 | auto aRowsSeqRange = asNonConstRange(aRowsSeq); |
1448 | 0 | for (size_t i = 0; i < nSize; ++i) |
1449 | 0 | aRowsSeqRange[i] = aRows[i]; |
1450 | |
|
1451 | 0 | return aRowsSeq; |
1452 | 0 | } |
1453 | | |
1454 | | Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllColumns(sal_Int32 nRow) |
1455 | 0 | { |
1456 | 0 | SolarMutexGuard aGuard; |
1457 | 0 | if (nRow < 0) |
1458 | 0 | throw IllegalArgumentException(); |
1459 | | |
1460 | 0 | std::vector<SCCOL> aCols; |
1461 | 0 | mpTable->getAllCols(static_cast<SCROW>(nRow), aCols); |
1462 | 0 | size_t nSize = aCols.size(); |
1463 | 0 | Sequence<sal_Int32> aColsSeq(nSize); |
1464 | 0 | auto aColsSeqRange = asNonConstRange(aColsSeq); |
1465 | 0 | for (size_t i = 0; i < nSize; ++i) |
1466 | 0 | aColsSeqRange[i] = aCols[i]; |
1467 | |
|
1468 | 0 | return aColsSeq; |
1469 | 0 | } |
1470 | | |
1471 | | sal_Int32 SAL_CALL ScExternalSheetCacheObj::getTokenIndex() |
1472 | 106 | { |
1473 | 106 | return static_cast< sal_Int32 >( mnIndex ); |
1474 | 106 | } |
1475 | | |
1476 | | ScExternalDocLinkObj::ScExternalDocLinkObj(ScDocShell* pDocShell, ScExternalRefManager* pRefMgr, sal_uInt16 nFileId) : |
1477 | 31 | mpDocShell(pDocShell), mpRefMgr(pRefMgr), mnFileId(nFileId) |
1478 | 31 | { |
1479 | 31 | } |
1480 | | |
1481 | | ScExternalDocLinkObj::~ScExternalDocLinkObj() |
1482 | 31 | { |
1483 | 31 | } |
1484 | | |
1485 | | uno::Reference< sheet::XExternalSheetCache > SAL_CALL ScExternalDocLinkObj::addSheetCache( |
1486 | | const OUString& aSheetName, sal_Bool bDynamicCache ) |
1487 | 106 | { |
1488 | 106 | SolarMutexGuard aGuard; |
1489 | 106 | size_t nIndex = 0; |
1490 | 106 | ScExternalRefCache::TableTypeRef xTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true, &nIndex); |
1491 | 106 | if (!bDynamicCache) |
1492 | 106 | { |
1493 | | // Set the whole table cached to prevent access to the source document. |
1494 | 106 | xTable->setWholeTableCached(); |
1495 | 106 | } |
1496 | | |
1497 | 106 | uno::Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj( |
1498 | 106 | mpDocShell, std::move(xTable), nIndex)); |
1499 | 106 | return aSheetCache; |
1500 | 106 | } |
1501 | | |
1502 | | Any SAL_CALL ScExternalDocLinkObj::getByName(const OUString &aName) |
1503 | 0 | { |
1504 | 0 | SolarMutexGuard aGuard; |
1505 | 0 | size_t nIndex = 0; |
1506 | 0 | ScExternalRefCache::TableTypeRef xTable = mpRefMgr->getCacheTable(mnFileId, aName, false, &nIndex); |
1507 | 0 | if (!xTable) |
1508 | 0 | throw container::NoSuchElementException(); |
1509 | | |
1510 | 0 | uno::Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj( |
1511 | 0 | mpDocShell, std::move(xTable), nIndex)); |
1512 | |
|
1513 | 0 | return Any(aSheetCache); |
1514 | 0 | } |
1515 | | |
1516 | | Sequence< OUString > SAL_CALL ScExternalDocLinkObj::getElementNames() |
1517 | 99 | { |
1518 | 99 | SolarMutexGuard aGuard; |
1519 | 99 | std::vector<OUString> aTabNames; |
1520 | 99 | mpRefMgr->getAllCachedTableNames(mnFileId, aTabNames); |
1521 | | |
1522 | | // #i116940# be consistent with getByName: include only table names which have a cache already |
1523 | 99 | std::vector<OUString> aValidNames; |
1524 | 99 | std::copy_if(aTabNames.begin(), aTabNames.end(), std::back_inserter(aValidNames), |
1525 | 381 | [&](const OUString& rTabName) { return mpRefMgr->getCacheTable(mnFileId, rTabName, false); }); |
1526 | | |
1527 | 99 | Sequence<OUString> aSeq(comphelper::containerToSequence(aValidNames)); |
1528 | 99 | return aSeq; |
1529 | 99 | } |
1530 | | |
1531 | | sal_Bool SAL_CALL ScExternalDocLinkObj::hasByName(const OUString &aName) |
1532 | 0 | { |
1533 | 0 | SolarMutexGuard aGuard; |
1534 | | |
1535 | | // #i116940# be consistent with getByName: allow only table names which have a cache already |
1536 | 0 | ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false); |
1537 | 0 | return bool(pTable); |
1538 | 0 | } |
1539 | | |
1540 | | sal_Int32 SAL_CALL ScExternalDocLinkObj::getCount() |
1541 | 0 | { |
1542 | 0 | SolarMutexGuard aGuard; |
1543 | | |
1544 | | // #i116940# be consistent with getByName: count only table names which have a cache already |
1545 | 0 | return getElementNames().getLength(); |
1546 | 0 | } |
1547 | | |
1548 | | Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nApiIndex) |
1549 | 99 | { |
1550 | 99 | SolarMutexGuard aGuard; |
1551 | | |
1552 | | // #i116940# Can't use nApiIndex as index for the ref manager, because the API counts only |
1553 | | // the entries which have a cache already. Quick solution: Use getElementNames. |
1554 | 99 | Sequence< OUString > aNames( getElementNames() ); |
1555 | 99 | if (nApiIndex < 0 || nApiIndex >= aNames.getLength()) |
1556 | 0 | throw lang::IndexOutOfBoundsException(); |
1557 | | |
1558 | 99 | size_t nIndex = 0; |
1559 | 99 | ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aNames[nApiIndex], false, &nIndex); |
1560 | 99 | if (!pTable) |
1561 | 0 | throw lang::IndexOutOfBoundsException(); |
1562 | | |
1563 | 99 | uno::Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(mpDocShell, std::move(pTable), nIndex)); |
1564 | | |
1565 | 99 | return Any(aSheetCache); |
1566 | 99 | } |
1567 | | |
1568 | | uno::Reference< container::XEnumeration > SAL_CALL ScExternalDocLinkObj::createEnumeration() |
1569 | 0 | { |
1570 | 0 | SolarMutexGuard aGuard; |
1571 | 0 | uno::Reference< container::XEnumeration > aRef( |
1572 | 0 | new ScIndexEnumeration(this, u"com.sun.star.sheet.ExternalDocLink"_ustr)); |
1573 | 0 | return aRef; |
1574 | 0 | } |
1575 | | |
1576 | | uno::Type SAL_CALL ScExternalDocLinkObj::getElementType() |
1577 | 0 | { |
1578 | 0 | return cppu::UnoType<sheet::XExternalDocLink>::get(); |
1579 | 0 | } |
1580 | | |
1581 | | sal_Bool SAL_CALL ScExternalDocLinkObj::hasElements() |
1582 | 0 | { |
1583 | 0 | SolarMutexGuard aGuard; |
1584 | | |
1585 | | // #i116940# be consistent with getByName: count only table names which have a cache already |
1586 | 0 | return getElementNames().hasElements(); |
1587 | 0 | } |
1588 | | |
1589 | | sal_Int32 SAL_CALL ScExternalDocLinkObj::getTokenIndex() |
1590 | 0 | { |
1591 | 0 | return static_cast<sal_Int32>(mnFileId); |
1592 | 0 | } |
1593 | | |
1594 | | ScExternalDocLinksObj::ScExternalDocLinksObj(ScDocShell* pDocShell) : |
1595 | 31 | mpDocShell(pDocShell), |
1596 | 31 | mpRefMgr(pDocShell->GetDocument().GetExternalRefManager()) |
1597 | 31 | { |
1598 | 31 | } |
1599 | | |
1600 | | ScExternalDocLinksObj::~ScExternalDocLinksObj() |
1601 | 31 | { |
1602 | 31 | } |
1603 | | |
1604 | | uno::Reference< sheet::XExternalDocLink > SAL_CALL ScExternalDocLinksObj::addDocLink( |
1605 | | const OUString& aDocName ) |
1606 | 31 | { |
1607 | 31 | SolarMutexGuard aGuard; |
1608 | 31 | OUString aDocUrl( ScGlobal::GetAbsDocName( aDocName, mpDocShell)); |
1609 | 31 | sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aDocUrl); |
1610 | 31 | uno::Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpDocShell, mpRefMgr, nFileId)); |
1611 | 31 | return aDocLink; |
1612 | 31 | } |
1613 | | |
1614 | | Any SAL_CALL ScExternalDocLinksObj::getByName(const OUString &aName) |
1615 | 0 | { |
1616 | 0 | SolarMutexGuard aGuard; |
1617 | 0 | OUString aDocUrl( ScGlobal::GetAbsDocName( aName, mpDocShell)); |
1618 | 0 | if (!mpRefMgr->hasExternalFile(aDocUrl)) |
1619 | 0 | throw container::NoSuchElementException(); |
1620 | | |
1621 | 0 | sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aDocUrl); |
1622 | 0 | uno::Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpDocShell, mpRefMgr, nFileId)); |
1623 | |
|
1624 | 0 | return Any(aDocLink); |
1625 | 0 | } |
1626 | | |
1627 | | Sequence< OUString > SAL_CALL ScExternalDocLinksObj::getElementNames() |
1628 | 0 | { |
1629 | 0 | SolarMutexGuard aGuard; |
1630 | 0 | sal_uInt16 n = mpRefMgr->getExternalFileCount(); |
1631 | 0 | Sequence<OUString> aSeq(n); |
1632 | 0 | auto aSeqRange = asNonConstRange(aSeq); |
1633 | 0 | for (sal_uInt16 i = 0; i < n; ++i) |
1634 | 0 | { |
1635 | 0 | const OUString* pName = mpRefMgr->getExternalFileName(i); |
1636 | 0 | aSeqRange[i] = pName ? *pName : OUString(); |
1637 | 0 | } |
1638 | |
|
1639 | 0 | return aSeq; |
1640 | 0 | } |
1641 | | |
1642 | | sal_Bool SAL_CALL ScExternalDocLinksObj::hasByName(const OUString &aName) |
1643 | 0 | { |
1644 | 0 | SolarMutexGuard aGuard; |
1645 | 0 | return mpRefMgr->hasExternalFile(aName); |
1646 | 0 | } |
1647 | | |
1648 | | sal_Int32 SAL_CALL ScExternalDocLinksObj::getCount() |
1649 | 0 | { |
1650 | 0 | SolarMutexGuard aGuard; |
1651 | 0 | return mpRefMgr->getExternalFileCount(); |
1652 | 0 | } |
1653 | | |
1654 | | Any SAL_CALL ScExternalDocLinksObj::getByIndex(sal_Int32 nIndex) |
1655 | 0 | { |
1656 | 0 | SolarMutexGuard aGuard; |
1657 | 0 | if (nIndex > ::std::numeric_limits<sal_uInt16>::max() || nIndex < ::std::numeric_limits<sal_uInt16>::min()) |
1658 | 0 | throw lang::IndexOutOfBoundsException(); |
1659 | | |
1660 | 0 | sal_uInt16 nFileId = static_cast<sal_uInt16>(nIndex); |
1661 | |
|
1662 | 0 | if (!mpRefMgr->hasExternalFile(nFileId)) |
1663 | 0 | throw lang::IndexOutOfBoundsException(); |
1664 | | |
1665 | 0 | uno::Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpDocShell, mpRefMgr, nFileId)); |
1666 | 0 | return Any(aDocLink); |
1667 | 0 | } |
1668 | | |
1669 | | uno::Reference< container::XEnumeration > SAL_CALL ScExternalDocLinksObj::createEnumeration() |
1670 | 0 | { |
1671 | 0 | SolarMutexGuard aGuard; |
1672 | 0 | uno::Reference< container::XEnumeration > aRef( |
1673 | 0 | new ScIndexEnumeration(this, u"com.sun.star.sheet.ExternalDocLinks"_ustr)); |
1674 | 0 | return aRef; |
1675 | 0 | } |
1676 | | |
1677 | | uno::Type SAL_CALL ScExternalDocLinksObj::getElementType() |
1678 | 0 | { |
1679 | 0 | return cppu::UnoType<sheet::XExternalDocLinks>::get(); |
1680 | 0 | } |
1681 | | |
1682 | | sal_Bool SAL_CALL ScExternalDocLinksObj::hasElements() |
1683 | 0 | { |
1684 | 0 | SolarMutexGuard aGuard; |
1685 | 0 | return mpRefMgr->getExternalFileCount() > 0; |
1686 | 0 | } |
1687 | | |
1688 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |