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