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