/* -*- 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 #include #include #include #include #include #include "ChartElementsPanel.hxx" #include "ChartController.hxx" #include #include #include #include #include #include #include #include #include #include #include "LegendHelper.hxx" #include "ChartModelHelper.hxx" #include "AxisHelper.hxx" #include "DiagramHelper.hxx" #include "ChartTypeHelper.hxx" #include "ChartModel.hxx" using namespace css; using namespace css::uno; namespace chart { namespace sidebar { namespace { enum class GridType { VERT_MAJOR, VERT_MINOR, HOR_MAJOR, HOR_MINOR }; enum class AxisType { X_MAIN, Y_MAIN, Z_MAIN, X_SECOND, Y_SECOND }; ChartModel* getChartModel(const css::uno::Reference& xModel) { ChartModel* pModel = dynamic_cast(xModel.get()); return pModel; } bool isLegendVisible(const css::uno::Reference& xModel) { ChartModel* pModel = getChartModel(xModel); if (!pModel) return false; Reference< beans::XPropertySet > xLegendProp( LegendHelper::getLegend(*pModel), uno::UNO_QUERY ); if( xLegendProp.is()) { try { bool bShow = false; if( xLegendProp->getPropertyValue( "Show") >>= bShow ) { return bShow; } } catch(const uno::Exception &) { } } return false; } void setLegendVisible(const css::uno::Reference& xModel, bool bVisible) { ChartModel* pModel = getChartModel(xModel); if (!pModel) return; if (bVisible) LegendHelper::showLegend(*pModel, comphelper::getProcessComponentContext()); else LegendHelper::hideLegend(*pModel); } bool isTitleVisisble(const css::uno::Reference& xModel, TitleHelper::eTitleType eTitle) { css::uno::Reference xTitle = TitleHelper::getTitle(eTitle, xModel); if (!xTitle.is()) return false; css::uno::Reference xPropSet(xTitle, css::uno::UNO_QUERY_THROW); css::uno::Any aAny = xPropSet->getPropertyValue("Visible"); bool bVisible = aAny.get(); return bVisible; } bool isGridVisible(const css::uno::Reference& xModel, GridType eType) { Reference< chart2::XDiagram > xDiagram(ChartModelHelper::findDiagram(xModel)); if(xDiagram.is()) { sal_Int32 nDimensionIndex = 0; if (eType == GridType::HOR_MAJOR || eType == GridType::HOR_MINOR) nDimensionIndex = 1; sal_Int32 nCooSysIndex = 0; bool bMajor = (eType == GridType::HOR_MAJOR || eType == GridType::VERT_MAJOR); bool bHasGrid = AxisHelper::isGridShown(nDimensionIndex, nCooSysIndex, bMajor, xDiagram); return bHasGrid; } return false; } void setGridVisible(const css::uno::Reference& xModel, GridType eType, bool bVisible) { Reference< chart2::XDiagram > xDiagram(ChartModelHelper::findDiagram(xModel)); if(xDiagram.is()) { sal_Int32 nDimensionIndex = 0; if (eType == GridType::HOR_MAJOR || eType == GridType::HOR_MINOR) nDimensionIndex = 1; sal_Int32 nCooSysIndex = 0; bool bMajor = (eType == GridType::HOR_MAJOR || eType == GridType::VERT_MAJOR); if (bVisible) AxisHelper::showGrid(nDimensionIndex, nCooSysIndex, bMajor, xDiagram, comphelper::getProcessComponentContext()); else AxisHelper::hideGrid(nDimensionIndex, nCooSysIndex, bMajor, xDiagram); } } bool isAxisVisible(const css::uno::Reference& xModel, AxisType eType) { Reference< chart2::XDiagram > xDiagram(ChartModelHelper::findDiagram(xModel)); if(xDiagram.is()) { sal_Int32 nDimensionIndex = 0; if (eType == AxisType::Y_MAIN || eType == AxisType::Y_SECOND) nDimensionIndex = 1; else if (eType == AxisType::Z_MAIN) nDimensionIndex = 2; bool bMajor = !(eType == AxisType::X_SECOND || eType == AxisType::Y_SECOND); bool bHasAxis = AxisHelper::isAxisShown(nDimensionIndex, bMajor, xDiagram); return bHasAxis; } return false; } void setAxisVisible(const css::uno::Reference& xModel, AxisType eType, bool bVisible) { Reference< chart2::XDiagram > xDiagram(ChartModelHelper::findDiagram(xModel)); if(xDiagram.is()) { sal_Int32 nDimensionIndex = 0; if (eType == AxisType::Y_MAIN || eType == AxisType::Y_SECOND) nDimensionIndex = 1; else if (eType == AxisType::Z_MAIN) nDimensionIndex = 2; bool bMajor = !(eType == AxisType::X_SECOND || eType == AxisType::Y_SECOND); if (bVisible) AxisHelper::showAxis(nDimensionIndex, bMajor, xDiagram, comphelper::getProcessComponentContext()); else AxisHelper::hideAxis(nDimensionIndex, bMajor, xDiagram); } } sal_Int32 getLegendPos(const css::uno::Reference& xModel) { ChartModel* pModel = getChartModel(xModel); if (!pModel) return 4; Reference< beans::XPropertySet > xLegendProp( LegendHelper::getLegend(*pModel), uno::UNO_QUERY ); if (!xLegendProp.is()) return 4; chart2::LegendPosition eLegendPos = chart2::LegendPosition_CUSTOM; xLegendProp->getPropertyValue("AnchorPosition") >>= eLegendPos; switch(eLegendPos) { case chart2::LegendPosition_LINE_START: return 3; case chart2::LegendPosition_LINE_END: return 0; case chart2::LegendPosition_PAGE_START: return 1; case chart2::LegendPosition_PAGE_END: return 2; default: return 4; } } void setLegendPos(const css::uno::Reference& xModel, sal_Int32 nPos) { ChartModel* pModel = getChartModel(xModel); if (!pModel) return; Reference< beans::XPropertySet > xLegendProp( LegendHelper::getLegend(*pModel), uno::UNO_QUERY ); if (!xLegendProp.is()) return; chart2::LegendPosition eLegendPos = chart2::LegendPosition_CUSTOM; css::chart::ChartLegendExpansion eExpansion = css::chart::ChartLegendExpansion_HIGH; switch(nPos) { case 1: eLegendPos = chart2::LegendPosition_PAGE_START; eExpansion = css::chart::ChartLegendExpansion_WIDE; break; case 3: eLegendPos = chart2::LegendPosition_LINE_START; break; case 0: eLegendPos = chart2::LegendPosition_LINE_END; break; case 2: eLegendPos = chart2::LegendPosition_PAGE_END; eExpansion = css::chart::ChartLegendExpansion_WIDE; break; case 4: eLegendPos = chart2::LegendPosition_CUSTOM; break; default: assert(false); } xLegendProp->setPropertyValue("AnchorPosition", css::uno::makeAny(eLegendPos)); xLegendProp->setPropertyValue("Expansion", css::uno::makeAny(eExpansion)); if (eLegendPos != chart2::LegendPosition_CUSTOM) { xLegendProp->setPropertyValue("RelativePosition", uno::Any()); } } } ChartElementsPanel::ChartElementsPanel( vcl::Window* pParent, const css::uno::Reference& rxFrame, ChartController* pController) : PanelLayout(pParent, "ChartElementsPanel", "modules/schart/ui/sidebarelements.ui", rxFrame), maContext(), mxModel(pController->getModel()), mxListener(new ChartSidebarModifyListener(this)), mbModelValid(true) { get(mpCBTitle, "checkbutton_title"); get(mpCBSubtitle, "checkbutton_subtitle"); get(mpCBXAxis, "checkbutton_x_axis"); get(mpCBXAxisTitle, "checkbutton_x_axis_title"); get(mpCBYAxis, "checkbutton_y_axis"); get(mpCBYAxisTitle, "checkbutton_y_axis_title"); get(mpCBZAxis, "checkbutton_z_axis"); get(mpCBZAxisTitle, "checkbutton_z_axis_title"); get(mpCB2ndXAxis, "checkbutton_2nd_x_axis"); get(mpCB2ndXAxisTitle, "checkbutton_2nd_x_axis_title"); get(mpCB2ndYAxis, "checkbutton_2nd_y_axis"); get(mpCB2ndYAxisTitle, "checkbutton_2nd_y_axis_title"); get(mpCBLegend, "checkbutton_legend"); get(mpCBGridVerticalMajor, "checkbutton_gridline_vertical_major"); get(mpCBGridHorizontalMajor, "checkbutton_gridline_horizontal_major"); get(mpCBGridVerticalMinor, "checkbutton_gridline_vertical_minor"); get(mpCBGridHorizontalMinor, "checkbutton_gridline_horizontal_minor"); get(mpLBAxis, "label_axes"); get(mpLBGrid, "label_gri"); get(mpLBLegendPosition, "comboboxtext_legend"); get(mpBoxLegend, "box_legend"); get(mpTextTitle, "text_title"); get(mpTextSubTitle, "text_subtitle"); maTextTitle = mpTextTitle->GetText(); maTextSubTitle = mpTextSubTitle->GetText(); Initialize(); } ChartElementsPanel::~ChartElementsPanel() { disposeOnce(); } void ChartElementsPanel::dispose() { css::uno::Reference xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW); xBroadcaster->removeModifyListener(mxListener); mpCBTitle.clear(); mpCBSubtitle.clear(); mpCBXAxis.clear(); mpCBXAxisTitle.clear(); mpCBYAxis.clear(); mpCBYAxisTitle.clear(); mpCBZAxis.clear(); mpCBZAxisTitle.clear(); mpCB2ndXAxis.clear(); mpCB2ndXAxisTitle.clear(); mpCB2ndYAxis.clear(); mpCB2ndYAxisTitle.clear(); mpCBLegend.clear(); mpCBGridVerticalMajor.clear(); mpCBGridHorizontalMajor.clear(); mpCBGridVerticalMinor.clear(); mpCBGridHorizontalMinor.clear(); mpLBLegendPosition.clear(); mpBoxLegend.clear(); mpLBAxis.clear(); mpLBGrid.clear(); mpTextTitle.clear(); mpTextSubTitle.clear(); PanelLayout::dispose(); } void ChartElementsPanel::Initialize() { css::uno::Reference xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW); xBroadcaster->addModifyListener(mxListener); updateData(); Link aLink = LINK(this, ChartElementsPanel, CheckBoxHdl); mpCBTitle->SetClickHdl(aLink); mpCBSubtitle->SetClickHdl(aLink); mpCBXAxis->SetClickHdl(aLink); mpCBXAxisTitle->SetClickHdl(aLink); mpCBYAxis->SetClickHdl(aLink); mpCBYAxisTitle->SetClickHdl(aLink); mpCBZAxis->SetClickHdl(aLink); mpCBZAxisTitle->SetClickHdl(aLink); mpCB2ndXAxis->SetClickHdl(aLink); mpCB2ndXAxisTitle->SetClickHdl(aLink); mpCB2ndYAxis->SetClickHdl(aLink); mpCB2ndYAxisTitle->SetClickHdl(aLink); mpCBLegend->SetClickHdl(aLink); mpCBGridVerticalMajor->SetClickHdl(aLink); mpCBGridHorizontalMajor->SetClickHdl(aLink); mpCBGridVerticalMinor->SetClickHdl(aLink); mpCBGridHorizontalMinor->SetClickHdl(aLink); mpLBLegendPosition->SetSelectHdl(LINK(this, ChartElementsPanel, LegendPosHdl)); } namespace { css::uno::Reference getChartType(const css::uno::Reference& xModel) { css::uno::Reference xChartDoc(xModel, css::uno::UNO_QUERY_THROW); css::uno::Reference xDiagram = xChartDoc->getFirstDiagram(); css::uno::Reference xCooSysContainer( xDiagram, css::uno::UNO_QUERY_THROW ); css::uno::Sequence> xCooSysSequence(xCooSysContainer->getCoordinateSystems()); css::uno::Reference xChartTypeContainer(xCooSysSequence[0], css::uno::UNO_QUERY_THROW); css::uno::Sequence> xChartTypeSequence(xChartTypeContainer->getChartTypes()); return xChartTypeSequence[0]; } } void ChartElementsPanel::updateData() { if (!mbModelValid) return; Reference< chart2::XDiagram > xDiagram(ChartModelHelper::findDiagram(mxModel)); sal_Int32 nDimension = DiagramHelper::getDimension(xDiagram); SolarMutexGuard aGuard; mpCBLegend->Check(isLegendVisible(mxModel)); mpCBTitle->Check(isTitleVisisble(mxModel, TitleHelper::MAIN_TITLE)); mpCBSubtitle->Check(isTitleVisisble(mxModel, TitleHelper::SUB_TITLE)); mpCBXAxisTitle->Check(isTitleVisisble(mxModel, TitleHelper::X_AXIS_TITLE)); mpCBYAxisTitle->Check(isTitleVisisble(mxModel, TitleHelper::Y_AXIS_TITLE)); mpCBZAxisTitle->Check(isTitleVisisble(mxModel, TitleHelper::Z_AXIS_TITLE)); mpCB2ndXAxisTitle->Check(isTitleVisisble(mxModel, TitleHelper::SECONDARY_X_AXIS_TITLE)); mpCB2ndYAxisTitle->Check(isTitleVisisble(mxModel, TitleHelper::SECONDARY_Y_AXIS_TITLE)); mpCBGridVerticalMajor->Check(isGridVisible(mxModel, GridType::VERT_MAJOR)); mpCBGridHorizontalMajor->Check(isGridVisible(mxModel, GridType::HOR_MAJOR)); mpCBGridVerticalMinor->Check(isGridVisible(mxModel, GridType::VERT_MINOR)); mpCBGridHorizontalMinor->Check(isGridVisible(mxModel, GridType::HOR_MINOR)); mpCBXAxis->Check(isAxisVisible(mxModel, AxisType::X_MAIN)); mpCBYAxis->Check(isAxisVisible(mxModel, AxisType::Y_MAIN)); mpCBZAxis->Check(isAxisVisible(mxModel, AxisType::Z_MAIN)); mpCB2ndXAxis->Check(isAxisVisible(mxModel, AxisType::X_SECOND)); mpCB2ndYAxis->Check(isAxisVisible(mxModel, AxisType::Y_SECOND)); bool bSupportsMainAxis = ChartTypeHelper::isSupportingMainAxis( getChartType(mxModel), 0, 0); if (bSupportsMainAxis) { mpCBXAxis->Show(); mpCBYAxis->Show(); mpCBZAxis->Show(); mpCBXAxisTitle->Show(); mpCBYAxisTitle->Show(); mpCBZAxisTitle->Show(); mpCBGridVerticalMajor->Show(); mpCBGridVerticalMinor->Show(); mpCBGridHorizontalMajor->Show(); mpCBGridHorizontalMinor->Show(); mpLBAxis->Show(); mpLBGrid->Show(); } else { mpCBXAxis->Hide(); mpCBYAxis->Hide(); mpCBZAxis->Hide(); mpCBXAxisTitle->Hide(); mpCBYAxisTitle->Hide(); mpCBZAxisTitle->Hide(); mpCBGridVerticalMajor->Hide(); mpCBGridVerticalMinor->Hide(); mpCBGridHorizontalMajor->Hide(); mpCBGridHorizontalMinor->Hide(); mpLBAxis->Hide(); mpLBGrid->Hide(); } if (nDimension == 3) { mpCBZAxis->Enable(); mpCBZAxisTitle->Enable(); } else { mpCBZAxis->Disable(); mpCBZAxisTitle->Disable(); } mpLBLegendPosition->SelectEntryPos(getLegendPos(mxModel)); } VclPtr ChartElementsPanel::Create ( vcl::Window* pParent, const css::uno::Reference& rxFrame, ChartController* pController) { if (pParent == nullptr) throw lang::IllegalArgumentException("no parent Window given to ChartElementsPanel::Create", nullptr, 0); if ( ! rxFrame.is()) throw lang::IllegalArgumentException("no XFrame given to ChartElementsPanel::Create", nullptr, 1); return VclPtr::Create( pParent, rxFrame, pController); } void ChartElementsPanel::DataChanged( const DataChangedEvent& ) { updateData(); } void ChartElementsPanel::HandleContextChange( const ::sfx2::sidebar::EnumContext& rContext) { if(maContext == rContext) { // Nothing to do. return; } maContext = rContext; updateData(); } void ChartElementsPanel::modelInvalid() { mbModelValid = false; } void ChartElementsPanel::updateModel( css::uno::Reference xModel) { if (mbModelValid) { css::uno::Reference xBroadcaster(mxModel, css::uno::UNO_QUERY_THROW); xBroadcaster->removeModifyListener(mxListener); } mxModel = xModel; mbModelValid = true; css::uno::Reference xBroadcasterNew(mxModel, css::uno::UNO_QUERY_THROW); xBroadcasterNew->addModifyListener(mxListener); } IMPL_LINK_TYPED(ChartElementsPanel, CheckBoxHdl, Button*, pButton, void) { CheckBox* pCheckBox = static_cast(pButton); bool bChecked = pCheckBox->IsChecked(); if (pCheckBox == mpCBTitle.get()) setTitleVisible(TitleHelper::MAIN_TITLE, bChecked); else if (pCheckBox == mpCBSubtitle.get()) setTitleVisible(TitleHelper::SUB_TITLE, bChecked); else if (pCheckBox == mpCBXAxis.get()) setAxisVisible(mxModel, AxisType::X_MAIN, bChecked); else if (pCheckBox == mpCBXAxisTitle.get()) setTitleVisible(TitleHelper::X_AXIS_TITLE, bChecked); else if (pCheckBox == mpCBYAxis.get()) setAxisVisible(mxModel, AxisType::Y_MAIN, bChecked); else if (pCheckBox == mpCBYAxisTitle.get()) setTitleVisible(TitleHelper::Y_AXIS_TITLE, bChecked); else if (pCheckBox == mpCBZAxis.get()) setAxisVisible(mxModel, AxisType::Z_MAIN, bChecked); else if (pCheckBox == mpCBZAxisTitle.get()) setTitleVisible(TitleHelper::Z_AXIS_TITLE, bChecked); else if (pCheckBox == mpCB2ndXAxis.get()) setAxisVisible(mxModel, AxisType::X_SECOND, bChecked); else if (pCheckBox == mpCB2ndXAxisTitle.get()) setTitleVisible(TitleHelper::SECONDARY_X_AXIS_TITLE, bChecked); else if (pCheckBox == mpCB2ndYAxis.get()) setAxisVisible(mxModel, AxisType::Y_SECOND, bChecked); else if (pCheckBox == mpCB2ndYAxisTitle.get()) setTitleVisible(TitleHelper::SECONDARY_Y_AXIS_TITLE, bChecked); else if (pCheckBox == mpCBLegend.get()) { mpBoxLegend->Enable( bChecked ); setLegendVisible(mxModel, bChecked); } else if (pCheckBox == mpCBGridVerticalMajor.get()) setGridVisible(mxModel, GridType::VERT_MAJOR, bChecked); else if (pCheckBox == mpCBGridHorizontalMajor.get()) setGridVisible(mxModel, GridType::HOR_MAJOR, bChecked); else if (pCheckBox == mpCBGridVerticalMinor.get()) setGridVisible(mxModel, GridType::VERT_MINOR, bChecked); else if (pCheckBox == mpCBGridHorizontalMinor.get()) setGridVisible(mxModel, GridType::HOR_MINOR, bChecked); } IMPL_LINK_NOARG_TYPED(ChartElementsPanel, LegendPosHdl, ListBox&, void) { sal_Int32 nPos = mpLBLegendPosition->GetSelectEntryPos(); setLegendPos(mxModel, nPos); } void ChartElementsPanel::setTitleVisible(TitleHelper::eTitleType eTitle, bool bVisible) { if (bVisible) { OUString aText = eTitle == TitleHelper::SUB_TITLE ? maTextSubTitle : maTextTitle; TitleHelper::createOrShowTitle(eTitle, aText, mxModel, comphelper::getProcessComponentContext()); } else { TitleHelper::hideTitle(eTitle, mxModel); } } }} // end of namespace ::chart::sidebar /* vim:set shiftwidth=4 softtabstop=4 expandtab: */