Coverage Report

Created: 2025-12-31 10:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/namedlg/namemgrtable.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
10
//ScRangeManagerTable
11
#include <memory>
12
#include <global.hxx>
13
#include <globstr.hrc>
14
#include <o3tl/safeint.hxx>
15
#include <scresid.hxx>
16
#include <globalnames.hxx>
17
#include <namemgrtable.hxx>
18
#include <rangenam.hxx>
19
20
#include <unotools/charclass.hxx>
21
#include <vcl/weld/weld.hxx>
22
#include <tools/link.hxx>
23
24
void ScRangeManagerTable::GetCurrentLine(ScRangeNameLine& rLine)
25
0
{
26
0
    std::unique_ptr<weld::TreeIter> xCurrentEntry(m_xTreeView->make_iterator());
27
0
    if (m_xTreeView->get_cursor(xCurrentEntry.get()))
28
0
        GetLine(rLine, *xCurrentEntry);
29
0
}
30
31
void ScRangeManagerTable::DeleteSelectedEntries()
32
0
{
33
0
    std::vector<int> aRows = m_xTreeView->get_selected_rows();
34
0
    std::sort(aRows.begin(), aRows.end());
35
0
    for (auto it = aRows.rbegin(); it != aRows.rend(); ++it)
36
0
        m_xTreeView->remove(*it);
37
0
}
38
39
bool ScRangeManagerTable::IsMultiSelection() const
40
0
{
41
0
    return m_xTreeView->count_selected_rows() > 1;
42
0
}
43
44
void ScRangeManagerTable::SetEntry(const ScRangeNameLine& rLine)
45
0
{
46
0
    for (int i = 0, nEntryCount = m_xTreeView->n_children(); i < nEntryCount; ++i)
47
0
    {
48
0
        if (rLine.aName == m_xTreeView->get_text(i, 0)
49
0
            && rLine.aScope == m_xTreeView->get_text(i, 2))
50
0
        {
51
0
            m_xTreeView->set_cursor(i);
52
0
        }
53
0
    }
54
0
}
55
56
ScRangeManagerTable::ScRangeManagerTable(std::unique_ptr<weld::TreeView> xTreeView,
57
                                         const std::map<OUString, ScRangeName>& rRangeMap,
58
                                         const ScAddress& rPos)
59
0
    : m_xTreeView(std::move(xTreeView))
60
0
    , maGlobalString(ScResId(STR_GLOBAL_SCOPE))
61
0
    , m_RangeMap(rRangeMap)
62
0
    , maPos(rPos)
63
0
    , m_nId(0)
64
0
    , mbNeedUpdate(true)
65
0
{
66
0
    auto nColWidth = m_xTreeView->get_size_request().Width() / 7;
67
0
    std::vector<int> aWidths{ o3tl::narrowing<int>(nColWidth * 2),
68
0
                              o3tl::narrowing<int>(nColWidth * 3) };
69
0
    m_xTreeView->set_column_fixed_widths(aWidths);
70
71
0
    Init();
72
0
    m_xTreeView->set_selection_mode(SelectionMode::Multiple);
73
0
    m_xTreeView->connect_size_allocate(LINK(this, ScRangeManagerTable, SizeAllocHdl));
74
0
    m_xTreeView->connect_visible_range_changed(LINK(this, ScRangeManagerTable, VisRowsScrolledHdl));
75
0
}
76
77
IMPL_LINK_NOARG(ScRangeManagerTable, VisRowsScrolledHdl, weld::TreeView&, void)
78
0
{
79
0
    CheckForFormulaString();
80
0
}
81
82
const ScRangeData* ScRangeManagerTable::findRangeData(const ScRangeNameLine& rLine)
83
0
{
84
0
    const ScRangeName* pRangeName;
85
0
    if (rLine.aScope == maGlobalString)
86
0
    {
87
0
        const auto iter = m_RangeMap.find(STR_GLOBAL_RANGE_NAME);
88
0
        assert(iter != m_RangeMap.end());
89
0
        pRangeName = &iter->second;
90
0
    }
91
0
    else
92
0
    {
93
0
        const auto iter = m_RangeMap.find(rLine.aScope);
94
0
        assert(iter != m_RangeMap.end());
95
0
        pRangeName = &iter->second;
96
0
    }
97
98
0
    return pRangeName->findByUpperName(ScGlobal::getCharClass().uppercase(rLine.aName));
99
0
}
100
101
void ScRangeManagerTable::CheckForFormulaString()
102
0
{
103
0
    if (UpdatesBlocked())
104
0
        return;
105
106
0
    auto lambda = [this](weld::TreeIter& rEntry) {
107
0
        OUString sId(m_xTreeView->get_id(rEntry));
108
0
        std::map<OUString, bool>::const_iterator itr = maCalculatedFormulaEntries.find(sId);
109
0
        if (itr == maCalculatedFormulaEntries.end() || !itr->second)
110
0
        {
111
0
            ScRangeNameLine aLine;
112
0
            GetLine(aLine, rEntry);
113
0
            const ScRangeData* pData = findRangeData(aLine);
114
0
            OUString aFormulaString = pData->GetSymbol(maPos);
115
0
            m_xTreeView->set_text(rEntry, aFormulaString, 1);
116
0
            maCalculatedFormulaEntries.insert(std::pair<OUString, bool>(sId, true));
117
0
        }
118
0
        return false;
119
0
    };
120
121
    // ensure all visible entries are up to date
122
0
    m_xTreeView->visible_foreach(lambda);
123
    // and ensure all selected entries are up to date
124
0
    m_xTreeView->selected_foreach(lambda);
125
0
}
126
127
0
IMPL_LINK_NOARG(ScRangeManagerTable, SizeAllocHdl, const Size&, void) { CheckForFormulaString(); }
128
129
void ScRangeManagerTable::addEntry(const ScRangeNameLine& rLine, bool bSetCurEntry)
130
0
{
131
0
    int nRow = m_xTreeView->n_children();
132
0
    m_xTreeView->append();
133
0
    m_xTreeView->set_text(nRow, rLine.aName, 0);
134
0
    m_xTreeView->set_text(nRow, rLine.aExpression, 1);
135
0
    m_xTreeView->set_text(nRow, rLine.aScope, 2);
136
    // just unique to track which one has been cached by maCalculatedFormulaEntries
137
0
    m_xTreeView->set_id(nRow, OUString::number(m_nId++));
138
0
    if (bSetCurEntry)
139
0
        m_xTreeView->set_cursor(nRow);
140
0
}
141
142
void ScRangeManagerTable::GetLine(ScRangeNameLine& rLine, const weld::TreeIter& rEntry)
143
0
{
144
0
    rLine.aName = m_xTreeView->get_text(rEntry, 0);
145
0
    rLine.aExpression = m_xTreeView->get_text(rEntry, 1);
146
0
    rLine.aScope = m_xTreeView->get_text(rEntry, 2);
147
0
}
148
149
void ScRangeManagerTable::Init()
150
0
{
151
0
    m_xTreeView->freeze();
152
0
    m_xTreeView->clear();
153
0
    for (auto const& itr : m_RangeMap)
154
0
    {
155
0
        const ScRangeName& rLocalRangeName = itr.second;
156
0
        ScRangeNameLine aLine;
157
0
        if (itr.first == STR_GLOBAL_RANGE_NAME)
158
0
            aLine.aScope = maGlobalString;
159
0
        else
160
0
            aLine.aScope = itr.first;
161
0
        for (const auto& rEntry : rLocalRangeName)
162
0
        {
163
            // Database and hidden named ranges are not shown in the Manage Names dialog
164
0
            if (!rEntry.second->HasType(ScRangeData::Type::Database)
165
0
                && !rEntry.second->HasType(ScRangeData::Type::Hidden))
166
0
            {
167
0
                aLine.aName = rEntry.second->GetName();
168
0
                addEntry(aLine, false);
169
0
            }
170
0
        }
171
0
    }
172
0
    m_xTreeView->thaw();
173
0
}
174
175
std::vector<ScRangeNameLine> ScRangeManagerTable::GetSelectedEntries()
176
0
{
177
0
    std::vector<ScRangeNameLine> aSelectedEntries;
178
0
    m_xTreeView->selected_foreach([this, &aSelectedEntries](weld::TreeIter& rEntry) {
179
0
        ScRangeNameLine aLine;
180
0
        GetLine(aLine, rEntry);
181
0
        aSelectedEntries.push_back(aLine);
182
0
        return false;
183
0
    });
184
0
    return aSelectedEntries;
185
0
}
186
187
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */