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