diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2017-05-11 21:04:31 +0200 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2017-05-11 22:56:04 +0200 |
commit | 9e92527f500a20de838a93201718a761278d8f8d (patch) | |
tree | d5a3c312dee318ad41f02d051eac739d8f3c0743 | |
parent | 8bb6dab0b4007501bd7a970658360520667e5093 (diff) |
tdf#107103 fixes for the legend in a pivot chart
- Solves issue described in the bug where the legend calculation
was not correct if using custom legend placing and the buttons
were added to the legend (like in a pivot chart).
- Place the legend buttons horizontally if the legend is placed
at the top or bottom (wide legend expansion), so the space is
used more efficiently.
- Fix automatic placing of the legend when we have buttons at the
bottom of the chart so that we don't cover them with the legend.
- It can happen that the button click is triggered when we resize
the legend, so make sure we trigger only when mouse-down and
mouse-up are on button.
Change-Id: I6a60e7885f7a2ddd6424b1cdfc22e8b046c89dd4
Reviewed-on: https://gerrit.libreoffice.org/37518
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
-rw-r--r-- | chart2/source/controller/inc/ChartController.hxx | 1 | ||||
-rw-r--r-- | chart2/source/controller/main/ChartController.cxx | 1 | ||||
-rw-r--r-- | chart2/source/controller/main/ChartController_Window.cxx | 20 | ||||
-rw-r--r-- | chart2/source/view/main/VLegend.cxx | 77 |
4 files changed, 71 insertions, 28 deletions
diff --git a/chart2/source/controller/inc/ChartController.hxx b/chart2/source/controller/inc/ChartController.hxx index b32b4b7e725d..19ac675b14ae 100644 --- a/chart2/source/controller/inc/ChartController.hxx +++ b/chart2/source/controller/inc/ChartController.hxx @@ -390,6 +390,7 @@ private: Timer m_aDoubleClickTimer; bool m_bWaitingForDoubleClick; bool m_bWaitingForMouseUp; + bool m_bFieldButtonDown; bool m_bConnectingToView; bool m_bDisposed; diff --git a/chart2/source/controller/main/ChartController.cxx b/chart2/source/controller/main/ChartController.cxx index 2c5b84f8a48a..119146a67de0 100644 --- a/chart2/source/controller/main/ChartController.cxx +++ b/chart2/source/controller/main/ChartController.cxx @@ -114,6 +114,7 @@ ChartController::ChartController(uno::Reference<uno::XComponentContext> const & m_eDragMode(SdrDragMode::Move), m_bWaitingForDoubleClick(false), m_bWaitingForMouseUp(false), + m_bFieldButtonDown(false), m_bConnectingToView(false), m_bDisposed(false), m_xUndoManager( nullptr ), diff --git a/chart2/source/controller/main/ChartController_Window.cxx b/chart2/source/controller/main/ChartController_Window.cxx index 7d42bcff5490..9b3d0e3ba69d 100644 --- a/chart2/source/controller/main/ChartController_Window.cxx +++ b/chart2/source/controller/main/ChartController_Window.cxx @@ -547,6 +547,7 @@ void ChartController::execute_MouseButtonDown( const MouseEvent& rMEvt ) SolarMutexGuard aGuard; m_bWaitingForMouseUp = true; + m_bFieldButtonDown = false; if( isDoubleClick(rMEvt) ) stopDoubleClickWaiting(); @@ -568,7 +569,10 @@ void ChartController::execute_MouseButtonDown( const MouseEvent& rMEvt ) { OUString aCID = pObject->GetName(); if (aCID.startsWith("FieldButton")) + { + m_bFieldButtonDown = true; return; // Don't take any action if button was clicked + } } if ( MOUSE_LEFT == rMEvt.GetButtons() ) @@ -738,14 +742,18 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt ) Point aMPos = pChartWindow->PixelToLogic(rMEvt.GetPosPixel()); // Check if button was clicked - SdrObject* pObject = pDrawViewWrapper->getHitObject(aMPos); - if (pObject) + if (m_bFieldButtonDown) { - OUString aCID = pObject->GetName(); - if (aCID.startsWith("FieldButton")) + m_bFieldButtonDown = false; + SdrObject* pObject = pDrawViewWrapper->getHitObject(aMPos); + if (pObject) { - sendPopupRequest(aCID, pObject->GetCurrentBoundRect()); - return; + OUString aCID = pObject->GetName(); + if (aCID.startsWith("FieldButton")) + { + sendPopupRequest(aCID, pObject->GetCurrentBoundRect()); + return; + } } } diff --git a/chart2/source/view/main/VLegend.cxx b/chart2/source/view/main/VLegend.cxx index bf51d0bd64d8..4790dec34763 100644 --- a/chart2/source/view/main/VLegend.cxx +++ b/chart2/source/view/main/VLegend.cxx @@ -267,12 +267,13 @@ awt::Size lcl_placeLegendEntries( tPropertyValues & rTextProperties, const Reference< drawing::XShapes > & xTarget, const Reference< lang::XMultiServiceFactory > & xShapeFactory, - const awt::Rectangle& rRemainingSpace) + const awt::Size& rRemainingSpace, + sal_Int32 nYStartPosition) { bool bIsCustomSize = (eExpansion == css::chart::ChartLegendExpansion_CUSTOM); awt::Size aResultingLegendSize(0,0); if( bIsCustomSize ) - aResultingLegendSize = awt::Size(rRemainingSpace.Width, rRemainingSpace.Height); + aResultingLegendSize = awt::Size(rRemainingSpace.Width, rRemainingSpace.Height + nYStartPosition); // #i109336# Improve auto positioning in chart sal_Int32 nXPadding = static_cast< sal_Int32 >( std::max( 100.0, fViewFontSize * 0.33 ) ); @@ -517,7 +518,7 @@ awt::Size lcl_placeLegendEntries( for (sal_Int32 nColumn = 0; nColumn < nNumberOfColumns; ++nColumn) { - sal_Int32 nCurrentYPos = nYPadding + rRemainingSpace.Y; + sal_Int32 nCurrentYPos = nYPadding + nYStartPosition; for (sal_Int32 nRow = 0; nRow < nNumberOfRows; ++nRow) { sal_Int32 nEntry = (nColumn + nRow * nNumberOfColumns); @@ -649,8 +650,13 @@ chart2::RelativePosition lcl_getDefaultPosition( LegendPosition ePos, const awt: // #i109336# Improve auto positioning in chart const double fDefaultDistance = ( static_cast< double >( lcl_getLegendTopBottomMargin() ) / static_cast< double >( rPageSize.Height ) ); + + double fDistance = double(rPageSize.Height - (rOutAvailableSpace.Y + rOutAvailableSpace.Height)); + fDistance += fDefaultDistance; + fDistance /= double(rPageSize.Height); + aResult = chart2::RelativePosition( - 0.5, 1.0 - fDefaultDistance, drawing::Alignment_BOTTOM ); + 0.5, 1.0 - fDistance, drawing::Alignment_BOTTOM ); } break; @@ -765,9 +771,9 @@ bool lcl_shouldSymbolsBePlacedOnTheLeftSide( const Reference< beans::XPropertySe } std::vector<std::shared_ptr<VButton>> lcl_createButtons( - const uno::Reference< drawing::XShapes>& xLegendContainer, - const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory, - ChartModel& rModel, long& nUsedHeight) + uno::Reference<drawing::XShapes> const & xLegendContainer, + uno::Reference<lang::XMultiServiceFactory> const & xShapeFactory, + ChartModel& rModel, bool bPlaceButtonsVertically, long & nUsedHeight) { std::vector<std::shared_ptr<VButton>> aButtons; @@ -779,13 +785,15 @@ std::vector<std::shared_ptr<VButton>> lcl_createButtons( return aButtons; awt::Size aSize(2000, 700); + int x = 100; int y = 100; + for (chart2::data::PivotTableFieldEntry const & sColumnFieldEntry : xPivotTableDataProvider->getColumnFields()) { std::shared_ptr<VButton> pButton(new VButton); aButtons.push_back(pButton); pButton->init(xLegendContainer, xShapeFactory); - awt::Point aNewPosition = awt::Point(100, y); + awt::Point aNewPosition = awt::Point(x, y); pButton->setLabel(sColumnFieldEntry.Name); pButton->setCID("FieldButton.Column." + OUString::number(sColumnFieldEntry.DimensionIndex)); pButton->setPosition(aNewPosition); @@ -794,9 +802,16 @@ std::vector<std::shared_ptr<VButton>> lcl_createButtons( pButton->showArrow(false); if (sColumnFieldEntry.HasHiddenMembers) pButton->setArrowColor(0x0000FF); - y += aSize.Height + 100; + + if (bPlaceButtonsVertically) + y += aSize.Height + 100; + else + x += aSize.Width + 100; } - nUsedHeight += y + 100; + if (bPlaceButtonsVertically) + nUsedHeight += y + 100; + else + nUsedHeight += aSize.Height + 100; return aButtons; } @@ -866,10 +881,6 @@ void VLegend::createShapes( Reference< drawing::XShapes > xLegendContainer( m_xShape, uno::UNO_QUERY ); if( xLegendContainer.is()) { - long nUsedHeight = 0; - std::vector<std::shared_ptr<VButton>> aButtons; - aButtons = lcl_createButtons(xLegendContainer, m_xShapeFactory, mrModel, nUsedHeight); - // for quickly setting properties tPropertyValues aLineFillProperties; tPropertyValues aTextProperties; @@ -878,21 +889,27 @@ void VLegend::createShapes( css::chart::ChartLegendExpansion eExpansion = css::chart::ChartLegendExpansion_HIGH; awt::Size aLegendSize( rAvailableSpace ); - if( xLegendProp.is()) + bool bCustom = false; + LegendPosition eLegendPosition = LegendPosition_CUSTOM; + if (xLegendProp.is()) { // get Expansion property - xLegendProp->getPropertyValue( "Expansion") >>= eExpansion; + xLegendProp->getPropertyValue("Expansion") >>= eExpansion; if( eExpansion == css::chart::ChartLegendExpansion_CUSTOM ) { RelativeSize aRelativeSize; - if ((xLegendProp->getPropertyValue( "RelativeSize") >>= aRelativeSize)) + if (xLegendProp->getPropertyValue("RelativeSize") >>= aRelativeSize) { aLegendSize.Width = static_cast<sal_Int32>(::rtl::math::approxCeil( aRelativeSize.Primary * rPageSize.Width )); aLegendSize.Height = static_cast<sal_Int32>(::rtl::math::approxCeil( aRelativeSize.Secondary * rPageSize.Height )); + bCustom = true; } else + { eExpansion = css::chart::ChartLegendExpansion_HIGH; + } } + xLegendProp->getPropertyValue("AnchorPosition") >>= eLegendPosition; lcl_getProperties( xLegendProp, aLineFillProperties, aTextProperties, rPageSize ); } @@ -933,18 +950,34 @@ void VLegend::createShapes( if (!aViewEntries.empty()) { - awt::Rectangle aRectangle(0, nUsedHeight, aLegendSize.Width, aLegendSize.Height - nUsedHeight); + // create buttons + long nUsedButtonHeight = 0; + bool bPlaceButtonsVertically = (eLegendPosition != LegendPosition_PAGE_START && + eLegendPosition != LegendPosition_PAGE_END && + eExpansion != css::chart::ChartLegendExpansion_WIDE); - // place entries - aLegendSize = lcl_placeLegendEntries(aViewEntries, eExpansion, bSymbolsLeftSide, fViewFontSize, aMaxSymbolExtent, - aTextProperties, xLegendContainer, m_xShapeFactory, aRectangle); + std::vector<std::shared_ptr<VButton>> aButtons; + aButtons = lcl_createButtons(xLegendContainer, m_xShapeFactory, mrModel, bPlaceButtonsVertically, nUsedButtonHeight); + // A custom size includes the size we used for buttons already, so we need to + // subtract that from the size that is available for the legend + if (bCustom) + aLegendSize.Height -= nUsedButtonHeight; + + // place the legend entries + aLegendSize = lcl_placeLegendEntries(aViewEntries, eExpansion, bSymbolsLeftSide, fViewFontSize, + aMaxSymbolExtent, aTextProperties, xLegendContainer, + m_xShapeFactory, aLegendSize, nUsedButtonHeight); uno::Reference<beans::XPropertySet> xModelPage(mrModel.getPageBackground()); for (std::shared_ptr<VButton> const & pButton : aButtons) { - pButton->setSize({aLegendSize.Width - 200, pButton->getSize().Height}); + // adjust the width of the buttons if we place them vertically + if (bPlaceButtonsVertically) + pButton->setSize({aLegendSize.Width - 200, pButton->getSize().Height}); + + // create the buttons pButton->createShapes(xModelPage); } } |