LibreOffice Module sc (master) 1
PivotLayoutTreeListData.cxx
Go to the documentation of this file.
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
12#include <memory>
13#include <string_view>
14
16#include <PivotLayoutDialog.hxx>
17
18#include <vcl/event.hxx>
19#include <pivot.hxx>
20#include <globstr.hrc>
21#include <scresid.hxx>
22
23namespace
24{
25
26OUString lclGetFunctionMaskName(const PivotFunc nFunctionMask)
27{
28 TranslateId pStrId;
29 switch (nFunctionMask)
30 {
31 case PivotFunc::Sum: pStrId = STR_FUN_TEXT_SUM; break;
32 case PivotFunc::Count: pStrId = STR_FUN_TEXT_COUNT; break;
33 case PivotFunc::Average: pStrId = STR_FUN_TEXT_AVG; break;
34 case PivotFunc::Median: pStrId = STR_FUN_TEXT_MEDIAN; break;
35 case PivotFunc::Max: pStrId = STR_FUN_TEXT_MAX; break;
36 case PivotFunc::Min: pStrId = STR_FUN_TEXT_MIN; break;
37 case PivotFunc::Product: pStrId = STR_FUN_TEXT_PRODUCT; break;
38 case PivotFunc::CountNum: pStrId = STR_FUN_TEXT_COUNT; break;
39 case PivotFunc::StdDev: pStrId = STR_FUN_TEXT_STDDEV; break;
40 case PivotFunc::StdDevP: pStrId = STR_FUN_TEXT_STDDEV; break;
41 case PivotFunc::StdVar: pStrId = STR_FUN_TEXT_VAR; break;
42 case PivotFunc::StdVarP: pStrId = STR_FUN_TEXT_VAR; break;
43 default:
44 assert(false);
45 break;
46 }
47 if (pStrId)
48 return ScResId(pStrId);
49 else
50 return OUString();
51}
52
53OUString lclCreateDataItemName(const PivotFunc nFunctionMask, std::u16string_view rName, const sal_uInt8 nDuplicationCount)
54{
55 OUString aBuffer = lclGetFunctionMaskName(nFunctionMask) + " - " + rName;
56 if(nDuplicationCount > 0)
57 {
58 aBuffer += " " + OUString::number(nDuplicationCount);
59 }
60 return aBuffer;
61}
62
63} // anonymous namespace
64
65ScPivotLayoutTreeListData::ScPivotLayoutTreeListData(std::unique_ptr<weld::TreeView> xControl)
66 : ScPivotLayoutTreeListBase(std::move(xControl))
67{
68 mxControl->connect_key_press(LINK(this, ScPivotLayoutTreeListData, KeyInputHdl));
69 mxControl->connect_row_activated(LINK(this, ScPivotLayoutTreeListData, DoubleClickHdl));
70}
71
73{
74 if (mpFunctionDlg)
75 {
76 mpFunctionDlg->Response(RET_CANCEL);
78 }
79}
80
82{
83 int nEntry = mxControl->get_cursor_index();
84 if (nEntry == -1)
85 return true;
86
87 ScItemValue* pCurrentItemValue = weld::fromId<ScItemValue*>(mxControl->get_id(nEntry));
88 ScPivotFuncData& rCurrentFunctionData = pCurrentItemValue->maFunctionData;
89
90 SCCOL nCurrentColumn = rCurrentFunctionData.mnCol;
91 ScDPLabelData& rCurrentLabelData = mpParent->GetLabelData(nCurrentColumn);
92
94
95 mpFunctionDlg = pFactory->CreateScDPFunctionDlg(mxControl.get(), mpParent->GetLabelDataVector(), rCurrentLabelData, rCurrentFunctionData);
96
97 mpFunctionDlg->StartExecuteAsync([this, pCurrentItemValue, nEntry](int nResult) mutable {
98 if (nResult == RET_OK)
99 {
100 ScPivotFuncData& rFunctionData = pCurrentItemValue->maFunctionData;
101 rFunctionData.mnFuncMask = mpFunctionDlg->GetFuncMask();
102 ScDPLabelData& rLabelData = mpParent->GetLabelData(rFunctionData.mnCol);
103 rLabelData.mnFuncMask = mpFunctionDlg->GetFuncMask();
104
105 rFunctionData.maFieldRef = mpFunctionDlg->GetFieldRef();
106
107 ScDPLabelData& rDFData = mpParent->GetLabelData(rFunctionData.mnCol);
108
109 AdjustDuplicateCount(pCurrentItemValue);
110
111 OUString sDataItemName = lclCreateDataItemName(
112 rFunctionData.mnFuncMask,
113 rDFData.maName,
114 rFunctionData.mnDupCount);
115
116 mxControl->set_text(nEntry, sDataItemName);
117 }
118
119 mpFunctionDlg->disposeOnce();
120 });
121
122 return true;
123}
124
126{
127 mxControl->clear();
128 maDataItemValues.clear();
129
130 for (const ScPivotField& rField : rDataFields)
131 {
132 if (rField.nCol == PIVOT_DATA_FIELD)
133 continue;
134
135 SCCOL nColumn;
136 if (rField.mnOriginalDim >= 0)
137 nColumn = rField.mnOriginalDim;
138 else
139 nColumn = rField.nCol;
140
141 ScItemValue* pOriginalItemValue = mpParent->GetItem(nColumn);
142 ScItemValue* pItemValue = new ScItemValue(pOriginalItemValue->maName, nColumn, rField.nFuncMask);
143
144 pItemValue->mpOriginalItemValue = pOriginalItemValue;
145 pItemValue->maFunctionData.mnOriginalDim = rField.mnOriginalDim;
146 pItemValue->maFunctionData.maFieldRef = rField.maFieldRef;
147
148 AdjustDuplicateCount(pItemValue);
149 OUString sDataItemName = lclCreateDataItemName(pItemValue->maFunctionData.mnFuncMask,
150 pItemValue->maName,
151 pItemValue->maFunctionData.mnDupCount);
152
153 maDataItemValues.push_back(std::unique_ptr<ScItemValue>(pItemValue));
154 OUString sId(weld::toId(pItemValue));
155 mxControl->append(sId, sDataItemName);
156 }
157}
158
159void ScPivotLayoutTreeListData::PushDataFieldNames(std::vector<ScDPName>& rDataFieldNames)
160{
161 std::unique_ptr<weld::TreeIter> xLoopEntry(mxControl->make_iterator());
162 if (!mxControl->get_iter_first(*xLoopEntry))
163 return;
164
165 do
166 {
167 ScItemValue* pEachItemValue = weld::fromId<ScItemValue*>(mxControl->get_id(*xLoopEntry));
168 SCCOL nColumn = pEachItemValue->maFunctionData.mnCol;
169
170 ScDPLabelData& rLabelData = mpParent->GetLabelData(nColumn);
171
172 if (rLabelData.maName.isEmpty())
173 continue;
174
175 OUString sLayoutName = rLabelData.maLayoutName;
176 if (sLayoutName.isEmpty())
177 {
178 sLayoutName = lclCreateDataItemName(
179 pEachItemValue->maFunctionData.mnFuncMask,
180 pEachItemValue->maName,
181 pEachItemValue->maFunctionData.mnDupCount);
182 }
183
184 rDataFieldNames.emplace_back(rLabelData.maName, sLayoutName, rLabelData.mnDupCount);
185 } while (mxControl->iter_next(*xLoopEntry));
186}
187
189{
190 if (rSource.count_selected_rows() <=0)
191 return;
192
193 ScItemValue* pItemValue = weld::fromId<ScItemValue*>(rSource.get_selected_id());
194
195 if (mpParent->IsDataElement(pItemValue->maFunctionData.mnCol))
196 return;
197
198 if (&rSource == mxControl.get())
199 {
200 OUString sText = mxControl->get_selected_text();
201 OUString sId(weld::toId(pItemValue));
202 mxControl->remove_id(sId);
203 mxControl->insert(nullptr, nTarget, &sText, &sId, nullptr, nullptr, false, nullptr);
204 }
205 else
206 {
207 InsertEntryForItem(pItemValue->mpOriginalItemValue, nTarget);
208 }
209}
210
212{
213 ScItemValue* pDataItemValue = new ScItemValue(pItemValue);
214 pDataItemValue->mpOriginalItemValue = pItemValue;
215 maDataItemValues.push_back(std::unique_ptr<ScItemValue>(pDataItemValue));
216
217 ScPivotFuncData& rFunctionData = pDataItemValue->maFunctionData;
218
219 if (rFunctionData.mnFuncMask == PivotFunc::NONE ||
220 rFunctionData.mnFuncMask == PivotFunc::Auto)
221 {
222 rFunctionData.mnFuncMask = PivotFunc::Sum;
223 }
224
225 AdjustDuplicateCount(pDataItemValue);
226
227 OUString sDataName = lclCreateDataItemName(
228 rFunctionData.mnFuncMask,
229 pDataItemValue->maName,
230 rFunctionData.mnDupCount);
231
232 OUString sId(weld::toId(pDataItemValue));
233 mxControl->insert(nullptr, nPosition, &sDataName, &sId, nullptr, nullptr, false, nullptr);
234}
235
237{
238 ScPivotFuncData& rInputFunctionData = pInputItemValue->maFunctionData;
239
240 bool bFoundDuplicate = false;
241
242 rInputFunctionData.mnDupCount = 0;
243 sal_uInt8 nMaxDuplicateCount = 0;
244
245 std::unique_ptr<weld::TreeIter> xEachEntry(mxControl->make_iterator());
246 if (!mxControl->get_iter_first(*xEachEntry))
247 return;
248 do
249 {
250 ScItemValue* pItemValue = weld::fromId<ScItemValue*>(mxControl->get_id(*xEachEntry));
251 if (pItemValue == pInputItemValue)
252 continue;
253
254 ScPivotFuncData& rFunctionData = pItemValue->maFunctionData;
255
256 if (rFunctionData.mnCol == rInputFunctionData.mnCol &&
257 rFunctionData.mnFuncMask == rInputFunctionData.mnFuncMask)
258 {
259 bFoundDuplicate = true;
260 if(rFunctionData.mnDupCount > nMaxDuplicateCount)
261 nMaxDuplicateCount = rFunctionData.mnDupCount;
262 }
263 } while (mxControl->iter_next(*xEachEntry));
264
265 if(bFoundDuplicate)
266 {
267 rInputFunctionData.mnDupCount = nMaxDuplicateCount + 1;
268 }
269}
270
271IMPL_LINK(ScPivotLayoutTreeListData, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
272{
273 vcl::KeyCode aCode = rKeyEvent.GetKeyCode();
274 sal_uInt16 nCode = aCode.GetCode();
275
276 if (nCode == KEY_DELETE)
277 {
278 int nEntry = mxControl->get_cursor_index();
279 if (nEntry != -1)
280 mxControl->remove(nEntry);
281 return true;
282 }
283
284 return false;
285}
286
287/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
IMPL_LINK_NOARG(ScPivotLayoutTreeListData, DoubleClickHdl, weld::TreeView &, bool)
IMPL_LINK(ScPivotLayoutTreeListData, KeyInputHdl, const KeyEvent &, rKeyEvent, bool)
virtual VclPtr< AbstractScDPFunctionDlg > CreateScDPFunctionDlg(weld::Widget *pParent, const ScDPLabelDataVector &rLabelVec, const ScDPLabelData &rLabelData, const ScPivotFuncData &rFuncData)=0
static SC_DLLPUBLIC ScAbstractDialogFactory * Create()
Definition: scabstdlg.cxx:37
ScPivotFuncData maFunctionData
ScItemValue * mpOriginalItemValue
ScDPLabelData & GetLabelData(SCCOL nColumn)
bool IsDataElement(SCCOL nColumn)
ScItemValue * GetItem(SCCOL nColumn)
std::unique_ptr< weld::TreeView > mxControl
virtual void InsertEntryForSourceTarget(weld::TreeView &rSource, int nTarget) override
void FillDataField(ScPivotFieldVector &rDataFields)
void AdjustDuplicateCount(ScItemValue *pInputItemValue)
VclPtr< AbstractScDPFunctionDlg > mpFunctionDlg
ScPivotLayoutTreeListData(std::unique_ptr< weld::TreeView > xControl)
void PushDataFieldNames(std::vector< ScDPName > &rDataFieldNames)
std::vector< std::unique_ptr< ScItemValue > > maDataItemValues
virtual ~ScPivotLayoutTreeListData() override
void InsertEntryForItem(ScItemValue *pItemValue, int nPosition)
void clear()
sal_uInt16 GetCode() const
virtual int count_selected_rows() const=0
virtual OUString get_selected_id() const=0
RegionData_Impl * mpParent
PivotFunc
Definition: dpglobal.hxx:24
constexpr sal_uInt16 KEY_DELETE
OUString toId(const void *pValue)
#define PIVOT_DATA_FIELD
Definition: pivot.hxx:54
std::vector< ScPivotField > ScPivotFieldVector
Definition: pivot.hxx:129
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
OUString maName
Original name of the dimension.
Definition: pivot.hxx:68
OUString maLayoutName
Layout name (display name)
Definition: pivot.hxx:69
sal_uInt8 mnDupCount
Definition: pivot.hxx:76
PivotFunc mnFuncMask
Page/Column/Row subtotal function.
Definition: pivot.hxx:73
css::sheet::DataPilotFieldReference maFieldRef
Definition: pivot.hxx:158
sal_uInt8 mnDupCount
Definition: pivot.hxx:163
tools::Long mnOriginalDim
Definition: pivot.hxx:160
PivotFunc mnFuncMask
Definition: pivot.hxx:161
unsigned char sal_uInt8
sal_Int16 SCCOL
Definition: types.hxx:21
OUString sId
RET_OK
RET_CANCEL
std::unique_ptr< char[]> aBuffer