1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
13 #include <string_view>
15 #include <PivotLayoutTreeListData.hxx>
16 #include <PivotLayoutDialog.hxx>
18 #include <vcl/event.hxx>
20 #include <globstr.hrc>
21 #include <scresid.hxx>
26 OUString
lclGetFunctionMaskName(const PivotFunc nFunctionMask
)
29 switch (nFunctionMask
)
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;
48 return ScResId(pStrId
);
53 OUString
lclCreateDataItemName(const PivotFunc nFunctionMask
, std::u16string_view rName
, const sal_uInt8 nDuplicationCount
)
55 OUString aBuffer
= lclGetFunctionMaskName(nFunctionMask
) + " - " + rName
;
56 if(nDuplicationCount
> 0)
58 aBuffer
+= " " + OUString::number(nDuplicationCount
);
63 } // anonymous namespace
65 ScPivotLayoutTreeListData::ScPivotLayoutTreeListData(std::unique_ptr
<weld::TreeView
> xControl
)
66 : ScPivotLayoutTreeListBase(std::move(xControl
))
68 mxControl
->connect_key_press(LINK(this, ScPivotLayoutTreeListData
, KeyInputHdl
));
69 mxControl
->connect_row_activated(LINK(this, ScPivotLayoutTreeListData
, DoubleClickHdl
));
72 ScPivotLayoutTreeListData::~ScPivotLayoutTreeListData()
76 mpFunctionDlg
->Response(RET_CANCEL
);
77 mpFunctionDlg
.clear();
81 IMPL_LINK_NOARG(ScPivotLayoutTreeListData
, DoubleClickHdl
, weld::TreeView
&, bool)
83 int nEntry
= mxControl
->get_cursor_index();
87 ScItemValue
* pCurrentItemValue
= weld::fromId
<ScItemValue
*>(mxControl
->get_id(nEntry
));
88 ScPivotFuncData
& rCurrentFunctionData
= pCurrentItemValue
->maFunctionData
;
90 SCCOL nCurrentColumn
= rCurrentFunctionData
.mnCol
;
91 ScDPLabelData
& rCurrentLabelData
= mpParent
->GetLabelData(nCurrentColumn
);
93 ScAbstractDialogFactory
* pFactory
= ScAbstractDialogFactory::Create();
95 mpFunctionDlg
= pFactory
->CreateScDPFunctionDlg(mxControl
.get(), mpParent
->GetLabelDataVector(), rCurrentLabelData
, rCurrentFunctionData
);
97 mpFunctionDlg
->StartExecuteAsync([this, pCurrentItemValue
, nEntry
](int nResult
) mutable {
98 if (nResult
== RET_OK
)
100 ScPivotFuncData
& rFunctionData
= pCurrentItemValue
->maFunctionData
;
101 rFunctionData
.mnFuncMask
= mpFunctionDlg
->GetFuncMask();
102 ScDPLabelData
& rLabelData
= mpParent
->GetLabelData(rFunctionData
.mnCol
);
103 rLabelData
.mnFuncMask
= mpFunctionDlg
->GetFuncMask();
105 rFunctionData
.maFieldRef
= mpFunctionDlg
->GetFieldRef();
107 ScDPLabelData
& rDFData
= mpParent
->GetLabelData(rFunctionData
.mnCol
);
109 AdjustDuplicateCount(pCurrentItemValue
);
111 OUString sDataItemName
= lclCreateDataItemName(
112 rFunctionData
.mnFuncMask
,
114 rFunctionData
.mnDupCount
);
116 mxControl
->set_text(nEntry
, sDataItemName
);
119 mpFunctionDlg
->disposeOnce();
125 void ScPivotLayoutTreeListData::FillDataField(ScPivotFieldVector
& rDataFields
)
128 maDataItemValues
.clear();
130 for (const ScPivotField
& rField
: rDataFields
)
132 if (rField
.nCol
== PIVOT_DATA_FIELD
)
136 if (rField
.mnOriginalDim
>= 0)
137 nColumn
= rField
.mnOriginalDim
;
139 nColumn
= rField
.nCol
;
141 ScItemValue
* pOriginalItemValue
= mpParent
->GetItem(nColumn
);
142 ScItemValue
* pItemValue
= new ScItemValue(pOriginalItemValue
->maName
, nColumn
, rField
.nFuncMask
);
144 pItemValue
->mpOriginalItemValue
= pOriginalItemValue
;
145 pItemValue
->maFunctionData
.mnOriginalDim
= rField
.mnOriginalDim
;
146 pItemValue
->maFunctionData
.maFieldRef
= rField
.maFieldRef
;
148 AdjustDuplicateCount(pItemValue
);
149 OUString sDataItemName
= lclCreateDataItemName(pItemValue
->maFunctionData
.mnFuncMask
,
151 pItemValue
->maFunctionData
.mnDupCount
);
153 maDataItemValues
.push_back(std::unique_ptr
<ScItemValue
>(pItemValue
));
154 OUString
sId(weld::toId(pItemValue
));
155 mxControl
->append(sId
, sDataItemName
);
159 void ScPivotLayoutTreeListData::PushDataFieldNames(std::vector
<ScDPName
>& rDataFieldNames
)
161 std::unique_ptr
<weld::TreeIter
> xLoopEntry(mxControl
->make_iterator());
162 if (!mxControl
->get_iter_first(*xLoopEntry
))
167 ScItemValue
* pEachItemValue
= weld::fromId
<ScItemValue
*>(mxControl
->get_id(*xLoopEntry
));
168 SCCOL nColumn
= pEachItemValue
->maFunctionData
.mnCol
;
170 ScDPLabelData
& rLabelData
= mpParent
->GetLabelData(nColumn
);
172 if (rLabelData
.maName
.isEmpty())
175 OUString sLayoutName
= rLabelData
.maLayoutName
;
176 if (sLayoutName
.isEmpty())
178 sLayoutName
= lclCreateDataItemName(
179 pEachItemValue
->maFunctionData
.mnFuncMask
,
180 pEachItemValue
->maName
,
181 pEachItemValue
->maFunctionData
.mnDupCount
);
184 rDataFieldNames
.emplace_back(rLabelData
.maName
, sLayoutName
, rLabelData
.mnDupCount
);
185 } while (mxControl
->iter_next(*xLoopEntry
));
188 void ScPivotLayoutTreeListData::InsertEntryForSourceTarget(weld::TreeView
& rSource
, int nTarget
)
190 if (rSource
.count_selected_rows() <=0)
193 ScItemValue
* pItemValue
= weld::fromId
<ScItemValue
*>(rSource
.get_selected_id());
195 if (mpParent
->IsDataElement(pItemValue
->maFunctionData
.mnCol
))
198 if (&rSource
== mxControl
.get())
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);
207 InsertEntryForItem(pItemValue
->mpOriginalItemValue
, nTarget
);
211 void ScPivotLayoutTreeListData::InsertEntryForItem(ScItemValue
* pItemValue
, int nPosition
)
213 ScItemValue
* pDataItemValue
= new ScItemValue(pItemValue
);
214 pDataItemValue
->mpOriginalItemValue
= pItemValue
;
215 maDataItemValues
.push_back(std::unique_ptr
<ScItemValue
>(pDataItemValue
));
217 ScPivotFuncData
& rFunctionData
= pDataItemValue
->maFunctionData
;
219 if (rFunctionData
.mnFuncMask
== PivotFunc::NONE
||
220 rFunctionData
.mnFuncMask
== PivotFunc::Auto
)
222 rFunctionData
.mnFuncMask
= PivotFunc::Sum
;
225 AdjustDuplicateCount(pDataItemValue
);
227 OUString sDataName
= lclCreateDataItemName(
228 rFunctionData
.mnFuncMask
,
229 pDataItemValue
->maName
,
230 rFunctionData
.mnDupCount
);
232 OUString
sId(weld::toId(pDataItemValue
));
233 mxControl
->insert(nullptr, nPosition
, &sDataName
, &sId
, nullptr, nullptr, false, nullptr);
236 void ScPivotLayoutTreeListData::AdjustDuplicateCount(ScItemValue
* pInputItemValue
)
238 ScPivotFuncData
& rInputFunctionData
= pInputItemValue
->maFunctionData
;
240 bool bFoundDuplicate
= false;
242 rInputFunctionData
.mnDupCount
= 0;
243 sal_uInt8 nMaxDuplicateCount
= 0;
245 std::unique_ptr
<weld::TreeIter
> xEachEntry(mxControl
->make_iterator());
246 if (!mxControl
->get_iter_first(*xEachEntry
))
250 ScItemValue
* pItemValue
= weld::fromId
<ScItemValue
*>(mxControl
->get_id(*xEachEntry
));
251 if (pItemValue
== pInputItemValue
)
254 ScPivotFuncData
& rFunctionData
= pItemValue
->maFunctionData
;
256 if (rFunctionData
.mnCol
== rInputFunctionData
.mnCol
&&
257 rFunctionData
.mnFuncMask
== rInputFunctionData
.mnFuncMask
)
259 bFoundDuplicate
= true;
260 if(rFunctionData
.mnDupCount
> nMaxDuplicateCount
)
261 nMaxDuplicateCount
= rFunctionData
.mnDupCount
;
263 } while (mxControl
->iter_next(*xEachEntry
));
267 rInputFunctionData
.mnDupCount
= nMaxDuplicateCount
+ 1;
271 IMPL_LINK(ScPivotLayoutTreeListData
, KeyInputHdl
, const KeyEvent
&, rKeyEvent
, bool)
273 vcl::KeyCode aCode
= rKeyEvent
.GetKeyCode();
274 sal_uInt16 nCode
= aCode
.GetCode();
276 if (nCode
== KEY_DELETE
)
278 int nEntry
= mxControl
->get_cursor_index();
280 mxControl
->remove(nEntry
);
287 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */