1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <PositionAndSizeHelper.hxx>
21 #include <ControllerLockGuard.hxx>
22 #include <com/sun/star/chart/ChartLegendExpansion.hpp>
23 #include <com/sun/star/chart2/XDiagram.hpp>
24 #include <com/sun/star/chart2/RelativePosition.hpp>
25 #include <com/sun/star/chart2/RelativeSize.hpp>
26 #include <com/sun/star/frame/XModel.hpp>
27 #include <tools/gen.hxx>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <com/sun/star/awt/Rectangle.hpp>
30 
31 namespace chart
32 {
33 using namespace ::com::sun::star;
34 using namespace ::com::sun::star::chart2;
35 
moveObject(ObjectType eObjectType,const uno::Reference<beans::XPropertySet> & xObjectProp,const awt::Rectangle & rNewPositionAndSize,const awt::Rectangle & rOldPositionAndSize,const awt::Rectangle & rPageRectangle)36 bool PositionAndSizeHelper::moveObject( ObjectType eObjectType
37                 , const uno::Reference< beans::XPropertySet >& xObjectProp
38                 , const awt::Rectangle& rNewPositionAndSize
39                 , const awt::Rectangle& rOldPositionAndSize
40                 , const awt::Rectangle& rPageRectangle
41                 )
42 {
43     if(!xObjectProp.is())
44         return false;
45     tools::Rectangle aObjectRect( Point(rNewPositionAndSize.X,rNewPositionAndSize.Y), Size(rNewPositionAndSize.Width,rNewPositionAndSize.Height) );
46     tools::Rectangle aPageRect( Point(rPageRectangle.X,rPageRectangle.Y), Size(rPageRectangle.Width,rPageRectangle.Height) );
47 
48     // every following branch divides by width and height
49     if (aPageRect.getWidth() == 0 || aPageRect.getHeight() == 0)
50         return false;
51 
52     if( eObjectType==OBJECTTYPE_TITLE )
53     {
54         //@todo decide whether x is primary or secondary
55         chart2::RelativePosition aRelativePosition;
56         aRelativePosition.Anchor = drawing::Alignment_CENTER;
57         //the anchor point at the title object is top/middle
58         Point aPos = aObjectRect.TopLeft();
59         aRelativePosition.Primary = (double(aPos.X())+double(aObjectRect.getWidth())/2.0)/double(aPageRect.getWidth());
60         aRelativePosition.Secondary = (double(aPos.Y())+double(aObjectRect.getHeight())/2.0)/double(aPageRect.getHeight());
61         xObjectProp->setPropertyValue( "RelativePosition", uno::Any(aRelativePosition) );
62     }
63     else if( eObjectType == OBJECTTYPE_DATA_LABEL )
64     {
65         RelativePosition aAbsolutePosition;
66         RelativePosition aCustomLabelPosition;
67         aAbsolutePosition.Primary = double(rOldPositionAndSize.X) / double(aPageRect.getWidth());
68         aAbsolutePosition.Secondary = double(rOldPositionAndSize.Y) / double(aPageRect.getHeight());
69 
70         if( xObjectProp->getPropertyValue("CustomLabelPosition") >>= aCustomLabelPosition )
71         {
72             aAbsolutePosition.Primary -= aCustomLabelPosition.Primary;
73             aAbsolutePosition.Secondary -= aCustomLabelPosition.Secondary;
74         }
75 
76         //the anchor point at the data label object is top/left
77         Point aPos = aObjectRect.TopLeft();
78         double fRotation = 0.0;
79         xObjectProp->getPropertyValue("TextRotation") >>= fRotation;
80         if( fRotation == 90.0 )
81             aPos = aObjectRect.BottomLeft();
82         else if( fRotation == 270.0 )
83             aPos = aObjectRect.TopRight();
84 
85         aCustomLabelPosition.Primary = double(aPos.X()) / double(aPageRect.getWidth()) - aAbsolutePosition.Primary;
86         aCustomLabelPosition.Secondary = double(aPos.Y()) / double(aPageRect.getHeight()) - aAbsolutePosition.Secondary;
87         xObjectProp->setPropertyValue("CustomLabelPosition", uno::Any(aCustomLabelPosition));
88     }
89     else if( eObjectType==OBJECTTYPE_DATA_CURVE_EQUATION )
90     {
91         //@todo decide whether x is primary or secondary
92         chart2::RelativePosition aRelativePosition;
93         aRelativePosition.Anchor = drawing::Alignment_TOP_LEFT;
94         //the anchor point at the title object is top/middle
95         Point aPos = aObjectRect.TopLeft();
96         aRelativePosition.Primary = double(aPos.X())/double(aPageRect.getWidth());
97         aRelativePosition.Secondary = double(aPos.Y())/double(aPageRect.getHeight());
98         xObjectProp->setPropertyValue( "RelativePosition", uno::Any(aRelativePosition) );
99     }
100     else if(eObjectType==OBJECTTYPE_LEGEND)
101     {
102         xObjectProp->setPropertyValue( "Expansion", uno::Any(css::chart::ChartLegendExpansion_CUSTOM));
103         chart2::RelativePosition aRelativePosition;
104         chart2::RelativeSize aRelativeSize;
105         Point aAnchor = aObjectRect.TopLeft();
106 
107         aRelativePosition.Primary =
108             static_cast< double >( aAnchor.X()) /
109             static_cast< double >( aPageRect.getWidth() );
110         aRelativePosition.Secondary =
111             static_cast< double >( aAnchor.Y()) /
112             static_cast< double >( aPageRect.getHeight());
113 
114         xObjectProp->setPropertyValue( "RelativePosition", uno::Any(aRelativePosition) );
115 
116         aRelativeSize.Primary =
117             static_cast< double >( aObjectRect.getWidth()) /
118             static_cast< double >( aPageRect.getWidth() );
119         if (aRelativeSize.Primary > 1.0)
120             aRelativeSize.Primary = 1.0;
121         aRelativeSize.Secondary =
122             static_cast< double >( aObjectRect.getHeight()) /
123             static_cast< double >( aPageRect.getHeight());
124         if (aRelativeSize.Secondary > 1.0)
125             aRelativeSize.Secondary = 1.0;
126 
127         xObjectProp->setPropertyValue( "RelativeSize", uno::Any(aRelativeSize) );
128     }
129     else if(eObjectType==OBJECTTYPE_DIAGRAM || eObjectType==OBJECTTYPE_DIAGRAM_WALL || eObjectType==OBJECTTYPE_DIAGRAM_FLOOR)
130     {
131         //@todo decide whether x is primary or secondary
132 
133         //set position:
134         chart2::RelativePosition aRelativePosition;
135         aRelativePosition.Anchor = drawing::Alignment_CENTER;
136 
137         Point aPos = aObjectRect.Center();
138         aRelativePosition.Primary = double(aPos.X())/double(aPageRect.getWidth());
139         aRelativePosition.Secondary = double(aPos.Y())/double(aPageRect.getHeight());
140         xObjectProp->setPropertyValue( "RelativePosition", uno::Any(aRelativePosition) );
141 
142         //set size:
143         RelativeSize aRelativeSize;
144         //the anchor points for the diagram are in the middle of the diagram
145         //and in the middle of the page
146         aRelativeSize.Primary = double(aObjectRect.getWidth())/double(aPageRect.getWidth());
147         aRelativeSize.Secondary = double(aObjectRect.getHeight())/double(aPageRect.getHeight());
148         xObjectProp->setPropertyValue( "RelativeSize", uno::Any(aRelativeSize) );
149     }
150     else
151         return false;
152     return true;
153 }
154 
moveObject(const OUString & rObjectCID,const uno::Reference<frame::XModel> & xChartModel,const awt::Rectangle & rNewPositionAndSize,const awt::Rectangle & rOldPositionAndSize,const awt::Rectangle & rPageRectangle)155 bool PositionAndSizeHelper::moveObject( const OUString& rObjectCID
156                 , const uno::Reference< frame::XModel >& xChartModel
157                 , const awt::Rectangle& rNewPositionAndSize
158                 , const awt::Rectangle& rOldPositionAndSize
159                 , const awt::Rectangle& rPageRectangle
160                 )
161 {
162     ControllerLockGuardUNO aLockedControllers( xChartModel );
163 
164     awt::Rectangle aNewPositionAndSize( rNewPositionAndSize );
165 
166     uno::Reference< beans::XPropertySet > xObjectProp = ObjectIdentifier::getObjectPropertySet( rObjectCID, xChartModel );
167     ObjectType eObjectType( ObjectIdentifier::getObjectType( rObjectCID ) );
168     if(eObjectType==OBJECTTYPE_DIAGRAM || eObjectType==OBJECTTYPE_DIAGRAM_WALL || eObjectType==OBJECTTYPE_DIAGRAM_FLOOR)
169     {
170         xObjectProp.set( ObjectIdentifier::getDiagramForCID( rObjectCID, xChartModel ), uno::UNO_QUERY );
171         if(!xObjectProp.is())
172             return false;
173     }
174     return moveObject( eObjectType, xObjectProp, aNewPositionAndSize, rOldPositionAndSize, rPageRectangle );
175 }
176 
177 } //namespace chart
178 
179 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
180