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