Coverage Report

Created: 2026-09-28 10:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/inc/columnspanset.hxx
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
#pragma once
11
12
#include "address.hxx"
13
14
#include <optional>
15
#include <vector>
16
#include <mdds/flat_segment_tree.hpp>
17
18
class ScDocument;
19
class ScColumn;
20
class ScMarkData;
21
class ScRangeList;
22
struct ScSheetLimits;
23
24
namespace sc {
25
26
struct ColumnBlockConstPosition;
27
class SingleColumnSpanSet;
28
29
struct RowSpan
30
{
31
    SCROW mnRow1;
32
    SCROW mnRow2;
33
34
    RowSpan(SCROW nRow1, SCROW nRow2);
35
};
36
37
struct SC_DLLPUBLIC ColRowSpan
38
{
39
    SCCOLROW mnStart;
40
    SCCOLROW mnEnd;
41
42
    ColRowSpan(SCCOLROW nStart, SCCOLROW nEnd);
43
};
44
45
/**
46
 * Structure that stores segments of boolean flags per column, and perform
47
 * custom action on those segments.
48
 */
49
class ColumnSpanSet
50
{
51
public:
52
    typedef mdds::flat_segment_tree<SCROW, bool> ColumnSpansType;
53
54
private:
55
    struct ColumnType
56
    {
57
        ColumnSpansType maSpans;
58
        ColumnSpansType::const_iterator miPos;
59
60
        ColumnType(SCROW nStart, SCROW nEnd, bool bInit);
61
        ColumnType(const ColumnType& rOther);
62
    };
63
64
    typedef std::vector<std::optional<ColumnType>> TableType;
65
66
    std::vector<TableType> maTables;
67
68
    ColumnType& getColumn(const ScDocument& rDoc, SCTAB nTab, SCCOL nCol);
69
70
public:
71
    class Action
72
    {
73
    public:
74
        virtual ~Action() = 0;
75
        virtual void startColumn(SCTAB nTab, SCCOL nCol);
76
        virtual void execute(const ScAddress& rPos, SCROW nLength, bool bVal) = 0;
77
    };
78
79
    class ColumnAction
80
    {
81
    public:
82
        virtual ~ColumnAction() = 0;
83
        virtual void startColumn(ScColumn* pCol) = 0;
84
        virtual void execute(SCROW nRow1, SCROW nRow2, bool bVal) = 0;
85
    };
86
87
    ColumnSpanSet();
88
    ColumnSpanSet(const ColumnSpanSet&) = delete;
89
    ColumnSpanSet& operator=(const ColumnSpanSet&) = delete;
90
0
    ColumnSpanSet(ColumnSpanSet&&) = default;
91
    ColumnSpanSet& operator=(ColumnSpanSet&&) = default;
92
    ~ColumnSpanSet();
93
94
    void set(const ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCROW nRow, bool bVal);
95
    void set(const ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCROW nRow1, SCROW nRow2, bool bVal);
96
    void set(const ScDocument& rDoc, const ScRange& rRange, bool bVal);
97
98
    void set(const ScDocument& rDoc, SCTAB nTab, SCCOL nCol, const SingleColumnSpanSet& rSingleSet, bool bVal );
99
100
    /**
101
     * Scan specified range in a specified sheet and mark all non-empty cells
102
     * with specified boolean value.
103
     */
104
    void scan(const ScDocument& rDoc, SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bVal);
105
106
    void executeAction(ScDocument& rDoc, Action& ac) const;
107
    void executeColumnAction(ScDocument& rDoc, ColumnAction& ac) const;
108
};
109
110
/**
111
 * Keep track of spans in a single column only.
112
 */
113
class SingleColumnSpanSet
114
{
115
public:
116
    typedef mdds::flat_segment_tree<SCROW, bool> ColumnSpansType;
117
118
    typedef std::vector<RowSpan> SpansType;
119
120
    SingleColumnSpanSet(ScSheetLimits const &);
121
122
    /**
123
     * Scan an entire column and tag all non-empty cell positions.
124
     */
125
    void scan(const ScColumn& rColumn);
126
127
    /**
128
     * Scan a column between specified range, and tag all non-empty cell
129
     * positions.
130
     */
131
    void scan(const ScColumn& rColumn, SCROW nStart, SCROW nEnd);
132
133
    void scan(
134
        ColumnBlockConstPosition& rBlockPos, const ScColumn& rColumn, SCROW nStart, SCROW nEnd);
135
136
    /**
137
     * Scan all marked data and tag all marked segments in specified column.
138
     */
139
    void scan(const ScMarkData& rMark, SCTAB nTab, SCCOL nCol);
140
141
    void scan(const ScRangeList& rRanges, SCTAB nTab, SCCOL nCol);
142
143
    void set(SCROW nRow1, SCROW nRow2, bool bVal);
144
145
    void getRows(std::vector<SCROW> &rRows) const;
146
147
    void getSpans(SpansType& rSpans) const;
148
149
    void swap( SingleColumnSpanSet& r );
150
151
    /** Whether there isn't any row tagged. */
152
    bool empty() const;
153
154
private:
155
    ScSheetLimits const & mrSheetLimits;
156
    ColumnSpansType maSpans;
157
};
158
159
/**
160
 * Optimized ColumnSpanSet version that operates on a single ScRange.
161
 */
162
class RangeColumnSpanSet
163
{
164
public:
165
    RangeColumnSpanSet( const ScRange& spanRange )
166
10.0k
         : range( spanRange ) {}
167
    void executeColumnAction(ScDocument& rDoc, sc::ColumnSpanSet::ColumnAction& ac) const;
168
private:
169
    ScRange range;
170
};
171
172
173
}
174
175
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */