Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/sc/source/ui/dbgui/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 32 kB image not shown  

Quelle  pvfundlg.cxx   Sprache: 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:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#undef SC_DLLIMPLEMENTATION

#include <pvfundlg.hxx>

#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
#include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
#include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>

#include <osl/diagnose.h>

#include <scresid.hxx>
#include <dpobject.hxx>
#include <dpsave.hxx>
#include <pvfundlg.hrc>
#include <globstr.hrc>
#include <dputil.hxx>

#include <vector>

using namespace ::com::sun::star::sheet;

using ::com::sun::star::uno::Sequence;
using ::std::vector;

namespace {

/** Appends all strings from the Sequence to the list box.

    Empty strings are replaced by a localized "(empty)" entry and inserted at
    the specified position.

    @return  true = The passed string list contains an empty string entry.
 */


bool lclFillListBox(weld::ComboBox& rLBox, const Sequence< OUString >& rStrings)
{
    bool bEmpty = false;
    for (const OUString& str : rStrings)
    {
        if (!str.isEmpty())
            rLBox.append_text(str);
        else
        {
            rLBox.append_text(ScResId(STR_EMPTYDATA));
            bEmpty = true;
        }
    }
    return bEmpty;
}

bool lclFillListBox(weld::ComboBox& rLBox, const vector<ScDPLabelData::Member>& ;rMembers, int nEmptyPos)
{
    bool bEmpty = false;
    vector<ScDPLabelData::Member>::const_iterator itr = rMembers.begin(), itrEnd = rMembers.end();
    for (; itr != itrEnd; ++itr)
    {
        OUString aName = itr->getDisplayName();
        if (!aName.isEmpty())
            rLBox.append_text(aName);
        else
        {
            rLBox.insert_text(nEmptyPos, ScResId(STR_EMPTYDATA));
            bEmpty = true;
        }
    }
    return bEmpty;
}

bool lclFillListBox(weld::TreeView& rLBox, const vector<ScDPLabelData::Member>& ;rMembers)
{
    bool bEmpty = false;
    for (const auto& rMember : rMembers)
    {
        rLBox.append();
        int pos = rLBox.n_children() - 1;
        rLBox.set_toggle(pos, TRISTATE_FALSE);
        const OUString& aName = rMember.getDisplayName();
        if (!aName.isEmpty())
            rLBox.set_text(pos, aName, 0);
        else
        {
            rLBox.set_text(pos, ScResId(STR_EMPTYDATA), 0);
            bEmpty = true;
        }
    }
    return bEmpty;
}

/** This table represents the order of the strings in the resource string array. */
const PivotFunc spnFunctions[] =
{
    PivotFunc::Sum,
    PivotFunc::Count,
    PivotFunc::Average,
    PivotFunc::Median,
    PivotFunc::Max,
    PivotFunc::Min,
    PivotFunc::Product,
    PivotFunc::CountNum,
    PivotFunc::StdDev,
    PivotFunc::StdDevP,
    PivotFunc::StdVar,
    PivotFunc::StdVarP
};

const sal_uInt16 SC_BASEITEM_PREV_POS = 0;
const sal_uInt16 SC_BASEITEM_NEXT_POS = 1;
const sal_uInt16 SC_BASEITEM_USER_POS = 2;

const sal_uInt16 SC_SORTNAME_POS = 0;
const sal_uInt16 SC_SORTDATA_POS = 1;

const tools::Long SC_SHOW_DEFAULT = 10;

// namespace

ScDPFunctionListBox::ScDPFunctionListBox(std::unique_ptr<weld::TreeView> xControl)
    : m_xControl(std::move(xControl))
{
    FillFunctionNames();
}

void ScDPFunctionListBox::SetSelection( PivotFunc nFuncMask )
{
    if( (nFuncMask == PivotFunc::NONE) || (nFuncMask == PivotFunc::Auto) )
        m_xControl->unselect_all();
    else
    {
        for( sal_Int32 nEntry = 0, nCount = m_xControl->n_children(); nEntry < nCount; ++nEntry )
        {
            if (bool(nFuncMask & spnFunctions[ nEntry ]))
                m_xControl->select(nEntry);
            else
                m_xControl->unselect(nEntry);
        }
    }
}

PivotFunc ScDPFunctionListBox::GetSelection() const
{
    PivotFunc nFuncMask = PivotFunc::NONE;
    std::vector<int> aRows = m_xControl->get_selected_rows();
    for (int nSel : aRows)
        nFuncMask |= spnFunctions[nSel];
    return nFuncMask;
}

void ScDPFunctionListBox::FillFunctionNames()
{
    OSL_ENSURE( !m_xControl->n_children(), "ScDPMultiFuncListBox::FillFunctionNames - do not add texts to resource" );
    m_xControl->clear();
    m_xControl->freeze();
    for (size_t nIndex = 0; nIndex < SAL_N_ELEMENTS(SCSTR_DPFUNCLISTBOX); ++nIndex)
        m_xControl->append_text(ScResId(SCSTR_DPFUNCLISTBOX[nIndex]));
    m_xControl->thaw();
    assert(m_xControl->n_children() == SAL_N_ELEMENTS(spnFunctions));
}

namespace
{
    int FromDataPilotFieldReferenceType(int eMode)
    {
        switch (eMode)
        {
            case DataPilotFieldReferenceType::NONE:
                return 0;
            case DataPilotFieldReferenceType::ITEM_DIFFERENCE:
                return 1;
            case DataPilotFieldReferenceType::ITEM_PERCENTAGE:
                return 2;
            case DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE:
                return 3;
            case DataPilotFieldReferenceType::RUNNING_TOTAL:
                return 4;
            case DataPilotFieldReferenceType::ROW_PERCENTAGE:
                return 5;
            case DataPilotFieldReferenceType::COLUMN_PERCENTAGE:
                return 6;
            case DataPilotFieldReferenceType::TOTAL_PERCENTAGE:
                return 7;
            case DataPilotFieldReferenceType::INDEX:
                return 8;
        }
        return -1;
    }

    int ToDataPilotFieldReferenceType(int nPos)
    {
        switch (nPos)
        {
            case 0:
                return DataPilotFieldReferenceType::NONE;
            case 1:
                return DataPilotFieldReferenceType::ITEM_DIFFERENCE;
            case 2:
                return DataPilotFieldReferenceType::ITEM_PERCENTAGE;
            case 3:
                return DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE;
            case 4:
                return DataPilotFieldReferenceType::RUNNING_TOTAL;
            case 5:
                return DataPilotFieldReferenceType::ROW_PERCENTAGE;
            case 6:
                return DataPilotFieldReferenceType::COLUMN_PERCENTAGE;
            case 7:
                return DataPilotFieldReferenceType::TOTAL_PERCENTAGE;
            case 8:
                return DataPilotFieldReferenceType::INDEX;
        }
        return DataPilotFieldReferenceType::NONE;

    }
}

ScDPFunctionDlg::ScDPFunctionDlg(
        weld::Widget* pParent, const ScDPLabelDataVector& rLabelVec,
        const ScDPLabelData& rLabelData, const ScPivotFuncData& rFuncData)
    : GenericDialogController(pParent, u"modules/scalc/ui/datafielddialog.ui"_ustr, u"DataFieldDialog"_ustr)
    , mxLbFunc(new ScDPFunctionListBox(m_xBuilder->weld_tree_view(u"functions"_ustr)))
    , mxFtName(m_xBuilder->weld_label(u"name"_ustr))
    , mxLbType(m_xBuilder->weld_combo_box(u"type"_ustr))
    , mxFtBaseField(m_xBuilder->weld_label(u"basefieldft"_ustr))
    , mxLbBaseField(m_xBuilder->weld_combo_box(u"basefield"_ustr))
    , mxFtBaseItem(m_xBuilder->weld_label(u"baseitemft"_ustr))
    , mxLbBaseItem(m_xBuilder->weld_combo_box(u"baseitem"_ustr))
    , mxBtnOk(m_xBuilder->weld_button(u"ok"_ustr))
    , mxBtnCancel(m_xBuilder->weld_button(u"cancel"_ustr))
    , mxExpander(m_xBuilder->weld_expander(u"expander"_ustr))
    , mrLabelVec(rLabelVec)
    , mbEmptyItem(false)
{
    mxLbFunc->set_size_request(-1, mxLbFunc->get_height_rows(8));

    Init(rLabelData, rFuncData);
}

ScDPFunctionDlg::~ScDPFunctionDlg()
{
}

PivotFunc ScDPFunctionDlg::GetFuncMask() const
{
    return mxLbFunc->GetSelection();
}

DataPilotFieldReference ScDPFunctionDlg::GetFieldRef() const
{
    DataPilotFieldReference aRef;

    aRef.ReferenceType = ToDataPilotFieldReferenceType(mxLbType->get_active());
    aRef.ReferenceField = GetBaseFieldName(mxLbBaseField->get_active_text());

    sal_Int32 nBaseItemPos = mxLbBaseItem->get_active();
    switch( nBaseItemPos )
    {
        case SC_BASEITEM_PREV_POS:
            aRef.ReferenceItemType = DataPilotFieldReferenceItemType::PREVIOUS;
        break;
        case SC_BASEITEM_NEXT_POS:
            aRef.ReferenceItemType = DataPilotFieldReferenceItemType::NEXT;
        break;
        default:
        {
            aRef.ReferenceItemType = DataPilotFieldReferenceItemType::NAMED;
            if( !mbEmptyItem || (nBaseItemPos > SC_BASEITEM_USER_POS) )
                aRef.ReferenceItemName = GetBaseItemName(mxLbBaseItem->get_active_text());
        }
    }

    return aRef;
}

void ScDPFunctionDlg::Init( const ScDPLabelData& rLabelData, const ScPivotFuncData&&nbsp;rFuncData )
{
    mxBtnOk->connect_clicked( LINK( this, ScDPFunctionDlg, ButtonClicked ) );
    mxBtnCancel->connect_clicked( LINK( this, ScDPFunctionDlg, ButtonClicked ) );

    // list box
    PivotFunc nFuncMask = (rFuncData.mnFuncMask == PivotFunc::NONE) ? PivotFunc::Sum : rFuncData.mnFuncMask;
    mxLbFunc->SetSelection( nFuncMask );

    // field name
    mxFtName->set_label(rLabelData.getDisplayName());

    // handlers
    mxLbFunc->connect_row_activated( LINK( this, ScDPFunctionDlg, DblClickHdl ) );
    mxLbType->connect_changed( LINK( this, ScDPFunctionDlg, SelectHdl ) );
    mxLbBaseField->connect_changed( LINK( this, ScDPFunctionDlg, SelectHdl ) );

    // base field list box
    OUString aSelectedEntry;
    forconst auto& rxLabel : mrLabelVec )
    {
        mxLbBaseField->append_text(rxLabel->getDisplayName());
        maBaseFieldNameMap.emplace(rxLabel->getDisplayName(), rxLabel->maName);
        if (rxLabel->maName == rFuncData.maFieldRef.ReferenceField)
            aSelectedEntry = rxLabel->getDisplayName();
    }

    // select field reference type
    mxLbType->set_active(FromDataPilotFieldReferenceType(rFuncData.maFieldRef.ReferenceType));
    SelectHdl( *mxLbType );         // enables base field/item list boxes

    // select base field
    mxLbBaseField->set_active_text(aSelectedEntry);
    if (mxLbBaseField->get_active() == -1)
        mxLbBaseField->set_active(0);
    SelectHdl( *mxLbBaseField );    // fills base item list, selects base item

    // select base item
    switch( rFuncData.maFieldRef.ReferenceItemType )
    {
        case DataPilotFieldReferenceItemType::PREVIOUS:
            mxLbBaseItem->set_active( SC_BASEITEM_PREV_POS );
        break;
        case DataPilotFieldReferenceItemType::NEXT:
            mxLbBaseItem->set_active( SC_BASEITEM_NEXT_POS );
        break;
        default:
        {
            if( mbEmptyItem && rFuncData.maFieldRef.ReferenceItemName.isEmpty() )
            {
                // select special "(empty)" entry added before other items
                mxLbBaseItem->set_active( SC_BASEITEM_USER_POS );
            }
            else
            {
                sal_Int32 nStartPos = mbEmptyItem ? (SC_BASEITEM_USER_POS + 1) : SC_BASEITEM_USER_POS;
                sal_Int32 nPos = FindBaseItemPos( rFuncData.maFieldRef.ReferenceItemName, nStartPos );
                if( nPos == -1)
                    nPos = (mxLbBaseItem->get_count() > SC_BASEITEM_USER_POS) ? SC_BASEITEM_USER_POS : SC_BASEITEM_PREV_POS;
                mxLbBaseItem->set_active( nPos );
            }
        }
    }
}

const OUString& ScDPFunctionDlg::GetBaseFieldName(const OUString& rLayoutName) const
{
    NameMapType::const_iterator itr = maBaseFieldNameMap.find(rLayoutName);
    return itr == maBaseFieldNameMap.end() ? rLayoutName : itr->second;
}

const OUString& ScDPFunctionDlg::GetBaseItemName(const OUString& rLayoutNameconst
{
    NameMapType::const_iterator itr = maBaseItemNameMap.find(rLayoutName);
    return itr == maBaseItemNameMap.end() ? rLayoutName : itr->second;
}

sal_Int32 ScDPFunctionDlg::FindBaseItemPos( std::u16string_view rEntry, sal_Int32 nStartPos ) const
{
    sal_Int32 nPos = nStartPos;
    bool bFound = false;
    while (nPos < mxLbBaseItem->get_count())
    {
        // translate the displayed field name back to its original field name.
        const OUString aInName = mxLbBaseItem->get_text(nPos);
        const OUString& rName = GetBaseItemName(aInName);
        if (rName == rEntry)
        {
            bFound = true;
            break;
        }
        ++nPos;
    }
    return bFound ? nPos : -1;
}

IMPL_LINK( ScDPFunctionDlg, SelectHdl, weld::ComboBox&, rLBox, void )
{
    if (&rLBox == mxLbType.get())
    {
        bool bEnableField, bEnableItem;
        switch (ToDataPilotFieldReferenceType(mxLbType->get_active()))
        {
            case DataPilotFieldReferenceType::ITEM_DIFFERENCE:
            case DataPilotFieldReferenceType::ITEM_PERCENTAGE:
            case DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE:
                bEnableField = bEnableItem = true;
            break;

            case DataPilotFieldReferenceType::RUNNING_TOTAL:
                bEnableField = true;
                bEnableItem = false;
            break;

            default:
                bEnableField = bEnableItem = false;
        }

        bEnableField &= (mxLbBaseField->get_count() > 0);
        mxFtBaseField->set_sensitive( bEnableField );
        mxLbBaseField->set_sensitive( bEnableField );

        bEnableItem &= bEnableField;
        mxFtBaseItem->set_sensitive( bEnableItem );
        mxLbBaseItem->set_sensitive( bEnableItem );
    }
    else if (&rLBox == mxLbBaseField.get())
    {
        // keep "previous" and "next" entries
        while (mxLbBaseItem->get_count() > SC_BASEITEM_USER_POS)
             mxLbBaseItem->remove(SC_BASEITEM_USER_POS);

        // update item list for current base field
        mbEmptyItem = false;
        size_t nBasePos = mxLbBaseField->get_active();
        if (nBasePos < mrLabelVec.size())
        {
            const vector<ScDPLabelData::Member>& rMembers = mrLabelVec[nBasePos]->maMembers;
            mbEmptyItem = lclFillListBox(*mxLbBaseItem, rMembers, SC_BASEITEM_USER_POS);
            // build cache for base names.
            NameMapType aMap;
            for (const auto& rMember : rMembers)
                aMap.emplace(rMember.getDisplayName(), rMember.maName);
            maBaseItemNameMap.swap(aMap);
        }

        // select base item
        sal_uInt16 nItemPos = (mxLbBaseItem->get_count() > SC_BASEITEM_USER_POS) ? SC_BASEITEM_USER_POS : SC_BASEITEM_PREV_POS;
        mxLbBaseItem->set_active( nItemPos );
    }
}

IMPL_LINK(ScDPFunctionDlg, ButtonClicked, weld::Button&, rButton, void)
{
    if (&rButton == mxBtnOk.get())
        response(RET_OK);
    else
        response(RET_CANCEL);
}

IMPL_LINK_NOARG(ScDPFunctionDlg, DblClickHdl, weld::TreeView&, bool)
{
    m_xDialog->response(RET_OK);
    return true;
}

ScDPSubtotalDlg::ScDPSubtotalDlg(weld::Widget* pParent, ScDPObject& rDPObj,
        const ScDPLabelData& rLabelData, const ScPivotFuncData& rFuncData,
        const ScDPNameVec& rDataFields, bool bEnableLayout)
    : GenericDialogController(pParent, u"modules/scalc/ui/pivotfielddialog.ui"_ustr, u"PivotFieldDialog"_ustr)
    , mrDPObj(rDPObj)
    , mrDataFields(rDataFields)
    , maLabelData(rLabelData)
    , mbEnableLayout(bEnableLayout)
    , mxRbNone(m_xBuilder->weld_radio_button(u"none"_ustr))
    , mxRbAuto(m_xBuilder->weld_radio_button(u"auto"_ustr))
    , mxRbUser(m_xBuilder->weld_radio_button(u"user"_ustr))
    , mxLbFunc(new ScDPFunctionListBox(m_xBuilder->weld_tree_view(u"functions"_ustr)))
    , mxFtName(m_xBuilder->weld_label(u"name"_ustr))
    , mxCbShowAll(m_xBuilder->weld_check_button(u"showall"_ustr))
    , mxBtnOk(m_xBuilder->weld_button(u"ok"_ustr))
    , mxBtnCancel(m_xBuilder->weld_button(u"cancel"_ustr))
    , mxBtnOptions(m_xBuilder->weld_button(u"options"_ustr))
{
    mxLbFunc->set_selection_mode(SelectionMode::Multiple);
    mxLbFunc->set_size_request(-1, mxLbFunc->get_height_rows(8));
    Init(rLabelData, rFuncData);
}

ScDPSubtotalDlg::~ScDPSubtotalDlg()
{
    CloseSubdialog();
}

void ScDPSubtotalDlg::CloseSubdialog()
{
    if (mxOptionsDlg && mxOptionsDlg->getDialog())
    {
        mxOptionsDlg->getDialog()->response(RET_CANCEL);
        mxOptionsDlg = nullptr;
    }
}

PivotFunc ScDPSubtotalDlg::GetFuncMask() const
{
    PivotFunc nFuncMask = PivotFunc::NONE;

    if (mxRbAuto->get_active())
        nFuncMask = PivotFunc::Auto;
    else if (mxRbUser->get_active())
        nFuncMask = mxLbFunc->GetSelection();

    return nFuncMask;
}

void ScDPSubtotalDlg::FillLabelData( ScDPLabelData& rLabelData ) const
{
    rLabelData.mnFuncMask = GetFuncMask();
    rLabelData.mnUsedHier = maLabelData.mnUsedHier;
    rLabelData.mbShowAll = mxCbShowAll->get_active();
    rLabelData.maMembers = maLabelData.maMembers;
    rLabelData.maSortInfo = maLabelData.maSortInfo;
    rLabelData.maLayoutInfo = maLabelData.maLayoutInfo;
    rLabelData.maShowInfo = maLabelData.maShowInfo;
    rLabelData.mbRepeatItemLabels = maLabelData.mbRepeatItemLabels;
}

void ScDPSubtotalDlg::Init( const ScDPLabelData& rLabelData, const ScPivotFuncData&&nbsp;rFuncData )
{
    mxBtnOk->connect_clicked( LINK( this, ScDPSubtotalDlg, ButtonClicked ) );
    mxBtnCancel->connect_clicked( LINK( this, ScDPSubtotalDlg, ButtonClicked ) );

    // field name
    mxFtName->set_label(rLabelData.getDisplayName());

    // radio buttons
    mxRbNone->connect_toggled( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) );
    mxRbAuto->connect_toggled( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) );
    mxRbUser->connect_toggled( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) );

    weld::RadioButton* pRBtn = nullptr;
    switch( rFuncData.mnFuncMask )
    {
        case PivotFunc::NONE:   pRBtn = mxRbNone.get();  break;
        case PivotFunc::Auto:   pRBtn = mxRbAuto.get();  break;
        default:                pRBtn = mxRbUser.get();
    }
    pRBtn->set_active(true);
    RadioClickHdl(*pRBtn);

    // list box
    mxLbFunc->SetSelection( rFuncData.mnFuncMask );
    mxLbFunc->connect_row_activated( LINK( this, ScDPSubtotalDlg, DblClickHdl ) );

    // show all
    mxCbShowAll->set_active( rLabelData.mbShowAll );

    // options
    mxBtnOptions->connect_clicked( LINK( this, ScDPSubtotalDlg, ClickHdl ) );
}

IMPL_LINK(ScDPSubtotalDlg, ButtonClicked, weld::Button&, rButton, void)
{
    CloseSubdialog();

    if (&rButton == mxBtnOk.get())
        response(RET_OK);
    else
        response(RET_CANCEL);
}

IMPL_LINK(ScDPSubtotalDlg, RadioClickHdl, weld::Toggleable&, rBtn, void)
{
    if (!rBtn.get_active())
        return;
    mxLbFunc->set_sensitive(mxRbUser->get_active());
}

IMPL_LINK_NOARG(ScDPSubtotalDlg, DblClickHdl, weld::TreeView&, bool)
{
    m_xDialog->response(RET_OK);
    return true;
}

IMPL_LINK(ScDPSubtotalDlg, ClickHdl, weld::Button&, rBtn, void)
{
    if (&rBtn == mxBtnOptions.get())
    {
        mxOptionsDlg = std::make_shared<ScDPSubtotalOptDlg>(m_xDialog.get(), mrDPObj, maLabelData, mrDataFields, mbEnableLayout);

        weld::DialogController::runAsync(mxOptionsDlg, [this](int nResult) {
            if (nResult == RET_OK)
                mxOptionsDlg->FillLabelData(maLabelData);
            mxOptionsDlg = nullptr;
        });
    }
}

namespace
{
    int FromDataPilotFieldLayoutMode(int eMode)
    {
        switch (eMode)
        {
            case DataPilotFieldLayoutMode::TABULAR_LAYOUT:
                return 0;
            case DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP:
                return 1;
            case DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM:
                return 2;
            case DataPilotFieldLayoutMode::COMPACT_LAYOUT:
                return 3;
        }
        return -1;
    }

    int ToDataPilotFieldLayoutMode(int nPos)
    {
        switch (nPos)
        {
            case 0:
                return DataPilotFieldLayoutMode::TABULAR_LAYOUT;
            case 1:
                return DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP;
            case 2:
                return DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM;
            case 3:
                return DataPilotFieldLayoutMode::COMPACT_LAYOUT;
        }
        return DataPilotFieldLayoutMode::TABULAR_LAYOUT;
    }

    int FromDataPilotFieldShowItemsMode(int eMode)
    {
        switch (eMode)
        {
            case DataPilotFieldShowItemsMode::FROM_TOP:
                return 0;
            case DataPilotFieldShowItemsMode::FROM_BOTTOM:
                return 1;
        }
        return -1;
    }

    int ToDataPilotFieldShowItemsMode(int nPos)
    {
        switch (nPos)
        {
            case 0:
                return DataPilotFieldShowItemsMode::FROM_TOP;
            case 1:
                return DataPilotFieldShowItemsMode::FROM_BOTTOM;
        }
        return DataPilotFieldShowItemsMode::FROM_TOP;
    }
}

ScDPSubtotalOptDlg::ScDPSubtotalOptDlg(weld::Window* pParent, ScDPObject& rDPObj,
        const ScDPLabelData& rLabelData, const ScDPNameVec& rDataFields,
        bool bEnableLayout )
    : GenericDialogController(pParent, u"modules/scalc/ui/datafieldoptionsdialog.ui"_ustr,
                              u"DataFieldOptionsDialog"_ustr)
    , m_xLbSortBy(m_xBuilder->weld_combo_box(u"sortby"_ustr))
    , m_xRbSortAsc(m_xBuilder->weld_radio_button(u"ascending"_ustr))
    , m_xRbSortDesc(m_xBuilder->weld_radio_button(u"descending"_ustr))
    , m_xRbSortMan(m_xBuilder->weld_radio_button(u"manual"_ustr))
    , m_xLayoutFrame(m_xBuilder->weld_widget(u"layoutframe"_ustr))
    , m_xLbLayout(m_xBuilder->weld_combo_box(u"layout"_ustr))
    , m_xCbLayoutEmpty(m_xBuilder->weld_check_button(u"emptyline"_ustr))
    , m_xCbRepeatItemLabels(m_xBuilder->weld_check_button(u"repeatitemlabels"_ustr))
    , m_xCbShow(m_xBuilder->weld_check_button(u"show"_ustr))
    , m_xNfShow(m_xBuilder->weld_spin_button(u"items"_ustr))
    , m_xFtShow(m_xBuilder->weld_label(u"showft"_ustr))
    , m_xFtShowFrom(m_xBuilder->weld_label(u"showfromft"_ustr))
    , m_xLbShowFrom(m_xBuilder->weld_combo_box(u"from"_ustr))
    , m_xFtShowUsing(m_xBuilder->weld_label(u"usingft"_ustr))
    , m_xLbShowUsing(m_xBuilder->weld_combo_box(u"using"_ustr))
    , m_xHideFrame(m_xBuilder->weld_widget(u"hideframe"_ustr))
    , m_xLbHide(m_xBuilder->weld_tree_view(u"hideitems"_ustr))
    , m_xFtHierarchy(m_xBuilder->weld_label(u"hierarchyft"_ustr))
    , m_xLbHierarchy(m_xBuilder->weld_combo_box(u"hierarchy"_ustr))
    , m_xBtnOk(m_xBuilder->weld_button(u"ok"_ustr))
    , m_xBtnCancel(m_xBuilder->weld_button(u"cancel"_ustr))
    , mrDPObj(rDPObj)
    , maLabelData(rLabelData)
{
    m_xLbHide->enable_toggle_buttons(weld::ColumnToggleType::Check);

    m_xLbSortBy->set_size_request(m_xLbSortBy->get_approximate_digit_width() * 18, -1);
    m_xLbHide->set_size_request(-1, m_xLbHide->get_height_rows(5));
    Init(rDataFields, bEnableLayout);
}

ScDPSubtotalOptDlg::~ScDPSubtotalOptDlg()
{
}

void ScDPSubtotalOptDlg::FillLabelData( ScDPLabelData& rLabelData ) const
{
    // *** SORTING ***

    if (m_xRbSortMan->get_active())
        rLabelData.maSortInfo.Mode = DataPilotFieldSortMode::MANUAL;
    else if (m_xLbSortBy->get_active() == SC_SORTNAME_POS)
        rLabelData.maSortInfo.Mode = DataPilotFieldSortMode::NAME;
    else
        rLabelData.maSortInfo.Mode = DataPilotFieldSortMode::DATA;

    ScDPName aFieldName = GetFieldName(m_xLbSortBy->get_active_text());
    if (!aFieldName.maName.isEmpty())
    {
        rLabelData.maSortInfo.Field =
            ScDPUtil::createDuplicateDimensionName(aFieldName.maName, aFieldName.mnDupCount);
    }

    if (rLabelData.maSortInfo.Mode != DataPilotFieldSortMode::MANUAL)
        rLabelData.maSortInfo.IsAscending = m_xRbSortAsc->get_active();

    // *** LAYOUT MODE ***

    rLabelData.maLayoutInfo.LayoutMode = ToDataPilotFieldLayoutMode(m_xLbLayout->get_active());
    rLabelData.maLayoutInfo.AddEmptyLines = m_xCbLayoutEmpty->get_active();
    rLabelData.mbRepeatItemLabels = m_xCbRepeatItemLabels->get_active();

    // *** AUTO SHOW ***

    aFieldName = GetFieldName(m_xLbShowUsing->get_active_text());
    if (!aFieldName.maName.isEmpty())
    {
        rLabelData.maShowInfo.IsEnabled = m_xCbShow->get_active();
        rLabelData.maShowInfo.ShowItemsMode = ToDataPilotFieldShowItemsMode(m_xLbShowFrom->get_active());
        rLabelData.maShowInfo.ItemCount = sal::static_int_cast<sal_Int32>( m_xNfShow->get_value() );
        rLabelData.maShowInfo.DataField =
            ScDPUtil::createDuplicateDimensionName(aFieldName.maName, aFieldName.mnDupCount);
    }

    // *** HIDDEN ITEMS ***

    rLabelData.maMembers = maLabelData.maMembers;
    int nVisCount = m_xLbHide->n_children();
    for (int nPos = 0; nPos < nVisCount; ++nPos)
        rLabelData.maMembers[nPos].mbVisible = m_xLbHide->get_toggle(nPos) == TRISTATE_FALSE;

    // *** HIERARCHY ***

    rLabelData.mnUsedHier = m_xLbHierarchy->get_active() != -1 ? m_xLbHierarchy->get_active() : 0;
}

void ScDPSubtotalOptDlg::Init( const ScDPNameVec& rDataFields, bool bEnableLayout )
{
    m_xBtnOk->connect_clicked(LINK(this, ScDPSubtotalOptDlg, ButtonClicked));
    m_xBtnCancel->connect_clicked(LINK(this, ScDPSubtotalOptDlg, ButtonClicked));

    // *** SORTING ***

    sal_Int32 nSortMode = maLabelData.maSortInfo.Mode;

    // sort fields list box
    m_xLbSortBy->append_text(maLabelData.getDisplayName());

    forconst auto& rDataField : rDataFields )
    {
        // Cache names for later lookup.
        maDataFieldNameMap.emplace(rDataField.maLayoutName, rDataField);

        m_xLbSortBy->append_text(rDataField.maLayoutName);
        m_xLbShowUsing->append_text(rDataField.maLayoutName);  // for AutoShow
    }

    sal_Int32 nSortPos = SC_SORTNAME_POS;
    if( nSortMode == DataPilotFieldSortMode::DATA )
    {
        nSortPos = FindListBoxEntry( *m_xLbSortBy, maLabelData.maSortInfo.Field, SC_SORTDATA_POS );
        if( nSortPos == -1 )
        {
            nSortPos = SC_SORTNAME_POS;
            nSortMode = DataPilotFieldSortMode::MANUAL;
        }
    }
    m_xLbSortBy->set_active(nSortPos);

    weld::RadioButton* pRBtn = nullptr;
    switch( nSortMode )
    {
        case DataPilotFieldSortMode::NONE:
        case DataPilotFieldSortMode::MANUAL:
            pRBtn = m_xRbSortMan.get();
        break;
        default:
            pRBtn = maLabelData.maSortInfo.IsAscending ? m_xRbSortAsc.get() : m_xRbSortDesc.get();
    }
    pRBtn->set_active(true);

    // *** LAYOUT MODE ***

    m_xLayoutFrame->set_sensitive(bEnableLayout);

    m_xLbLayout->set_active(FromDataPilotFieldLayoutMode(maLabelData.maLayoutInfo.LayoutMode));
    m_xCbLayoutEmpty->set_active( maLabelData.maLayoutInfo.AddEmptyLines );
    m_xCbRepeatItemLabels->set_active( maLabelData.mbRepeatItemLabels );

    // *** AUTO SHOW ***

    m_xCbShow->set_active( maLabelData.maShowInfo.IsEnabled );
    m_xCbShow->connect_toggled( LINK( this, ScDPSubtotalOptDlg, CheckHdl ) );

    m_xLbShowFrom->set_active(FromDataPilotFieldShowItemsMode(maLabelData.maShowInfo.ShowItemsMode));
    tools::Long nCount = static_cast< tools::Long >( maLabelData.maShowInfo.ItemCount );
    if( nCount < 1 )
        nCount = SC_SHOW_DEFAULT;
    m_xNfShow->set_value( nCount );

    // m_xLbShowUsing already filled above
    m_xLbShowUsing->set_active_text(maLabelData.maShowInfo.DataField);
    if (m_xLbShowUsing->get_active() == -1)
        m_xLbShowUsing->set_active(0);

    CheckHdl(*m_xCbShow);      // enable/disable dependent controls

    // *** HIDDEN ITEMS ***

    InitHideListBox();

    // *** HIERARCHY ***

    if( maLabelData.maHiers.getLength() > 1 )
    {
        lclFillListBox(*m_xLbHierarchy, maLabelData.maHiers);
        sal_Int32 nHier = maLabelData.mnUsedHier;
        if( (nHier < 0) || (nHier >= maLabelData.maHiers.getLength()) ) nHier = 0;
        m_xLbHierarchy->set_active( nHier );
        m_xLbHierarchy->connect_changed( LINK( this, ScDPSubtotalOptDlg, SelectHdl ) );
    }
    else
    {
        m_xFtHierarchy->set_sensitive(false);
        m_xLbHierarchy->set_sensitive(false);
    }
}

void ScDPSubtotalOptDlg::InitHideListBox()
{
    m_xLbHide->clear();
    lclFillListBox(*m_xLbHide, maLabelData.maMembers);
    size_t n = maLabelData.maMembers.size();
    for (size_t i = 0; i < n; ++i)
        m_xLbHide->set_toggle(i, maLabelData.maMembers[i].mbVisible ? TRISTATE_FALSE : TRISTATE_TRUE);
    bool bEnable = m_xLbHide->n_children() > 0;
    m_xHideFrame->set_sensitive(bEnable);
}

ScDPName ScDPSubtotalOptDlg::GetFieldName(const OUString& rLayoutName) const
{
    NameMapType::const_iterator itr = maDataFieldNameMap.find(rLayoutName);
    return itr == maDataFieldNameMap.end() ? ScDPName() : itr->second;
}

sal_Int32 ScDPSubtotalOptDlg::FindListBoxEntry(
    const weld::ComboBox& rLBox, std::u16string_view rEntry, sal_Int32 nStartPos ) const
{
    sal_Int32 nPos = nStartPos;
    bool bFound = false;
    while (nPos < rLBox.get_count())
    {
        // translate the displayed field name back to its original field name.
        ScDPName aName = GetFieldName(rLBox.get_text(nPos));
        OUString aUnoName = ScDPUtil::createDuplicateDimensionName(aName.maName, aName.mnDupCount);
        if (aUnoName == rEntry)
        {
            bFound = true;
            break;
        }
        ++nPos;
    }
    return bFound ? nPos : -1;
}

IMPL_LINK(ScDPSubtotalOptDlg, ButtonClicked, weld::Button&, rButton, void)
{
    if (&rButton == m_xBtnOk.get())
        response(RET_OK);
    else
        response(RET_CANCEL);
}

IMPL_LINK(ScDPSubtotalOptDlg, CheckHdl, weld::Toggleable&, rCBox, void)
{
    if (&rCBox == m_xCbShow.get())
    {
        bool bEnable = m_xCbShow->get_active();
        m_xNfShow->set_sensitive( bEnable );
        m_xFtShow->set_sensitive( bEnable );
        m_xFtShowFrom->set_sensitive( bEnable );
        m_xLbShowFrom->set_sensitive( bEnable );

        bool bEnableUsing = bEnable && (m_xLbShowUsing->get_count() > 0);
        m_xFtShowUsing->set_sensitive(bEnableUsing);
        m_xLbShowUsing->set_sensitive(bEnableUsing);
    }
}

IMPL_LINK_NOARG(ScDPSubtotalOptDlg, SelectHdl, weld::ComboBox&, void)
{
    mrDPObj.GetMembers(maLabelData.mnCol, m_xLbHierarchy->get_active(), maLabelData.maMembers);
    InitHideListBox();
}

ScDPShowDetailDlg::ScDPShowDetailDlg(weld::Window* pParent, ScDPObject& rDPObj, css::sheet::DataPilotFieldOrientation nOrient)
    : GenericDialogController(pParent, u"modules/scalc/ui/showdetaildialog.ui"_ustr, u"ShowDetail"_ustr)
    , mrDPObj(rDPObj)
    , mxLbDims(m_xBuilder->weld_tree_view(u"dimsTreeview"_ustr))
{
    ScDPSaveData* pSaveData = rDPObj.GetSaveData();
    tools::Long nDimCount = rDPObj.GetDimCount();
    for (tools::Long nDim=0; nDim<nDimCount; nDim++)
    {
        bool bIsDataLayout;
        sal_Int32 nDimFlags = 0;
        OUString aName = rDPObj.GetDimName( nDim, bIsDataLayout, &nDimFlags );
        if ( !bIsDataLayout && !rDPObj.IsDuplicated( nDim ) && ScDPObject::IsOrientationAllowed( nOrient, nDimFlags ) )
        {
            const ScDPSaveDimension* pDimension = pSaveData ? pSaveData->GetExistingDimensionByName(aName) : nullptr;
            if ( !pDimension || (pDimension->GetOrientation() != nOrient) )
            {
                if (pDimension)
                {
                    const std::optional<OUString> & pLayoutName = pDimension->GetLayoutName();
                    if (pLayoutName)
                        aName = *pLayoutName;
                }
                mxLbDims->append_text(aName);
                maNameIndexMap.emplace(aName, nDim);
            }
        }
    }
    if (mxLbDims->n_children())
       mxLbDims->select(0);

    mxLbDims->connect_row_activated(LINK(this, ScDPShowDetailDlg, DblClickHdl));
}

ScDPShowDetailDlg::~ScDPShowDetailDlg()
{
}

short ScDPShowDetailDlg::run()
{
    return mxLbDims->n_children() ? GenericDialogController::run() : static_cast<short>(RET_CANCEL);
}

OUString ScDPShowDetailDlg::GetDimensionName() const
{
    // Look up the internal dimension name which may be different from the
    // displayed field name.
    OUString aSelectedName = mxLbDims->get_selected_text();
    DimNameIndexMap::const_iterator itr = maNameIndexMap.find(aSelectedName);
    if (itr == maNameIndexMap.end())
        // This should never happen!
        return aSelectedName;

    tools::Long nDim = itr->second;
    bool bIsDataLayout = false;
    return mrDPObj.GetDimName(nDim, bIsDataLayout);
}

IMPL_LINK_NOARG(ScDPShowDetailDlg, DblClickHdl, weld::TreeView&, bool)
{
    m_xDialog->response(RET_OK);
    return true;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=93 H=95 G=93

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.