Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/undo/areasave.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 <sfx2/linkmgr.hxx>
21
22
#include <areasave.hxx>
23
#include <arealink.hxx>
24
#include <document.hxx>
25
#include <documentlinkmgr.hxx>
26
#include <docsh.hxx>
27
28
ScAreaLinkSaver::ScAreaLinkSaver( const ScAreaLink& rSource ) :
29
0
    aFileName   ( rSource.GetFile() ),
30
0
    aFilterName ( rSource.GetFilter() ),
31
0
    aOptions    ( rSource.GetOptions() ),
32
0
    aSourceArea ( rSource.GetSource() ),
33
0
    aDestArea   ( rSource.GetDestArea() ),
34
0
    nRefreshDelaySeconds ( rSource.GetRefreshDelaySeconds() )       // seconds
35
0
{
36
0
}
37
38
bool ScAreaLinkSaver::IsEqualSource( const ScAreaLink& rCompare ) const
39
0
{
40
0
    return ( aFileName == rCompare.GetFile() &&
41
0
             aFilterName == rCompare.GetFilter() &&
42
0
             aOptions == rCompare.GetOptions() &&
43
0
             aSourceArea == rCompare.GetSource() &&
44
0
             nRefreshDelaySeconds == rCompare.GetRefreshDelaySeconds() );
45
0
}
46
47
bool ScAreaLinkSaver::IsEqual( const ScAreaLink& rCompare ) const
48
0
{
49
0
    return ( IsEqualSource( rCompare ) &&
50
0
             aDestArea == rCompare.GetDestArea() );
51
0
}
52
53
void ScAreaLinkSaver::WriteToLink( ScAreaLink& rLink ) const
54
0
{
55
0
    rLink.SetDestArea( aDestArea );
56
0
}
57
58
void ScAreaLinkSaver::InsertNewLink( ScDocument& rDoc )
59
0
{
60
    // (see ScUndoRemoveAreaLink::Undo)
61
62
0
    sfx2::LinkManager* pLinkManager = rDoc.GetLinkManager();
63
0
    ScDocShell* pObjSh = rDoc.GetDocumentShell();
64
65
0
    if ( pLinkManager && pObjSh )
66
0
    {
67
0
        ScAreaLink* pLink = new ScAreaLink( *pObjSh, aFileName, aFilterName, aOptions,
68
0
                                            aSourceArea, ScRange(aDestArea.aStart), nRefreshDelaySeconds );
69
0
        pLink->SetInCreate( true );
70
0
        pLink->SetDestArea( aDestArea );
71
0
        OUString aTmp1(aFilterName), aTmp2(aSourceArea);
72
0
        pLinkManager->InsertFileLink( *pLink, sfx2::SvBaseLinkObjectType::ClientFile, aFileName, &aTmp1, &aTmp2 );
73
0
        pLink->Update();
74
0
        pLink->SetInCreate( false );
75
0
    }
76
0
}
77
78
0
ScAreaLinkSaveCollection::ScAreaLinkSaveCollection() {}
79
80
0
ScAreaLinkSaveCollection::~ScAreaLinkSaveCollection() {}
81
82
bool ScAreaLinkSaveCollection::IsEqual( ScDocument& rDoc ) const
83
0
{
84
    // IsEqual can be checked in sequence.
85
    // Neither ref-update nor removing links will change the order.
86
87
0
    const sfx2::LinkManager* pLinkManager = rDoc.GetLinkManager();
88
0
    if (pLinkManager)
89
0
    {
90
0
        size_t nPos = 0;
91
0
        const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
92
0
        sal_uInt16 nLinkCount = rLinks.size();
93
0
        for (sal_uInt16 i=0; i<nLinkCount; i++)
94
0
        {
95
0
            ::sfx2::SvBaseLink* pBase = rLinks[i].get();
96
0
            if (auto pAreaLink = dynamic_cast<ScAreaLink*>( pBase))
97
0
            {
98
0
                if ( nPos >= size() || !(*this)[nPos].IsEqual( *pAreaLink ) )
99
0
                    return false;
100
101
0
                ++nPos;
102
0
            }
103
0
        }
104
0
        if ( nPos < size() )
105
0
            return false;           // fewer links in the document than in the save collection
106
0
    }
107
108
0
    return true;
109
0
}
110
111
static ScAreaLink* lcl_FindLink( const ::sfx2::SvBaseLinks& rLinks, const ScAreaLinkSaver& rSaver )
112
0
{
113
0
    sal_uInt16 nLinkCount = rLinks.size();
114
0
    for (sal_uInt16 i=0; i<nLinkCount; i++)
115
0
    {
116
0
        ::sfx2::SvBaseLink* pBase = rLinks[i].get();
117
0
        if ( auto pAreaLink = dynamic_cast<ScAreaLink*>( pBase) )
118
0
            if ( rSaver.IsEqualSource( *pAreaLink ) )
119
0
                return pAreaLink;     // found
120
0
    }
121
0
    return nullptr;    // not found
122
0
}
123
124
void ScAreaLinkSaveCollection::Restore( ScDocument& rDoc )
125
0
{
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).
130
131
0
    sfx2::LinkManager* pLinkManager = rDoc.GetDocLinkManager().getLinkManager(false);
132
0
    if (!pLinkManager)
133
0
        return;
134
135
0
    const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
136
0
    size_t nSaveCount = size();
137
0
    for (size_t nPos=0; nPos<nSaveCount; ++nPos)
138
0
    {
139
0
        ScAreaLinkSaver& rSaver = (*this)[nPos];
140
0
        ScAreaLink* pLink = lcl_FindLink( rLinks, rSaver );
141
0
        if ( pLink )
142
0
            rSaver.WriteToLink( *pLink );          // restore output position
143
0
        else
144
0
            rSaver.InsertNewLink( rDoc );          // re-insert deleted link
145
0
    }
146
0
}
147
148
std::unique_ptr<ScAreaLinkSaveCollection> ScAreaLinkSaveCollection::CreateFromDoc( ScDocument& rDoc )
149
0
{
150
0
    std::unique_ptr<ScAreaLinkSaveCollection> pColl;
151
152
0
    sfx2::LinkManager* pLinkManager = rDoc.GetLinkManager();
153
0
    if (pLinkManager)
154
0
    {
155
0
        const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
156
0
        sal_uInt16 nLinkCount = rLinks.size();
157
0
        for (sal_uInt16 i=0; i<nLinkCount; i++)
158
0
        {
159
0
            ::sfx2::SvBaseLink* pBase = rLinks[i].get();
160
0
            if (auto pAreaLink = dynamic_cast<ScAreaLink*>( pBase))
161
0
            {
162
0
                if (!pColl)
163
0
                    pColl.reset(new ScAreaLinkSaveCollection);
164
165
0
                pColl->push_back( ScAreaLinkSaver( *pAreaLink ) );
166
0
            }
167
0
        }
168
0
    }
169
170
0
    return pColl;
171
0
}
172
173
ScAreaLinkSaver& ScAreaLinkSaveCollection::operator [](size_t nIndex)
174
0
{
175
0
    return maData[nIndex];
176
0
}
177
178
const ScAreaLinkSaver& ScAreaLinkSaveCollection::operator [](size_t nIndex) const
179
0
{
180
0
    return maData[nIndex];
181
0
}
182
183
size_t ScAreaLinkSaveCollection::size() const
184
0
{
185
0
    return maData.size();
186
0
}
187
188
void ScAreaLinkSaveCollection::push_back(const ScAreaLinkSaver& p)
189
0
{
190
0
    maData.push_back(p);
191
0
}
192
193
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */