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 <PivotLayoutTreeList.hxx>
13 #include <PivotLayoutDialog.hxx>
14 #include <reffact.hxx>
15
16 #include <rangeutl.hxx>
17 #include <uiitems.hxx>
18 #include <dputil.hxx>
19 #include <dbdocfun.hxx>
20 #include <dpsave.hxx>
21 #include <dpshttab.hxx>
22 #include <scmod.hxx>
23
24 #include <memory>
25 #include <vector>
26
27 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
28 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
29
30 using namespace css::uno;
31 using namespace css::sheet;
32
ScItemValue(OUString const & aName,SCCOL nColumn,PivotFunc nFunctionMask)33 ScItemValue::ScItemValue(OUString const & aName, SCCOL nColumn, PivotFunc nFunctionMask) :
34 maName(aName),
35 maFunctionData(nColumn, nFunctionMask),
36 mpOriginalItemValue(this)
37 {}
38
ScItemValue(const ScItemValue * pInputItemValue)39 ScItemValue::ScItemValue(const ScItemValue* pInputItemValue) :
40 maName(pInputItemValue->maName),
41 maFunctionData(pInputItemValue->maFunctionData),
42 mpOriginalItemValue(this)
43 {}
44
~ScItemValue()45 ScItemValue::~ScItemValue()
46 {}
47
48 namespace
49 {
50
lclGetRangeForNamedRange(OUString const & aName,const ScDocument & rDocument)51 ScRange lclGetRangeForNamedRange(OUString const & aName, const ScDocument& rDocument)
52 {
53 ScRange aInvalidRange(ScAddress::INITIALIZE_INVALID);
54 ScRangeName* pRangeName = rDocument.GetRangeName();
55 if (pRangeName == nullptr)
56 return aInvalidRange;
57
58 const ScRangeData* pData = pRangeName->findByUpperName(aName.toAsciiUpperCase());
59 if (pData == nullptr)
60 return aInvalidRange;
61
62 ScRange aRange;
63 if (pData->IsReference(aRange))
64 return aRange;
65
66 return aInvalidRange;
67 }
68
69 }
70
ScPivotLayoutDialog(SfxBindings * pSfxBindings,SfxChildWindow * pChildWindow,weld::Window * pParent,ScViewData * pViewData,const ScDPObject * pPivotTableObject,bool bNewPivotTable)71 ScPivotLayoutDialog::ScPivotLayoutDialog(
72 SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow, weld::Window* pParent,
73 ScViewData* pViewData, const ScDPObject* pPivotTableObject, bool bNewPivotTable)
74 : ScAnyRefDlgController(pSfxBindings, pChildWindow, pParent, "modules/scalc/ui/pivottablelayoutdialog.ui", "PivotTableLayout")
75 , maPivotTableObject(*pPivotTableObject)
76 , mpPreviouslyFocusedListBox(nullptr)
77 , mpViewData(pViewData)
78 , mrDocument(pViewData->GetDocument())
79 , mbNewPivotTable(bNewPivotTable)
80 , maAddressDetails(mrDocument.GetAddressConvention(), 0, 0)
81 , mbDialogLostFocus(false)
82 , mpActiveEdit(nullptr)
83 , mxListBoxField(new ScPivotLayoutTreeListLabel(m_xBuilder->weld_tree_view("listbox-fields")))
84 , mxListBoxPage(new ScPivotLayoutTreeList(m_xBuilder->weld_tree_view("listbox-page")))
85 , mxListBoxColumn(new ScPivotLayoutTreeList(m_xBuilder->weld_tree_view("listbox-column")))
86 , mxListBoxRow(new ScPivotLayoutTreeList(m_xBuilder->weld_tree_view("listbox-row")))
87 , mxListBoxData(new ScPivotLayoutTreeListData(m_xBuilder->weld_tree_view("listbox-data")))
88 , mxCheckIgnoreEmptyRows(m_xBuilder->weld_check_button("check-ignore-empty-rows"))
89 , mxCheckTotalColumns(m_xBuilder->weld_check_button("check-total-columns"))
90 , mxCheckAddFilter(m_xBuilder->weld_check_button("check-add-filter"))
91 , mxCheckIdentifyCategories(m_xBuilder->weld_check_button("check-identify-categories"))
92 , mxCheckTotalRows(m_xBuilder->weld_check_button("check-total-rows"))
93 , mxCheckDrillToDetail(m_xBuilder->weld_check_button("check-drill-to-details"))
94 , mxSourceRadioNamedRange(m_xBuilder->weld_radio_button("source-radio-named-range"))
95 , mxSourceRadioSelection(m_xBuilder->weld_radio_button("source-radio-selection"))
96 , mxSourceListBox(m_xBuilder->weld_combo_box("source-list"))
97 , mxSourceEdit(new formula::RefEdit(m_xBuilder->weld_entry("source-edit")))
98 , mxSourceButton(new formula::RefButton(m_xBuilder->weld_button("source-button")))
99 , mxDestinationRadioNewSheet(m_xBuilder->weld_radio_button("destination-radio-new-sheet"))
100 , mxDestinationRadioNamedRange(m_xBuilder->weld_radio_button("destination-radio-named-range"))
101 , mxDestinationRadioSelection(m_xBuilder->weld_radio_button("destination-radio-selection"))
102 , mxDestinationListBox(m_xBuilder->weld_combo_box("destination-list"))
103 , mxDestinationEdit(new formula::RefEdit(m_xBuilder->weld_entry("destination-edit")))
104 , mxDestinationButton(new formula::RefButton(m_xBuilder->weld_button("destination-button")))
105 , mxBtnOK(m_xBuilder->weld_button("ok"))
106 , mxBtnCancel(m_xBuilder->weld_button("cancel"))
107 , mxSourceFrame(m_xBuilder->weld_frame("frame2"))
108 , mxSourceLabel(mxSourceFrame->weld_label_widget())
109 , mxDestFrame(m_xBuilder->weld_frame("frame1"))
110 , mxDestLabel(mxDestFrame->weld_label_widget())
111 , mxOptions(m_xBuilder->weld_expander("options"))
112 , mxMore(m_xBuilder->weld_expander("more"))
113 {
114 // Source UI
115 Link<weld::Toggleable&,void> aLink2 = LINK(this, ScPivotLayoutDialog, ToggleSource);
116 mxSourceRadioNamedRange->connect_toggled(aLink2);
117 mxSourceRadioSelection->connect_toggled(aLink2);
118
119 mxSourceEdit->SetReferences(this, mxSourceLabel.get());
120 mxSourceButton->SetReferences(this, mxSourceEdit.get());
121
122 Link<formula::RefEdit&,void> aEditLink = LINK(this, ScPivotLayoutDialog, GetEditFocusHandler);
123 mxDestinationEdit->SetGetFocusHdl(aEditLink);
124 mxSourceEdit->SetGetFocusHdl(aEditLink);
125
126 aEditLink = LINK(this, ScPivotLayoutDialog, LoseEditFocusHandler);
127 mxDestinationEdit->SetLoseFocusHdl(aEditLink);
128 mxSourceEdit->SetLoseFocusHdl(aEditLink);
129
130 mxSourceEdit->SetModifyHdl(LINK(this, ScPivotLayoutDialog, SourceEditModified));
131 mxSourceListBox->connect_changed(LINK(this, ScPivotLayoutDialog, SourceListSelected));
132
133 // Destination UI
134 aLink2 = LINK(this, ScPivotLayoutDialog, ToggleDestination);
135 mxDestinationRadioNewSheet->connect_toggled(aLink2);
136 mxDestinationRadioNamedRange->connect_toggled(aLink2);
137 mxDestinationRadioSelection->connect_toggled(aLink2);
138
139 mxDestinationEdit->SetReferences(this, mxDestLabel.get());
140 mxDestinationButton->SetReferences(this, mxDestinationEdit.get());
141
142 Link<formula::RefButton&,void> aButtonLink = LINK(this, ScPivotLayoutDialog, GetButtonFocusHandler);
143 mxSourceButton->SetGetFocusHdl(aButtonLink);
144 mxDestinationButton->SetGetFocusHdl(aButtonLink);
145
146 aButtonLink = LINK(this, ScPivotLayoutDialog, LoseButtonFocusHandler);
147 mxSourceButton->SetLoseFocusHdl(aButtonLink);
148 mxDestinationButton->SetLoseFocusHdl(aButtonLink);
149
150 // Buttons
151 mxBtnCancel->connect_clicked(LINK(this, ScPivotLayoutDialog, CancelClicked));
152 mxBtnOK->connect_clicked(LINK(this, ScPivotLayoutDialog, OKClicked));
153
154 // Initialize Data
155 maPivotTableObject.FillOldParam(maPivotParameters);
156 maPivotTableObject.FillLabelData(maPivotParameters);
157
158 mxListBoxField->Setup (this);
159 mxListBoxPage->Setup (this, ScPivotLayoutTreeList::PAGE_LIST);
160 mxListBoxColumn->Setup(this, ScPivotLayoutTreeList::COLUMN_LIST);
161 mxListBoxRow->Setup (this, ScPivotLayoutTreeList::ROW_LIST);
162 mxListBoxData->Setup (this);
163
164 FillValuesToListBoxes();
165
166 // Initialize Options
167 const ScDPSaveData* pSaveData = maPivotTableObject.GetSaveData();
168 if (pSaveData == nullptr)
169 {
170 mxCheckAddFilter->set_active(false);
171 mxCheckDrillToDetail->set_active(false);
172 }
173 else
174 {
175 mxCheckAddFilter->set_active(pSaveData->GetFilterButton());
176 mxCheckDrillToDetail->set_active(pSaveData->GetDrillDown());
177 }
178
179 mxCheckIgnoreEmptyRows->set_active(maPivotParameters.bIgnoreEmptyRows);
180 mxCheckIdentifyCategories->set_active(maPivotParameters.bDetectCategories);
181 mxCheckTotalColumns->set_active(maPivotParameters.bMakeTotalCol);
182 mxCheckTotalRows->set_active(maPivotParameters.bMakeTotalRow);
183
184 SetupSource();
185 SetupDestination();
186 }
187
~ScPivotLayoutDialog()188 ScPivotLayoutDialog::~ScPivotLayoutDialog()
189 {
190 }
191
SetupSource()192 void ScPivotLayoutDialog::SetupSource()
193 {
194 mxSourceListBox->clear();
195
196 ScRange aSourceRange;
197 OUString sSourceNamedRangeName;
198
199 if (maPivotTableObject.GetSheetDesc())
200 {
201 const ScSheetSourceDesc* pSheetSourceDesc = maPivotTableObject.GetSheetDesc();
202 aSourceRange = pSheetSourceDesc->GetSourceRange();
203
204 if(!aSourceRange.IsValid())
205 {
206 // Source is probably a DB Range
207 mxSourceRadioNamedRange->set_sensitive(false);
208 mxSourceRadioSelection->set_sensitive(false);
209 ToggleSource();
210 return;
211 }
212 else
213 {
214 OUString aSourceRangeName = aSourceRange.Format(mrDocument, ScRefFlags::RANGE_ABS_3D, maAddressDetails);
215 mxSourceEdit->SetText(aSourceRangeName);
216 }
217 }
218 else
219 {
220 mxSourceRadioNamedRange->set_sensitive(false);
221 mxSourceRadioSelection->set_sensitive(false);
222 ToggleSource();
223 return;
224 }
225
226 // Setup Named Ranges
227 bool bIsNamedRange = false;
228
229 ScAreaNameIterator aIterator(mrDocument);
230 OUString aEachName;
231 ScRange aEachRange;
232
233 while (aIterator.Next(aEachName, aEachRange))
234 {
235 if (!aIterator.WasDBName())
236 {
237 mxSourceListBox->append_text(aEachName);
238 if (aEachRange == aSourceRange)
239 {
240 sSourceNamedRangeName = aEachName;
241 bIsNamedRange = true;
242 }
243 }
244 }
245
246 bool bSourceBoxHasEntries = mxSourceListBox->get_count() > 0;
247
248 if (bIsNamedRange)
249 {
250 mxSourceListBox->set_active_text(sSourceNamedRangeName);
251 mxSourceRadioNamedRange->set_active(true);
252 }
253 else
254 {
255 // If entries - select first entry
256 mxSourceListBox->set_active(bSourceBoxHasEntries ? 0 : -1);
257 mxSourceRadioSelection->set_active(true);
258 }
259
260 // If no entries disable the radio button.
261 if (!bSourceBoxHasEntries)
262 mxSourceRadioNamedRange->set_sensitive(false);
263
264 ToggleSource();
265 }
266
SetupDestination()267 void ScPivotLayoutDialog::SetupDestination()
268 {
269 mxDestinationListBox->clear();
270
271 // Fill up named ranges
272 ScAreaNameIterator aIterator(mrDocument);
273 OUString aName;
274 ScRange aRange;
275
276 while (aIterator.Next(aName, aRange))
277 {
278 if (!aIterator.WasDBName())
279 {
280 mxDestinationListBox->append_text(aName);
281 }
282 }
283
284 // If entries - select first entry, otherwise disable the radio button.
285 if (mxDestinationListBox->get_count() > 0)
286 mxDestinationListBox->set_active(0);
287 else
288 mxDestinationRadioNamedRange->set_sensitive(false);
289
290 //
291 if (mbNewPivotTable)
292 {
293 mxDestinationRadioNewSheet->set_active(true);
294 }
295 else
296 {
297 if (maPivotParameters.nTab != MAXTAB + 1)
298 {
299 ScAddress aAddress(maPivotParameters.nCol, maPivotParameters.nRow, maPivotParameters.nTab);
300 OUString aAddressString = aAddress.Format(ScRefFlags::ADDR_ABS_3D, &mrDocument, maAddressDetails);
301 mxDestinationEdit->SetText(aAddressString);
302 mxDestinationRadioSelection->set_active(true);
303 }
304 }
305
306 ToggleDestination();
307 }
308
FillValuesToListBoxes()309 void ScPivotLayoutDialog::FillValuesToListBoxes()
310 {
311 mxListBoxField->FillLabelFields(maPivotParameters.maLabelArray);
312 mxListBoxData->FillDataField(maPivotParameters.maDataFields);
313 mxListBoxColumn->FillFields(maPivotParameters.maColFields);
314 mxListBoxRow->FillFields(maPivotParameters.maRowFields);
315 mxListBoxPage->FillFields(maPivotParameters.maPageFields);
316 }
317
SetActive()318 void ScPivotLayoutDialog::SetActive()
319 {
320 if (mbDialogLostFocus)
321 {
322 mbDialogLostFocus = false;
323 if(mpActiveEdit != nullptr)
324 {
325 mpActiveEdit->GrabFocus();
326 if (mpActiveEdit == mxSourceEdit.get())
327 UpdateSourceRange();
328 }
329 }
330 else
331 {
332 m_xDialog->grab_focus();
333 }
334
335 RefInputDone();
336 }
337
SetReference(const ScRange & rReferenceRange,ScDocument & rDocument)338 void ScPivotLayoutDialog::SetReference(const ScRange& rReferenceRange, ScDocument& rDocument)
339 {
340 if (!mbDialogLostFocus)
341 return;
342
343 if (mpActiveEdit == nullptr)
344 return;
345
346 if (rReferenceRange.aStart != rReferenceRange.aEnd)
347 RefInputStart(mpActiveEdit);
348
349 OUString aReferenceString = rReferenceRange.Format(rDocument, ScRefFlags::RANGE_ABS_3D, maAddressDetails);
350
351 if (mpActiveEdit == mxSourceEdit.get())
352 {
353 mxSourceEdit->SetRefString(aReferenceString);
354 }
355 else if (mpActiveEdit == mxDestinationEdit.get())
356 {
357 mxDestinationEdit->SetRefString(aReferenceString);
358 }
359 }
360
IsRefInputMode() const361 bool ScPivotLayoutDialog::IsRefInputMode() const
362 {
363 return mbDialogLostFocus;
364 }
365
ItemInserted(const ScItemValue * pItemValue,ScPivotLayoutTreeList::SvPivotTreeListType eType)366 void ScPivotLayoutDialog::ItemInserted(const ScItemValue* pItemValue, ScPivotLayoutTreeList::SvPivotTreeListType eType)
367 {
368 if (pItemValue == nullptr)
369 return;
370
371 switch (eType)
372 {
373 case ScPivotLayoutTreeList::ROW_LIST:
374 case ScPivotLayoutTreeList::COLUMN_LIST:
375 case ScPivotLayoutTreeList::PAGE_LIST:
376 {
377 mxListBoxRow->RemoveEntryForItem(pItemValue);
378 mxListBoxColumn->RemoveEntryForItem(pItemValue);
379 mxListBoxPage->RemoveEntryForItem(pItemValue);
380 }
381 break;
382 case ScPivotLayoutTreeList::LABEL_LIST:
383 {
384 mxListBoxRow->RemoveEntryForItem(pItemValue);
385 mxListBoxColumn->RemoveEntryForItem(pItemValue);
386 mxListBoxPage->RemoveEntryForItem(pItemValue);
387 mxListBoxData->RemoveEntryForItem(pItemValue);
388 }
389 break;
390 default:
391 break;
392 }
393 }
394
UpdateSourceRange()395 void ScPivotLayoutDialog::UpdateSourceRange()
396 {
397 if (!maPivotTableObject.GetSheetDesc())
398 return;
399
400 ScSheetSourceDesc aSourceSheet = *maPivotTableObject.GetSheetDesc();
401
402 if (mxSourceRadioNamedRange->get_active())
403 {
404 OUString aEntryString = mxSourceListBox->get_active_text();
405 ScRange aSourceRange = lclGetRangeForNamedRange(aEntryString, mrDocument);
406 if (!aSourceRange.IsValid() || aSourceSheet.GetSourceRange() == aSourceRange)
407 return;
408 aSourceSheet.SetRangeName(aEntryString);
409 }
410 else if (mxSourceRadioSelection->get_active())
411 {
412 OUString aSourceString = mxSourceEdit->GetText();
413 ScRange aSourceRange;
414 ScRefFlags nResult = aSourceRange.Parse(aSourceString, mrDocument, maAddressDetails);
415
416 bool bIsValid = (nResult & ScRefFlags::VALID) == ScRefFlags::VALID; // aSourceString is valid
417
418 mxSourceEdit->SetRefValid(true);
419
420 if (bIsValid)
421 {
422 ScRefAddress aStart;
423 ScRefAddress aEnd;
424
425 ConvertDoubleRef(mrDocument, aSourceString, 1, aStart, aEnd, maAddressDetails);
426 aSourceRange.aStart = aStart.GetAddress();
427 aSourceRange.aEnd = aEnd.GetAddress();
428 }
429 else
430 {
431 aSourceRange = lclGetRangeForNamedRange(aSourceString, mrDocument);
432 }
433
434 if (!aSourceRange.IsValid())
435 {
436 mxSourceEdit->SetRefValid(false);
437 return;
438 }
439
440 if (aSourceSheet.GetSourceRange() == aSourceRange)
441 return;
442
443 aSourceSheet.SetSourceRange(aSourceRange);
444 if (aSourceSheet.CheckSourceRange() != nullptr)
445 {
446 mxSourceEdit->SetRefValid(false);
447 return;
448 }
449 }
450 else
451 {
452 return;
453 }
454
455 maPivotTableObject.SetSheetDesc(aSourceSheet);
456 maPivotTableObject.FillOldParam(maPivotParameters);
457 maPivotTableObject.FillLabelData(maPivotParameters);
458
459 FillValuesToListBoxes();
460 }
461
ApplyChanges()462 void ScPivotLayoutDialog::ApplyChanges()
463 {
464 ScDPSaveData aSaveData;
465 ApplySaveData(aSaveData);
466 ApplyLabelData(aSaveData);
467
468 ScDPObject *pOldDPObj = mrDocument.GetDPAtCursor( maPivotParameters.nCol, maPivotParameters.nRow, maPivotParameters.nTab);
469 ScRange aDestinationRange;
470 bool bToNewSheet = false;
471
472 if (!GetDestination(aDestinationRange, bToNewSheet))
473 return;
474
475 SetDispatcherLock(false);
476 SwitchToDocument();
477
478 sal_uInt16 nWhichPivot = SC_MOD()->GetPool().GetWhich(SID_PIVOT_TABLE);
479 ScPivotItem aPivotItem(nWhichPivot, &aSaveData, &aDestinationRange, bToNewSheet);
480 mpViewData->GetViewShell()->SetDialogDPObject(std::make_unique<ScDPObject>(maPivotTableObject));
481
482
483 SfxDispatcher* pDispatcher = GetBindings().GetDispatcher();
484 SfxCallMode const nCallMode = SfxCallMode::SLOT | SfxCallMode::RECORD;
485 const SfxPoolItem* pResult = pDispatcher->ExecuteList(SID_PIVOT_TABLE,
486 nCallMode, { &aPivotItem });
487
488 if (pResult != nullptr)
489 {
490 // existing pivot table might have moved to a new range or a new sheet
491 if ( pOldDPObj != nullptr )
492 {
493 const ScRange& rOldRange = pOldDPObj->GetOutRange();
494
495 ScDPObject *pDPObj = nullptr;
496 // FIXME: if the new range overlaps with the old one, the table actually doesn't move
497 // and shouldn't therefore be deleted
498 if ( ( ( rOldRange != aDestinationRange ) && !rOldRange.In( aDestinationRange ) )
499 || bToNewSheet )
500 {
501 pDPObj = mrDocument.GetDPAtCursor( maPivotParameters.nCol, maPivotParameters.nRow, maPivotParameters.nTab);
502 }
503 if (pDPObj)
504 {
505 ScDBDocFunc aFunc( *(mpViewData->GetDocShell() ));
506 aFunc.RemovePivotTable( *pDPObj, true, false);
507 mpViewData->GetView()->CursorPosChanged();
508 }
509 }
510 return;
511 }
512
513 SetDispatcherLock(true);
514 }
515
ApplySaveData(ScDPSaveData & rSaveData)516 void ScPivotLayoutDialog::ApplySaveData(ScDPSaveData& rSaveData)
517 {
518 rSaveData.SetIgnoreEmptyRows(mxCheckIgnoreEmptyRows->get_active());
519 rSaveData.SetRepeatIfEmpty(mxCheckIdentifyCategories->get_active());
520 rSaveData.SetColumnGrand(mxCheckTotalColumns->get_active());
521 rSaveData.SetRowGrand(mxCheckTotalRows->get_active());
522 rSaveData.SetFilterButton(mxCheckAddFilter->get_active());
523 rSaveData.SetDrillDown(mxCheckDrillToDetail->get_active());
524
525 Reference<XDimensionsSupplier> xSource = maPivotTableObject.GetSource();
526
527 ScPivotFieldVector aPageFieldVector;
528 mxListBoxPage->PushEntriesToPivotFieldVector(aPageFieldVector);
529 ScDPObject::ConvertOrientation(rSaveData, aPageFieldVector, DataPilotFieldOrientation_PAGE,
530 xSource, maPivotParameters.maLabelArray);
531
532 ScPivotFieldVector aColFieldVector;
533 mxListBoxColumn->PushEntriesToPivotFieldVector(aColFieldVector);
534 ScDPObject::ConvertOrientation(rSaveData, aColFieldVector, DataPilotFieldOrientation_COLUMN,
535 xSource, maPivotParameters.maLabelArray);
536
537 ScPivotFieldVector aRowFieldVector;
538 mxListBoxRow->PushEntriesToPivotFieldVector(aRowFieldVector);
539 ScDPObject::ConvertOrientation(rSaveData, aRowFieldVector, DataPilotFieldOrientation_ROW,
540 xSource, maPivotParameters.maLabelArray);
541
542 ScPivotFieldVector aDataFieldVector;
543 mxListBoxData->PushEntriesToPivotFieldVector(aDataFieldVector);
544 ScDPObject::ConvertOrientation(rSaveData, aDataFieldVector, DataPilotFieldOrientation_DATA,
545 xSource, maPivotParameters.maLabelArray,
546 &aColFieldVector, &aRowFieldVector, &aPageFieldVector);
547 }
548
ApplyLabelData(const ScDPSaveData & rSaveData)549 void ScPivotLayoutDialog::ApplyLabelData(const ScDPSaveData& rSaveData)
550 {
551 ScDPLabelDataVector& rLabelDataVector = GetLabelDataVector();
552
553 for (std::unique_ptr<ScDPLabelData> const & pLabelData : rLabelDataVector)
554 {
555 OUString aUnoName = ScDPUtil::createDuplicateDimensionName(pLabelData->maName, pLabelData->mnDupCount);
556 ScDPSaveDimension* pSaveDimensions = rSaveData.GetExistingDimensionByName(aUnoName);
557
558 if (pSaveDimensions == nullptr)
559 continue;
560
561 pSaveDimensions->SetUsedHierarchy(pLabelData->mnUsedHier);
562 pSaveDimensions->SetShowEmpty(pLabelData->mbShowAll);
563 pSaveDimensions->SetRepeatItemLabels(pLabelData->mbRepeatItemLabels);
564 pSaveDimensions->SetSortInfo(&pLabelData->maSortInfo);
565 pSaveDimensions->SetLayoutInfo(&pLabelData->maLayoutInfo);
566 pSaveDimensions->SetAutoShowInfo(&pLabelData->maShowInfo);
567
568 bool bManualSort = (pLabelData->maSortInfo.Mode == DataPilotFieldSortMode::MANUAL);
569
570 for (ScDPLabelData::Member const & rLabelMember : pLabelData->maMembers)
571 {
572 ScDPSaveMember* pMember = pSaveDimensions->GetMemberByName(rLabelMember.maName);
573
574 if (bManualSort || !rLabelMember.mbVisible || !rLabelMember.mbShowDetails)
575 {
576 pMember->SetIsVisible(rLabelMember.mbVisible);
577 pMember->SetShowDetails(rLabelMember.mbShowDetails);
578 }
579 }
580 }
581 }
582
GetDestination(ScRange & aDestinationRange,bool & bToNewSheet)583 bool ScPivotLayoutDialog::GetDestination(ScRange& aDestinationRange, bool& bToNewSheet)
584 {
585 bToNewSheet = false;
586
587 if (mxDestinationRadioNamedRange->get_active())
588 {
589 OUString aName = mxDestinationListBox->get_active_text();
590 aDestinationRange = lclGetRangeForNamedRange(aName, mrDocument);
591 if (!aDestinationRange.IsValid())
592 return false;
593 }
594 else if (mxDestinationRadioSelection->get_active())
595 {
596 ScAddress aAddress;
597 aAddress.Parse(mxDestinationEdit->GetText(), mrDocument, maAddressDetails);
598 aDestinationRange = ScRange(aAddress);
599 }
600 else
601 {
602 bToNewSheet = true;
603 aDestinationRange = ScRange(maPivotParameters.nCol, maPivotParameters.nRow, maPivotParameters.nTab);
604 }
605 return true;
606 }
607
GetItem(SCCOL nColumn)608 ScItemValue* ScPivotLayoutDialog::GetItem(SCCOL nColumn)
609 {
610 return mxListBoxField->GetItem(nColumn);
611 }
612
IsDataElement(SCCOL nColumn)613 bool ScPivotLayoutDialog::IsDataElement(SCCOL nColumn)
614 {
615 return mxListBoxField->IsDataElement(nColumn);
616 }
617
GetLabelData(SCCOL nColumn)618 ScDPLabelData& ScPivotLayoutDialog::GetLabelData(SCCOL nColumn)
619 {
620 return *maPivotParameters.maLabelArray[nColumn];
621 }
622
PushDataFieldNames(std::vector<ScDPName> & rDataFieldNames)623 void ScPivotLayoutDialog::PushDataFieldNames(std::vector<ScDPName>& rDataFieldNames)
624 {
625 mxListBoxData->PushDataFieldNames(rDataFieldNames);
626 }
627
Close()628 void ScPivotLayoutDialog::Close()
629 {
630 DoClose(ScPivotLayoutWrapper::GetChildWindowId());
631 SfxDialogController::Close();
632 }
633
IMPL_LINK_NOARG(ScPivotLayoutDialog,OKClicked,weld::Button &,void)634 IMPL_LINK_NOARG( ScPivotLayoutDialog, OKClicked, weld::Button&, void )
635 {
636 /* tdf#137726 hide so it's not a candidate to be parent of any error
637 messages that may appear because this dialog is going to disappear on
638 response(RET_OK) and the error dialog is not run in its own event loop
639 but instead async */
640 m_xDialog->hide();
641
642 ApplyChanges();
643 m_xDialog->response(RET_OK);
644 }
645
IMPL_LINK_NOARG(ScPivotLayoutDialog,CancelClicked,weld::Button &,void)646 IMPL_LINK_NOARG( ScPivotLayoutDialog, CancelClicked, weld::Button&, void )
647 {
648 m_xDialog->response(RET_CANCEL);
649 }
650
IMPL_LINK(ScPivotLayoutDialog,GetEditFocusHandler,formula::RefEdit &,rCtrl,void)651 IMPL_LINK(ScPivotLayoutDialog, GetEditFocusHandler, formula::RefEdit&, rCtrl, void)
652 {
653 mpActiveEdit = &rCtrl;
654 mpActiveEdit->SelectAll();
655 }
656
IMPL_LINK(ScPivotLayoutDialog,GetButtonFocusHandler,formula::RefButton &,rCtrl,void)657 IMPL_LINK(ScPivotLayoutDialog, GetButtonFocusHandler, formula::RefButton&, rCtrl, void)
658 {
659 mpActiveEdit = nullptr;
660
661 if (&rCtrl == mxSourceButton.get())
662 mpActiveEdit = mxSourceEdit.get();
663 else if (&rCtrl == mxDestinationButton.get())
664 mpActiveEdit = mxDestinationEdit.get();
665
666 if (mpActiveEdit)
667 mpActiveEdit->SelectAll();
668 }
669
IMPL_LINK_NOARG(ScPivotLayoutDialog,LoseEditFocusHandler,formula::RefEdit &,void)670 IMPL_LINK_NOARG(ScPivotLayoutDialog, LoseEditFocusHandler, formula::RefEdit&, void)
671 {
672 mbDialogLostFocus = !m_xDialog->has_toplevel_focus();
673 }
674
IMPL_LINK_NOARG(ScPivotLayoutDialog,LoseButtonFocusHandler,formula::RefButton &,void)675 IMPL_LINK_NOARG(ScPivotLayoutDialog, LoseButtonFocusHandler, formula::RefButton&, void)
676 {
677 mbDialogLostFocus = !m_xDialog->has_toplevel_focus();
678 }
679
IMPL_LINK_NOARG(ScPivotLayoutDialog,SourceListSelected,weld::ComboBox &,void)680 IMPL_LINK_NOARG(ScPivotLayoutDialog, SourceListSelected, weld::ComboBox&, void)
681 {
682 UpdateSourceRange();
683 }
684
IMPL_LINK_NOARG(ScPivotLayoutDialog,SourceEditModified,formula::RefEdit &,void)685 IMPL_LINK_NOARG(ScPivotLayoutDialog, SourceEditModified, formula::RefEdit&, void)
686 {
687 UpdateSourceRange();
688 }
689
IMPL_LINK_NOARG(ScPivotLayoutDialog,ToggleSource,weld::Toggleable &,void)690 IMPL_LINK_NOARG(ScPivotLayoutDialog, ToggleSource, weld::Toggleable&, void)
691 {
692 ToggleSource();
693 }
694
ToggleSource()695 void ScPivotLayoutDialog::ToggleSource()
696 {
697 bool bNamedRange = mxSourceRadioNamedRange->get_active();
698 bool bSelection = mxSourceRadioSelection->get_active();
699 mxSourceListBox->set_sensitive(bNamedRange);
700 mxSourceButton->GetWidget()->set_sensitive(bSelection);
701 mxSourceEdit->GetWidget()->set_sensitive(bSelection);
702 UpdateSourceRange();
703 }
704
IMPL_LINK_NOARG(ScPivotLayoutDialog,ToggleDestination,weld::Toggleable &,void)705 IMPL_LINK_NOARG(ScPivotLayoutDialog, ToggleDestination, weld::Toggleable&, void)
706 {
707 ToggleDestination();
708 }
709
ToggleDestination()710 void ScPivotLayoutDialog::ToggleDestination()
711 {
712 bool bNamedRange = mxDestinationRadioNamedRange->get_active();
713 bool bSelection = mxDestinationRadioSelection->get_active();
714 mxDestinationListBox->set_sensitive(bNamedRange);
715 mxDestinationButton->GetWidget()->set_sensitive(bSelection);
716 mxDestinationEdit->GetWidget()->set_sensitive(bSelection);
717 }
718
719 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
720