/src/libreoffice/sc/inc/sharedformula.hxx
Line | Count | Source (jump to first uncovered line) |
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 "formulacell.hxx" |
13 | | #include "mtvelements.hxx" |
14 | | |
15 | | #include <vector> |
16 | | |
17 | | #define USE_FORMULA_GROUP_LISTENER 1 |
18 | | |
19 | | namespace sc { |
20 | | |
21 | | class StartListeningContext; |
22 | | |
23 | | class SharedFormulaUtil |
24 | | { |
25 | | public: |
26 | | |
27 | | /** |
28 | | * Group formula cells stored in the passed container. The formula cells |
29 | | * in the container are assumed to be all <b>non-shared</b>. |
30 | | */ |
31 | | template<typename Iter> |
32 | | static void groupFormulaCells(const Iter& itBeg, const Iter& itEnd) |
33 | 0 | { |
34 | 0 | Iter it = itBeg; |
35 | 0 | ScFormulaCell* pPrev = *it; |
36 | 0 | ScFormulaCell* pCur = nullptr; |
37 | 0 | for (++it; it != itEnd; ++it, pPrev = pCur) |
38 | 0 | { |
39 | 0 | pCur = *it; |
40 | 0 | ScFormulaCell::CompareState eState = pCur->CompareByTokenArray(*pPrev); |
41 | 0 | if (eState == ScFormulaCell::NotEqual) |
42 | 0 | continue; |
43 | | |
44 | 0 | ScFormulaCellGroupRef xGroup = pPrev->GetCellGroup(); |
45 | 0 | if (xGroup) |
46 | 0 | { |
47 | | // Extend the group. |
48 | 0 | ++xGroup->mnLength; |
49 | 0 | pCur->SetCellGroup(xGroup); |
50 | 0 | continue; |
51 | 0 | } |
52 | | |
53 | | // Create a new group. |
54 | 0 | xGroup = pPrev->CreateCellGroup(2, eState == ScFormulaCell::EqualInvariant); |
55 | 0 | pCur->SetCellGroup(xGroup); |
56 | 0 | } |
57 | 0 | } |
58 | | |
59 | | /** Get shared formula top cell from position, if any, else nullptr. */ |
60 | | static const ScFormulaCell* getSharedTopFormulaCell(const CellStoreType::position_type& aPos); |
61 | | |
62 | | /** |
63 | | * Split existing shared formula range at specified position. The cell at |
64 | | * specified position becomes the top cell of the lower shared formula |
65 | | * range after this call. This method does nothing if the cell at |
66 | | * specified position is not a formula cell. |
67 | | * |
68 | | * @param aPos position of cell to examine. |
69 | | * @param pCxt context to be used, if any, may be nullptr. |
70 | | * |
71 | | * @return TRUE if there indeed was a split, else FALSE (e.g. split |
72 | | * position was top or bottom cell or no formula group). |
73 | | */ |
74 | | static bool splitFormulaCellGroup(const CellStoreType::position_type& aPos, sc::EndListeningContext* pCxt); |
75 | | |
76 | | /** |
77 | | * Split existing shared formula ranges at specified row positions. |
78 | | * |
79 | | * @param rCells cell storage container |
80 | | * @param rBounds row positions at which to split existing shared formula |
81 | | * ranges. Note that this method will directly modify this |
82 | | * parameter to sort and remove duplicates. |
83 | | * |
84 | | * @return TRUE if there indeed was a split, else FALSE (e.g. split |
85 | | * positions were only top or bottom cells or no formula group). |
86 | | */ |
87 | | static bool splitFormulaCellGroups(const ScDocument& rDoc, CellStoreType& rCells, std::vector<SCROW>& rBounds); |
88 | | |
89 | | /** |
90 | | * See if two specified adjacent formula cells can be merged, and if they |
91 | | * can, merge them into the same group. |
92 | | * |
93 | | * @param rPos position object of the first cell |
94 | | * @param rCell1 first cell |
95 | | * @param rCell2 second cell located immediately below the first cell. |
96 | | * |
97 | | * @return true if the cells are merged, false otherwise. If the two |
98 | | * cells already belong to the same group, it returns false. |
99 | | */ |
100 | | static bool joinFormulaCells( |
101 | | const CellStoreType::position_type& rPos, ScFormulaCell& rCell1, ScFormulaCell& rCell2 ); |
102 | | /** |
103 | | * Merge with an existing formula group (if any) located immediately above |
104 | | * if the cell at specified position is a formula cell, and its formula |
105 | | * tokens are identical to that of the above formula group. |
106 | | * |
107 | | * @param aPos position of cell to examine. |
108 | | * |
109 | | * @return true if the cells are merged, false otherwise. If the two |
110 | | * cells already belong to the same group, it returns false. |
111 | | */ |
112 | | static bool joinFormulaCellAbove( const CellStoreType::position_type& aPos ); |
113 | | |
114 | | /** |
115 | | * Turn a shared formula cell into a non-shared one, and split it off from |
116 | | * the adjacent formula cell groups. |
117 | | * |
118 | | * @param aPos position of cell to examine |
119 | | * @param rCell formula cell instance |
120 | | */ |
121 | | static void unshareFormulaCell(const CellStoreType::position_type& aPos, ScFormulaCell& rCell); |
122 | | |
123 | | /** |
124 | | * Make specified formula cells non-shared ones, and split them off from |
125 | | * their respective adjacent formula cell groups. |
126 | | * |
127 | | * @param rCells cell storage container |
128 | | * @param rRows row positions at which to unshare formula cells. |
129 | | */ |
130 | | static void unshareFormulaCells(const ScDocument& rDoc, CellStoreType& rCells, std::vector<SCROW>& rRows); |
131 | | |
132 | | /** |
133 | | * Have all formula cells belonging to a group start listening to their |
134 | | * references. |
135 | | * |
136 | | * @param rCxt context object. |
137 | | * @param ppSharedTop memory position of the pointer of the topmost |
138 | | * formula cell instance in the cell storage. The |
139 | | * caller is responsible for ensuring that it is indeed |
140 | | * the topmost cell of a shared formula group. |
141 | | */ |
142 | | static void startListeningAsGroup( StartListeningContext& rCxt, ScFormulaCell** ppSharedTop ); |
143 | | }; |
144 | | |
145 | | } |
146 | | |
147 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |