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