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 <sfx2/linkmgr.hxx>
22 #include <areasave.hxx>
23 #include <arealink.hxx>
24 #include <document.hxx>
25 #include <documentlinkmgr.hxx>
28 ScAreaLinkSaver::ScAreaLinkSaver( const ScAreaLink
& rSource
) :
29 aFileName ( rSource
.GetFile() ),
30 aFilterName ( rSource
.GetFilter() ),
31 aOptions ( rSource
.GetOptions() ),
32 aSourceArea ( rSource
.GetSource() ),
33 aDestArea ( rSource
.GetDestArea() ),
34 nRefreshDelaySeconds ( rSource
.GetRefreshDelaySeconds() ) // seconds
38 bool ScAreaLinkSaver::IsEqualSource( const ScAreaLink
& rCompare
) const
40 return ( aFileName
== rCompare
.GetFile() &&
41 aFilterName
== rCompare
.GetFilter() &&
42 aOptions
== rCompare
.GetOptions() &&
43 aSourceArea
== rCompare
.GetSource() &&
44 nRefreshDelaySeconds
== rCompare
.GetRefreshDelaySeconds() );
47 bool ScAreaLinkSaver::IsEqual( const ScAreaLink
& rCompare
) const
49 return ( IsEqualSource( rCompare
) &&
50 aDestArea
== rCompare
.GetDestArea() );
53 void ScAreaLinkSaver::WriteToLink( ScAreaLink
& rLink
) const
55 rLink
.SetDestArea( aDestArea
);
58 void ScAreaLinkSaver::InsertNewLink( ScDocument
* pDoc
)
60 // (see ScUndoRemoveAreaLink::Undo)
62 sfx2::LinkManager
* pLinkManager
= pDoc
->GetLinkManager();
63 ScDocShell
* pObjSh
= pDoc
->GetDocumentShell();
65 if ( pLinkManager
&& pObjSh
)
67 ScAreaLink
* pLink
= new ScAreaLink( pObjSh
, aFileName
, aFilterName
, aOptions
,
68 aSourceArea
, ScRange(aDestArea
.aStart
), nRefreshDelaySeconds
);
69 pLink
->SetInCreate( true );
70 pLink
->SetDestArea( aDestArea
);
71 OUString
aTmp1(aFilterName
), aTmp2(aSourceArea
);
72 pLinkManager
->InsertFileLink( *pLink
, sfx2::SvBaseLinkObjectType::ClientFile
, aFileName
, &aTmp1
, &aTmp2
);
74 pLink
->SetInCreate( false );
78 ScAreaLinkSaveCollection::ScAreaLinkSaveCollection() {}
80 ScAreaLinkSaveCollection::~ScAreaLinkSaveCollection() {}
82 bool ScAreaLinkSaveCollection::IsEqual( const ScDocument
* pDoc
) const
84 // IsEqual can be checked in sequence.
85 // Neither ref-update nor removing links will change the order.
87 const sfx2::LinkManager
* pLinkManager
= pDoc
->GetLinkManager();
91 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
92 sal_uInt16 nLinkCount
= rLinks
.size();
93 for (sal_uInt16 i
=0; i
<nLinkCount
; i
++)
95 ::sfx2::SvBaseLink
* pBase
= rLinks
[i
].get();
96 if (auto pAreaLink
= dynamic_cast<ScAreaLink
*>( pBase
))
98 if ( nPos
>= size() || !(*this)[nPos
].IsEqual( *pAreaLink
) )
105 return false; // fewer links in the document than in the save collection
111 static ScAreaLink
* lcl_FindLink( const ::sfx2::SvBaseLinks
& rLinks
, const ScAreaLinkSaver
& rSaver
)
113 sal_uInt16 nLinkCount
= rLinks
.size();
114 for (sal_uInt16 i
=0; i
<nLinkCount
; i
++)
116 ::sfx2::SvBaseLink
* pBase
= rLinks
[i
].get();
117 if ( auto pAreaLink
= dynamic_cast<ScAreaLink
*>( pBase
) )
118 if ( rSaver
.IsEqualSource( *pAreaLink
) )
119 return pAreaLink
; // found
121 return nullptr; // not found
124 void ScAreaLinkSaveCollection::Restore( ScDocument
* pDoc
)
126 // The save collection may contain additional entries that are not in the document.
127 // They must be inserted again.
128 // Entries from the save collection must be searched via source data, as the order
129 // of links changes if deleted entries are re-added to the link manager (always at the end).
131 sfx2::LinkManager
* pLinkManager
= pDoc
->GetDocLinkManager().getLinkManager(false);
135 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
136 size_t nSaveCount
= size();
137 for (size_t nPos
=0; nPos
<nSaveCount
; ++nPos
)
139 ScAreaLinkSaver
& rSaver
= (*this)[nPos
];
140 ScAreaLink
* pLink
= lcl_FindLink( rLinks
, rSaver
);
142 rSaver
.WriteToLink( *pLink
); // restore output position
144 rSaver
.InsertNewLink( pDoc
); // re-insert deleted link
148 std::unique_ptr
<ScAreaLinkSaveCollection
> ScAreaLinkSaveCollection::CreateFromDoc( const ScDocument
* pDoc
)
150 std::unique_ptr
<ScAreaLinkSaveCollection
> pColl
;
152 sfx2::LinkManager
* pLinkManager
= const_cast<ScDocument
*>(pDoc
)->GetLinkManager();
155 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
156 sal_uInt16 nLinkCount
= rLinks
.size();
157 for (sal_uInt16 i
=0; i
<nLinkCount
; i
++)
159 ::sfx2::SvBaseLink
* pBase
= rLinks
[i
].get();
160 if (auto pAreaLink
= dynamic_cast<ScAreaLink
*>( pBase
))
163 pColl
.reset(new ScAreaLinkSaveCollection
);
165 pColl
->push_back( ScAreaLinkSaver( *pAreaLink
) );
173 ScAreaLinkSaver
& ScAreaLinkSaveCollection::operator [](size_t nIndex
)
175 return maData
[nIndex
];
178 const ScAreaLinkSaver
& ScAreaLinkSaveCollection::operator [](size_t nIndex
) const
180 return maData
[nIndex
];
183 size_t ScAreaLinkSaveCollection::size() const
185 return maData
.size();
188 void ScAreaLinkSaveCollection::push_back(const ScAreaLinkSaver
& p
)
193 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */