/* -*- 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 <ChartController.hxx>
#include <ChartView.hxx>
#include <chartview/DrawModelWrapper.hxx>
#include <chartview/ChartSfxItemIds.hxx>
#include <ObjectIdentifier.hxx>
#include <chartview/ExplicitScaleValues.hxx>
#include <chartview/ExplicitValueProvider.hxx>
#include <dlg_ObjectProperties.hxx>
#include <dlg_View3D.hxx>
#include <dlg_InsertErrorBars.hxx>
#include <ViewElementListProvider.hxx>
#include <DataPointItemConverter.hxx>
#include <TextLabelItemConverter.hxx>
#include <AxisItemConverter.hxx>
#include <MultipleChartConverters.hxx>
#include <TitleItemConverter.hxx>
#include <LegendItemConverter.hxx>
#include <DataTableItemConverter.hxx>
#include <RegressionCurveItemConverter.hxx>
#include <RegressionEquationItemConverter.hxx>
#include <ErrorBarItemConverter.hxx>
#include <ChartModelHelper.hxx>
#include <Axis.hxx>
#include <AxisHelper.hxx>
#include <TitleHelper.hxx>
#include <ChartType.hxx>
#include <ChartTypeHelper.hxx>
#include <ChartModel.hxx>
#include <ColorPerPointHelper.hxx>
#include <DataSeries.hxx>
#include <DataSeriesProperties.hxx>
#include <Diagram.hxx>
#include <ControllerLockGuard.hxx>
#include "UndoGuard.hxx"
#include <ObjectNameProvider.hxx>
#include <ResId.hxx>
#include <strings.hrc>
#include <ReferenceSizeProvider.hxx>
#include <RegressionCurveHelper.hxx>
#include <RegressionCurveModel.hxx>
#include <o3tl/string_view.hxx>
#include <com/sun/star/util/CloseVetoException.hpp>
#include <memory>
#include <vcl/svapp.hxx>
#include <svx/ActionDescriptionProvider.hxx>
#include <comphelper/diagnose_ex.hxx>
namespace chart
{
using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;
using namespace ::chart::DataSeriesProperties;
using ::com::sun::star::uno::Reference;
namespace
{
wrapper::ItemConverter* createItemConverter(
std::u16string_view aObjectCID, const rtl::Reference<::chart::ChartModel>& xChartModel,
const uno::Reference<uno::XComponentContext>& xContext, SdrModel& rDrawModel,
ExplicitValueProvider* pExplicitValueProvider, ReferenceSizeProvider const * pRefSizeProvider )
{
wrapper::ItemConverter* pItemConverter=nullptr;
//get type of selected object
ObjectType eObjectType = ObjectIdentifier::getObjectType( aObjectCID );
if( eObjectType==OBJECTTYPE_UNKNOWN )
{
OSL_FAIL("unknown ObjectType");
return nullptr;
}
std::u16string_view aParticleID = ObjectIdentifier::getParticleID( aObjectCID );
bool bAffectsMultipleObjects = aParticleID == u"ALLELEMENTS";
if( !bAffectsMultipleObjects )
{
uno::Reference< beans::XPropertySet > xObjectProperties =
ObjectIdentifier::getObjectPropertySet( aObjectCID, xChartModel );
if(!xObjectProperties.is())
return nullptr;
//create itemconverter for a single object
switch(eObjectType)
{
case OBJECTTYPE_DATA_STOCK_LOSS:
case OBJECTTYPE_DATA_STOCK_GAIN:
case OBJECTTYPE_DIAGRAM_WALL:
case OBJECTTYPE_DIAGRAM_FLOOR:
case OBJECTTYPE_PAGE:
pItemConverter = new wrapper::GraphicPropertyItemConverter(
xObjectProperties, rDrawModel.GetItemPool(),
rDrawModel, xChartModel,
wrapper::GraphicObjectType::LineAndFillProperties );
break;
case OBJECTTYPE_TITLE:
{
std::optional<awt::Size> pRefSize;
if (pRefSizeProvider)
pRefSize.emplace(pRefSizeProvider->getPageSize());
pItemConverter = new wrapper::TitleItemConverter(
xObjectProperties, rDrawModel.GetItemPool(), rDrawModel,
xChartModel,
pRefSize);
}
break;
case OBJECTTYPE_LEGEND:
{
std::optional<awt::Size> pRefSize;
if (pRefSizeProvider)
pRefSize.emplace( pRefSizeProvider->getPageSize() );
pItemConverter = new wrapper::LegendItemConverter(
xObjectProperties, rDrawModel.GetItemPool(), rDrawModel,
xChartModel,
pRefSize);
}
break;
case OBJECTTYPE_LEGEND_ENTRY:
break;
case OBJECTTYPE_DIAGRAM:
break;
case OBJECTTYPE_AXIS:
{
std::optional<awt::Size> pRefSize;
if (pRefSizeProvider)
pRefSize.emplace( pRefSizeProvider->getPageSize() );
// the second property set contains the property CoordinateOrigin
// nOriginIndex is the index of the corresponding index of the
// origin (x=0, y=1, z=2)
ExplicitScaleData aExplicitScale;
ExplicitIncrementData aExplicitIncrement;
if( pExplicitValueProvider )
pExplicitValueProvider->getExplicitValuesForAxis(
dynamic_cast< Axis* >( xObjectProperties.get() ),
aExplicitScale, aExplicitIncrement );
pItemConverter = new wrapper::AxisItemConverter(
xObjectProperties, rDrawModel.GetItemPool(),
rDrawModel,
xChartModel,
&aExplicitScale, &aExplicitIncrement,
pRefSize );
}
break;
case OBJECTTYPE_AXIS_UNITLABEL:
break;
case OBJECTTYPE_DATA_LABELS:
case OBJECTTYPE_DATA_LABEL:
{
std::optional<awt::Size> pRefSize;
if (pRefSizeProvider)
pRefSize.emplace( pRefSizeProvider->getPageSize() );
rtl::Reference<DataSeries> xSeries = ObjectIdentifier::getDataSeriesForCID(aObjectCID, xChartModel);
bool bDataSeries = eObjectType == OBJECTTYPE_DATA_LABELS;
sal_Int32 nNumberFormat = ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel( xObjectProperties );
sal_Int32 nPercentNumberFormat = ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForDataLabel(
xObjectProperties, xChartModel);
pItemConverter = new wrapper::TextLabelItemConverter(
xChartModel, xObjectProperties, xSeries,
rDrawModel.GetItemPool(), pRefSize, bDataSeries,
nNumberFormat, nPercentNumberFormat);
}
break;
case OBJECTTYPE_DATA_SERIES:
case OBJECTTYPE_DATA_POINT:
{
std::optional<awt::Size> pRefSize;
if (pRefSizeProvider)
pRefSize.emplace( pRefSizeProvider->getPageSize() );
wrapper::GraphicObjectType eMapTo =
wrapper::GraphicObjectType::FilledDataPoint;
rtl::Reference< DataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( aObjectCID, xChartModel );
rtl::Reference< ChartType > xChartType = ChartModelHelper::getChartTypeOfSeries( xChartModel, xSeries );
rtl::Reference< Diagram > xDiagram = xChartModel->getFirstChartDiagram();
sal_Int32 nDimensionCount = xDiagram->getDimension();
if( !ChartTypeHelper::isSupportingAreaProperties( xChartType, nDimensionCount ) )
eMapTo = wrapper::GraphicObjectType::LineDataPoint;
bool bDataSeries = eObjectType == OBJECTTYPE_DATA_SERIES;
//special color for pie chart:
bool bUseSpecialFillColor = false;
sal_Int32 nSpecialFillColor =0;
sal_Int32 nPointIndex = -1; /*-1 for whole series*/
if(!bDataSeries)
{
nPointIndex = o3tl::toInt32(aParticleID);
bool bVaryColorsByPoint = false;
if( xSeries.is() &&
// "VaryColorsByPoint"
(xSeries->getFastPropertyValue(PROP_DATASERIES_VARY_COLORS_BY_POINT) >>= bVaryColorsByPoint) &&
bVaryColorsByPoint )
{
if( !ColorPerPointHelper::hasPointOwnColor( xSeries, nPointIndex, xObjectProperties ) )
{
bUseSpecialFillColor = true;
OSL_ASSERT( xDiagram.is());
uno::Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme() );
if( xColorScheme.is())
nSpecialFillColor = xColorScheme->getColorByIndex( nPointIndex );
}
}
}
sal_Int32 nNumberFormat=ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel( xObjectProperties );
sal_Int32 nPercentNumberFormat=ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForDataLabel(
xObjectProperties, xChartModel);
pItemConverter = new wrapper::DataPointItemConverter( xChartModel, xContext,
xObjectProperties, xSeries, rDrawModel.GetItemPool(), rDrawModel,
xChartModel,
eMapTo, pRefSize, bDataSeries, bUseSpecialFillColor, nSpecialFillColor, true,
nNumberFormat, nPercentNumberFormat, nPointIndex );
break;
}
case OBJECTTYPE_GRID:
case OBJECTTYPE_SUBGRID:
case OBJECTTYPE_DATA_AVERAGE_LINE:
pItemConverter = new wrapper::GraphicPropertyItemConverter(
xObjectProperties, rDrawModel.GetItemPool(),
rDrawModel, xChartModel,
wrapper::GraphicObjectType::LineProperties );
break;
case OBJECTTYPE_DATA_ERRORS_X:
case OBJECTTYPE_DATA_ERRORS_Y:
case OBJECTTYPE_DATA_ERRORS_Z:
pItemConverter = new wrapper::ErrorBarItemConverter(
xChartModel, xObjectProperties, rDrawModel.GetItemPool(),
rDrawModel, xChartModel);
break;
case OBJECTTYPE_DATA_CURVE:
pItemConverter = new wrapper::RegressionCurveItemConverter(
xObjectProperties,
ObjectIdentifier::getDataSeriesForCID( aObjectCID, xChartModel ),
rDrawModel.GetItemPool(), rDrawModel,
xChartModel);
break;
case OBJECTTYPE_DATA_CURVE_EQUATION:
{
std::optional<awt::Size> pRefSize;
if (pRefSizeProvider)
pRefSize.emplace(pRefSizeProvider->getPageSize());
pItemConverter = new wrapper::RegressionEquationItemConverter(
xObjectProperties, rDrawModel.GetItemPool(), rDrawModel,
xChartModel,
pRefSize);
break;
}
case OBJECTTYPE_DATA_STOCK_RANGE:
break;
case OBJECTTYPE_DATA_TABLE:
{
pItemConverter = new wrapper::DataTableItemConverter(
xObjectProperties, rDrawModel.GetItemPool(),
rDrawModel, xChartModel);
}
break;
default: //OBJECTTYPE_UNKNOWN
break;
}
}
else
{
//create itemconverter for all objects of given type
switch(eObjectType)
{
case OBJECTTYPE_TITLE:
pItemConverter = new wrapper::AllTitleItemConverter( xChartModel, rDrawModel.GetItemPool(),
rDrawModel, xChartModel);
break;
case OBJECTTYPE_AXIS:
{
std::optional<awt::Size> pRefSize;
if (pRefSizeProvider)
pRefSize.emplace( pRefSizeProvider->getPageSize() );
pItemConverter = new wrapper::AllAxisItemConverter(
xChartModel, rDrawModel.GetItemPool(),
rDrawModel, pRefSize );
}
break;
case OBJECTTYPE_GRID:
case OBJECTTYPE_SUBGRID:
pItemConverter = new wrapper::AllGridItemConverter( xChartModel, rDrawModel.GetItemPool(),
rDrawModel, xChartModel);
break;
default: //for this type it is not supported to change all elements at once
break;
}
}
return pItemConverter;
}
OUString lcl_getTitleCIDForCommand( std::string_view rDispatchCommand, const rtl::Reference<::chart::ChartModel> & xChartModel )
{
if( rDispatchCommand == "AllTitles")
return ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_TITLE, u"ALLELEMENTS" );
TitleHelper::eTitleType nTitleType( TitleHelper::MAIN_TITLE );
if( rDispatchCommand == "SubTitle" )
nTitleType = TitleHelper::SUB_TITLE;
else if( rDispatchCommand == "XTitle" )
nTitleType = TitleHelper::X_AXIS_TITLE;
else if( rDispatchCommand == "YTitle" )
nTitleType = TitleHelper::Y_AXIS_TITLE;
else if( rDispatchCommand == "ZTitle" )
nTitleType = TitleHelper::Z_AXIS_TITLE;
else if( rDispatchCommand == "SecondaryXTitle" )
nTitleType = TitleHelper::SECONDARY_X_AXIS_TITLE;
else if( rDispatchCommand == "SecondaryYTitle" )
nTitleType = TitleHelper::SECONDARY_Y_AXIS_TITLE;
rtl::Reference< Title > xTitle( TitleHelper::getTitle( nTitleType, xChartModel ) );
return ObjectIdentifier::createClassifiedIdentifierForObject( xTitle, xChartModel );
}
OUString lcl_getAxisCIDForCommand( std::string_view rDispatchCommand, const rtl::Reference<::chart::ChartModel>& xChartModel )
{
if( rDispatchCommand == "DiagramAxisAll")
return ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_AXIS, u"ALLELEMENTS" );
sal_Int32 nDimensionIndex=0;
bool bMainAxis=true;
if( rDispatchCommand == "DiagramAxisX")
{
nDimensionIndex=0; bMainAxis=true;
}
else if( rDispatchCommand == "DiagramAxisY")
{
nDimensionIndex=1; bMainAxis=true;
}
else if( rDispatchCommand == "DiagramAxisZ")
{
nDimensionIndex=2; bMainAxis=true;
}
else if( rDispatchCommand == "DiagramAxisA")
{
nDimensionIndex=0; bMainAxis=false;
}
else if( rDispatchCommand == "DiagramAxisB")
{
nDimensionIndex=1; bMainAxis=false;
}
rtl::Reference< Diagram > xDiagram = xChartModel->getFirstChartDiagram();
rtl::Reference< Axis > xAxis = AxisHelper::getAxis( nDimensionIndex, bMainAxis, xDiagram );
return ObjectIdentifier::createClassifiedIdentifierForObject( xAxis, xChartModel );
}
OUString lcl_getGridCIDForCommand( std::string_view rDispatchCommand, const rtl::Reference<::chart::ChartModel>& xChartModel )
{
rtl::Reference< Diagram > xDiagram = xChartModel->getFirstChartDiagram();
if( rDispatchCommand == "DiagramGridAll")
return ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_GRID, u"ALLELEMENTS" );
sal_Int32 nDimensionIndex=0;
bool bMainGrid=true;
//x and y is swapped in the commands
if( rDispatchCommand == "DiagramGridYMain")
{
nDimensionIndex=0; bMainGrid=true;
}
else if( rDispatchCommand == "DiagramGridXMain")
{
nDimensionIndex=1; bMainGrid=true;
}
else if( rDispatchCommand == "DiagramGridZMain")
{
nDimensionIndex=2; bMainGrid=true;
}
else if( rDispatchCommand == "DiagramGridYHelp")
{
nDimensionIndex=0; bMainGrid=false;
}
else if( rDispatchCommand == "DiagramGridXHelp")
{
nDimensionIndex=1; bMainGrid=false;
}
else if( rDispatchCommand == "DiagramGridZHelp")
{
nDimensionIndex=2; bMainGrid=false;
}
rtl::Reference< Axis > xAxis = AxisHelper::getAxis( nDimensionIndex, true/*bMainAxis*/, xDiagram );
sal_Int32 nSubGridIndex= bMainGrid ? -1 : 0;
OUString aCID( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel, nSubGridIndex ) );
return aCID;
}
OUString lcl_getErrorCIDForCommand( const ObjectType eDispatchType, const ObjectType &eSelectedType, const OUString &rSelectedCID)
{
if( eSelectedType == eDispatchType )
return rSelectedCID;
return ObjectIdentifier::createClassifiedIdentifierWithParent( eDispatchType, u"", rSelectedCID );
}
OUString lcl_getObjectCIDForCommand( std::string_view rDispatchCommand, const rtl::Reference<::chart::ChartModel> & xChartDocument, const OUString& rSelectedCID )
{
ObjectType eObjectType = OBJECTTYPE_UNKNOWN;
const ObjectType eSelectedType = ObjectIdentifier::getObjectType( rSelectedCID );
rtl::Reference< DataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( rSelectedCID, xChartDocument );
//legend
if( rDispatchCommand == "Legend" || rDispatchCommand == "FormatLegend" )
{
eObjectType = OBJECTTYPE_LEGEND;
//@todo set particular aParticleID if we have more than one legend
}
//wall floor area
else if( rDispatchCommand == "DiagramWall" || rDispatchCommand == "FormatWall" )
{
//OBJECTTYPE_DIAGRAM;
eObjectType = OBJECTTYPE_DIAGRAM_WALL;
//@todo set particular aParticleID if we have more than one diagram
}
else if( rDispatchCommand == "DiagramFloor" || rDispatchCommand == "FormatFloor" )
{
eObjectType = OBJECTTYPE_DIAGRAM_FLOOR;
//@todo set particular aParticleID if we have more than one diagram
}
else if( rDispatchCommand == "DiagramArea" || rDispatchCommand == "FormatChartArea" )
{
eObjectType = OBJECTTYPE_PAGE;
}
//title
else if( rDispatchCommand == "MainTitle"
|| rDispatchCommand == "SubTitle"
|| rDispatchCommand == "XTitle"
|| rDispatchCommand == "YTitle"
|| rDispatchCommand == "ZTitle"
|| rDispatchCommand == "SecondaryXTitle"
|| rDispatchCommand == "SecondaryYTitle"
|| rDispatchCommand == "AllTitles"
)
{
return lcl_getTitleCIDForCommand( rDispatchCommand, xChartDocument );
}
//axis
else if( rDispatchCommand == "DiagramAxisX"
|| rDispatchCommand == "DiagramAxisY"
|| rDispatchCommand == "DiagramAxisZ"
|| rDispatchCommand == "DiagramAxisA"
|| rDispatchCommand == "DiagramAxisB"
|| rDispatchCommand == "DiagramAxisAll"
)
{
return lcl_getAxisCIDForCommand( rDispatchCommand, xChartDocument );
}
//grid
else if( rDispatchCommand == "DiagramGridYMain"
|| rDispatchCommand == "DiagramGridXMain"
|| rDispatchCommand == "DiagramGridZMain"
|| rDispatchCommand == "DiagramGridYHelp"
|| rDispatchCommand == "DiagramGridXHelp"
|| rDispatchCommand == "DiagramGridZHelp"
|| rDispatchCommand == "DiagramGridAll"
)
{
return lcl_getGridCIDForCommand( rDispatchCommand, xChartDocument );
}
//data series
else if( rDispatchCommand == "FormatDataSeries" )
{
if( eSelectedType == OBJECTTYPE_DATA_SERIES )
return rSelectedCID;
else
return ObjectIdentifier::createClassifiedIdentifier(
OBJECTTYPE_DATA_SERIES, ObjectIdentifier::getSeriesParticleFromCID( rSelectedCID ) );
}
//data point
else if( rDispatchCommand == "FormatDataPoint" )
{
return rSelectedCID;
}
//data labels
else if( rDispatchCommand == "FormatDataLabels" )
{
if( eSelectedType == OBJECTTYPE_DATA_LABELS )
return rSelectedCID;
else
return ObjectIdentifier::createClassifiedIdentifierWithParent(
OBJECTTYPE_DATA_LABELS, u"", rSelectedCID );
}
//data labels
else if( rDispatchCommand == "FormatDataLabel" )
{
if( eSelectedType == OBJECTTYPE_DATA_LABEL )
return rSelectedCID;
else
{
sal_Int32 nPointIndex = o3tl::toInt32(ObjectIdentifier::getParticleID( rSelectedCID ));
if( nPointIndex>=0 )
{
OUString aSeriesParticle = ObjectIdentifier::getSeriesParticleFromCID( rSelectedCID );
OUString aChildParticle( ObjectIdentifier::getStringForType( OBJECTTYPE_DATA_LABELS ) + "=" );
OUString aLabelsCID = ObjectIdentifier::createClassifiedIdentifierForParticles( aSeriesParticle, aChildParticle );
OUString aLabelCID_Stub = ObjectIdentifier::createClassifiedIdentifierWithParent(
OBJECTTYPE_DATA_LABEL, u"", aLabelsCID );
return ObjectIdentifier::createPointCID( aLabelCID_Stub, nPointIndex );
}
}
}
//mean value line
else if( rDispatchCommand == "FormatMeanValue" )
{
if( eSelectedType == OBJECTTYPE_DATA_AVERAGE_LINE )
return rSelectedCID;
else
return ObjectIdentifier::createDataCurveCID(
ObjectIdentifier::getSeriesParticleFromCID( rSelectedCID ),
RegressionCurveHelper::getRegressionCurveIndex( xSeries,
RegressionCurveHelper::getMeanValueLine( xSeries ) ), true );
}
//trend line
else if( rDispatchCommand == "FormatTrendline" )
{
if( eSelectedType == OBJECTTYPE_DATA_CURVE )
return rSelectedCID;
else
return ObjectIdentifier::createDataCurveCID(
ObjectIdentifier::getSeriesParticleFromCID( rSelectedCID ),
RegressionCurveHelper::getRegressionCurveIndex( xSeries,
RegressionCurveHelper::getFirstCurveNotMeanValueLine( xSeries ) ), false );
}
//trend line equation
else if( rDispatchCommand == "FormatTrendlineEquation" )
{
if( eSelectedType == OBJECTTYPE_DATA_CURVE_EQUATION )
return rSelectedCID;
else
return ObjectIdentifier::createDataCurveEquationCID(
ObjectIdentifier::getSeriesParticleFromCID( rSelectedCID ),
RegressionCurveHelper::getRegressionCurveIndex( xSeries,
RegressionCurveHelper::getFirstCurveNotMeanValueLine( xSeries ) ) );
}
// y error bars
else if( rDispatchCommand == "FormatXErrorBars" )
{
return lcl_getErrorCIDForCommand(OBJECTTYPE_DATA_ERRORS_X, eSelectedType, rSelectedCID );
}
// y error bars
else if( rDispatchCommand == "FormatYErrorBars" )
{
return lcl_getErrorCIDForCommand(OBJECTTYPE_DATA_ERRORS_Y, eSelectedType, rSelectedCID );
}
// axis
else if( rDispatchCommand == "FormatAxis" )
{
if( eSelectedType == OBJECTTYPE_AXIS )
return rSelectedCID;
else
{
rtl::Reference< Axis > xAxis = ObjectIdentifier::getAxisForCID( rSelectedCID, xChartDocument );
return ObjectIdentifier::createClassifiedIdentifierForObject( xAxis , xChartDocument );
}
}
// major grid
else if( rDispatchCommand == "FormatMajorGrid" )
{
if( eSelectedType == OBJECTTYPE_GRID )
return rSelectedCID;
else
{
rtl::Reference< Axis > xAxis = ObjectIdentifier::getAxisForCID( rSelectedCID, xChartDocument );
return ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartDocument );
}
}
// minor grid
else if( rDispatchCommand == "FormatMinorGrid" )
{
if( eSelectedType == OBJECTTYPE_SUBGRID )
return rSelectedCID;
else
{
rtl::Reference< Axis > xAxis = ObjectIdentifier::getAxisForCID( rSelectedCID, xChartDocument );
return ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartDocument, 0 /*sub grid index*/ );
}
}
// title
else if( rDispatchCommand == "FormatTitle" )
{
if( eSelectedType == OBJECTTYPE_TITLE )
return rSelectedCID;
}
// stock loss
else if( rDispatchCommand == "FormatStockLoss" )
{
if( eSelectedType == OBJECTTYPE_DATA_STOCK_LOSS )
return rSelectedCID;
else
return ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DATA_STOCK_LOSS, u"");
}
// stock gain
else if( rDispatchCommand == "FormatStockGain" )
{
if( eSelectedType == OBJECTTYPE_DATA_STOCK_GAIN )
return rSelectedCID;
else
return ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DATA_STOCK_GAIN, u"" );
}
return ObjectIdentifier::createClassifiedIdentifier(
eObjectType,
u"" ); // aParticleID
}
}
// anonymous namespace
void ChartController::executeDispatch_FormatObject(std::u16string_view rDispatchCommand)
{
rtl::Reference<::chart::ChartModel> xChartDocument( getChartModel() );
OString aCommand( OUStringToOString( rDispatchCommand, RTL_TEXTENCODING_ASCII_US ) );
OUString rObjectCID = lcl_getObjectCIDForCommand( aCommand, xChartDocument, m_aSelection.getSelectedCID() );
executeDlg_ObjectProperties( rObjectCID );
}
void ChartController::executeDispatch_ObjectProperties()
{
executeDlg_ObjectProperties( m_aSelection.getSelectedCID() );
}
namespace
{
OUString lcl_getFormatCIDforSelectedCID( const OUString& rSelectedCID )
{
OUString aFormatCID(rSelectedCID);
//get type of selected object
ObjectType eObjectType = ObjectIdentifier::getObjectType( aFormatCID );
// some legend entries are handled as if they were data series
if( eObjectType==OBJECTTYPE_LEGEND_ENTRY )
{
std::u16string_view aParentParticle( ObjectIdentifier::getFullParentParticle( rSelectedCID ) );
aFormatCID = ObjectIdentifier::createClassifiedIdentifierForParticle( aParentParticle );
}
// treat diagram as wall
if( eObjectType==OBJECTTYPE_DIAGRAM )
aFormatCID = ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, u"" );
return aFormatCID;
}
}//end anonymous namespace
void ChartController::executeDlg_ObjectProperties( const OUString& rSelectedObjectCID )
{
OUString aObjectCID = lcl_getFormatCIDforSelectedCID( rSelectedObjectCID );
auto xUndoGuard = std::make_shared<UndoGuard>(
ActionDescriptionProvider::createDescription(
ActionDescriptionProvider::ActionType::Format,
ObjectNameProvider::getName( ObjectIdentifier::getObjectType( aObjectCID ))),
m_xUndoManager );
ChartController::executeDlg_ObjectProperties_withUndoGuard(std::move(xUndoGuard), aObjectCID, false );
}
void ChartController::executeDlg_ObjectProperties_withUndoGuard(
std::shared_ptr<UndoGuard> xUndoGuard, const OUString& rObjectCID, bool bSuccessOnUnchanged )
{
//return true if the properties were changed successfully
if( rObjectCID.isEmpty() )
{
return;
}
try
{
//get type of object
ObjectType eObjectType = ObjectIdentifier::getObjectType( rObjectCID );
if( eObjectType==OBJECTTYPE_UNKNOWN )
{
return;
}
if( eObjectType==OBJECTTYPE_DIAGRAM_WALL || eObjectType==OBJECTTYPE_DIAGRAM_FLOOR )
{
if( !getFirstDiagram()->isSupportingFloorAndWall() )
return;
}
//convert properties to ItemSet
ReferenceSizeProvider aRefSizeProv(impl_createReferenceSizeProvider());
rtl::Reference<::chart::ChartModel> xChartDoc(getChartModel());
std::shared_ptr<wrapper::ItemConverter> pItemConverter(
createItemConverter( rObjectCID, xChartDoc, m_xCC,
m_pDrawModelWrapper->getSdrModel(),
m_xChartView.get(),
&aRefSizeProv));
if (!pItemConverter)
return;
SfxItemSet aItemSet = pItemConverter->CreateEmptyItemSet();
if ( eObjectType == OBJECTTYPE_DATA_ERRORS_X || eObjectType == OBJECTTYPE_DATA_ERRORS_Y )
aItemSet.Put(SfxBoolItem(SCHATTR_STAT_ERRORBAR_TYPE, eObjectType == OBJECTTYPE_DATA_ERRORS_Y ));
pItemConverter->FillItemSet(aItemSet);
//prepare dialog
ObjectPropertiesDialogParameter aDialogParameter( rObjectCID );
aDialogParameter.init(xChartDoc);
ViewElementListProvider aViewElementListProvider( m_pDrawModelWrapper.get() );
SolarMutexGuard aGuard;
std::shared_ptr<SchAttribTabDlg> aDlgPtr = std::make_shared<SchAttribTabDlg>(
GetChartFrame(), &aItemSet, &aDialogParameter,
&aViewElementListProvider,
xChartDoc);
if(aDialogParameter.HasSymbolProperties())
{
uno::Reference< beans::XPropertySet > xObjectProperties =
ObjectIdentifier::getObjectPropertySet( rObjectCID, xChartDoc );
wrapper::DataPointItemConverter aSymbolItemConverter( xChartDoc, m_xCC
, xObjectProperties, ObjectIdentifier::getDataSeriesForCID( rObjectCID, xChartDoc )
, m_pDrawModelWrapper->getSdrModel().GetItemPool()
, m_pDrawModelWrapper->getSdrModel()
, xChartDoc
, wrapper::GraphicObjectType::FilledDataPoint );
SfxItemSet aSymbolShapeProperties(aSymbolItemConverter.CreateEmptyItemSet() );
aSymbolItemConverter.FillItemSet( aSymbolShapeProperties );
sal_Int32 const nStandardSymbol=0;//@todo get from somewhere
std::optional<Graphic> oAutoSymbolGraphic(std::in_place, aViewElementListProvider.GetSymbolGraphic( nStandardSymbol, &aSymbolShapeProperties ) );
// note: the dialog takes the ownership of pSymbolShapeProperties and pAutoSymbolGraphic
aDlgPtr->setSymbolInformation( std::move(aSymbolShapeProperties), std::move(oAutoSymbolGraphic) );
}
if( aDialogParameter.HasStatisticProperties() )
{
aDlgPtr->SetAxisMinorStepWidthForErrorBarDecimals(
InsertErrorBarsDialog::getAxisMinorStepWidthForErrorBarDecimals( xChartDoc, m_xChartView, rObjectCID ) );
}
//open the dialog
SfxTabDialogController::runAsync(aDlgPtr, [aDlgPtr, xChartDoc, pItemConverter=std::move(pItemConverter),
bSuccessOnUnchanged, xUndoGuard=std::move(xUndoGuard)] (int nResult)
{
if (nResult == RET_OK || (bSuccessOnUnchanged && aDlgPtr->DialogWasClosedWithOK())) {
const SfxItemSet* pOutItemSet = aDlgPtr->GetOutputItemSet();
if(pOutItemSet) {
ControllerLockGuardUNO aCLGuard(xChartDoc);
(void)pItemConverter->ApplyItemSet(*pOutItemSet); //model should be changed now
xUndoGuard->commit();
}
}
});
}
catch( const util::CloseVetoException& )
{
}
catch( const uno::RuntimeException& )
{
}
}
void ChartController::executeDispatch_View3D()
{
try
{
UndoLiveUpdateGuard aUndoGuard(
SchResId( STR_ACTION_EDIT_3D_VIEW ),
m_xUndoManager );
//open dialog
SolarMutexGuard aSolarGuard;
View3DDialog aDlg(GetChartFrame(), getChartModel());
if (aDlg.run() == RET_OK)
aUndoGuard.commit();
}
catch(const uno::RuntimeException&)
{
TOOLS_WARN_EXCEPTION("chart2", "" );
}
}
} //namespace chart
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V1019 Compound assignment expression is used inside condition.
↑ V1048 The 'bMainAxis' variable was assigned the same value.
↑ V1048 The 'bMainAxis' variable was assigned the same value.
↑ V1048 The 'bMainAxis' variable was assigned the same value.
↑ V1048 The 'bMainGrid' variable was assigned the same value.
↑ V1048 The 'bMainGrid' variable was assigned the same value.
↑ V1048 The 'bMainGrid' variable was assigned the same value.