724 lines
24 KiB
C++
724 lines
24 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*/
|
|
|
|
#include <PivotLayoutTreeList.hxx>
|
|
#include <PivotLayoutDialog.hxx>
|
|
#include <reffact.hxx>
|
|
|
|
#include <rangeutl.hxx>
|
|
#include <uiitems.hxx>
|
|
#include <dputil.hxx>
|
|
#include <dbdocfun.hxx>
|
|
#include <dpsave.hxx>
|
|
#include <dpshttab.hxx>
|
|
#include <scmod.hxx>
|
|
|
|
#include <memory>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
|
|
#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
|
|
|
|
using namespace css::uno;
|
|
using namespace css::sheet;
|
|
|
|
ScItemValue::ScItemValue(OUString aName, SCCOL nColumn, PivotFunc nFunctionMask) :
|
|
maName(std::move(aName)),
|
|
maFunctionData(nColumn, nFunctionMask),
|
|
mpOriginalItemValue(this)
|
|
{}
|
|
|
|
ScItemValue::ScItemValue(const ScItemValue* pInputItemValue) :
|
|
maName(pInputItemValue->maName),
|
|
maFunctionData(pInputItemValue->maFunctionData),
|
|
mpOriginalItemValue(this)
|
|
{}
|
|
|
|
ScItemValue::~ScItemValue()
|
|
{}
|
|
|
|
namespace
|
|
{
|
|
|
|
ScRange lclGetRangeForNamedRange(OUString const & aName, const ScDocument& rDocument)
|
|
{
|
|
ScRange aInvalidRange(ScAddress::INITIALIZE_INVALID);
|
|
ScRangeName* pRangeName = rDocument.GetRangeName();
|
|
if (pRangeName == nullptr)
|
|
return aInvalidRange;
|
|
|
|
const ScRangeData* pData = pRangeName->findByUpperName(aName.toAsciiUpperCase());
|
|
if (pData == nullptr)
|
|
return aInvalidRange;
|
|
|
|
ScRange aRange;
|
|
if (pData->IsReference(aRange))
|
|
return aRange;
|
|
|
|
return aInvalidRange;
|
|
}
|
|
|
|
}
|
|
|
|
ScPivotLayoutDialog::ScPivotLayoutDialog(
|
|
SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow, weld::Window* pParent,
|
|
ScViewData* pViewData, const ScDPObject* pPivotTableObject, bool bNewPivotTable)
|
|
: ScAnyRefDlgController(pSfxBindings, pChildWindow, pParent, u"modules/scalc/ui/pivottablelayoutdialog.ui"_ustr, u"PivotTableLayout"_ustr)
|
|
, maPivotTableObject(*pPivotTableObject)
|
|
, mpPreviouslyFocusedListBox(nullptr)
|
|
, mpViewData(pViewData)
|
|
, mrDocument(pViewData->GetDocument())
|
|
, mbNewPivotTable(bNewPivotTable)
|
|
, maAddressDetails(mrDocument.GetAddressConvention(), 0, 0)
|
|
, mbDialogLostFocus(false)
|
|
, mpActiveEdit(nullptr)
|
|
, mxListBoxField(new ScPivotLayoutTreeListLabel(m_xBuilder->weld_tree_view(u"listbox-fields"_ustr)))
|
|
, mxListBoxPage(new ScPivotLayoutTreeList(m_xBuilder->weld_tree_view(u"listbox-page"_ustr)))
|
|
, mxListBoxColumn(new ScPivotLayoutTreeList(m_xBuilder->weld_tree_view(u"listbox-column"_ustr)))
|
|
, mxListBoxRow(new ScPivotLayoutTreeList(m_xBuilder->weld_tree_view(u"listbox-row"_ustr)))
|
|
, mxListBoxData(new ScPivotLayoutTreeListData(m_xBuilder->weld_tree_view(u"listbox-data"_ustr)))
|
|
, mxCheckIgnoreEmptyRows(m_xBuilder->weld_check_button(u"check-ignore-empty-rows"_ustr))
|
|
, mxCheckTotalColumns(m_xBuilder->weld_check_button(u"check-total-columns"_ustr))
|
|
, mxCheckAddFilter(m_xBuilder->weld_check_button(u"check-add-filter"_ustr))
|
|
, mxCheckIdentifyCategories(m_xBuilder->weld_check_button(u"check-identify-categories"_ustr))
|
|
, mxCheckTotalRows(m_xBuilder->weld_check_button(u"check-total-rows"_ustr))
|
|
, mxCheckDrillToDetail(m_xBuilder->weld_check_button(u"check-drill-to-details"_ustr))
|
|
, mxCheckExpandCollapse(m_xBuilder->weld_check_button(u"check-show-expand-collapse"_ustr))
|
|
, mxSourceRadioNamedRange(m_xBuilder->weld_radio_button(u"source-radio-named-range"_ustr))
|
|
, mxSourceRadioSelection(m_xBuilder->weld_radio_button(u"source-radio-selection"_ustr))
|
|
, mxSourceListBox(m_xBuilder->weld_combo_box(u"source-list"_ustr))
|
|
, mxSourceEdit(new formula::RefEdit(m_xBuilder->weld_entry(u"source-edit"_ustr)))
|
|
, mxSourceButton(new formula::RefButton(m_xBuilder->weld_button(u"source-button"_ustr)))
|
|
, mxDestinationRadioNewSheet(m_xBuilder->weld_radio_button(u"destination-radio-new-sheet"_ustr))
|
|
, mxDestinationRadioNamedRange(m_xBuilder->weld_radio_button(u"destination-radio-named-range"_ustr))
|
|
, mxDestinationRadioSelection(m_xBuilder->weld_radio_button(u"destination-radio-selection"_ustr))
|
|
, mxDestinationListBox(m_xBuilder->weld_combo_box(u"destination-list"_ustr))
|
|
, mxDestinationEdit(new formula::RefEdit(m_xBuilder->weld_entry(u"destination-edit"_ustr)))
|
|
, mxDestinationButton(new formula::RefButton(m_xBuilder->weld_button(u"destination-button"_ustr)))
|
|
, mxBtnOK(m_xBuilder->weld_button(u"ok"_ustr))
|
|
, mxBtnCancel(m_xBuilder->weld_button(u"cancel"_ustr))
|
|
, mxSourceFrame(m_xBuilder->weld_frame(u"frame2"_ustr))
|
|
, mxSourceLabel(mxSourceFrame->weld_label_widget())
|
|
, mxDestFrame(m_xBuilder->weld_frame(u"frame1"_ustr))
|
|
, mxDestLabel(mxDestFrame->weld_label_widget())
|
|
, mxOptions(m_xBuilder->weld_expander(u"options"_ustr))
|
|
, mxMore(m_xBuilder->weld_expander(u"more"_ustr))
|
|
{
|
|
// Source UI
|
|
Link<weld::Toggleable&,void> aLink2 = LINK(this, ScPivotLayoutDialog, ToggleSource);
|
|
mxSourceRadioNamedRange->connect_toggled(aLink2);
|
|
mxSourceRadioSelection->connect_toggled(aLink2);
|
|
|
|
mxSourceEdit->SetReferences(this, mxSourceLabel.get());
|
|
mxSourceButton->SetReferences(this, mxSourceEdit.get());
|
|
|
|
Link<formula::RefEdit&,void> aEditLink = LINK(this, ScPivotLayoutDialog, GetEditFocusHandler);
|
|
mxDestinationEdit->SetGetFocusHdl(aEditLink);
|
|
mxSourceEdit->SetGetFocusHdl(aEditLink);
|
|
|
|
aEditLink = LINK(this, ScPivotLayoutDialog, LoseEditFocusHandler);
|
|
mxDestinationEdit->SetLoseFocusHdl(aEditLink);
|
|
mxSourceEdit->SetLoseFocusHdl(aEditLink);
|
|
|
|
mxSourceEdit->SetModifyHdl(LINK(this, ScPivotLayoutDialog, SourceEditModified));
|
|
mxSourceListBox->connect_changed(LINK(this, ScPivotLayoutDialog, SourceListSelected));
|
|
|
|
// Destination UI
|
|
aLink2 = LINK(this, ScPivotLayoutDialog, ToggleDestination);
|
|
mxDestinationRadioNewSheet->connect_toggled(aLink2);
|
|
mxDestinationRadioNamedRange->connect_toggled(aLink2);
|
|
mxDestinationRadioSelection->connect_toggled(aLink2);
|
|
|
|
mxDestinationEdit->SetReferences(this, mxDestLabel.get());
|
|
mxDestinationButton->SetReferences(this, mxDestinationEdit.get());
|
|
|
|
Link<formula::RefButton&,void> aButtonLink = LINK(this, ScPivotLayoutDialog, GetButtonFocusHandler);
|
|
mxSourceButton->SetGetFocusHdl(aButtonLink);
|
|
mxDestinationButton->SetGetFocusHdl(aButtonLink);
|
|
|
|
aButtonLink = LINK(this, ScPivotLayoutDialog, LoseButtonFocusHandler);
|
|
mxSourceButton->SetLoseFocusHdl(aButtonLink);
|
|
mxDestinationButton->SetLoseFocusHdl(aButtonLink);
|
|
|
|
// Buttons
|
|
mxBtnCancel->connect_clicked(LINK(this, ScPivotLayoutDialog, CancelClicked));
|
|
mxBtnOK->connect_clicked(LINK(this, ScPivotLayoutDialog, OKClicked));
|
|
|
|
// Initialize Data
|
|
maPivotTableObject.FillOldParam(maPivotParameters);
|
|
maPivotTableObject.FillLabelData(maPivotParameters);
|
|
|
|
mxListBoxField->Setup (this);
|
|
mxListBoxPage->Setup (this, ScPivotLayoutTreeList::PAGE_LIST);
|
|
mxListBoxColumn->Setup(this, ScPivotLayoutTreeList::COLUMN_LIST);
|
|
mxListBoxRow->Setup (this, ScPivotLayoutTreeList::ROW_LIST);
|
|
mxListBoxData->Setup (this);
|
|
|
|
FillValuesToListBoxes();
|
|
|
|
// Initialize Options
|
|
const ScDPSaveData* pSaveData = maPivotTableObject.GetSaveData();
|
|
if (pSaveData == nullptr)
|
|
{
|
|
mxCheckAddFilter->set_active(false);
|
|
mxCheckDrillToDetail->set_active(false);
|
|
mxCheckExpandCollapse->set_active(false);
|
|
}
|
|
else
|
|
{
|
|
mxCheckAddFilter->set_active(pSaveData->GetFilterButton());
|
|
mxCheckDrillToDetail->set_active(pSaveData->GetDrillDown());
|
|
mxCheckExpandCollapse->set_active(pSaveData->GetExpandCollapse());
|
|
}
|
|
|
|
mxCheckIgnoreEmptyRows->set_active(maPivotParameters.bIgnoreEmptyRows);
|
|
mxCheckIdentifyCategories->set_active(maPivotParameters.bDetectCategories);
|
|
mxCheckTotalColumns->set_active(maPivotParameters.bMakeTotalCol);
|
|
mxCheckTotalRows->set_active(maPivotParameters.bMakeTotalRow);
|
|
|
|
SetupSource();
|
|
SetupDestination();
|
|
}
|
|
|
|
ScPivotLayoutDialog::~ScPivotLayoutDialog()
|
|
{
|
|
}
|
|
|
|
void ScPivotLayoutDialog::SetupSource()
|
|
{
|
|
mxSourceListBox->clear();
|
|
|
|
ScRange aSourceRange;
|
|
OUString sSourceNamedRangeName;
|
|
|
|
if (maPivotTableObject.GetSheetDesc())
|
|
{
|
|
const ScSheetSourceDesc* pSheetSourceDesc = maPivotTableObject.GetSheetDesc();
|
|
aSourceRange = pSheetSourceDesc->GetSourceRange();
|
|
|
|
if(!aSourceRange.IsValid())
|
|
{
|
|
// Source is probably a DB Range
|
|
mxSourceRadioNamedRange->set_sensitive(false);
|
|
mxSourceRadioSelection->set_sensitive(false);
|
|
ToggleSource();
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
OUString aSourceRangeName = aSourceRange.Format(mrDocument, ScRefFlags::RANGE_ABS_3D, maAddressDetails);
|
|
mxSourceEdit->SetText(aSourceRangeName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mxSourceRadioNamedRange->set_sensitive(false);
|
|
mxSourceRadioSelection->set_sensitive(false);
|
|
ToggleSource();
|
|
return;
|
|
}
|
|
|
|
// Setup Named Ranges
|
|
bool bIsNamedRange = false;
|
|
|
|
ScAreaNameIterator aIterator(mrDocument);
|
|
OUString aEachName;
|
|
ScRange aEachRange;
|
|
|
|
while (aIterator.Next(aEachName, aEachRange))
|
|
{
|
|
if (!aIterator.WasDBName())
|
|
{
|
|
mxSourceListBox->append_text(aEachName);
|
|
if (aEachRange == aSourceRange)
|
|
{
|
|
sSourceNamedRangeName = aEachName;
|
|
bIsNamedRange = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool bSourceBoxHasEntries = mxSourceListBox->get_count() > 0;
|
|
|
|
if (bIsNamedRange)
|
|
{
|
|
mxSourceListBox->set_active_text(sSourceNamedRangeName);
|
|
mxSourceRadioNamedRange->set_active(true);
|
|
}
|
|
else
|
|
{
|
|
// If entries - select first entry
|
|
mxSourceListBox->set_active(bSourceBoxHasEntries ? 0 : -1);
|
|
mxSourceRadioSelection->set_active(true);
|
|
}
|
|
|
|
// If no entries disable the radio button.
|
|
if (!bSourceBoxHasEntries)
|
|
mxSourceRadioNamedRange->set_sensitive(false);
|
|
|
|
ToggleSource();
|
|
}
|
|
|
|
void ScPivotLayoutDialog::SetupDestination()
|
|
{
|
|
mxDestinationListBox->clear();
|
|
|
|
// Fill up named ranges
|
|
ScAreaNameIterator aIterator(mrDocument);
|
|
OUString aName;
|
|
ScRange aRange;
|
|
|
|
while (aIterator.Next(aName, aRange))
|
|
{
|
|
if (!aIterator.WasDBName())
|
|
{
|
|
mxDestinationListBox->append_text(aName);
|
|
}
|
|
}
|
|
|
|
// If entries - select first entry, otherwise disable the radio button.
|
|
if (mxDestinationListBox->get_count() > 0)
|
|
mxDestinationListBox->set_active(0);
|
|
else
|
|
mxDestinationRadioNamedRange->set_sensitive(false);
|
|
|
|
//
|
|
if (mbNewPivotTable)
|
|
{
|
|
mxDestinationRadioNewSheet->set_active(true);
|
|
}
|
|
else
|
|
{
|
|
if (maPivotParameters.nTab != MAXTAB + 1)
|
|
{
|
|
ScAddress aAddress(maPivotParameters.nCol, maPivotParameters.nRow, maPivotParameters.nTab);
|
|
OUString aAddressString = aAddress.Format(ScRefFlags::ADDR_ABS_3D, &mrDocument, maAddressDetails);
|
|
mxDestinationEdit->SetText(aAddressString);
|
|
mxDestinationRadioSelection->set_active(true);
|
|
}
|
|
}
|
|
|
|
ToggleDestination();
|
|
}
|
|
|
|
void ScPivotLayoutDialog::FillValuesToListBoxes()
|
|
{
|
|
mxListBoxField->FillLabelFields(maPivotParameters.maLabelArray);
|
|
mxListBoxData->FillDataField(maPivotParameters.maDataFields);
|
|
mxListBoxColumn->FillFields(maPivotParameters.maColFields);
|
|
mxListBoxRow->FillFields(maPivotParameters.maRowFields);
|
|
mxListBoxPage->FillFields(maPivotParameters.maPageFields);
|
|
}
|
|
|
|
void ScPivotLayoutDialog::SetActive()
|
|
{
|
|
if (mbDialogLostFocus)
|
|
{
|
|
mbDialogLostFocus = false;
|
|
if(mpActiveEdit != nullptr)
|
|
{
|
|
mpActiveEdit->GrabFocus();
|
|
if (mpActiveEdit == mxSourceEdit.get())
|
|
UpdateSourceRange();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_xDialog->grab_focus();
|
|
}
|
|
|
|
RefInputDone();
|
|
}
|
|
|
|
void ScPivotLayoutDialog::SetReference(const ScRange& rReferenceRange, ScDocument& rDocument)
|
|
{
|
|
if (!mbDialogLostFocus)
|
|
return;
|
|
|
|
if (mpActiveEdit == nullptr)
|
|
return;
|
|
|
|
if (rReferenceRange.aStart != rReferenceRange.aEnd)
|
|
RefInputStart(mpActiveEdit);
|
|
|
|
OUString aReferenceString = rReferenceRange.Format(rDocument, ScRefFlags::RANGE_ABS_3D, maAddressDetails);
|
|
|
|
if (mpActiveEdit == mxSourceEdit.get())
|
|
{
|
|
mxSourceEdit->SetRefString(aReferenceString);
|
|
}
|
|
else if (mpActiveEdit == mxDestinationEdit.get())
|
|
{
|
|
mxDestinationEdit->SetRefString(aReferenceString);
|
|
}
|
|
}
|
|
|
|
bool ScPivotLayoutDialog::IsRefInputMode() const
|
|
{
|
|
return mbDialogLostFocus;
|
|
}
|
|
|
|
void ScPivotLayoutDialog::ItemInserted(const ScItemValue* pItemValue, ScPivotLayoutTreeList::SvPivotTreeListType eType)
|
|
{
|
|
if (pItemValue == nullptr)
|
|
return;
|
|
|
|
switch (eType)
|
|
{
|
|
case ScPivotLayoutTreeList::ROW_LIST:
|
|
case ScPivotLayoutTreeList::COLUMN_LIST:
|
|
case ScPivotLayoutTreeList::PAGE_LIST:
|
|
{
|
|
mxListBoxRow->RemoveEntryForItem(pItemValue);
|
|
mxListBoxColumn->RemoveEntryForItem(pItemValue);
|
|
mxListBoxPage->RemoveEntryForItem(pItemValue);
|
|
}
|
|
break;
|
|
case ScPivotLayoutTreeList::LABEL_LIST:
|
|
{
|
|
mxListBoxRow->RemoveEntryForItem(pItemValue);
|
|
mxListBoxColumn->RemoveEntryForItem(pItemValue);
|
|
mxListBoxPage->RemoveEntryForItem(pItemValue);
|
|
mxListBoxData->RemoveEntryForItem(pItemValue);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void ScPivotLayoutDialog::UpdateSourceRange()
|
|
{
|
|
if (!maPivotTableObject.GetSheetDesc())
|
|
return;
|
|
|
|
ScSheetSourceDesc aSourceSheet = *maPivotTableObject.GetSheetDesc();
|
|
|
|
if (mxSourceRadioNamedRange->get_active())
|
|
{
|
|
OUString aEntryString = mxSourceListBox->get_active_text();
|
|
ScRange aSourceRange = lclGetRangeForNamedRange(aEntryString, mrDocument);
|
|
if (!aSourceRange.IsValid() || aSourceSheet.GetSourceRange() == aSourceRange)
|
|
return;
|
|
aSourceSheet.SetRangeName(aEntryString);
|
|
}
|
|
else if (mxSourceRadioSelection->get_active())
|
|
{
|
|
OUString aSourceString = mxSourceEdit->GetText();
|
|
ScRange aSourceRange;
|
|
ScRefFlags nResult = aSourceRange.Parse(aSourceString, mrDocument, maAddressDetails);
|
|
|
|
bool bIsValid = (nResult & ScRefFlags::VALID) == ScRefFlags::VALID; // aSourceString is valid
|
|
|
|
mxSourceEdit->SetRefValid(true);
|
|
|
|
if (bIsValid)
|
|
{
|
|
ScRefAddress aStart;
|
|
ScRefAddress aEnd;
|
|
|
|
ConvertDoubleRef(mrDocument, aSourceString, 1, aStart, aEnd, maAddressDetails);
|
|
aSourceRange.aStart = aStart.GetAddress();
|
|
aSourceRange.aEnd = aEnd.GetAddress();
|
|
}
|
|
else
|
|
{
|
|
aSourceRange = lclGetRangeForNamedRange(aSourceString, mrDocument);
|
|
}
|
|
|
|
if (!aSourceRange.IsValid())
|
|
{
|
|
mxSourceEdit->SetRefValid(false);
|
|
return;
|
|
}
|
|
|
|
if (aSourceSheet.GetSourceRange() == aSourceRange)
|
|
return;
|
|
|
|
aSourceSheet.SetSourceRange(aSourceRange);
|
|
if (aSourceSheet.CheckSourceRange())
|
|
{
|
|
mxSourceEdit->SetRefValid(false);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
|
|
maPivotTableObject.SetSheetDesc(aSourceSheet);
|
|
maPivotTableObject.FillOldParam(maPivotParameters);
|
|
maPivotTableObject.FillLabelData(maPivotParameters);
|
|
|
|
FillValuesToListBoxes();
|
|
}
|
|
|
|
void ScPivotLayoutDialog::ApplyChanges()
|
|
{
|
|
ScDPSaveData aSaveData;
|
|
ApplySaveData(aSaveData);
|
|
ApplyLabelData(aSaveData);
|
|
|
|
ScDPObject *pOldDPObj = mrDocument.GetDPAtCursor( maPivotParameters.nCol, maPivotParameters.nRow, maPivotParameters.nTab);
|
|
ScRange aDestinationRange;
|
|
bool bToNewSheet = false;
|
|
|
|
if (!GetDestination(aDestinationRange, bToNewSheet))
|
|
return;
|
|
|
|
SetDispatcherLock(false);
|
|
SwitchToDocument();
|
|
|
|
sal_uInt16 nWhichPivot = ScModule::get()->GetPool().GetWhichIDFromSlotID(SID_PIVOT_TABLE);
|
|
ScPivotItem aPivotItem(nWhichPivot, &aSaveData, &aDestinationRange, bToNewSheet);
|
|
mpViewData->GetViewShell()->SetDialogDPObject(std::make_unique<ScDPObject>(maPivotTableObject));
|
|
|
|
|
|
SfxDispatcher* pDispatcher = GetBindings().GetDispatcher();
|
|
SfxCallMode const nCallMode = SfxCallMode::SLOT | SfxCallMode::RECORD;
|
|
const SfxPoolItemHolder aResult(pDispatcher->ExecuteList(SID_PIVOT_TABLE,
|
|
nCallMode, { &aPivotItem }));
|
|
|
|
if (aResult)
|
|
{
|
|
// existing pivot table might have moved to a new range or a new sheet
|
|
if ( pOldDPObj != nullptr )
|
|
{
|
|
const ScRange& rOldRange = pOldDPObj->GetOutRange();
|
|
|
|
ScDPObject *pDPObj = nullptr;
|
|
// FIXME: if the new range overlaps with the old one, the table actually doesn't move
|
|
// and shouldn't therefore be deleted
|
|
if ( ( ( rOldRange != aDestinationRange ) && !rOldRange.Contains( aDestinationRange ) )
|
|
|| bToNewSheet )
|
|
{
|
|
pDPObj = mrDocument.GetDPAtCursor( maPivotParameters.nCol, maPivotParameters.nRow, maPivotParameters.nTab);
|
|
}
|
|
if (pDPObj)
|
|
{
|
|
ScDBDocFunc aFunc( *(mpViewData->GetDocShell() ));
|
|
aFunc.RemovePivotTable( *pDPObj, true, false);
|
|
mpViewData->GetView()->CursorPosChanged();
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
SetDispatcherLock(true);
|
|
}
|
|
|
|
void ScPivotLayoutDialog::ApplySaveData(ScDPSaveData& rSaveData)
|
|
{
|
|
rSaveData.SetIgnoreEmptyRows(mxCheckIgnoreEmptyRows->get_active());
|
|
rSaveData.SetRepeatIfEmpty(mxCheckIdentifyCategories->get_active());
|
|
rSaveData.SetColumnGrand(mxCheckTotalColumns->get_active());
|
|
rSaveData.SetRowGrand(mxCheckTotalRows->get_active());
|
|
rSaveData.SetFilterButton(mxCheckAddFilter->get_active());
|
|
rSaveData.SetDrillDown(mxCheckDrillToDetail->get_active());
|
|
rSaveData.SetExpandCollapse(mxCheckExpandCollapse->get_active());
|
|
|
|
Reference<XDimensionsSupplier> xSource = maPivotTableObject.GetSource();
|
|
|
|
ScPivotFieldVector aPageFieldVector;
|
|
mxListBoxPage->PushEntriesToPivotFieldVector(aPageFieldVector);
|
|
ScDPObject::ConvertOrientation(rSaveData, aPageFieldVector, DataPilotFieldOrientation_PAGE,
|
|
xSource, maPivotParameters.maLabelArray);
|
|
|
|
ScPivotFieldVector aColFieldVector;
|
|
mxListBoxColumn->PushEntriesToPivotFieldVector(aColFieldVector);
|
|
ScDPObject::ConvertOrientation(rSaveData, aColFieldVector, DataPilotFieldOrientation_COLUMN,
|
|
xSource, maPivotParameters.maLabelArray);
|
|
|
|
ScPivotFieldVector aRowFieldVector;
|
|
mxListBoxRow->PushEntriesToPivotFieldVector(aRowFieldVector);
|
|
ScDPObject::ConvertOrientation(rSaveData, aRowFieldVector, DataPilotFieldOrientation_ROW,
|
|
xSource, maPivotParameters.maLabelArray);
|
|
|
|
ScPivotFieldVector aDataFieldVector;
|
|
mxListBoxData->PushEntriesToPivotFieldVector(aDataFieldVector);
|
|
ScDPObject::ConvertOrientation(rSaveData, aDataFieldVector, DataPilotFieldOrientation_DATA,
|
|
xSource, maPivotParameters.maLabelArray,
|
|
&aColFieldVector, &aRowFieldVector, &aPageFieldVector);
|
|
}
|
|
|
|
void ScPivotLayoutDialog::ApplyLabelData(const ScDPSaveData& rSaveData)
|
|
{
|
|
ScDPLabelDataVector& rLabelDataVector = GetLabelDataVector();
|
|
|
|
for (std::unique_ptr<ScDPLabelData> const & pLabelData : rLabelDataVector)
|
|
{
|
|
OUString aUnoName = ScDPUtil::createDuplicateDimensionName(pLabelData->maName, pLabelData->mnDupCount);
|
|
ScDPSaveDimension* pSaveDimensions = rSaveData.GetExistingDimensionByName(aUnoName);
|
|
|
|
if (pSaveDimensions == nullptr)
|
|
continue;
|
|
|
|
pSaveDimensions->SetUsedHierarchy(pLabelData->mnUsedHier);
|
|
pSaveDimensions->SetShowEmpty(pLabelData->mbShowAll);
|
|
pSaveDimensions->SetRepeatItemLabels(pLabelData->mbRepeatItemLabels);
|
|
pSaveDimensions->SetSortInfo(&pLabelData->maSortInfo);
|
|
pSaveDimensions->SetLayoutInfo(&pLabelData->maLayoutInfo);
|
|
pSaveDimensions->SetAutoShowInfo(&pLabelData->maShowInfo);
|
|
|
|
bool bManualSort = (pLabelData->maSortInfo.Mode == DataPilotFieldSortMode::MANUAL);
|
|
|
|
for (ScDPLabelData::Member const & rLabelMember : pLabelData->maMembers)
|
|
{
|
|
ScDPSaveMember* pMember = pSaveDimensions->GetMemberByName(rLabelMember.maName);
|
|
|
|
if (bManualSort || !rLabelMember.mbVisible || !rLabelMember.mbShowDetails)
|
|
{
|
|
pMember->SetIsVisible(rLabelMember.mbVisible);
|
|
pMember->SetShowDetails(rLabelMember.mbShowDetails);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool ScPivotLayoutDialog::GetDestination(ScRange& aDestinationRange, bool& bToNewSheet)
|
|
{
|
|
bToNewSheet = false;
|
|
|
|
if (mxDestinationRadioNamedRange->get_active())
|
|
{
|
|
OUString aName = mxDestinationListBox->get_active_text();
|
|
aDestinationRange = lclGetRangeForNamedRange(aName, mrDocument);
|
|
if (!aDestinationRange.IsValid())
|
|
return false;
|
|
}
|
|
else if (mxDestinationRadioSelection->get_active())
|
|
{
|
|
ScAddress aAddress;
|
|
aAddress.Parse(mxDestinationEdit->GetText(), mrDocument, maAddressDetails);
|
|
aDestinationRange = ScRange(aAddress);
|
|
}
|
|
else
|
|
{
|
|
bToNewSheet = true;
|
|
aDestinationRange = ScRange(maPivotParameters.nCol, maPivotParameters.nRow, maPivotParameters.nTab);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
ScItemValue* ScPivotLayoutDialog::GetItem(SCCOL nColumn)
|
|
{
|
|
return mxListBoxField->GetItem(nColumn);
|
|
}
|
|
|
|
bool ScPivotLayoutDialog::IsDataElement(SCCOL nColumn)
|
|
{
|
|
return mxListBoxField->IsDataElement(nColumn);
|
|
}
|
|
|
|
ScDPLabelData& ScPivotLayoutDialog::GetLabelData(SCCOL nColumn)
|
|
{
|
|
return *maPivotParameters.maLabelArray[nColumn];
|
|
}
|
|
|
|
void ScPivotLayoutDialog::PushDataFieldNames(std::vector<ScDPName>& rDataFieldNames)
|
|
{
|
|
mxListBoxData->PushDataFieldNames(rDataFieldNames);
|
|
}
|
|
|
|
void ScPivotLayoutDialog::Close()
|
|
{
|
|
DoClose(ScPivotLayoutWrapper::GetChildWindowId());
|
|
SfxDialogController::Close();
|
|
}
|
|
|
|
IMPL_LINK_NOARG( ScPivotLayoutDialog, OKClicked, weld::Button&, void )
|
|
{
|
|
/* tdf#137726 hide so it's not a candidate to be parent of any error
|
|
messages that may appear because this dialog is going to disappear on
|
|
response(RET_OK) and the error dialog is not run in its own event loop
|
|
but instead async */
|
|
m_xDialog->hide();
|
|
|
|
ApplyChanges();
|
|
m_xDialog->response(RET_OK);
|
|
}
|
|
|
|
IMPL_LINK_NOARG( ScPivotLayoutDialog, CancelClicked, weld::Button&, void )
|
|
{
|
|
m_xDialog->response(RET_CANCEL);
|
|
}
|
|
|
|
IMPL_LINK(ScPivotLayoutDialog, GetEditFocusHandler, formula::RefEdit&, rCtrl, void)
|
|
{
|
|
mpActiveEdit = &rCtrl;
|
|
mpActiveEdit->SelectAll();
|
|
}
|
|
|
|
IMPL_LINK(ScPivotLayoutDialog, GetButtonFocusHandler, formula::RefButton&, rCtrl, void)
|
|
{
|
|
mpActiveEdit = nullptr;
|
|
|
|
if (&rCtrl == mxSourceButton.get())
|
|
mpActiveEdit = mxSourceEdit.get();
|
|
else if (&rCtrl == mxDestinationButton.get())
|
|
mpActiveEdit = mxDestinationEdit.get();
|
|
|
|
if (mpActiveEdit)
|
|
mpActiveEdit->SelectAll();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScPivotLayoutDialog, LoseEditFocusHandler, formula::RefEdit&, void)
|
|
{
|
|
mbDialogLostFocus = !m_xDialog->has_toplevel_focus();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScPivotLayoutDialog, LoseButtonFocusHandler, formula::RefButton&, void)
|
|
{
|
|
mbDialogLostFocus = !m_xDialog->has_toplevel_focus();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScPivotLayoutDialog, SourceListSelected, weld::ComboBox&, void)
|
|
{
|
|
UpdateSourceRange();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScPivotLayoutDialog, SourceEditModified, formula::RefEdit&, void)
|
|
{
|
|
UpdateSourceRange();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScPivotLayoutDialog, ToggleSource, weld::Toggleable&, void)
|
|
{
|
|
ToggleSource();
|
|
}
|
|
|
|
void ScPivotLayoutDialog::ToggleSource()
|
|
{
|
|
bool bNamedRange = mxSourceRadioNamedRange->get_active();
|
|
bool bSelection = mxSourceRadioSelection->get_active();
|
|
mxSourceListBox->set_sensitive(bNamedRange);
|
|
mxSourceButton->GetWidget()->set_sensitive(bSelection);
|
|
mxSourceEdit->GetWidget()->set_sensitive(bSelection);
|
|
UpdateSourceRange();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScPivotLayoutDialog, ToggleDestination, weld::Toggleable&, void)
|
|
{
|
|
ToggleDestination();
|
|
}
|
|
|
|
void ScPivotLayoutDialog::ToggleDestination()
|
|
{
|
|
bool bNamedRange = mxDestinationRadioNamedRange->get_active();
|
|
bool bSelection = mxDestinationRadioSelection->get_active();
|
|
mxDestinationListBox->set_sensitive(bNamedRange);
|
|
mxDestinationButton->GetWidget()->set_sensitive(bSelection);
|
|
mxDestinationEdit->GetWidget()->set_sensitive(bSelection);
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|