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