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_extensions.hxx"
30 #include "handlerhelper.hxx"
31 #ifndef EXTENSIONS_PROPRESID_HRC
32 #include "propresid.hrc"
33 #endif
34 #include "formresid.hrc"
35 #include <comphelper/extract.hxx>
36 #ifndef _EXTENSIONS_PROPCTRLR_MODULEPRC_HXX_
37 #include "modulepcr.hxx"
38 #endif
39 #include "enumrepresentation.hxx"
40 #include "formmetadata.hxx"
41 #include "pcrcomponentcontext.hxx"
42 
43 /** === begin UNO includes === **/
44 #include "com/sun/star/inspection/StringRepresentation.hpp"
45 #include <com/sun/star/beans/PropertyAttribute.hpp>
46 #include <com/sun/star/uno/XComponentContext.hpp>
47 #include <com/sun/star/util/XModifiable.hpp>
48 #include <com/sun/star/awt/XWindow.hpp>
49 #include <com/sun/star/inspection/LineDescriptor.hpp>
50 #include <com/sun/star/inspection/PropertyControlType.hpp>
51 #include <com/sun/star/inspection/XStringListControl.hpp>
52 #include <com/sun/star/inspection/XNumericControl.hpp>
53 /** === end UNO includes === **/
54 #include <tools/debug.hxx>
55 #include <tools/diagnose_ex.h>
56 #include <tools/StringListResource.hxx>
57 #include <toolkit/helper/vclunohelper.hxx>
58 
59 #include <algorithm>
60 
61 //........................................................................
62 namespace pcr
63 {
64 //........................................................................
65 
66     using namespace ::com::sun::star::uno;
67     using namespace ::com::sun::star::lang;
68     using namespace ::com::sun::star::awt;
69     using namespace ::com::sun::star::util;
70     using namespace ::com::sun::star::beans;
71     using namespace ::com::sun::star::script;
72     using namespace ::com::sun::star::inspection;
73 
74 	//====================================================================
75 	//= PropertyHandlerHelper
76 	//====================================================================
77 	//--------------------------------------------------------------------
78     void PropertyHandlerHelper::describePropertyLine( const Property& _rProperty,
79         LineDescriptor& /* [out] */ _out_rDescriptor, const Reference< XPropertyControlFactory >& _rxControlFactory )
80     {
81         // display the pure property name - no L10N
82         _out_rDescriptor.DisplayName = _rProperty.Name;
83 
84         OSL_PRECOND( _rxControlFactory.is(), "PropertyHandlerHelper::describePropertyLine: no factory -> no control!" );
85         if ( !_rxControlFactory.is() )
86             return;
87 
88         sal_Bool bReadOnlyControl = requiresReadOnlyControl( _rProperty.Attributes );
89 
90         // special handling for booleans (this will become a list)
91         if ( _rProperty.Type.getTypeClass() == TypeClass_BOOLEAN )
92         {
93             ::std::vector< ::rtl::OUString > aListEntries;
94             tools::StringListResource aRes(PcrRes(RID_RSC_ENUM_YESNO),aListEntries);
95             _out_rDescriptor.Control = createListBoxControl( _rxControlFactory, aListEntries, bReadOnlyControl, sal_False );
96             return;
97         }
98 
99         sal_Int16 nControlType = PropertyControlType::TextField;
100         switch ( _rProperty.Type.getTypeClass() )
101         {
102         case TypeClass_BYTE:
103         case TypeClass_SHORT:
104         case TypeClass_UNSIGNED_SHORT:
105         case TypeClass_LONG:
106         case TypeClass_UNSIGNED_LONG:
107         case TypeClass_HYPER:
108         case TypeClass_UNSIGNED_HYPER:
109         case TypeClass_FLOAT:
110         case TypeClass_DOUBLE:
111             nControlType = PropertyControlType::NumericField;
112             break;
113 
114         case TypeClass_SEQUENCE:
115             nControlType = PropertyControlType::StringListField;
116 			break;
117 
118         default:
119             DBG_ERROR( "PropertyHandlerHelper::describePropertyLine: don't know how to represent this at the UI!" );
120             // NO break!
121 
122         case TypeClass_STRING:
123             nControlType = PropertyControlType::TextField;
124             break;
125         }
126 
127         // create a control
128         _out_rDescriptor.Control = _rxControlFactory->createPropertyControl( nControlType, bReadOnlyControl );
129     }
130 
131 	//--------------------------------------------------------------------
132     namespace
133     {
134         Reference< XPropertyControl > lcl_implCreateListLikeControl(
135                 const Reference< XPropertyControlFactory >& _rxControlFactory,
136                 const ::std::vector< ::rtl::OUString >& _rInitialListEntries,
137                 sal_Bool _bReadOnlyControl,
138                 sal_Bool _bSorted,
139                 sal_Bool _bTrueIfListBoxFalseIfComboBox
140             )
141         {
142             Reference< XStringListControl > xListControl(
143                 _rxControlFactory->createPropertyControl(
144                     _bTrueIfListBoxFalseIfComboBox ? PropertyControlType::ListBox : PropertyControlType::ComboBox, _bReadOnlyControl
145                 ),
146                 UNO_QUERY_THROW
147             );
148 
149             ::std::vector< ::rtl::OUString > aInitialEntries( _rInitialListEntries );
150             if ( _bSorted )
151                 ::std::sort( aInitialEntries.begin(), aInitialEntries.end() );
152 
153             for (   ::std::vector< ::rtl::OUString >::const_iterator loop = aInitialEntries.begin();
154                     loop != aInitialEntries.end();
155                     ++loop
156                 )
157                 xListControl->appendListEntry( *loop );
158             return xListControl.get();
159         }
160     }
161 
162 	//--------------------------------------------------------------------
163     Reference< XPropertyControl > PropertyHandlerHelper::createListBoxControl( const Reference< XPropertyControlFactory >& _rxControlFactory,
164                 const ::std::vector< ::rtl::OUString >& _rInitialListEntries, sal_Bool _bReadOnlyControl, sal_Bool _bSorted )
165     {
166         return lcl_implCreateListLikeControl( _rxControlFactory, _rInitialListEntries, _bReadOnlyControl, _bSorted, sal_True );
167     }
168 
169 	//--------------------------------------------------------------------
170     Reference< XPropertyControl > PropertyHandlerHelper::createComboBoxControl( const Reference< XPropertyControlFactory >& _rxControlFactory,
171                 const ::std::vector< ::rtl::OUString >& _rInitialListEntries, sal_Bool _bReadOnlyControl, sal_Bool _bSorted )
172     {
173         return lcl_implCreateListLikeControl( _rxControlFactory, _rInitialListEntries, _bReadOnlyControl, _bSorted, sal_False );
174     }
175 
176 	//--------------------------------------------------------------------
177     Reference< XPropertyControl > PropertyHandlerHelper::createNumericControl( const Reference< XPropertyControlFactory >& _rxControlFactory,
178             sal_Int16 _nDigits, const Optional< double >& _rMinValue, const Optional< double >& _rMaxValue, sal_Bool _bReadOnlyControl )
179     {
180         Reference< XNumericControl > xNumericControl(
181             _rxControlFactory->createPropertyControl( PropertyControlType::NumericField, _bReadOnlyControl ),
182             UNO_QUERY_THROW
183         );
184 
185         xNumericControl->setDecimalDigits( _nDigits );
186         xNumericControl->setMinValue( _rMinValue );
187         xNumericControl->setMaxValue( _rMaxValue );
188 
189         return xNumericControl.get();
190     }
191 
192 	//--------------------------------------------------------------------
193     Any PropertyHandlerHelper::convertToPropertyValue( const Reference< XComponentContext >& _rxContext,const Reference< XTypeConverter >& _rxTypeConverter,
194         const Property& _rProperty, const Any& _rControlValue )
195     {
196         Any aPropertyValue( _rControlValue );
197         if ( !aPropertyValue.hasValue() )
198             // NULL is converted to NULL
199             return aPropertyValue;
200 
201         if ( aPropertyValue.getValueType().equals( _rProperty.Type ) )
202             // nothing to do, type is already as desired
203             return aPropertyValue;
204 
205         if ( _rControlValue.getValueType().getTypeClass() == TypeClass_STRING )
206         {
207             ::rtl::OUString sControlValue;
208             _rControlValue >>= sControlValue;
209 
210             Reference< XStringRepresentation > xConversionHelper = StringRepresentation::create( _rxContext,_rxTypeConverter );
211             aPropertyValue = xConversionHelper->convertToPropertyValue( sControlValue, _rProperty.Type );
212         }
213         else
214         {
215             try
216             {
217                 if ( _rxTypeConverter.is() )
218                     aPropertyValue = _rxTypeConverter->convertTo( _rControlValue, _rProperty.Type );
219             }
220             catch( const Exception& )
221             {
222                 OSL_ENSURE( sal_False, "PropertyHandlerHelper::convertToPropertyValue: caught an exception while converting via TypeConverter!" );
223             }
224         }
225 
226         return aPropertyValue;
227     }
228 
229 	//--------------------------------------------------------------------
230     Any PropertyHandlerHelper::convertToControlValue( const Reference< XComponentContext >& _rxContext,const Reference< XTypeConverter >& _rxTypeConverter,
231         const Any& _rPropertyValue, const Type& _rControlValueType )
232     {
233         Any aControlValue( _rPropertyValue );
234         if ( !aControlValue.hasValue() )
235             // NULL is converted to NULL
236             return aControlValue;
237 
238         if ( _rControlValueType.getTypeClass() == TypeClass_STRING )
239         {
240             Reference< XStringRepresentation > xConversionHelper = StringRepresentation::create( _rxContext,_rxTypeConverter );
241             aControlValue <<= xConversionHelper->convertToControlValue( _rPropertyValue );
242         }
243         else
244         {
245             try
246             {
247                 if ( _rxTypeConverter.is() )
248                     aControlValue = _rxTypeConverter->convertTo( _rPropertyValue, _rControlValueType );
249             }
250             catch( const Exception& )
251             {
252                 OSL_ENSURE( sal_False, "PropertyHandlerHelper::convertToControlValue: caught an exception while converting via TypeConverter!" );
253             }
254         }
255 
256         return aControlValue;
257     }
258 
259 	//--------------------------------------------------------------------
260     void PropertyHandlerHelper::setContextDocumentModified( const ComponentContext& _rContext )
261     {
262         try
263         {
264             Reference< XModifiable > xDocumentModifiable( _rContext.getContextValueByAsciiName( "ContextDocument" ), UNO_QUERY_THROW );
265 			xDocumentModifiable->setModified( sal_True );
266         }
267         catch( const Exception& )
268         {
269             DBG_UNHANDLED_EXCEPTION();
270         }
271     }
272 
273 	//--------------------------------------------------------------------
274     Window* PropertyHandlerHelper::getDialogParentWindow( const ComponentContext& _rContext )
275     {
276         Window* pInspectorWindow = NULL;
277         try
278         {
279             Reference< XWindow > xInspectorWindow( _rContext.getContextValueByAsciiName( "DialogParentWindow" ), UNO_QUERY_THROW );
280             pInspectorWindow = VCLUnoHelper::GetWindow( xInspectorWindow );
281         }
282         catch( const Exception& )
283         {
284             DBG_UNHANDLED_EXCEPTION();
285         }
286         return pInspectorWindow;
287     }
288 
289 //........................................................................
290 } // namespace pcr
291 //........................................................................
292