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