xref: /AOO41X/main/svx/source/form/fmcontrollayout.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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_svx.hxx"
30 
31 #include "fmcontrollayout.hxx"
32 #include "fmprop.hrc"
33 
34 /** === begin UNO includes === **/
35 #include <com/sun/star/form/FormComponentType.hpp>
36 #include <com/sun/star/awt/VisualEffect.hpp>
37 #include <com/sun/star/i18n/ScriptType.hpp>
38 #include <com/sun/star/lang/Locale.hpp>
39 #include <com/sun/star/awt/FontDescriptor.hpp>
40 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
41 #include <com/sun/star/lang/XServiceInfo.hpp>
42 #include <com/sun/star/container/XChild.hpp>
43 /** === end UNO includes === **/
44 
45 #include <comphelper/processfactory.hxx>
46 #include <i18npool/mslangid.hxx>
47 #include <unotools/syslocale.hxx>
48 
49 #include <toolkit/helper/vclunohelper.hxx>
50 #include <tools/debug.hxx>
51 #include <tools/diagnose_ex.h>
52 #include <vcl/outdev.hxx>
53 
54 //........................................................................
55 namespace svxform
56 {
57 //........................................................................
58 
59     using namespace ::utl;
60 	/** === begin UNO using === **/
61 	using ::com::sun::star::uno::Reference;
62 	using ::com::sun::star::uno::XInterface;
63 	using ::com::sun::star::uno::UNO_QUERY;
64 	using ::com::sun::star::uno::UNO_QUERY_THROW;
65 	using ::com::sun::star::uno::UNO_SET_THROW;
66 	using ::com::sun::star::uno::Exception;
67 	using ::com::sun::star::uno::RuntimeException;
68 	using ::com::sun::star::uno::Any;
69 	using ::com::sun::star::uno::makeAny;
70 	using ::com::sun::star::uno::Sequence;
71 	using ::com::sun::star::uno::Type;
72     using ::com::sun::star::beans::XPropertySet;
73     using ::com::sun::star::beans::XPropertySetInfo;
74     using ::com::sun::star::lang::Locale;
75     using ::com::sun::star::awt::FontDescriptor;
76     using ::com::sun::star::style::XStyleFamiliesSupplier;
77     using ::com::sun::star::lang::XServiceInfo;
78     using ::com::sun::star::container::XNameAccess;
79     using ::com::sun::star::container::XChild;
80 	/** === end UNO using === **/
81     namespace FormComponentType = ::com::sun::star::form::FormComponentType;
82     namespace VisualEffect = ::com::sun::star::awt::VisualEffect;
83     namespace ScriptType = ::com::sun::star::i18n::ScriptType;
84 
85 	//--------------------------------------------------------------------
86     namespace
87     {
88         //....................................................................
89         template< class INTERFACE_TYPE >
90         Reference< INTERFACE_TYPE > getTypedModelNode( const Reference< XInterface >& _rxModelNode )
91         {
92             Reference< INTERFACE_TYPE > xTypedNode( _rxModelNode, UNO_QUERY );
93             if ( xTypedNode.is() )
94                 return xTypedNode;
95             else
96             {
97                 Reference< XChild > xChild( _rxModelNode, UNO_QUERY );
98                 if ( xChild.is() )
99                     return getTypedModelNode< INTERFACE_TYPE >( xChild->getParent() );
100                 else
101                     return NULL;
102             }
103         }
104 
105         //....................................................................
106         static bool lcl_getDocumentDefaultStyleAndFamily( const Reference< XInterface >& _rxDocument, ::rtl::OUString& _rFamilyName, ::rtl::OUString& _rStyleName ) SAL_THROW(( Exception ))
107         {
108             bool bSuccess = true;
109             Reference< XServiceInfo > xDocumentSI( _rxDocument, UNO_QUERY );
110             if ( xDocumentSI.is() )
111             {
112                 if (  xDocumentSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" ) ) )
113                    || xDocumentSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.WebDocument" ) ) )
114                    )
115                 {
116                     _rFamilyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParagraphStyles" ) );
117                     _rStyleName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
118                 }
119                 else if ( xDocumentSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocument" ) ) ) )
120                 {
121                     _rFamilyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CellStyles" ) );
122                     _rStyleName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Default" ) );
123                 }
124                 else if (  xDocumentSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" ) ) )
125                         || xDocumentSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ) ) )
126                         )
127                 {
128                     _rFamilyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "graphics" ) );
129                     _rStyleName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "standard" ) );
130                 }
131                 else
132                     bSuccess = false;
133             }
134             return bSuccess;
135         }
136 
137         //....................................................................
138         static void lcl_initializeControlFont( const Reference< XPropertySet >& _rxModel )
139         {
140             try
141             {
142                 Reference< XPropertySet > xStyle( ControlLayouter::getDefaultDocumentTextStyle( _rxModel ), UNO_SET_THROW );
143                 Reference< XPropertySetInfo > xStylePSI( xStyle->getPropertySetInfo(), UNO_SET_THROW );
144 
145                 // determine the script type associated with the system locale
146                 const LocaleDataWrapper& rSysLocaleData = SvtSysLocale().GetLocaleData();
147                 const sal_Int16 eSysLocaleScriptType = MsLangId::getScriptType( MsLangId::convertLocaleToLanguage( rSysLocaleData.getLocale() ) );
148 
149                 // depending on this script type, use the right property from the document's style which controls the
150                 // default locale for document content
151                 const sal_Char* pCharLocalePropertyName = "CharLocale";
152                 switch ( eSysLocaleScriptType )
153                 {
154                 case ScriptType::LATIN:
155                     // already defaulted above
156                     break;
157                 case ScriptType::ASIAN:
158                     pCharLocalePropertyName = "CharLocaleAsian";
159                     break;
160                 case ScriptType::COMPLEX:
161                     pCharLocalePropertyName = "CharLocaleComplex";
162                     break;
163                 default:
164                     OSL_ENSURE( false, "lcl_initializeControlFont: unexpected script type for system locale!" );
165                     break;
166                 }
167 
168                 ::rtl::OUString sCharLocalePropertyName = ::rtl::OUString::createFromAscii( pCharLocalePropertyName );
169                 Locale aDocumentCharLocale;
170                 if ( xStylePSI->hasPropertyByName( sCharLocalePropertyName ) )
171                 {
172                     OSL_VERIFY( xStyle->getPropertyValue( sCharLocalePropertyName ) >>= aDocumentCharLocale );
173                 }
174                 // fall back to CharLocale property at the style
175                 if ( !aDocumentCharLocale.Language.getLength() )
176                 {
177                     sCharLocalePropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharLocale" ) );
178                     if ( xStylePSI->hasPropertyByName( sCharLocalePropertyName ) )
179                     {
180                         OSL_VERIFY( xStyle->getPropertyValue( sCharLocalePropertyName ) >>= aDocumentCharLocale );
181                     }
182                 }
183                 // fall back to the system locale
184                 if ( !aDocumentCharLocale.Language.getLength() )
185                 {
186                     aDocumentCharLocale = rSysLocaleData.getLocale();
187                 }
188 
189                 // retrieve a default font for this locale, and set it at the control
190                 Font aFont = OutputDevice::GetDefaultFont( DEFAULTFONT_SANS, MsLangId::convertLocaleToLanguage( aDocumentCharLocale ), DEFAULTFONT_FLAGS_ONLYONE );
191                 FontDescriptor aFontDesc = VCLUnoHelper::CreateFontDescriptor( aFont );
192                 _rxModel->setPropertyValue(
193                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FontDescriptor" ) ),
194                     makeAny( aFontDesc )
195                 );
196             }
197             catch( const Exception& )
198             {
199                 DBG_UNHANDLED_EXCEPTION();
200             }
201         }
202     }
203 
204     //====================================================================
205 	//= ControlLayouter
206 	//====================================================================
207 	//--------------------------------------------------------------------
208     Reference< XPropertySet > ControlLayouter::getDefaultDocumentTextStyle( const Reference< XPropertySet >& _rxModel )
209     {
210         // the style family collection
211         Reference< XStyleFamiliesSupplier > xSuppStyleFamilies( getTypedModelNode< XStyleFamiliesSupplier >( _rxModel.get() ), UNO_SET_THROW );
212         Reference< XNameAccess > xStyleFamilies( xSuppStyleFamilies->getStyleFamilies(), UNO_SET_THROW );
213 
214         // the names of the family, and the style - depends on the document type we live in
215         ::rtl::OUString sFamilyName, sStyleName;
216         if ( !lcl_getDocumentDefaultStyleAndFamily( xSuppStyleFamilies.get(), sFamilyName, sStyleName ) )
217             throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unknown document type!" ) ), NULL );
218 
219         // the concrete style
220         Reference< XNameAccess > xStyleFamily( xStyleFamilies->getByName( sFamilyName ), UNO_QUERY_THROW );
221         return Reference< XPropertySet >( xStyleFamily->getByName( sStyleName ), UNO_QUERY_THROW );
222     }
223 
224 	//--------------------------------------------------------------------
225     void ControlLayouter::initializeControlLayout( const Reference< XPropertySet >& _rxControlModel, DocumentType _eDocType )
226     {
227         DBG_ASSERT( _rxControlModel.is(), "ControlLayouter::initializeControlLayout: invalid model!" );
228         if ( !_rxControlModel.is() )
229             return;
230 
231         try
232         {
233             Reference< XPropertySetInfo > xPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW );
234 
235             // the control type
236             sal_Int16 nClassId = FormComponentType::CONTROL;
237             _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId;
238 
239             // the document type
240             if ( _eDocType == eUnknownDocumentType )
241                 _eDocType = DocumentClassification::classifyHostDocument( _rxControlModel.get() );
242 
243             // let's see what the configuration says about the visual effect
244             OConfigurationNode  aConfig = getLayoutSettings( _eDocType );
245             Any aVisualEffect = aConfig.getNodeValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VisualEffect" ) ) );
246             if ( aVisualEffect.hasValue() )
247             {
248                 ::rtl::OUString sVisualEffect;
249                 OSL_VERIFY( aVisualEffect >>= sVisualEffect );
250 
251                 sal_Int16 nVisualEffect = VisualEffect::NONE;
252                 if ( sVisualEffect.equalsAscii( "flat" ) )
253                     nVisualEffect = VisualEffect::FLAT;
254                 else if ( sVisualEffect.equalsAscii( "3D" ) )
255                     nVisualEffect = VisualEffect::LOOK3D;
256 
257                 if ( xPSI->hasPropertyByName( FM_PROP_BORDER ) )
258                 {
259                     if  (  ( nClassId != FormComponentType::COMMANDBUTTON )
260                         && ( nClassId != FormComponentType::RADIOBUTTON )
261 						&& ( nClassId != FormComponentType::CHECKBOX	)
262                         && ( nClassId != FormComponentType::GROUPBOX )
263                         && ( nClassId != FormComponentType::FIXEDTEXT )
264                         && ( nClassId != FormComponentType::SCROLLBAR )
265                         && ( nClassId != FormComponentType::SPINBUTTON )
266                         )
267                     {
268                         _rxControlModel->setPropertyValue( FM_PROP_BORDER, makeAny( nVisualEffect ) );
269                         if  (   ( nVisualEffect == VisualEffect::FLAT )
270                             &&  ( xPSI->hasPropertyByName( FM_PROP_BORDERCOLOR ) )
271                             )
272                             // light gray flat border
273                             _rxControlModel->setPropertyValue( FM_PROP_BORDERCOLOR, makeAny( (sal_Int32)0x00C0C0C0 ) );
274                     }
275                 }
276                 if ( xPSI->hasPropertyByName( FM_PROP_VISUALEFFECT ) )
277                     _rxControlModel->setPropertyValue( FM_PROP_VISUALEFFECT, makeAny( nVisualEffect ) );
278             }
279 
280             // the font (only if we use the document's ref devices for rendering control text, otherwise, the
281             // default font of VCL controls is assumed to be fine)
282             if  (   useDocumentReferenceDevice( _eDocType )
283                 &&  xPSI->hasPropertyByName( FM_PROP_FONT )
284                 )
285                 lcl_initializeControlFont( _rxControlModel );
286         }
287         catch( const Exception& )
288         {
289         	OSL_ENSURE( sal_False, "ControlLayouter::initializeControlLayout: caught an exception!" );
290         }
291     }
292 
293 	//--------------------------------------------------------------------
294     ::utl::OConfigurationNode ControlLayouter::getLayoutSettings( DocumentType _eDocType )
295     {
296         ::rtl::OUString sConfigName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/Forms/ControlLayout/" ) );
297         sConfigName += DocumentClassification::getModuleIdentifierForDocumentType( _eDocType );
298         return OConfigurationTreeRoot::createWithServiceFactory(
299             ::comphelper::getProcessServiceFactory(),    // TODO
300             sConfigName );
301     }
302 
303 	//--------------------------------------------------------------------
304     bool ControlLayouter::useDynamicBorderColor( DocumentType _eDocType )
305     {
306         OConfigurationNode aConfig = getLayoutSettings( _eDocType );
307         Any aDynamicBorderColor = aConfig.getNodeValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DynamicBorderColors" ) ) );
308         bool bDynamicBorderColor = false;
309         OSL_VERIFY( aDynamicBorderColor >>= bDynamicBorderColor );
310         return bDynamicBorderColor;
311     }
312 
313 	//--------------------------------------------------------------------
314     bool ControlLayouter::useDocumentReferenceDevice( DocumentType _eDocType )
315     {
316         if ( _eDocType == eUnknownDocumentType )
317             return false;
318         OConfigurationNode aConfig = getLayoutSettings( _eDocType );
319         Any aUseRefDevice = aConfig.getNodeValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseDocumentTextMetrics" ) ) );
320         bool bUseRefDevice = false;
321         OSL_VERIFY( aUseRefDevice >>= bUseRefDevice );
322         return bUseRefDevice;
323     }
324 
325 //........................................................................
326 } // namespace svxform
327 //........................................................................
328 
329