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_sc.hxx" 30 31 32 #include <editeng/memberids.hrc> 33 #include <svl/smplhint.hxx> 34 #include <svl/itemprop.hxx> 35 #include <svx/unomid.hxx> 36 #include <i18npool/mslangid.hxx> 37 38 #include <com/sun/star/beans/PropertyAttribute.hpp> 39 40 #include "scitems.hxx" 41 #include "defltuno.hxx" 42 #include "miscuno.hxx" 43 #include "docsh.hxx" 44 #include "docpool.hxx" 45 #include "unoguard.hxx" 46 #include "unonames.hxx" 47 #include "docoptio.hxx" 48 49 #include <limits> 50 51 using namespace ::com::sun::star; 52 53 //------------------------------------------------------------------------ 54 55 const SfxItemPropertyMapEntry* lcl_GetDocDefaultsMap() 56 { 57 static SfxItemPropertyMapEntry aDocDefaultsMap_Impl[] = 58 { 59 {MAP_CHAR_LEN(SC_UNONAME_CFCHARS), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET }, 60 {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET }, 61 {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_CHAR_SET }, 62 {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY }, 63 {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY }, 64 {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_FAMILY }, 65 {MAP_CHAR_LEN(SC_UNONAME_CFNAME), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME }, 66 {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME }, 67 {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_FAMILY_NAME }, 68 {MAP_CHAR_LEN(SC_UNONAME_CFPITCH), ATTR_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH }, 69 {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH), ATTR_CJK_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH }, 70 {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH), ATTR_CTL_FONT, &getCppuType((sal_Int16*)0), 0, MID_FONT_PITCH }, 71 {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE), ATTR_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME }, 72 {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE), ATTR_CJK_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME }, 73 {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE), ATTR_CTL_FONT, &getCppuType((rtl::OUString*)0), 0, MID_FONT_STYLE_NAME }, 74 {MAP_CHAR_LEN(SC_UNONAME_CLOCAL), ATTR_FONT_LANGUAGE, &getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE }, 75 {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL), ATTR_CJK_FONT_LANGUAGE, &getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE }, 76 {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL), ATTR_CTL_FONT_LANGUAGE, &getCppuType((lang::Locale*)0), 0, MID_LANG_LOCALE }, 77 {MAP_CHAR_LEN(SC_UNO_STANDARDDEC), 0, &getCppuType((sal_Int16*)0), 0, 0 }, 78 {MAP_CHAR_LEN(SC_UNO_TABSTOPDIS), 0, &getCppuType((sal_Int32*)0), 0, 0 }, 79 {0,0,0,0,0,0} 80 }; 81 return aDocDefaultsMap_Impl; 82 } 83 84 inline long TwipsToHMM(long nTwips) { return (nTwips * 127 + 36) / 72; } 85 inline long HMMToTwips(long nHMM) { return (nHMM * 72 + 63) / 127; } 86 inline long TwipsToEvenHMM(long nTwips) { return ( (nTwips * 127 + 72) / 144 ) * 2; } 87 88 //------------------------------------------------------------------------ 89 90 SC_SIMPLE_SERVICE_INFO( ScDocDefaultsObj, "ScDocDefaultsObj", "com.sun.star.sheet.Defaults" ) 91 92 //------------------------------------------------------------------------ 93 94 ScDocDefaultsObj::ScDocDefaultsObj(ScDocShell* pDocSh) : 95 pDocShell( pDocSh ), 96 aPropertyMap(lcl_GetDocDefaultsMap()) 97 { 98 pDocShell->GetDocument()->AddUnoObject(*this); 99 } 100 101 ScDocDefaultsObj::~ScDocDefaultsObj() 102 { 103 if (pDocShell) 104 pDocShell->GetDocument()->RemoveUnoObject(*this); 105 } 106 107 void ScDocDefaultsObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) 108 { 109 if ( rHint.ISA( SfxSimpleHint ) && 110 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) 111 { 112 pDocShell = NULL; // document gone 113 } 114 } 115 116 void ScDocDefaultsObj::ItemsChanged() 117 { 118 if (pDocShell) 119 { 120 //! if not in XML import, adjust row heights 121 122 pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID ); 123 } 124 } 125 126 // XPropertySet 127 128 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDocDefaultsObj::getPropertySetInfo() 129 throw(uno::RuntimeException) 130 { 131 ScUnoGuard aGuard; 132 static uno::Reference<beans::XPropertySetInfo> aRef = new SfxItemPropertySetInfo( 133 &aPropertyMap ); 134 return aRef; 135 } 136 137 void SAL_CALL ScDocDefaultsObj::setPropertyValue( 138 const rtl::OUString& aPropertyName, const uno::Any& aValue ) 139 throw(beans::UnknownPropertyException, beans::PropertyVetoException, 140 lang::IllegalArgumentException, lang::WrappedTargetException, 141 uno::RuntimeException) 142 { 143 ScUnoGuard aGuard; 144 145 if ( !pDocShell ) 146 throw uno::RuntimeException(); 147 148 const SfxItemPropertySimpleEntry* pEntry = aPropertyMap.getByName( aPropertyName ); 149 if ( !pEntry ) 150 throw beans::UnknownPropertyException(); 151 if(!pEntry->nWID) 152 { 153 if(aPropertyName.compareToAscii(SC_UNO_STANDARDDEC) == 0) 154 { 155 ScDocument* pDoc = pDocShell->GetDocument(); 156 if (pDoc) 157 { 158 ScDocOptions aDocOpt(pDoc->GetDocOptions()); 159 sal_Int16 nValue = 0; 160 if (aValue >>= nValue) 161 { 162 aDocOpt.SetStdPrecision(static_cast<sal_uInt16> (nValue)); 163 pDoc->SetDocOptions(aDocOpt); 164 } 165 } 166 else 167 throw uno::RuntimeException(); 168 } 169 else if (aPropertyName.compareToAscii(SC_UNO_TABSTOPDIS) == 0) 170 { 171 ScDocument* pDoc = pDocShell->GetDocument(); 172 if (pDoc) 173 { 174 ScDocOptions aDocOpt(pDoc->GetDocOptions()); 175 sal_Int32 nValue = 0; 176 if (aValue >>= nValue) 177 { 178 aDocOpt.SetTabDistance(static_cast<sal_uInt16>(HMMToTwips(nValue))); 179 pDoc->SetDocOptions(aDocOpt); 180 } 181 } 182 else 183 throw uno::RuntimeException(); 184 } 185 } 186 else if ( pEntry->nWID == ATTR_FONT_LANGUAGE || 187 pEntry->nWID == ATTR_CJK_FONT_LANGUAGE || 188 pEntry->nWID == ATTR_CTL_FONT_LANGUAGE ) 189 { 190 // for getPropertyValue the PoolDefaults are sufficient, 191 // but setPropertyValue has to be handled differently 192 193 lang::Locale aLocale; 194 if ( aValue >>= aLocale ) 195 { 196 LanguageType eNew; 197 if (aLocale.Language.getLength() || aLocale.Country.getLength()) 198 eNew = MsLangId::convertLocaleToLanguage( aLocale ); 199 else 200 eNew = LANGUAGE_NONE; 201 202 ScDocument* pDoc = pDocShell->GetDocument(); 203 LanguageType eLatin, eCjk, eCtl; 204 pDoc->GetLanguage( eLatin, eCjk, eCtl ); 205 206 if ( pEntry->nWID == ATTR_CJK_FONT_LANGUAGE ) 207 eCjk = eNew; 208 else if ( pEntry->nWID == ATTR_CTL_FONT_LANGUAGE ) 209 eCtl = eNew; 210 else 211 eLatin = eNew; 212 213 pDoc->SetLanguage( eLatin, eCjk, eCtl ); 214 } 215 } 216 else 217 { 218 ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool(); 219 SfxPoolItem* pNewItem = pPool->GetDefaultItem(pEntry->nWID).Clone(); 220 221 if( !pNewItem->PutValue( aValue, pEntry->nMemberId ) ) 222 throw lang::IllegalArgumentException(); 223 224 pPool->SetPoolDefaultItem( *pNewItem ); 225 delete pNewItem; // copied in SetPoolDefaultItem 226 227 ItemsChanged(); 228 } 229 } 230 231 uno::Any SAL_CALL ScDocDefaultsObj::getPropertyValue( const rtl::OUString& aPropertyName ) 232 throw(beans::UnknownPropertyException, lang::WrappedTargetException, 233 uno::RuntimeException) 234 { 235 // use pool default if set 236 237 ScUnoGuard aGuard; 238 239 if ( !pDocShell ) 240 throw uno::RuntimeException(); 241 242 uno::Any aRet; 243 const SfxItemPropertySimpleEntry* pEntry = aPropertyMap.getByName( aPropertyName ); 244 if ( !pEntry ) 245 throw beans::UnknownPropertyException(); 246 247 if (!pEntry->nWID) 248 { 249 if(aPropertyName.compareToAscii(SC_UNO_STANDARDDEC) == 0) 250 { 251 ScDocument* pDoc = pDocShell->GetDocument(); 252 if (pDoc) 253 { 254 const ScDocOptions& aDocOpt = pDoc->GetDocOptions(); 255 sal_uInt16 nPrec = aDocOpt.GetStdPrecision(); 256 // the max value of unsigned 16-bit integer is used as the flag 257 // value for unlimited precision, c.f. 258 // SvNumberFormatter::UNLIMITED_PRECISION. 259 if (nPrec <= ::std::numeric_limits<sal_Int16>::max()) 260 aRet <<= static_cast<sal_Int16> (nPrec); 261 } 262 else 263 throw uno::RuntimeException(); 264 } 265 else if (aPropertyName.compareToAscii(SC_UNO_TABSTOPDIS) == 0) 266 { 267 ScDocument* pDoc = pDocShell->GetDocument(); 268 if (pDoc) 269 { 270 const ScDocOptions& aDocOpt = pDoc->GetDocOptions(); 271 sal_Int32 nValue (TwipsToEvenHMM(aDocOpt.GetTabDistance())); 272 aRet <<= nValue; 273 } 274 else 275 throw uno::RuntimeException(); 276 } 277 } 278 else 279 { 280 ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool(); 281 const SfxPoolItem& rItem = pPool->GetDefaultItem( pEntry->nWID ); 282 rItem.QueryValue( aRet, pEntry->nMemberId ); 283 } 284 return aRet; 285 } 286 287 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDocDefaultsObj ) 288 289 // XPropertyState 290 291 beans::PropertyState SAL_CALL ScDocDefaultsObj::getPropertyState( const rtl::OUString& aPropertyName ) 292 throw(beans::UnknownPropertyException, uno::RuntimeException) 293 { 294 ScUnoGuard aGuard; 295 296 if ( !pDocShell ) 297 throw uno::RuntimeException(); 298 299 const SfxItemPropertySimpleEntry* pEntry = aPropertyMap.getByName( aPropertyName ); 300 if ( !pEntry ) 301 throw beans::UnknownPropertyException(); 302 303 beans::PropertyState eRet = beans::PropertyState_DEFAULT_VALUE; 304 305 sal_uInt16 nWID = pEntry->nWID; 306 if ( nWID == ATTR_FONT || nWID == ATTR_CJK_FONT || nWID == ATTR_CTL_FONT || !nWID ) 307 { 308 // static default for font is system-dependent, 309 // so font default is always treated as "direct value". 310 311 eRet = beans::PropertyState_DIRECT_VALUE; 312 } 313 else 314 { 315 // check if pool default is set 316 317 ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool(); 318 if ( pPool->GetPoolDefaultItem( nWID ) != NULL ) 319 eRet = beans::PropertyState_DIRECT_VALUE; 320 } 321 322 return eRet; 323 } 324 325 uno::Sequence<beans::PropertyState> SAL_CALL ScDocDefaultsObj::getPropertyStates( 326 const uno::Sequence<rtl::OUString>& aPropertyNames ) 327 throw(beans::UnknownPropertyException, uno::RuntimeException) 328 { 329 // the simple way: call getPropertyState 330 331 ScUnoGuard aGuard; 332 const rtl::OUString* pNames = aPropertyNames.getConstArray(); 333 uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength()); 334 beans::PropertyState* pStates = aRet.getArray(); 335 for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++) 336 pStates[i] = getPropertyState(pNames[i]); 337 return aRet; 338 } 339 340 void SAL_CALL ScDocDefaultsObj::setPropertyToDefault( const rtl::OUString& aPropertyName ) 341 throw(beans::UnknownPropertyException, uno::RuntimeException) 342 { 343 ScUnoGuard aGuard; 344 345 if ( !pDocShell ) 346 throw uno::RuntimeException(); 347 348 const SfxItemPropertySimpleEntry* pEntry = aPropertyMap.getByName( aPropertyName ); 349 if ( !pEntry ) 350 throw beans::UnknownPropertyException(); 351 352 if (pEntry->nWID) 353 { 354 ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool(); 355 pPool->ResetPoolDefaultItem( pEntry->nWID ); 356 357 ItemsChanged(); 358 } 359 } 360 361 uno::Any SAL_CALL ScDocDefaultsObj::getPropertyDefault( const rtl::OUString& aPropertyName ) 362 throw(beans::UnknownPropertyException, lang::WrappedTargetException, 363 uno::RuntimeException) 364 { 365 // always use static default 366 367 ScUnoGuard aGuard; 368 369 if ( !pDocShell ) 370 throw uno::RuntimeException(); 371 372 const SfxItemPropertySimpleEntry* pEntry = aPropertyMap.getByName( aPropertyName ); 373 if ( !pEntry ) 374 throw beans::UnknownPropertyException(); 375 376 uno::Any aRet; 377 if (pEntry->nWID) 378 { 379 ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool(); 380 const SfxPoolItem* pItem = pPool->GetItem2( pEntry->nWID, SFX_ITEMS_DEFAULT ); 381 if (pItem) 382 pItem->QueryValue( aRet, pEntry->nMemberId ); 383 } 384 return aRet; 385 } 386 387 388