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