xref: /trunk/main/sc/source/ui/unoobj/defltuno.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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