1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_chart2.hxx"
26 
27 #include "tp_3D_SceneGeometry.hxx"
28 #include "tp_3D_SceneGeometry.hrc"
29 #include "ResId.hxx"
30 #include "NoWarningThisInCTOR.hxx"
31 #include "BaseGFXHelper.hxx"
32 #include "macros.hxx"
33 #include "DiagramHelper.hxx"
34 #include "ChartTypeHelper.hxx"
35 #include "ThreeDHelper.hxx"
36 #include <rtl/math.hxx>
37 #include <editeng/unoprnms.hxx>
38 #include <com/sun/star/drawing/ProjectionMode.hpp>
39 
40 //.............................................................................
41 namespace chart
42 {
43 //.............................................................................
44 
45 using namespace ::com::sun::star;
46 //using namespace ::com::sun::star::chart2;
47 
48 namespace
49 {
50 
lcl_shiftAngleToValidRange(sal_Int64 & rnAngleDegree)51 void lcl_shiftAngleToValidRange( sal_Int64& rnAngleDegree )
52 {
53     //valid range:  ]-180,180]
54     while( rnAngleDegree<=-180 )
55         rnAngleDegree+=360;
56     while( rnAngleDegree>180 )
57         rnAngleDegree-=360;
58 }
59 
lcl_SetMetricFieldLimits(MetricField & rField,sal_Int64 nLimit)60 void lcl_SetMetricFieldLimits( MetricField& rField, sal_Int64 nLimit )
61 {
62     rField.SetMin(-1*nLimit);
63     rField.SetFirst(-1*nLimit);
64     rField.SetMax(nLimit);
65     rField.SetLast(nLimit);
66 }
67 
68 }
ThreeD_SceneGeometry_TabPage(Window * pWindow,const uno::Reference<beans::XPropertySet> & xSceneProperties,ControllerLockHelper & rControllerLockHelper)69 ThreeD_SceneGeometry_TabPage::ThreeD_SceneGeometry_TabPage( Window* pWindow
70                 , const uno::Reference< beans::XPropertySet > & xSceneProperties
71                 , ControllerLockHelper & rControllerLockHelper )
72                 : TabPage 	    ( pWindow, SchResId( TP_3D_SCENEGEOMETRY ) )
73                 , m_xSceneProperties( xSceneProperties )
74                 , m_aCbxRightAngledAxes( this, SchResId( CBX_RIGHT_ANGLED_AXES ) )
75                 , m_aFtXRotation	( this, SchResId( FT_X_ROTATION ) )
76 				, m_aMFXRotation	( this, SchResId( MTR_FLD_X_ROTATION ) )
77 				, m_aFtYRotation	( this, SchResId( FT_Y_ROTATION ) )
78 				, m_aMFYRotation	( this, SchResId( MTR_FLD_Y_ROTATION ) )
79                 , m_aFtZRotation	( this, SchResId( FT_Z_ROTATION ) )
80                 , m_aMFZRotation    ( this, SchResId( MTR_FLD_Z_ROTATION ) )
81                 , m_aCbxPerspective ( this, SchResId( CBX_PERSPECTIVE ) )
82                 , m_aMFPerspective  ( this, SchResId( MTR_FLD_PERSPECTIVE ) )
83                 , m_nXRotation(0)
84                 , m_nYRotation(0)
85                 , m_nZRotation(0)
86                 , m_bAngleChangePending( false )
87                 , m_bPerspectiveChangePending( false )
88                 , m_rControllerLockHelper( rControllerLockHelper )
89 {
90 	FreeResource();
91 
92     double fXAngle, fYAngle, fZAngle;
93     ThreeDHelper::getRotationAngleFromDiagram( m_xSceneProperties, fXAngle, fYAngle, fZAngle );
94 
95     fXAngle = BaseGFXHelper::Rad2Deg( fXAngle );
96     fYAngle = BaseGFXHelper::Rad2Deg( fYAngle );
97     fZAngle = BaseGFXHelper::Rad2Deg( fZAngle );
98 
99     DBG_ASSERT( fZAngle>=-90 && fZAngle<=90, "z angle is out of valid range" );
100 
101     lcl_SetMetricFieldLimits( m_aMFZRotation, 90 );
102 
103     m_nXRotation = ::basegfx::fround(fXAngle*pow(10.0,m_aMFXRotation.GetDecimalDigits()));
104     m_nYRotation = ::basegfx::fround(-1.0*fYAngle*pow(10.0,m_aMFYRotation.GetDecimalDigits()));
105     m_nZRotation = ::basegfx::fround(-1.0*fZAngle*pow(10.0,m_aMFZRotation.GetDecimalDigits()));
106 
107     lcl_shiftAngleToValidRange( m_nXRotation );
108     lcl_shiftAngleToValidRange( m_nYRotation );
109     lcl_shiftAngleToValidRange( m_nZRotation );
110 
111     m_aMFXRotation.SetValue(m_nXRotation);
112 	m_aMFYRotation.SetValue(m_nYRotation);
113     m_aMFZRotation.SetValue(m_nZRotation);
114 
115     const sal_uLong nTimeout = 4*EDIT_UPDATEDATA_TIMEOUT;
116     Link aAngleChangedLink( LINK( this, ThreeD_SceneGeometry_TabPage, AngleChanged ));
117     Link aAngleEditedLink( LINK( this, ThreeD_SceneGeometry_TabPage, AngleEdited ));
118 
119     m_aMFXRotation.EnableUpdateData( nTimeout );
120     m_aMFXRotation.SetUpdateDataHdl( aAngleChangedLink );
121     m_aMFXRotation.SetModifyHdl( aAngleEditedLink );
122 
123     m_aMFYRotation.EnableUpdateData( nTimeout );
124     m_aMFYRotation.SetUpdateDataHdl( aAngleChangedLink );
125     m_aMFYRotation.SetModifyHdl( aAngleEditedLink );
126 
127     m_aMFZRotation.EnableUpdateData( nTimeout );
128     m_aMFZRotation.SetUpdateDataHdl( aAngleChangedLink );
129     m_aMFZRotation.SetModifyHdl( aAngleEditedLink );
130 
131     drawing::ProjectionMode aProjectionMode = drawing::ProjectionMode_PERSPECTIVE;
132     m_xSceneProperties->getPropertyValue( C2U("D3DScenePerspective")) >>= aProjectionMode;
133     m_aCbxPerspective.Check( aProjectionMode == drawing::ProjectionMode_PERSPECTIVE );
134     m_aCbxPerspective.SetToggleHdl( LINK( this, ThreeD_SceneGeometry_TabPage, PerspectiveToggled ));
135 
136     sal_Int32 nPerspectivePercentage = 20;
137     m_xSceneProperties->getPropertyValue( C2U("Perspective")) >>= nPerspectivePercentage;
138     m_aMFPerspective.SetValue( nPerspectivePercentage );
139 
140     m_aMFPerspective.EnableUpdateData( nTimeout );
141     m_aMFPerspective.SetUpdateDataHdl( LINK( this, ThreeD_SceneGeometry_TabPage, PerspectiveChanged ) );
142     m_aMFPerspective.SetModifyHdl( LINK( this, ThreeD_SceneGeometry_TabPage, PerspectiveEdited ) );
143     m_aMFPerspective.Enable( m_aCbxPerspective.IsChecked() );
144 
145 
146     //RightAngledAxes
147     sal_Bool bRightAngledAxes = false;
148 
149     uno::Reference< chart2::XDiagram > xDiagram( m_xSceneProperties, uno::UNO_QUERY );
150     if( ChartTypeHelper::isSupportingRightAngledAxes(
151             DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
152     {
153         m_xSceneProperties->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes;
154         m_aCbxRightAngledAxes.SetToggleHdl( LINK( this, ThreeD_SceneGeometry_TabPage, RightAngledAxesToggled ));
155         m_aCbxRightAngledAxes.Check( bRightAngledAxes );
156     }
157     else
158     {
159         m_aCbxRightAngledAxes.Enable(false);
160     }
161 	m_aMFPerspective.SetAccessibleName(m_aCbxPerspective.GetText());
162 	m_aMFPerspective.SetAccessibleRelationLabeledBy(&m_aCbxPerspective);
163 }
164 
~ThreeD_SceneGeometry_TabPage()165 ThreeD_SceneGeometry_TabPage::~ThreeD_SceneGeometry_TabPage()
166 {
167 }
168 
commitPendingChanges()169 void ThreeD_SceneGeometry_TabPage::commitPendingChanges()
170 {
171     ControllerLockHelperGuard aGuard( m_rControllerLockHelper );
172 
173     if( m_bAngleChangePending )
174         applyAnglesToModel();
175     if( m_bPerspectiveChangePending )
176         applyPerspectiveToModel();
177 }
178 
applyAnglesToModel()179 void ThreeD_SceneGeometry_TabPage::applyAnglesToModel()
180 {
181     ControllerLockHelperGuard aGuard( m_rControllerLockHelper );
182 
183     double fXAngle = 0.0, fYAngle = 0.0, fZAngle = 0.0;
184 
185     if( !m_aMFZRotation.IsEmptyFieldValue() )
186         m_nZRotation = m_aMFZRotation.GetValue();
187 
188     fXAngle = double(m_nXRotation)/double(pow(10.0,m_aMFXRotation.GetDecimalDigits()));
189     fYAngle = double(-1.0*m_nYRotation)/double(pow(10.0,m_aMFYRotation.GetDecimalDigits()));
190     fZAngle = double(-1.0*m_nZRotation)/double(pow(10.0,m_aMFZRotation.GetDecimalDigits()));
191 
192     fXAngle = BaseGFXHelper::Deg2Rad( fXAngle );
193     fYAngle = BaseGFXHelper::Deg2Rad( fYAngle );
194     fZAngle = BaseGFXHelper::Deg2Rad( fZAngle );
195 
196     ThreeDHelper::setRotationAngleToDiagram( m_xSceneProperties, fXAngle, fYAngle, fZAngle );
197 
198     m_bAngleChangePending = false;
199 }
200 
IMPL_LINK(ThreeD_SceneGeometry_TabPage,AngleEdited,void *,EMPTYARG)201 IMPL_LINK( ThreeD_SceneGeometry_TabPage, AngleEdited, void*, EMPTYARG )
202 {
203     m_nXRotation = m_aMFXRotation.GetValue();
204     m_nYRotation = m_aMFYRotation.GetValue();
205 
206     m_bAngleChangePending = true;
207     return 0;
208 }
209 
IMPL_LINK(ThreeD_SceneGeometry_TabPage,AngleChanged,void *,EMPTYARG)210 IMPL_LINK( ThreeD_SceneGeometry_TabPage, AngleChanged, void*, EMPTYARG )
211 {
212     applyAnglesToModel();
213     return 0;
214 }
215 
applyPerspectiveToModel()216 void ThreeD_SceneGeometry_TabPage::applyPerspectiveToModel()
217 {
218     ControllerLockHelperGuard aGuard( m_rControllerLockHelper );
219 
220     drawing::ProjectionMode aMode = m_aCbxPerspective.IsChecked()
221         ? drawing::ProjectionMode_PERSPECTIVE
222         : drawing::ProjectionMode_PARALLEL;
223 
224     try
225     {
226         m_xSceneProperties->setPropertyValue( C2U("D3DScenePerspective"), uno::makeAny( aMode ));
227         m_xSceneProperties->setPropertyValue( C2U("Perspective"), uno::makeAny( (sal_Int32)m_aMFPerspective.GetValue() ));
228     }
229     catch( const uno::Exception & ex )
230     {
231         ASSERT_EXCEPTION( ex );
232     }
233 
234     m_bPerspectiveChangePending = false;
235 }
236 
IMPL_LINK(ThreeD_SceneGeometry_TabPage,PerspectiveEdited,void *,EMPTYARG)237 IMPL_LINK( ThreeD_SceneGeometry_TabPage, PerspectiveEdited, void*, EMPTYARG )
238 {
239     m_bPerspectiveChangePending = true;
240     return 0;
241 }
242 
IMPL_LINK(ThreeD_SceneGeometry_TabPage,PerspectiveChanged,void *,EMPTYARG)243 IMPL_LINK( ThreeD_SceneGeometry_TabPage, PerspectiveChanged, void*, EMPTYARG )
244 {
245     applyPerspectiveToModel();
246     return 0;
247 }
248 
IMPL_LINK(ThreeD_SceneGeometry_TabPage,PerspectiveToggled,void *,EMPTYARG)249 IMPL_LINK( ThreeD_SceneGeometry_TabPage, PerspectiveToggled, void*, EMPTYARG )
250 {
251     m_aMFPerspective.Enable( m_aCbxPerspective.IsChecked() );
252     applyPerspectiveToModel();
253     return 0;
254 }
255 
IMPL_LINK(ThreeD_SceneGeometry_TabPage,RightAngledAxesToggled,void *,EMPTYARG)256 IMPL_LINK( ThreeD_SceneGeometry_TabPage, RightAngledAxesToggled, void*, EMPTYARG )
257 {
258     ControllerLockHelperGuard aGuard( m_rControllerLockHelper );
259 
260     bool bEnableZ = !m_aCbxRightAngledAxes.IsChecked();
261     m_aFtZRotation.Enable( bEnableZ );
262     m_aMFZRotation.Enable( bEnableZ );
263     m_aMFZRotation.EnableEmptyFieldValue( !bEnableZ );
264     if( !bEnableZ )
265     {
266         m_nXRotation = m_aMFXRotation.GetValue();
267         m_nYRotation = m_aMFYRotation.GetValue();
268         m_nZRotation = m_aMFZRotation.GetValue();
269 
270         m_aMFXRotation.SetValue(static_cast<sal_Int64>(ThreeDHelper::getValueClippedToRange(static_cast<double>(m_nXRotation), ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes())));
271         m_aMFYRotation.SetValue(static_cast<sal_Int64>(ThreeDHelper::getValueClippedToRange(static_cast<double>(m_nYRotation), ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes())));
272         m_aMFZRotation.SetEmptyFieldValue();
273 
274         lcl_SetMetricFieldLimits( m_aMFXRotation, static_cast<sal_Int64>(ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()));
275         lcl_SetMetricFieldLimits( m_aMFYRotation, static_cast<sal_Int64>(ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()));
276     }
277     else
278     {
279         lcl_SetMetricFieldLimits( m_aMFXRotation, 180 );
280         lcl_SetMetricFieldLimits( m_aMFYRotation, 180 );
281 
282         m_aMFXRotation.SetValue(m_nXRotation);
283         m_aMFYRotation.SetValue(m_nYRotation);
284         m_aMFZRotation.SetValue(m_nZRotation);
285     }
286 
287     ThreeDHelper::switchRightAngledAxes( m_xSceneProperties, m_aCbxRightAngledAxes.IsChecked(), true /*bRotateLights*/ );
288 
289     return 0;
290 }
291 
292 //.............................................................................
293 } //namespace chart
294 //.............................................................................
295