Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / docshell / documentlinkmgr.cxx
blob520b8542afc037ad4905fbf11ac520cb9822bbe1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <documentlinkmgr.hxx>
21 #include <datastream.hxx>
22 #include <ddelink.hxx>
23 #include <sc.hrc>
24 #include <scresid.hxx>
26 #include <svx/svdoole2.hxx>
27 #include <vcl/layout.hxx>
29 #include <memory>
31 namespace sc {
33 struct DocumentLinkManagerImpl
35 SfxObjectShell* mpShell;
36 std::unique_ptr<DataStream> mpDataStream;
37 std::unique_ptr<sfx2::LinkManager> mpLinkManager;
39 DocumentLinkManagerImpl(const DocumentLinkManagerImpl&) = delete;
40 const DocumentLinkManagerImpl& operator=(const DocumentLinkManagerImpl&) = delete;
42 explicit DocumentLinkManagerImpl(SfxObjectShell* pShell)
43 : mpShell(pShell), mpDataStream(nullptr), mpLinkManager(nullptr) {}
45 ~DocumentLinkManagerImpl()
47 // Shared base links
48 if (mpLinkManager)
50 sfx2::SvLinkSources aTemp = mpLinkManager->GetServers();
51 for (sfx2::SvLinkSources::const_iterator it = aTemp.begin(); it != aTemp.end(); ++it)
52 (*it)->Closed();
54 if (!mpLinkManager->GetLinks().empty())
55 mpLinkManager->Remove(0, mpLinkManager->GetLinks().size());
60 DocumentLinkManager::DocumentLinkManager( SfxObjectShell* pShell ) :
61 mpImpl(new DocumentLinkManagerImpl(pShell)) {}
63 DocumentLinkManager::~DocumentLinkManager()
67 void DocumentLinkManager::setDataStream( DataStream* p )
69 mpImpl->mpDataStream.reset(p);
72 DataStream* DocumentLinkManager::getDataStream()
74 return mpImpl->mpDataStream.get();
77 const DataStream* DocumentLinkManager::getDataStream() const
79 return mpImpl->mpDataStream.get();
82 sfx2::LinkManager* DocumentLinkManager::getLinkManager( bool bCreate )
84 if (!mpImpl->mpLinkManager && bCreate && mpImpl->mpShell)
85 mpImpl->mpLinkManager.reset(new sfx2::LinkManager(mpImpl->mpShell));
86 return mpImpl->mpLinkManager.get();
89 const sfx2::LinkManager* DocumentLinkManager::getExistingLinkManager() const
91 return mpImpl->mpLinkManager.get();
94 bool DocumentLinkManager::idleCheckLinks()
96 if (!mpImpl->mpLinkManager)
97 return false;
99 bool bAnyLeft = false;
100 const sfx2::SvBaseLinks& rLinks = mpImpl->mpLinkManager->GetLinks();
101 for (const auto & rLink : rLinks)
103 sfx2::SvBaseLink* pBase = rLink.get();
104 ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase);
105 if (!pDdeLink || !pDdeLink->NeedsUpdate())
106 continue;
108 pDdeLink->TryUpdate();
109 if (pDdeLink->NeedsUpdate()) // Was not successful?
110 bAnyLeft = true;
113 return bAnyLeft;
116 bool DocumentLinkManager::hasDdeLinks() const
118 return hasDdeOrOleLinks(true, false);
121 bool DocumentLinkManager::hasDdeOrOleLinks() const
123 return hasDdeOrOleLinks(true, true);
126 bool DocumentLinkManager::hasDdeOrOleLinks(bool bDde, bool bOle) const
128 if (!mpImpl->mpLinkManager)
129 return false;
131 const sfx2::SvBaseLinks& rLinks = mpImpl->mpLinkManager->GetLinks();
132 for (const auto & rLink : rLinks)
134 sfx2::SvBaseLink* pBase = rLink.get();
135 if (bDde && dynamic_cast<ScDdeLink*>(pBase))
136 return true;
137 if (bOle && dynamic_cast<SdrEmbedObjectLink*>(pBase))
138 return true;
141 return false;
144 bool DocumentLinkManager::updateDdeOrOleLinks( vcl::Window* pWin )
146 if (!mpImpl->mpLinkManager)
147 return false;
149 sfx2::LinkManager* pMgr = mpImpl->mpLinkManager.get();
150 const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
152 // If the update takes longer, reset all values so that nothing
153 // old (wrong) is left behind
154 bool bAny = false;
155 for (const auto & rLink : rLinks)
157 sfx2::SvBaseLink* pBase = rLink.get();
159 SdrEmbedObjectLink* pOleLink = dynamic_cast<SdrEmbedObjectLink*>(pBase);
160 if (pOleLink)
162 pOleLink->Update();
163 continue;
166 ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase);
167 if (!pDdeLink)
168 continue;
170 if (pDdeLink->Update())
171 bAny = true;
172 else
174 // Update failed. Notify the user.
175 OUString aFile = pDdeLink->GetTopic();
176 OUString aElem = pDdeLink->GetItem();
177 OUString aType = pDdeLink->GetAppl();
179 OUStringBuffer aBuf;
180 aBuf.append(OUString(ScResId(SCSTR_DDEDOC_NOT_LOADED)));
181 aBuf.append("\n\n");
182 aBuf.append("Source : ");
183 aBuf.append(aFile);
184 aBuf.append("\nElement : ");
185 aBuf.append(aElem);
186 aBuf.append("\nType : ");
187 aBuf.append(aType);
188 ScopedVclPtrInstance< MessageDialog > aBox(pWin, aBuf.makeStringAndClear());
189 aBox->Execute();
193 pMgr->CloseCachedComps();
195 return bAny;
198 void DocumentLinkManager::updateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem )
200 if (!mpImpl->mpLinkManager)
201 return;
203 sfx2::LinkManager* pMgr = mpImpl->mpLinkManager.get();
204 const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
206 for (const auto & rLink : rLinks)
208 ::sfx2::SvBaseLink* pBase = rLink.get();
209 ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase);
210 if (!pDdeLink)
211 continue;
213 if ( OUString(pDdeLink->GetAppl()) == rAppl &&
214 OUString(pDdeLink->GetTopic()) == rTopic &&
215 OUString(pDdeLink->GetItem()) == rItem )
217 pDdeLink->TryUpdate();
218 // Could be multiple (Mode), so continue searching
223 size_t DocumentLinkManager::getDdeLinkCount() const
225 if (!mpImpl->mpLinkManager)
226 return 0;
228 size_t nDdeCount = 0;
229 const sfx2::SvBaseLinks& rLinks = mpImpl->mpLinkManager->GetLinks();
230 for (const auto & rLink : rLinks)
232 ::sfx2::SvBaseLink* pBase = rLink.get();
233 ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase);
234 if (!pDdeLink)
235 continue;
237 ++nDdeCount;
240 return nDdeCount;
243 void DocumentLinkManager::disconnectDdeLinks()
245 if (!mpImpl->mpLinkManager)
246 return;
248 const sfx2::SvBaseLinks& rLinks = mpImpl->mpLinkManager->GetLinks();
249 for (const auto & rLink : rLinks)
251 ::sfx2::SvBaseLink* pBase = rLink.get();
252 ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase);
253 if (pDdeLink)
254 pDdeLink->Disconnect();
260 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */