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 { 126 ScUnoGuard aGuard; 127 static uno::Reference<beans::XPropertySetInfo> aRef = new SfxItemPropertySetInfo( 128 &aPropertyMap ); 129 return aRef; 130 } 131 132 void SAL_CALL ScDocDefaultsObj::setPropertyValue( 133 const rtl::OUString& aPropertyName, const uno::Any& aValue ) 134 { 135 ScUnoGuard aGuard; 136 137 if ( !pDocShell ) 138 throw uno::RuntimeException(); 139 140 const SfxItemPropertySimpleEntry* pEntry = aPropertyMap.getByName( aPropertyName ); 141 if ( !pEntry ) 142 throw beans::UnknownPropertyException(); 143 if(!pEntry->nWID) 144 { 145 if(aPropertyName.compareToAscii(SC_UNO_STANDARDDEC) == 0) 146 { 147 ScDocument* pDoc = pDocShell->GetDocument(); 148 if (pDoc) 149 { 150 ScDocOptions aDocOpt(pDoc->GetDocOptions()); 151 sal_Int16 nValue = 0; 152 if (aValue >>= nValue) 153 { 154 aDocOpt.SetStdPrecision(static_cast<sal_uInt16> (nValue)); 155 pDoc->SetDocOptions(aDocOpt); 156 } 157 } 158 else 159 throw uno::RuntimeException(); 160 } 161 else if (aPropertyName.compareToAscii(SC_UNO_TABSTOPDIS) == 0) 162 { 163 ScDocument* pDoc = pDocShell->GetDocument(); 164 if (pDoc) 165 { 166 ScDocOptions aDocOpt(pDoc->GetDocOptions()); 167 sal_Int32 nValue = 0; 168 if (aValue >>= nValue) 169 { 170 aDocOpt.SetTabDistance(static_cast<sal_uInt16>(HMMToTwips(nValue))); 171 pDoc->SetDocOptions(aDocOpt); 172 } 173 } 174 else 175 throw uno::RuntimeException(); 176 } 177 } 178 else if ( pEntry->nWID == ATTR_FONT_LANGUAGE || 179 pEntry->nWID == ATTR_CJK_FONT_LANGUAGE || 180 pEntry->nWID == ATTR_CTL_FONT_LANGUAGE ) 181 { 182 // for getPropertyValue the PoolDefaults are sufficient, 183 // but setPropertyValue has to be handled differently 184 185 lang::Locale aLocale; 186 if ( aValue >>= aLocale ) 187 { 188 LanguageType eNew; 189 if (aLocale.Language.getLength() || aLocale.Country.getLength()) 190 eNew = MsLangId::convertLocaleToLanguage( aLocale ); 191 else 192 eNew = LANGUAGE_NONE; 193 194 ScDocument* pDoc = pDocShell->GetDocument(); 195 LanguageType eLatin, eCjk, eCtl; 196 pDoc->GetLanguage( eLatin, eCjk, eCtl ); 197 198 if ( pEntry->nWID == ATTR_CJK_FONT_LANGUAGE ) 199 eCjk = eNew; 200 else if ( pEntry->nWID == ATTR_CTL_FONT_LANGUAGE ) 201 eCtl = eNew; 202 else 203 eLatin = eNew; 204 205 pDoc->SetLanguage( eLatin, eCjk, eCtl ); 206 } 207 } 208 else 209 { 210 ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool(); 211 SfxPoolItem* pNewItem = pPool->GetDefaultItem(pEntry->nWID).Clone(); 212 213 if( !pNewItem->PutValue( aValue, pEntry->nMemberId ) ) 214 throw lang::IllegalArgumentException(); 215 216 pPool->SetPoolDefaultItem( *pNewItem ); 217 delete pNewItem; // copied in SetPoolDefaultItem 218 219 ItemsChanged(); 220 } 221 } 222 223 uno::Any SAL_CALL ScDocDefaultsObj::getPropertyValue( const rtl::OUString& aPropertyName ) 224 { 225 // use pool default if set 226 227 ScUnoGuard aGuard; 228 229 if ( !pDocShell ) 230 throw uno::RuntimeException(); 231 232 uno::Any aRet; 233 const SfxItemPropertySimpleEntry* pEntry = aPropertyMap.getByName( aPropertyName ); 234 if ( !pEntry ) 235 throw beans::UnknownPropertyException(); 236 237 if (!pEntry->nWID) 238 { 239 if(aPropertyName.compareToAscii(SC_UNO_STANDARDDEC) == 0) 240 { 241 ScDocument* pDoc = pDocShell->GetDocument(); 242 if (pDoc) 243 { 244 const ScDocOptions& aDocOpt = pDoc->GetDocOptions(); 245 sal_uInt16 nPrec = aDocOpt.GetStdPrecision(); 246 // the max value of unsigned 16-bit integer is used as the flag 247 // value for unlimited precision, c.f. 248 // SvNumberFormatter::UNLIMITED_PRECISION. 249 if (nPrec <= ::std::numeric_limits<sal_Int16>::max()) 250 aRet <<= static_cast<sal_Int16> (nPrec); 251 } 252 else 253 throw uno::RuntimeException(); 254 } 255 else if (aPropertyName.compareToAscii(SC_UNO_TABSTOPDIS) == 0) 256 { 257 ScDocument* pDoc = pDocShell->GetDocument(); 258 if (pDoc) 259 { 260 const ScDocOptions& aDocOpt = pDoc->GetDocOptions(); 261 sal_Int32 nValue (TwipsToEvenHMM(aDocOpt.GetTabDistance())); 262 aRet <<= nValue; 263 } 264 else 265 throw uno::RuntimeException(); 266 } 267 } 268 else 269 { 270 ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool(); 271 const SfxPoolItem& rItem = pPool->GetDefaultItem( pEntry->nWID ); 272 rItem.QueryValue( aRet, pEntry->nMemberId ); 273 } 274 return aRet; 275 } 276 277 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDocDefaultsObj ) 278 279 // XPropertyState 280 281 beans::PropertyState SAL_CALL ScDocDefaultsObj::getPropertyState( const rtl::OUString& aPropertyName ) 282 { 283 ScUnoGuard aGuard; 284 285 if ( !pDocShell ) 286 throw uno::RuntimeException(); 287 288 const SfxItemPropertySimpleEntry* pEntry = aPropertyMap.getByName( aPropertyName ); 289 if ( !pEntry ) 290 throw beans::UnknownPropertyException(); 291 292 beans::PropertyState eRet = beans::PropertyState_DEFAULT_VALUE; 293 294 sal_uInt16 nWID = pEntry->nWID; 295 if ( nWID == ATTR_FONT || nWID == ATTR_CJK_FONT || nWID == ATTR_CTL_FONT || !nWID ) 296 { 297 // static default for font is system-dependent, 298 // so font default is always treated as "direct value". 299 300 eRet = beans::PropertyState_DIRECT_VALUE; 301 } 302 else 303 { 304 // check if pool default is set 305 306 ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool(); 307 if ( pPool->GetPoolDefaultItem( nWID ) != NULL ) 308 eRet = beans::PropertyState_DIRECT_VALUE; 309 } 310 311 return eRet; 312 } 313 314 uno::Sequence<beans::PropertyState> SAL_CALL ScDocDefaultsObj::getPropertyStates( 315 const uno::Sequence<rtl::OUString>& aPropertyNames ) 316 { 317 // the simple way: call getPropertyState 318 319 ScUnoGuard aGuard; 320 const rtl::OUString* pNames = aPropertyNames.getConstArray(); 321 uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength()); 322 beans::PropertyState* pStates = aRet.getArray(); 323 for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++) 324 pStates[i] = getPropertyState(pNames[i]); 325 return aRet; 326 } 327 328 void SAL_CALL ScDocDefaultsObj::setPropertyToDefault( const rtl::OUString& aPropertyName ) 329 { 330 ScUnoGuard aGuard; 331 332 if ( !pDocShell ) 333 throw uno::RuntimeException(); 334 335 const SfxItemPropertySimpleEntry* pEntry = aPropertyMap.getByName( aPropertyName ); 336 if ( !pEntry ) 337 throw beans::UnknownPropertyException(); 338 339 if (pEntry->nWID) 340 { 341 ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool(); 342 pPool->ResetPoolDefaultItem( pEntry->nWID ); 343 344 ItemsChanged(); 345 } 346 } 347 348 uno::Any SAL_CALL ScDocDefaultsObj::getPropertyDefault( const rtl::OUString& aPropertyName ) 349 { 350 // always use static default 351 352 ScUnoGuard aGuard; 353 354 if ( !pDocShell ) 355 throw uno::RuntimeException(); 356 357 const SfxItemPropertySimpleEntry* pEntry = aPropertyMap.getByName( aPropertyName ); 358 if ( !pEntry ) 359 throw beans::UnknownPropertyException(); 360 361 uno::Any aRet; 362 if (pEntry->nWID) 363 { 364 ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool(); 365 const SfxPoolItem* pItem = pPool->GetItem2( pEntry->nWID, SFX_ITEMS_DEFAULT ); 366 if (pItem) 367 pItem->QueryValue( aRet, pEntry->nMemberId ); 368 } 369 return aRet; 370 } 371