[Libreoffice-commits] core.git: chart2/source

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Thu May 11 20:56:42 UTC 2017


 chart2/source/controller/inc/ChartController.hxx         |    1 
 chart2/source/controller/main/ChartController.cxx        |    1 
 chart2/source/controller/main/ChartController_Window.cxx |   20 ++-
 chart2/source/view/main/VLegend.cxx                      |   77 ++++++++++-----
 4 files changed, 71 insertions(+), 28 deletions(-)

New commits:
commit 9e92527f500a20de838a93201718a761278d8f8d
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu May 11 21:04:31 2017 +0200

    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 at libreoffice.org>
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

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);
                 }
             }


More information about the Libreoffice-commits mailing list