Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/chart2/source/controller/dialogs/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 31 kB image not shown  

Impressum tp_DataSource.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 .
 */


#include "tp_DataSource.hxx"
#include <strings.hrc>
#include <ResId.hxx>
#include <ChartType.hxx>
#include <ChartTypeTemplateProvider.hxx>
#include <ChartTypeTemplate.hxx>
#include <ChartModel.hxx>
#include <RangeSelectionHelper.hxx>
#include <DataSeries.hxx>
#include <DataSeriesHelper.hxx>
#include <ControllerLockGuard.hxx>
#include <DataSourceHelper.hxx>
#include <LabeledDataSequence.hxx>
#include "DialogModel.hxx"
#include <o3tl/safeint.hxx>
#include <TabPageNotifiable.hxx>
#include <com/sun/star/chart2/data/XDataProvider.hpp>

#include <comphelper/diagnose_ex.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;

using ::com::sun::star::uno::Reference;

namespace
{

constexpr OUString lcl_aLabelRole( u"label"_ustr );

void lcl_UpdateCurrentRange(weld::TreeView& rOutListBox, const OUString & rRole,
                            const OUString& rRange)
{
    int nEntry = rOutListBox.get_selected_index();
    if (nEntry != -1)
    {
        rOutListBox.set_text(nEntry, ::chart::DialogModel::ConvertRoleFromInternalToUI(rRole), 0);
        rOutListBox.set_text(nEntry, rRange, 1);
        ::chart::SeriesEntry* pEntry = weld::fromId<::chart::SeriesEntry*>(rOutListBox.get_id(nEntry));
        pEntry->m_sRole = rRole;
    }
}

bool lcl_UpdateCurrentSeriesName(weld::TreeView& rOutListBox)
{
    int nEntry = rOutListBox.get_selected_index();
    if (nEntry == -1)
        return false;

    bool bResult = false;
    ::chart::SeriesEntry * pEntry = weld::fromId<::chart::SeriesEntry*>(rOutListBox.get_id(nEntry));
    if (pEntry->m_xDataSeries.is() && pEntry->m_xChartType.is())
    {
        OUString aLabel(pEntry->m_xDataSeries->getLabelForRole(
                        pEntry->m_xChartType->getRoleOfSequenceForSeriesLabel()));
        if (!aLabel.isEmpty())
        {
            rOutListBox.set_text(nEntry, aLabel);
            bResult = true;
        }
    }
    return bResult;
}

OUString lcl_GetSelectedRole(const weld::TreeView& rRoleListBox, bool bUITranslated = false)
{
    int nEntry = rRoleListBox.get_selected_index();
    if (nEntry != -1)
    {
        if (bUITranslated)
            return rRoleListBox.get_text(nEntry);
        ::chart::SeriesEntry* pEntry = weld::fromId<::chart::SeriesEntry*>(rRoleListBox.get_id(nEntry));
        return pEntry->m_sRole;
    }
    return OUString();
}

OUString lcl_GetSelectedRolesRange( const weld::TreeView& rRoleListBox )
{
    OUString aResult;
    int nEntry = rRoleListBox.get_selected_index();
    if (nEntry != -1)
        aResult = rRoleListBox.get_text(nEntry, 1);
    return aResult;
}

OUString lcl_GetSequenceNameForLabel(const ::chart::SeriesEntry* pEntry)
{
    OUString aResult(u"values-y"_ustr);
    if (pEntry && pEntry->m_xChartType.is())
        aResult = pEntry->m_xChartType->getRoleOfSequenceForSeriesLabel();
    return aResult;
}

void lcl_addLSequenceToDataSource(
    const uno::Reference< chart2::data::XLabeledDataSequence > & xLSequence,
    const Reference< ::chart::DataSeries > & xSource )
{
    if( xSource.is())
    {
        std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aData = xSource->getDataSequences2();
        aData.push_back( xLSequence );
        xSource->setData( aData );
    }
}

uno::Reference< chart2::data::XLabeledDataSequence > lcl_findLSequenceWithOnlyLabel(
    const rtl::Reference< ::chart::DataSeries > & xDataSource )
{
    uno::Reference< chart2::data::XLabeledDataSequence > xResult;

    for( uno::Reference< chart2::data::XLabeledDataSequence > const & labeledDataSeq : xDataSource->getDataSequences2() )
    {
        // no values are set but a label exists
        if( ! labeledDataSeq->getValues().is() &&
            labeledDataSeq->getLabel().is())
        {
            xResult = labeledDataSeq;
            break;
        }
    }

    return xResult;
}

//  anonymous namespace

namespace chart
{

DataSourceTabPage::DataSourceTabPage(weld::Container* pPage, weld::DialogController* pController,
                                     DialogModel & rDialogModel,
                                     ChartTypeTemplateProvider* pTemplateProvider,
                                     bool bHideDescription /* = false */)
    : ::vcl::OWizardPage(pPage, pController, u"modules/schart/ui/tp_DataSource.ui"_ustr, u"tp_DataSource"_ustr)
    , m_pTemplateProvider(pTemplateProvider)
    , m_rDialogModel(rDialogModel)
    , m_pCurrentRangeChoosingField( nullptr )
    , m_bIsDirty( false )
    , m_pTabPageNotifiable(dynamic_cast<TabPageNotifiable*>(pController))
    , m_xFT_CAPTION(m_xBuilder->weld_label(u"FT_CAPTION_FOR_WIZARD"_ustr))
    , m_xFT_SERIES(m_xBuilder->weld_label(u"FT_SERIES"_ustr))
    , m_xLB_SERIES(m_xBuilder->weld_tree_view(u"LB_SERIES"_ustr))
    , m_xBTN_ADD(m_xBuilder->weld_button(u"BTN_ADD"_ustr))
    , m_xBTN_REMOVE(m_xBuilder->weld_button(u"BTN_REMOVE"_ustr))
    , m_xBTN_UP(m_xBuilder->weld_button(u"BTN_UP"_ustr))
    , m_xBTN_DOWN(m_xBuilder->weld_button(u"BTN_DOWN"_ustr))
    , m_xFT_ROLE(m_xBuilder->weld_label(u"FT_ROLE"_ustr))
    , m_xLB_ROLE(m_xBuilder->weld_tree_view(u"LB_ROLE"_ustr))
    , m_xFT_RANGE(m_xBuilder->weld_label(u"FT_RANGE"_ustr))
    , m_xEDT_RANGE(m_xBuilder->weld_entry(u"EDT_RANGE"_ustr))
    , m_xIMB_RANGE_MAIN(m_xBuilder->weld_button(u"IMB_RANGE_MAIN"_ustr))
    , m_xFT_CATEGORIES(m_xBuilder->weld_label(u"FT_CATEGORIES"_ustr))
    , m_xFT_DATALABELS(m_xBuilder->weld_label(u"FT_DATALABELS"_ustr))
    , m_xEDT_CATEGORIES(m_xBuilder->weld_entry(u"EDT_CATEGORIES"_ustr))
    , m_xIMB_RANGE_CAT(m_xBuilder->weld_button(u"IMB_RANGE_CAT"_ustr))
{
    m_xLB_SERIES->set_size_request(m_xLB_SERIES->get_approximate_digit_width() * 25,
                                   m_xLB_SERIES->get_height_rows(10));
    m_xLB_ROLE->set_size_request(m_xLB_ROLE->get_approximate_digit_width() * 60,
                                 m_xLB_ROLE->get_height_rows(5));
    m_xFT_CAPTION->set_visible(!bHideDescription);

    m_aFixedTextRange = m_xFT_RANGE->get_label();
    SetPageTitle(SchResId(STR_OBJECT_DATASERIES_PLURAL));

    // set handlers
    m_xLB_SERIES->connect_selection_changed(
        LINK(this, DataSourceTabPage, SeriesSelectionChangedHdl));
    m_xLB_ROLE->connect_selection_changed(LINK(this, DataSourceTabPage, RoleSelectionChangedHdl));

    m_xIMB_RANGE_MAIN->connect_clicked(LINK(this, DataSourceTabPage, MainRangeButtonClickedHdl));
    m_xIMB_RANGE_CAT->connect_clicked(LINK(this, DataSourceTabPage, CategoriesRangeButtonClickedHdl));

    m_xBTN_ADD->connect_clicked(LINK(this, DataSourceTabPage, AddButtonClickedHdl));
    m_xBTN_REMOVE->connect_clicked(LINK(this, DataSourceTabPage, RemoveButtonClickedHdl));

    m_xBTN_UP->connect_clicked(LINK(this, DataSourceTabPage, UpButtonClickedHdl));
    m_xBTN_DOWN->connect_clicked(LINK(this, DataSourceTabPage, DownButtonClickedHdl));

    m_xEDT_RANGE->connect_changed(LINK(this, DataSourceTabPage, RangeModifiedHdl));
    m_xEDT_CATEGORIES->connect_changed(LINK( this, DataSourceTabPage, RangeModifiedHdl));

    // init controls
    std::vector<int> aWidths { o3tl::narrowing<int>(m_xLB_ROLE->get_approximate_digit_width() * 20) };
    m_xLB_ROLE->set_column_fixed_widths(aWidths);
    m_xLB_ROLE->show();

    updateControlsFromDialogModel();

    // select first series
    if (m_xLB_SERIES->n_children())
        m_xLB_SERIES->select(0);
}

void DataSourceTabPage::InsertRoleLBEntry(const OUString& rRole, const OUString&&nbsp;rRange)
{
    m_aEntries.emplace_back(new SeriesEntry);
    SeriesEntry* pEntry = m_aEntries.back().get();
    pEntry->m_sRole = rRole;
    m_xLB_ROLE->append(weld::toId(pEntry),
                       ::chart::DialogModel::ConvertRoleFromInternalToUI(rRole));
    m_xLB_ROLE->set_text(m_xLB_ROLE->n_children() - 1, rRange, 1);
}

DataSourceTabPage::~DataSourceTabPage()
{
}

void DataSourceTabPage::Activate()
{
    OWizardPage::Activate();
    updateControlsFromDialogModel();
    m_xLB_SERIES->grab_focus();
}

void DataSourceTabPage::initializePage()
{
}

void DataSourceTabPage::Deactivate()
{
    commitPage();
    vcl::OWizardPage::Deactivate();
}

void DataSourceTabPage::commitPage()
{
    commitPage(::vcl::WizardTypes::eFinish);
}

bool DataSourceTabPage::commitPage( ::vcl::WizardTypes::CommitPageReason /*eReason*/ )
{
    //ranges may have been edited in the meanwhile (dirty is true in that case here)
    if( isValid() )
    {
        updateModelFromControl();
        return true//return false if this page should not be left
    }
    else
        return false;
}

bool DataSourceTabPage::isRangeFieldContentValid(weld::Entry& rEdit )
{
    OUString aRange(rEdit.get_text());
    bool bIsValid = aRange.isEmpty() ||
        m_rDialogModel.getRangeSelectionHelper()->verifyCellRange(aRange);
    rEdit.set_message_type(bIsValid ? weld::EntryMessageType::Normal : weld::EntryMessageType::Error);
    return bIsValid;
}

bool DataSourceTabPage::isValid()
{
    bool bRoleRangeValid = true;
    bool bCategoriesRangeValid = true;
    bool bHasSelectedEntry = (m_xLB_SERIES->get_selected_index() != -1);

    if (bHasSelectedEntry)
        bRoleRangeValid = isRangeFieldContentValid(*m_xEDT_RANGE);
    if (m_xEDT_CATEGORIES->get_sensitive())
        bCategoriesRangeValid = isRangeFieldContentValid( *m_xEDT_CATEGORIES );
    bool bValid = ( bRoleRangeValid && bCategoriesRangeValid );

    if( m_pTabPageNotifiable )
    {
        if( bValid )
            m_pTabPageNotifiable->setValidPage( this );
        else
            m_pTabPageNotifiable->setInvalidPage( this );
    }

    return bValid;
}

void DataSourceTabPage::setDirty()
{
    m_bIsDirty = true;
}

void DataSourceTabPage::updateControlsFromDialogModel()
{
    // series
    fillSeriesListBox();
    SeriesSelectionChangedHdl(*m_xLB_SERIES);

    // categories
    m_xEDT_CATEGORIES->set_text(m_rDialogModel.getCategoriesRange());

    updateControlState();
}

void DataSourceTabPage::fillSeriesListBox()
{
    rtl::Reference< DataSeries > xSelected;
    SeriesEntry* pEntry = nullptr;
    int nEntry = m_xLB_SERIES->get_selected_index();
    if (nEntry != -1)
    {
        pEntry = weld::fromId<SeriesEntry*>(m_xLB_SERIES->get_id(nEntry));
        xSelected = pEntry->m_xDataSeries;
    }

    bool bHasSelectedEntry = (pEntry != nullptr);
    int nSelectedEntry = -1;

    m_xLB_SERIES->freeze();
    m_xLB_SERIES->clear();

    std::vector< DialogModel::tSeriesWithChartTypeByName > aSeries(
        m_rDialogModel.getAllDataSeriesWithLabel() );

    sal_Int32 nUnnamedSeriesIndex = 1;
    nEntry = 0;
    for (auto const& series : aSeries)
    {
        OUString aLabel(series.first);
        if (aLabel.isEmpty())
        {
            if( nUnnamedSeriesIndex > 1 )
            {
                OUString aResString(::chart::SchResId( STR_DATA_UNNAMED_SERIES_WITH_INDEX ));

                // replace index of unnamed series
                static constexpr OUString aReplacementStr( u"%NUMBER"_ustr );
                sal_Int32 nIndex = aResString.indexOf( aReplacementStr );
                if( nIndex != -1 )
                    aLabel = aResString.replaceAt(
                                         nIndex, aReplacementStr.getLength(),
                                         OUString::number(nUnnamedSeriesIndex));
            }
            if( aLabel.isEmpty() )
                aLabel = ::chart::SchResId( STR_DATA_UNNAMED_SERIES );

            ++nUnnamedSeriesIndex;
        }

        m_aEntries.emplace_back(new SeriesEntry);
        pEntry = m_aEntries.back().get();
        pEntry->m_xDataSeries = series.second.first;
        pEntry->m_xChartType = series.second.second;
        m_xLB_SERIES->append(weld::toId(pEntry), aLabel);
        if (bHasSelectedEntry && series.second.first == xSelected)
            nSelectedEntry = nEntry;
        ++nEntry;
    }

    m_xLB_SERIES->thaw();

    if (bHasSelectedEntry && nSelectedEntry != -1)
        m_xLB_SERIES->select(nSelectedEntry);
}

void DataSourceTabPage::fillRoleListBox()
{
    int nSeriesEntry = m_xLB_SERIES->get_selected_index();
    SeriesEntry* pSeriesEntry = nullptr;
    if (nSeriesEntry != -1)
        pSeriesEntry = weld::fromId<SeriesEntry*>(m_xLB_SERIES->get_id(nSeriesEntry));
    bool bHasSelectedEntry = (pSeriesEntry != nullptr);

    int nRoleIndex = m_xLB_ROLE->get_selected_index();
    if (!bHasSelectedEntry)
        return;

    DialogModel::tRolesWithRanges aRoles(
        DialogModel::getRolesWithRanges(
            pSeriesEntry->m_xDataSeries,
            lcl_GetSequenceNameForLabel( pSeriesEntry ),
            pSeriesEntry->m_xChartType ));

    // fill role list
    m_xLB_ROLE->freeze();
    m_xLB_ROLE->clear();

    for (auto const& elemRole : aRoles)
    {
        InsertRoleLBEntry(elemRole.first, elemRole.second);
    }

    m_xLB_ROLE->thaw();

    // series may contain no roles, check listbox size before selecting entries
    if (m_xLB_ROLE->n_children() > 0)
    {
        if (nRoleIndex == -1 || nRoleIndex >= m_xLB_ROLE->n_children())
            nRoleIndex = 0;
        m_xLB_ROLE->select(nRoleIndex);
    }
}

void DataSourceTabPage::updateControlState()
{
    int nSeriesEntry = m_xLB_SERIES->get_selected_index();
    bool bHasSelectedSeries = nSeriesEntry != -1;
    bool bHasValidRole = false;
    bool bHasRangeChooser = m_rDialogModel.getRangeSelectionHelper()->hasRangeSelection();

    if( bHasSelectedSeries )
    {
        int nRoleEntry = m_xLB_ROLE->get_selected_index();
        bHasValidRole = nRoleEntry != -1;
    }

    m_xBTN_ADD->set_sensitive(true);
    m_xBTN_REMOVE->set_sensitive(bHasSelectedSeries);

    m_xBTN_UP->set_sensitive(bHasSelectedSeries && (nSeriesEntry != 0));
    m_xBTN_DOWN->set_sensitive(bHasSelectedSeries && (nSeriesEntry != m_xLB_SERIES->n_children() - 1));

    bool bHasCategories = m_rDialogModel.isCategoryDiagram();

    m_xFT_DATALABELS->set_visible(!bHasCategories);
    m_xFT_CATEGORIES->set_visible( bHasCategories);
    bool bShowIB = bHasRangeChooser;

    m_xIMB_RANGE_CAT->set_visible(bShowIB);

    m_xFT_ROLE->set_sensitive(bHasSelectedSeries);
    m_xLB_ROLE->set_sensitive(bHasSelectedSeries);

    m_xFT_RANGE->set_sensitive(bHasValidRole);
    m_xEDT_RANGE->set_sensitive(bHasValidRole);

    m_xFT_SERIES->set_sensitive(true);
    m_xLB_SERIES->set_sensitive(true);

    m_xIMB_RANGE_MAIN->set_visible(bShowIB);

    isValid();
}

IMPL_LINK_NOARG(DataSourceTabPage, SeriesSelectionChangedHdl, weld::TreeView&, void)
{
    m_rDialogModel.startControllerLockTimer();
    if (m_xLB_SERIES->get_selected_index() != -1)
    {
        fillRoleListBox();
        RoleSelectionChangedHdl(*m_xLB_ROLE);
    }
    updateControlState();
}

IMPL_LINK_NOARG(DataSourceTabPage, RoleSelectionChangedHdl, weld::TreeView&, void)
{
    m_rDialogModel.startControllerLockTimer();
    int nEntry = m_xLB_ROLE->get_selected_index();
    if (nEntry == -1)
        return;

    OUString aSelectedRoleUI = lcl_GetSelectedRole( *m_xLB_ROLE, true );
    OUString aSelectedRange = lcl_GetSelectedRolesRange( *m_xLB_ROLE );

    // replace role in fixed text label
    static constexpr OUString aReplacementStr( u"%VALUETYPE"_ustr );
    sal_Int32 nIndex = m_aFixedTextRange.indexOf( aReplacementStr );
    if( nIndex != -1 )
    {
        m_xFT_RANGE->set_label(
            m_aFixedTextRange.replaceAt(
                        nIndex, aReplacementStr.getLength(), aSelectedRoleUI ));
    }

    m_xEDT_RANGE->set_text(aSelectedRange);
    isValid();
}

IMPL_LINK_NOARG(DataSourceTabPage, MainRangeButtonClickedHdl, weld::Button&, void)
{
    OSL_ASSERT( m_pCurrentRangeChoosingField == nullptr );
    m_pCurrentRangeChoosingField = m_xEDT_RANGE.get();
    if (!m_xEDT_RANGE->get_text().isEmpty() &&
        !updateModelFromControl( m_pCurrentRangeChoosingField))
        return;

    int nEntry = m_xLB_SERIES->get_selected_index();
    bool bHasSelectedEntry = (nEntry != -1);

    OUString aSelectedRolesRange = lcl_GetSelectedRolesRange(*m_xLB_ROLE);

    if (bHasSelectedEntry && (m_xLB_ROLE->get_selected_index() != -1))
    {
        OUString aUIStr(SchResId(STR_DATA_SELECT_RANGE_FOR_SERIES));

        // replace role
        OUString aReplacement( u"%VALUETYPE"_ustr );
        sal_Int32 nIndex = aUIStr.indexOf( aReplacement );
        if( nIndex != -1 )
        {
            aUIStr = aUIStr.replaceAt( nIndex, aReplacement.getLength(),
                                       lcl_GetSelectedRole( *m_xLB_ROLE, true ));
        }
        // replace series name
        aReplacement = "%SERIESNAME";
        nIndex = aUIStr.indexOf( aReplacement );
        if( nIndex != -1 )
        {
            aUIStr = aUIStr.replaceAt(nIndex, aReplacement.getLength(),
                                      m_xLB_SERIES->get_text(nEntry));
        }

        enableRangeChoosing(true, m_pDialogController);
        m_rDialogModel.getRangeSelectionHelper()->chooseRange( aSelectedRolesRange, aUIStr, *this );
    }
    else
        m_pCurrentRangeChoosingField = nullptr;
}

IMPL_LINK_NOARG(DataSourceTabPage, CategoriesRangeButtonClickedHdl, weld::Button&,&nbsp;void)
{
    OSL_ASSERT( m_pCurrentRangeChoosingField == nullptr );
    m_pCurrentRangeChoosingField = m_xEDT_CATEGORIES.get();
    if( !m_xEDT_CATEGORIES->get_text().isEmpty() &&
        ! updateModelFromControl( m_pCurrentRangeChoosingField ))
        return;

    OUString aStr(SchResId(m_xFT_CATEGORIES->get_visible() ? STR_DATA_SELECT_RANGE_FOR_CATEGORIES : STR_DATA_SELECT_RANGE_FOR_DATALABELS));
    enableRangeChoosing(true, m_pDialogController);
    m_rDialogModel.getRangeSelectionHelper()->chooseRange(
        m_rDialogModel.getCategoriesRange(), aStr, *this );
}

IMPL_LINK_NOARG(DataSourceTabPage, AddButtonClickedHdl, weld::Button&, void)
{
    m_rDialogModel.startControllerLockTimer();
    int nEntry = m_xLB_SERIES->get_selected_index();
    rtl::Reference< DataSeries > xSeriesToInsertAfter;
    rtl::Reference< ChartType > xChartTypeForNewSeries;
    if( m_pTemplateProvider )
            m_rDialogModel.setTemplate( m_pTemplateProvider->getCurrentTemplate());

    if (nEntry != -1)
    {
        ::chart::SeriesEntry* pEntry = weld::fromId<::chart::SeriesEntry*>(m_xLB_SERIES->get_id(nEntry));
        xSeriesToInsertAfter = pEntry->m_xDataSeries;
        xChartTypeForNewSeries = pEntry->m_xChartType;
    }
    else
    {
        std::vector< rtl::Reference< ChartType > > aCntVec(
            m_rDialogModel.getAllDataSeriesContainers());
        if( ! aCntVec.empty())
            xChartTypeForNewSeries = aCntVec.front();
    }
    OSL_ENSURE( xChartTypeForNewSeries.is(), "Cannot insert new series" );

    m_rDialogModel.insertSeriesAfter( xSeriesToInsertAfter, xChartTypeForNewSeries );
    setDirty();

    fillSeriesListBox();
    // note the box was cleared and refilled, so nEntry is invalid now

    int nSelEntry = m_xLB_SERIES->get_selected_index();
    if (nSelEntry != -1)
    {
        ++nSelEntry;
        if (nSelEntry < m_xLB_SERIES->n_children())
            m_xLB_SERIES->select(nSelEntry);
    }
    SeriesSelectionChangedHdl(*m_xLB_SERIES);
}

IMPL_LINK_NOARG(DataSourceTabPage, RemoveButtonClickedHdl, weld::Button&, void)
{
    m_rDialogModel.startControllerLockTimer();
    int nEntry = m_xLB_SERIES->get_selected_index();
    if (nEntry == -1)
        return;

    SeriesEntry* pEntry = weld::fromId<::chart::SeriesEntry*>(m_xLB_SERIES->get_id(nEntry));
    rtl::Reference< DataSeries > xNewSelSeries;
    SeriesEntry * pNewSelEntry = nullptr;
    if (nEntry + 1 < m_xLB_SERIES->n_children())
        pNewSelEntry = weld::fromId<::chart::SeriesEntry*>(m_xLB_SERIES->get_id(nEntry + 1));
    else if (nEntry > 0)
        pNewSelEntry = weld::fromId<::chart::SeriesEntry*>(m_xLB_SERIES->get_id(nEntry - 1));
    if (pNewSelEntry)
        xNewSelSeries = pNewSelEntry->m_xDataSeries;

    m_rDialogModel.deleteSeries( pEntry->m_xDataSeries, pEntry->m_xChartType );
    setDirty();

    m_xLB_SERIES->remove(nEntry);
    fillSeriesListBox();

    // select previous or next series
    if (xNewSelSeries.is())
    {
        for (int i = 0; i < m_xLB_SERIES->n_children(); ++i)
        {
            pEntry = weld::fromId<::chart::SeriesEntry*>(m_xLB_SERIES->get_id(i));
            if (pEntry->m_xDataSeries == xNewSelSeries)
            {
                m_xLB_SERIES->select(i);
                break;
            }
        }
    }
    SeriesSelectionChangedHdl(*m_xLB_SERIES);
}

IMPL_LINK_NOARG(DataSourceTabPage, UpButtonClickedHdl, weld::Button&, void)
{
    m_rDialogModel.startControllerLockTimer();

    int nEntry = m_xLB_SERIES->get_selected_index();
    SeriesEntry* pEntry = nullptr;
    if (nEntry != -1)
        pEntry = weld::fromId<SeriesEntry*>(m_xLB_SERIES->get_id(nEntry));

    bool bHasSelectedEntry = (pEntry != nullptr);

    if (bHasSelectedEntry)
    {
        m_rDialogModel.moveSeries( pEntry->m_xDataSeries, DialogModel::MoveDirection::Up );
        setDirty();
        fillSeriesListBox();
        SeriesSelectionChangedHdl(*m_xLB_SERIES);
    }
}

IMPL_LINK_NOARG(DataSourceTabPage, DownButtonClickedHdl, weld::Button&, void)
{
    m_rDialogModel.startControllerLockTimer();

    int nEntry = m_xLB_SERIES->get_selected_index();
    SeriesEntry* pEntry = nullptr;
    if (nEntry != -1)
        pEntry = weld::fromId<SeriesEntry*>(m_xLB_SERIES->get_id(nEntry));

    bool bHasSelectedEntry = (pEntry != nullptr);

    if (bHasSelectedEntry)
    {
        m_rDialogModel.moveSeries( pEntry->m_xDataSeries, DialogModel::MoveDirection::Down );
        setDirty();
        fillSeriesListBox();
        SeriesSelectionChangedHdl(*m_xLB_SERIES);
    }
}

IMPL_LINK(DataSourceTabPage, RangeModifiedHdl, weld::Entry&, rEdit, void)
{
    // note: isValid sets the color of the edit field
    if( isRangeFieldContentValid( rEdit ))
    {
        setDirty();
        updateModelFromControl( &rEdit );
        if (&rEdit == m_xEDT_RANGE.get())
        {
            if( ! lcl_UpdateCurrentSeriesName( *m_xLB_SERIES ))
                fillSeriesListBox();
        }
    }

    // enable/disable OK button
    isValid();
}

void DataSourceTabPage::listeningFinished(
    const OUString & rNewRange )
{
    // rNewRange becomes invalid after removing the listener
    OUString aRange( rNewRange );

    m_rDialogModel.startControllerLockTimer();

    // stop listening
    m_rDialogModel.getRangeSelectionHelper()->stopRangeListening();

    // change edit field
    if( m_pCurrentRangeChoosingField )
    {
        m_pCurrentRangeChoosingField->set_text(aRange);
        m_pCurrentRangeChoosingField->grab_focus();
    }

    if (m_pCurrentRangeChoosingField == m_xEDT_RANGE.get())
    {
        m_xEDT_RANGE->set_text(aRange);
        setDirty();
    }
    else if (m_pCurrentRangeChoosingField == m_xEDT_CATEGORIES.get())
    {
        m_xEDT_CATEGORIES->set_text(aRange);
        setDirty();
    }

    updateModelFromControl(m_pCurrentRangeChoosingField);
    if (!lcl_UpdateCurrentSeriesName(*m_xLB_SERIES))
        fillSeriesListBox();

    m_pCurrentRangeChoosingField = nullptr;

    updateControlState();
    enableRangeChoosing(false, m_pDialogController);
}

void DataSourceTabPage::disposingRangeSelection()
{
    m_rDialogModel.getRangeSelectionHelper()->stopRangeListening( false );
}

bool DataSourceTabPage::updateModelFromControl(const weld::Entry* pField)
{
    if (!m_bIsDirty)
        return true;

    ControllerLockGuardUNO aLockedControllers( m_rDialogModel.getChartModel() );

    // @todo: validity check of field content
    bool bResult = true;
    bool bAll = (pField == nullptr);
    Reference< data::XDataProvider > xDataProvider( m_rDialogModel.getDataProvider());

    if (bAll || (pField == m_xEDT_CATEGORIES.get()))
    {
        uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSeq( m_rDialogModel.getCategories() );
        if( xDataProvider.is())
        {
            OUString aRange(m_xEDT_CATEGORIES->get_text());
            if (!aRange.isEmpty())
            {
                // create or change categories
                if( !xLabeledSeq.is())
                {
                    xLabeledSeq = DataSourceHelper::createLabeledDataSequence();
                    m_rDialogModel.setCategories( xLabeledSeq );
                }
                try
                {
                    xLabeledSeq->setValues( xDataProvider->createDataSequenceByRangeRepresentation( aRange ));
                }
                catchconst uno::Exception & )
                {
                    // should work as validation should have happened before
                    DBG_UNHANDLED_EXCEPTION("chart2");
                }
            }
            else if( xLabeledSeq.is())
            {
                // clear existing categories
                xLabeledSeq.clear();
                m_rDialogModel.setCategories( xLabeledSeq );
            }
        }
    }

    int nSeriesEntry = m_xLB_SERIES->get_selected_index();
    SeriesEntry* pSeriesEntry = nullptr;
    if (nSeriesEntry != -1)
        pSeriesEntry = weld::fromId<SeriesEntry*>(m_xLB_SERIES->get_id(nSeriesEntry));
    bool bHasSelectedEntry = (pSeriesEntry != nullptr);

    if( bHasSelectedEntry )
    {
        if( bAll || (pField == m_xEDT_RANGE.get()) )
        {
            try
            {
                OUString aSelectedRole = lcl_GetSelectedRole( *m_xLB_ROLE );
                OUString aRange(m_xEDT_RANGE->get_text());
                OUString aSequenceRole( aSelectedRole );
                bool bIsLabel = (aSequenceRole == lcl_aLabelRole );
                OUString aSequenceNameForLabel( lcl_GetSequenceNameForLabel( pSeriesEntry ));

                if( bIsLabel )
                    aSequenceRole = aSequenceNameForLabel;

                uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSeq =
                    DataSeriesHelper::getDataSequenceByRole( pSeriesEntry->m_xDataSeries, aSequenceRole );

                if( xDataProvider.is())
                {
                    if( bIsLabel )
                    {
                        if( ! xLabeledSeq.is())
                        {
                            // check if there is already an "orphan" label sequence
                            xLabeledSeq = lcl_findLSequenceWithOnlyLabel( pSeriesEntry->m_xDataSeries );
                            if( ! xLabeledSeq.is())
                            {
                                // no corresponding labeled data sequence for label found
                                xLabeledSeq = DataSourceHelper::createLabeledDataSequence();
                                lcl_addLSequenceToDataSource( xLabeledSeq, pSeriesEntry->m_xDataSeries );
                            }
                        }
                        if( xLabeledSeq.is())
                        {
                            if( !aRange.isEmpty())
                            {
                                Reference< data::XDataSequence > xNewSeq;
                                try
                                {
                                    xNewSeq.set( xDataProvider->createDataSequenceByRangeRepresentation( aRange ));
                                }
                                catchconst uno::Exception & )
                                {
                                    // should work as validation should have happened before
                                    DBG_UNHANDLED_EXCEPTION("chart2");
                                }
                                if( xNewSeq.is())
                                {
                                    // update range name by the full string provided
                                    // by the data provider. E.g. "a1" might become
                                    // "$Sheet1.$A$1"
                                    aRange = xNewSeq->getSourceRangeRepresentation();
                                    Reference< beans::XPropertySet > xProp( xNewSeq, uno::UNO_QUERY_THROW );
                                    xProp->setPropertyValue( u"Role"_ustr , uno::Any( lcl_aLabelRole ));

                                    //Labels should always include hidden cells, regardless of the setting chosen
                                    xProp->setPropertyValue( u"IncludeHiddenCells"_ustr, uno::Any(true));
                                    xLabeledSeq->setLabel( xNewSeq );
                                }
                            }
                            else
                            {
                                xLabeledSeq->setLabel( Reference< data::XDataSequence >());
                            }
                        }
                    }
                    else
                    {
                        if( !aRange.isEmpty())
                        {
                            Reference< data::XDataSequence > xNewSeq;
                            try
                            {
                                xNewSeq.set( xDataProvider->createDataSequenceByRangeRepresentation( aRange ));
                            }
                            catchconst uno::Exception & )
                            {
                                // should work as validation should have happened before
                                DBG_UNHANDLED_EXCEPTION("chart2");
                            }
                            if( xNewSeq.is())
                            {
                                // update range name by the full string provided
                                // by the data provider. E.g. "a1:e1" might become
                                // "$Sheet1.$A$1:$E$1"
                                aRange = xNewSeq->getSourceRangeRepresentation();

                                Reference< beans::XPropertySet > xProp( xNewSeq, uno::UNO_QUERY_THROW );
                                xProp->setPropertyValue( u"Role"_ustr , uno::Any( aSelectedRole ));
                                if( !xLabeledSeq.is())
                                {
                                    if( aSelectedRole == aSequenceNameForLabel )
                                        xLabeledSeq = lcl_findLSequenceWithOnlyLabel( pSeriesEntry->m_xDataSeries );
                                    if( ! xLabeledSeq.is())
                                    {
                                        xLabeledSeq = DataSourceHelper::createLabeledDataSequence();
                                        lcl_addLSequenceToDataSource( xLabeledSeq, pSeriesEntry->m_xDataSeries );
                                    }
                                }
                                xLabeledSeq->setValues( xNewSeq );
                            }
                        }
                    }
                }

                lcl_UpdateCurrentRange( *m_xLB_ROLE, aSelectedRole, aRange );
            }
            catchconst uno::Exception & )
            {
                DBG_UNHANDLED_EXCEPTION("chart2");
                bResult = false;
            }
        }
    }

    // update View
    // @todo remove this when automatic view updates from calc, writer and own data sequences are available
    if( bResult )
    {
        try
        {
            if( m_rDialogModel.getChartModel() )
                m_rDialogModel.getChartModel()->setModified( true );
            const DialogModelTimeBasedInfo& rInfo = m_rDialogModel.getTimeBasedInfo();
            if(rInfo.bTimeBased)
            {
                m_rDialogModel.setTimeBasedRange(rInfo.bTimeBased, rInfo.nStart, rInfo.nEnd);
            }
        }
        catchconst uno::Exception & )
        {
            DBG_UNHANDLED_EXCEPTION("chart2");
        }
    }

    return bResult;
}

//  namespace chart

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

94%


¤ Dauer der Verarbeitung: 0.18 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 ist noch experimentell.