LibreOffice Module sc (master) 1
documentlinkmgr.cxx
Go to the documentation of this file.
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
21#include <documentlinkmgr.hxx>
22#include <datastream.hxx>
23#include <ddelink.hxx>
24#include <webservicelink.hxx>
25#include <strings.hrc>
26#include <scresid.hxx>
27#include <sfx2/linkmgr.hxx>
28#include <sfx2/linksrc.hxx>
29#include <o3tl/deleter.hxx>
30#include <svx/svdoole2.hxx>
31#include <vcl/svapp.hxx>
32#include <vcl/weld.hxx>
33
34#include <memory>
35
36namespace sc {
37
39{
41 std::unique_ptr<DataStream, o3tl::default_delete<DataStream>> mpDataStream;
42 std::atomic<sfx2::LinkManager*> mpLinkManager;
43
46
48 : mpShell(pShell), mpLinkManager(nullptr) {}
49
51 {
52 // Shared base links
53 sfx2::LinkManager* linkManager = mpLinkManager;
54 if (linkManager)
55 {
56 sfx2::SvLinkSources aTemp = linkManager->GetServers();
57 for (const auto& pLinkSource : aTemp)
58 pLinkSource->Closed();
59
60 if (!linkManager->GetLinks().empty())
61 linkManager->Remove(0, linkManager->GetLinks().size());
62 }
63 delete linkManager;
64 }
65};
66
68 mpImpl(new DocumentLinkManagerImpl(pShell)) {}
69
71{
72}
73
75{
76 mpImpl->mpDataStream.reset(p);
77}
78
80{
81 return mpImpl->mpDataStream.get();
82}
83
85{
86 return mpImpl->mpDataStream.get();
87}
88
90{
91 if (bCreate && mpImpl->mpShell)
92 return comphelper::doubleCheckedInit( mpImpl->mpLinkManager,
93 [this]() { return new sfx2::LinkManager(mpImpl->mpShell); } );
94 return mpImpl->mpLinkManager;
95}
96
98{
99 return mpImpl->mpLinkManager;
100}
101
103{
104 sfx2::LinkManager* pMgr = mpImpl->mpLinkManager;
105 if (!pMgr)
106 return false;
107
108 bool bAnyLeft = false;
109 const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
110 for (const auto & rLink : rLinks)
111 {
112 sfx2::SvBaseLink* pBase = rLink.get();
113 ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase);
114 if (!pDdeLink || !pDdeLink->NeedsUpdate())
115 continue;
116
117 pDdeLink->TryUpdate();
118 if (pDdeLink->NeedsUpdate()) // Was not successful?
119 bAnyLeft = true;
120 }
121
122 return bAnyLeft;
123}
124
126{
127 return hasDdeOrOleOrWebServiceLinks(true, false, false);
128}
129
131{
132 return hasDdeOrOleOrWebServiceLinks(true, true, true);
133}
134
135bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const
136{
137 sfx2::LinkManager* pMgr = mpImpl->mpLinkManager;
138 if (!pMgr)
139 return false;
140
141 const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
142 for (const auto & rLink : rLinks)
143 {
144 sfx2::SvBaseLink* pBase = rLink.get();
145 if (bDde && dynamic_cast<ScDdeLink*>(pBase))
146 return true;
147 if (bOle && dynamic_cast<SdrEmbedObjectLink*>(pBase))
148 return true;
149 if (bWebService && dynamic_cast<ScWebServiceLink*>(pBase))
150 return true;
151 }
152
153 return false;
154}
155
157{
158 sfx2::LinkManager* pMgr = mpImpl->mpLinkManager;
159 if (!pMgr)
160 return false;
161
162 const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
163
164 // If the update takes longer, reset all values so that nothing
165 // old (wrong) is left behind
166 bool bAny = false;
167 for (const auto & rLink : rLinks)
168 {
169 sfx2::SvBaseLink* pBase = rLink.get();
170
171 SdrEmbedObjectLink* pOleLink = dynamic_cast<SdrEmbedObjectLink*>(pBase);
172 if (pOleLink)
173 {
174 pOleLink->Update();
175 continue;
176 }
177
178 ScWebServiceLink* pWebserviceLink = dynamic_cast<ScWebServiceLink*>(pBase);
179 if (pWebserviceLink)
180 {
181 pWebserviceLink->Update();
182 continue;
183 }
184
185 ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase);
186 if (!pDdeLink)
187 continue;
188
189 if (pDdeLink->Update())
190 bAny = true;
191 else
192 {
193 // Update failed. Notify the user.
194 const OUString& aFile = pDdeLink->GetTopic();
195 const OUString& aElem = pDdeLink->GetItem();
196 const OUString& aType = pDdeLink->GetAppl();
197
198 OUString sMessage =
199 ScResId(SCSTR_DDEDOC_NOT_LOADED) +
200 "\n\n"
201 "Source : " +
202 aFile +
203 "\nElement : " +
204 aElem +
205 "\nType : " +
206 aType;
207 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pWin,
208 VclMessageType::Warning, VclButtonsType::Ok,
209 sMessage));
210 xBox->run();
211 }
212 }
213
214 pMgr->CloseCachedComps();
215
216 return bAny;
217}
218
219void DocumentLinkManager::updateDdeLink( std::u16string_view rAppl, std::u16string_view rTopic, std::u16string_view rItem )
220{
221 sfx2::LinkManager* pMgr = mpImpl->mpLinkManager;
222 if (!pMgr)
223 return;
224
225 const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
226
227 for (const auto & rLink : rLinks)
228 {
229 ::sfx2::SvBaseLink* pBase = rLink.get();
230 ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase);
231 if (!pDdeLink)
232 continue;
233
234 if ( pDdeLink->GetAppl() == rAppl &&
235 pDdeLink->GetTopic() == rTopic &&
236 pDdeLink->GetItem() == rItem )
237 {
238 pDdeLink->TryUpdate();
239 // Could be multiple (Mode), so continue searching
240 }
241 }
242}
243
245{
246 sfx2::LinkManager* pMgr = mpImpl->mpLinkManager;
247 if (!pMgr)
248 return 0;
249
250 size_t nDdeCount = 0;
251 const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
252 for (const auto & rLink : rLinks)
253 {
254 ::sfx2::SvBaseLink* pBase = rLink.get();
255 ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase);
256 if (!pDdeLink)
257 continue;
258
259 ++nDdeCount;
260 }
261
262 return nDdeCount;
263}
264
265}
266
267/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
const sfx2::LinkManager * getExistingLinkManager() const
bool hasDdeOrOleOrWebServiceLinks() const
DataStream * getDataStream()
std::unique_ptr< DocumentLinkManagerImpl > mpImpl
sfx2::LinkManager * getLinkManager(bool bCreate=true)
void setDataStream(DataStream *p)
void updateDdeLink(std::u16string_view rAppl, std::u16string_view rTopic, std::u16string_view rItem)
size_t getDdeLinkCount() const
DocumentLinkManager(SfxObjectShell *pShell)
bool updateDdeOrOleOrWebServiceLinks(weld::Window *pWin)
const SvLinkSources & GetServers() const
void Remove(SvBaseLink const *pLink)
const SvBaseLinks & GetLinks() const
void * p
static Type * doubleCheckedInit(std::atomic< Type * > &pointer, Function function, GuardCtor guardCtor=osl::GetGlobalMutex())
CAUTION! The following defines must be in the same namespace as the respective type.
Definition: broadcast.cxx:15
std::vector< tools::SvRef< SvBaseLink > > SvBaseLinks
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
OUString sMessage
DocumentLinkManagerImpl(const DocumentLinkManagerImpl &)=delete
DocumentLinkManagerImpl(SfxObjectShell *pShell)
std::unique_ptr< DataStream, o3tl::default_delete< DataStream > > mpDataStream
std::atomic< sfx2::LinkManager * > mpLinkManager
const DocumentLinkManagerImpl & operator=(const DocumentLinkManagerImpl &)=delete