1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 #include "vbaformat.hxx"
20 #include <ooo/vba/excel/XFont.hpp>
21 #include <ooo/vba/excel/XStyle.hpp>
22 #include <ooo/vba/excel/XlVAlign.hpp>
23 #include <ooo/vba/excel/XlHAlign.hpp>
24 #include <ooo/vba/excel/XlOrientation.hpp>
25 #include <ooo/vba/excel/Constants.hpp>
26 #include <ooo/vba/excel/XRange.hpp>
27 #include <com/sun/star/table/CellVertJustify2.hpp>
28 #include <com/sun/star/table/CellHoriJustify.hpp>
29 #include <com/sun/star/table/CellOrientation.hpp>
30 #include <com/sun/star/table/XCellRange.hpp>
31 #include <com/sun/star/text/WritingMode.hpp>
32 #include <com/sun/star/util/CellProtection.hpp>
33 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
34 #include <com/sun/star/util/XNumberFormats.hpp>
35 #include <com/sun/star/util/XNumberFormatTypes.hpp>
36 #include <com/sun/star/frame/XModel.hpp>
37 
38 #include <basic/sberrors.hxx>
39 #include <rtl/math.hxx>
40 
41 #include "excelvbahelper.hxx"
42 #include "vbaborders.hxx"
43 #include "vbapalette.hxx"
44 #include "vbafont.hxx"
45 #include "vbainterior.hxx"
46 
47 #include <docsh.hxx>
48 #include <unonames.hxx>
49 #include <cellsuno.hxx>
50 #include <scitems.hxx>
51 #include <attrib.hxx>
52 
53 using namespace ::ooo::vba;
54 using namespace ::com::sun::star;
55 
56 #define FORMATSTRING "FormatString"
57 #define LOCALE "Locale"
58 
59 template< typename... Ifc >
ScVbaFormat(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<beans::XPropertySet> & _xPropertySet,const uno::Reference<frame::XModel> & xModel,bool bCheckAmbiguoity)60 ScVbaFormat< Ifc... >::ScVbaFormat( const uno::Reference< XHelperInterface >& xParent,
61                                     const uno::Reference< uno::XComponentContext > & xContext,
62                                     const uno::Reference< beans::XPropertySet >& _xPropertySet,
63                                     const uno::Reference< frame::XModel >& xModel,
64                                     bool bCheckAmbiguoity )
65     : ScVbaFormat_BASE( xParent, xContext ),
66       m_aDefaultLocale( "en", "US", OUString() ),
67       mxPropertySet( _xPropertySet ),
68       mxModel( xModel ),
69       mbCheckAmbiguoity( bCheckAmbiguoity ),
70       mbAddIndent( false )
71 {
72     try
73     {
74         if ( !mxModel.is() )
75             DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, u"XModel Interface could not be retrieved" );
76         // mxServiceInfo is unused,
77         // mxNumberFormatsSupplier is initialized when needed in initializeNumberFormats.
78     }
79     catch (const uno::Exception& )
80     {
81         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
82     }
83 }
84 
85 template< typename... Ifc >
86 void SAL_CALL
setVerticalAlignment(const uno::Any & _oAlignment)87 ScVbaFormat< Ifc... >::setVerticalAlignment( const uno::Any& _oAlignment)
88 {
89     try
90     {
91         uno::Any aVal;
92         sal_Int32 nAlignment = 0;
93         if ( !(_oAlignment >>= nAlignment ))
94             throw uno::RuntimeException();
95         switch (nAlignment)
96         {
97             case excel::XlVAlign::xlVAlignBottom :
98                 aVal <<= table::CellVertJustify2::BOTTOM;
99                 break;
100             case excel::XlVAlign::xlVAlignCenter :
101                 aVal <<= table::CellVertJustify2::CENTER;
102                 break;
103             case excel::XlVAlign::xlVAlignDistributed:
104             case excel::XlVAlign::xlVAlignJustify:
105                 aVal <<= table::CellVertJustify2::STANDARD;
106                 break;
107 
108             case excel::XlVAlign::xlVAlignTop:
109                 aVal <<= table::CellVertJustify2::TOP;
110                 break;
111             default:
112                 aVal <<= table::CellVertJustify2::STANDARD;
113                 break;
114         }
115         mxPropertySet->setPropertyValue( SC_UNONAME_CELLVJUS, aVal );
116     }
117     catch (const uno::Exception&)
118     {
119         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
120     }
121 }
122 
123 template< typename... Ifc >
124 uno::Any SAL_CALL
getVerticalAlignment()125 ScVbaFormat< Ifc... >::getVerticalAlignment(  )
126 {
127     uno::Any aResult = aNULL();
128     try
129     {
130         if (!isAmbiguous( SC_UNONAME_CELLVJUS ) )
131         {
132             sal_Int32 aAPIAlignment = table::CellVertJustify2::STANDARD;
133             mxPropertySet->getPropertyValue( SC_UNONAME_CELLVJUS ) >>= aAPIAlignment;
134             switch( aAPIAlignment )
135             {
136                 case table::CellVertJustify2::BOTTOM:
137                     aResult <<= excel::XlVAlign::xlVAlignBottom;
138                     break;
139                 case table::CellVertJustify2::CENTER:
140                     aResult <<= excel::XlVAlign::xlVAlignCenter;
141                     break;
142                 case table::CellVertJustify2::STANDARD:
143                     aResult <<= excel::XlVAlign::xlVAlignBottom;
144                     break;
145                 case table::CellVertJustify2::TOP:
146                     aResult <<= excel::XlVAlign::xlVAlignTop;
147                     break;
148                 default:
149                     break;
150             }
151         }
152     }
153     catch (const uno::Exception& )
154     {
155         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
156     }
157     return aResult;
158 }
159 
160 template< typename... Ifc >
161 void SAL_CALL
setHorizontalAlignment(const uno::Any & HorizontalAlignment)162 ScVbaFormat< Ifc... >::setHorizontalAlignment( const uno::Any& HorizontalAlignment )
163 {
164     try
165     {
166         uno::Any aVal;
167         sal_Int32 nAlignment = 0;
168         if ( !( HorizontalAlignment >>= nAlignment ) )
169             throw uno::RuntimeException();
170         switch ( nAlignment )
171         {
172             case excel::XlHAlign::xlHAlignJustify:
173                 aVal <<= table::CellHoriJustify_BLOCK;
174                 break;
175             case excel::XlHAlign::xlHAlignCenter:
176                 aVal <<= table::CellHoriJustify_CENTER;
177                 break;
178             case excel::XlHAlign::xlHAlignDistributed:
179                 aVal <<= table::CellHoriJustify_BLOCK;
180                 break;
181             case excel::XlHAlign::xlHAlignLeft:
182                 aVal <<= table::CellHoriJustify_LEFT;
183                 break;
184             case excel::XlHAlign::xlHAlignRight:
185                 aVal <<= table::CellHoriJustify_RIGHT;
186                 break;
187         }
188         // #FIXME what about the default case above?
189         // shouldn't need the test below
190         if ( aVal.hasValue() )
191             mxPropertySet->setPropertyValue( SC_UNONAME_CELLHJUS, aVal );
192     }
193     catch (const uno::Exception& )
194     {
195         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
196     }
197 
198 }
199 
200 template< typename... Ifc >
201 uno::Any SAL_CALL
getHorizontalAlignment()202 ScVbaFormat< Ifc... >::getHorizontalAlignment(  )
203 {
204     uno::Any NRetAlignment = aNULL();
205     try
206     {
207         OUString sHoriJust( SC_UNONAME_CELLHJUS );
208         if (!isAmbiguous(sHoriJust))
209         {
210             table::CellHoriJustify aAPIAlignment = table::CellHoriJustify_BLOCK;
211 
212             if ( mxPropertySet->getPropertyValue(sHoriJust) >>= aAPIAlignment )
213             {
214                 switch( aAPIAlignment )
215                 {
216                     case table::CellHoriJustify_BLOCK:
217                         NRetAlignment <<= excel::XlHAlign::xlHAlignJustify;
218                         break;
219                     case table::CellHoriJustify_CENTER:
220                         NRetAlignment <<= excel::XlHAlign::xlHAlignCenter;
221                         break;
222                     case table::CellHoriJustify_LEFT:
223                         NRetAlignment <<= excel::XlHAlign::xlHAlignLeft;
224                         break;
225                     case table::CellHoriJustify_RIGHT:
226                         NRetAlignment <<= excel::XlHAlign::xlHAlignRight;
227                         break;
228                      default: // handle those other cases with a NULL return
229                         break;
230                 }
231             }
232         }
233     }
234     catch (const uno::Exception& )
235     {
236         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
237     }
238     return NRetAlignment;
239 }
240 
241 template< typename... Ifc >
242 void SAL_CALL
setOrientation(const uno::Any & _aOrientation)243 ScVbaFormat< Ifc... >::setOrientation( const uno::Any& _aOrientation )
244 {
245     try
246     {
247         sal_Int32 nOrientation = 0;
248         if ( !( _aOrientation >>= nOrientation ) )
249             throw uno::RuntimeException();
250         uno::Any aVal;
251         switch( nOrientation )
252         {
253             case excel::XlOrientation::xlDownward:
254                 aVal <<= table::CellOrientation_TOPBOTTOM;
255                 break;
256             case excel::XlOrientation::xlHorizontal:
257                 aVal <<= table::CellOrientation_STANDARD;
258                 mxPropertySet->setPropertyValue( SC_UNONAME_ROTANG, uno::makeAny( sal_Int32(0) ) );
259                 break;
260             case excel::XlOrientation::xlUpward:
261                 aVal <<= table::CellOrientation_BOTTOMTOP;
262                 break;
263             case excel::XlOrientation::xlVertical:
264                 aVal <<= table::CellOrientation_STACKED;
265                 break;
266         }
267         // #FIXME what about the default case above?
268         // shouldn't need the test below
269         if ( aVal.hasValue() )
270             mxPropertySet->setPropertyValue( SC_UNONAME_CELLORI, aVal );
271 
272     }
273     catch (const uno::Exception& )
274     {
275         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
276     }
277 }
278 template< typename... Ifc >
279 uno::Any SAL_CALL
getOrientation()280 ScVbaFormat< Ifc... >::getOrientation(  )
281 {
282     uno::Any NRetOrientation = aNULL();
283     try
284     {
285         if (!isAmbiguous(SC_UNONAME_CELLORI))
286         {
287             table::CellOrientation aOrientation = table::CellOrientation_STANDARD;
288             if ( !(  mxPropertySet->getPropertyValue( SC_UNONAME_CELLORI ) >>= aOrientation ) )
289                 throw uno::RuntimeException();
290 
291             switch(aOrientation)
292             {
293                 case table::CellOrientation_STANDARD:
294                     NRetOrientation <<= excel::XlOrientation::xlHorizontal;
295                     break;
296                 case table::CellOrientation_BOTTOMTOP:
297                     NRetOrientation <<= excel::XlOrientation::xlUpward;
298                     break;
299                 case table::CellOrientation_TOPBOTTOM:
300                     NRetOrientation <<= excel::XlOrientation::xlDownward;
301                     break;
302                 case table::CellOrientation_STACKED:
303                     NRetOrientation <<= excel::XlOrientation::xlVertical;
304                     break;
305                 default:
306                     NRetOrientation <<= excel::XlOrientation::xlHorizontal;
307             }
308         }
309     }
310     catch (const uno::Exception& )
311     {
312         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
313     }
314     return NRetOrientation;
315 }
316 
317 template< typename... Ifc >
318 void SAL_CALL
setWrapText(const uno::Any & _aWrapText)319 ScVbaFormat< Ifc... >::setWrapText( const uno::Any& _aWrapText )
320 {
321     try
322     {
323         mxPropertySet->setPropertyValue( SC_UNONAME_WRAP, _aWrapText);
324     }
325     catch (const uno::Exception& )
326     {
327         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
328     }
329 }
330 
331 template< typename... Ifc >
332 uno::Any SAL_CALL
getWrapText()333 ScVbaFormat< Ifc... >::getWrapText(  )
334 {
335     uno::Any aWrap = aNULL();
336     try
337     {
338         OUString aPropName( SC_UNONAME_WRAP );
339         if (!isAmbiguous( aPropName ))
340         {
341             aWrap = mxPropertySet->getPropertyValue(aPropName);
342         }
343     }
344     catch (const uno::Exception&)
345     {
346         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
347     }
348     return aWrap;
349 }
350 
351 template< typename... Ifc >
352 uno::Any SAL_CALL
Borders(const uno::Any & Index)353 ScVbaFormat< Ifc... >::Borders( const uno::Any& Index )
354 {
355     ScVbaPalette aPalette( excel::getDocShell( mxModel ) );
356     uno::Reference< XCollection > xColl =  new ScVbaBorders( thisHelperIface(), ScVbaFormat_BASE::mxContext, uno::Reference< table::XCellRange >( mxPropertySet, uno::UNO_QUERY_THROW ), aPalette );
357 
358     if ( Index.hasValue() )
359     {
360         return xColl->Item( Index, uno::Any() );
361     }
362     return uno::makeAny( xColl );
363 }
364 
365 template< typename... Ifc >
366 uno::Reference< excel::XFont > SAL_CALL
Font()367 ScVbaFormat< Ifc... >::Font(  )
368 {
369     ScVbaPalette aPalette( excel::getDocShell( mxModel ) );
370     return new ScVbaFont( thisHelperIface(), ScVbaFormat_BASE::mxContext, aPalette, mxPropertySet );
371 }
372 
373 template< typename... Ifc >
374 uno::Reference< excel::XInterior > SAL_CALL
Interior()375 ScVbaFormat< Ifc... >::Interior(  )
376 {
377     return new ScVbaInterior( thisHelperIface(), ScVbaFormat_BASE::mxContext, mxPropertySet );
378 }
379 
380 template< typename... Ifc >
381 uno::Any SAL_CALL
getNumberFormatLocal()382 ScVbaFormat< Ifc... >::getNumberFormatLocal(  )
383 {
384     uno::Any aRet = uno::makeAny( OUString() );
385     try
386     {
387         OUString sPropName( SC_UNO_DP_NUMBERFO );
388         if (!isAmbiguous( sPropName ))
389         {
390 
391             initializeNumberFormats();
392 
393             sal_Int32 nFormat = 0;
394             if ( ! (mxPropertySet->getPropertyValue( sPropName ) >>= nFormat ) )
395                 throw uno::RuntimeException();
396 
397             OUString sFormat;
398             xNumberFormats->getByKey(nFormat)->getPropertyValue( FORMATSTRING ) >>= sFormat;
399             aRet <<= sFormat.toAsciiLowerCase();
400 
401         }
402     }
403     catch (const uno::Exception&)
404     {
405         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
406     }
407     return aRet;
408 
409 }
410 
411 template< typename... Ifc >
412 void SAL_CALL
setNumberFormatLocal(const uno::Any & _oLocalFormatString)413 ScVbaFormat< Ifc... >::setNumberFormatLocal( const uno::Any& _oLocalFormatString )
414 {
415     try
416     {
417         OUString sLocalFormatString;
418         sal_Int32 nFormat = -1;
419         OUString sNumFormat( SC_UNO_DP_NUMBERFO );
420         if ( !(_oLocalFormatString >>= sLocalFormatString )
421         || !( mxPropertySet->getPropertyValue(sNumFormat) >>= nFormat ) )
422             throw uno::RuntimeException();
423 
424         sLocalFormatString = sLocalFormatString.toAsciiUpperCase();
425         initializeNumberFormats();
426         lang::Locale aRangeLocale;
427         xNumberFormats->getByKey(nFormat)->getPropertyValue( LOCALE ) >>= aRangeLocale;
428         sal_Int32 nNewFormat = xNumberFormats->queryKey(sLocalFormatString, aRangeLocale, true);
429 
430         if (nNewFormat == -1)
431             nNewFormat = xNumberFormats->addNew(sLocalFormatString, aRangeLocale);
432         mxPropertySet->setPropertyValue(sNumFormat, uno::makeAny( nNewFormat ));
433     }
434     catch (const uno::Exception& )
435     {
436         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
437     }
438 }
439 
440 template< typename... Ifc >
441 void SAL_CALL
setNumberFormat(const uno::Any & _oFormatString)442 ScVbaFormat< Ifc... >::setNumberFormat( const uno::Any& _oFormatString )
443 {
444     try
445     {
446         OUString sFormatString;
447         if ( !( _oFormatString >>= sFormatString ) )
448             throw uno::RuntimeException();
449 
450         sFormatString = sFormatString.toAsciiUpperCase();
451 
452         lang::Locale aDefaultLocale = m_aDefaultLocale;
453         initializeNumberFormats();
454         sal_Int32 nFormat = xNumberFormats->queryKey(sFormatString, aDefaultLocale, true);
455 
456         if (nFormat == -1)
457             nFormat = xNumberFormats->addNew(sFormatString, aDefaultLocale);
458 
459         lang::Locale aRangeLocale;
460         xNumberFormats->getByKey(nFormat)->getPropertyValue( LOCALE ) >>= aRangeLocale;
461         sal_Int32 nNewFormat = xNumberFormatTypes->getFormatForLocale(nFormat, aRangeLocale);
462         mxPropertySet->setPropertyValue( SC_UNO_DP_NUMBERFO, uno::makeAny( nNewFormat));
463     }
464     catch (const uno::Exception& )
465     {
466         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
467     }
468 
469 }
470 
471 template< typename... Ifc >
472 void SAL_CALL
setIndentLevel(const uno::Any & _aLevel)473 ScVbaFormat< Ifc... >::setIndentLevel( const uno::Any& _aLevel )
474 {
475     try
476     {
477         sal_Int32 nLevel = 0;
478         if ( !(_aLevel >>= nLevel ) )
479             throw uno::RuntimeException();
480         table::CellHoriJustify aAPIAlignment = table::CellHoriJustify_STANDARD;
481 
482         OUString sHoriJust( SC_UNONAME_CELLHJUS );
483         if ( !( mxPropertySet->getPropertyValue(sHoriJust) >>= aAPIAlignment ) )
484             throw uno::RuntimeException();
485         if (aAPIAlignment == table::CellHoriJustify_STANDARD)
486             mxPropertySet->setPropertyValue( sHoriJust, uno::makeAny( table::CellHoriJustify_LEFT) ) ;
487         mxPropertySet->setPropertyValue( SC_UNONAME_PINDENT, uno::makeAny( sal_Int16(nLevel * 352.8) ) );
488     }
489     catch (const uno::Exception&)
490     {
491         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
492     }
493 }
494 
495 template< typename... Ifc >
496 uno::Any SAL_CALL
getIndentLevel()497 ScVbaFormat< Ifc... >::getIndentLevel(  )
498 {
499     uno::Any NRetIndentLevel = aNULL();
500     try
501     {
502         OUString sParaIndent( SC_UNONAME_PINDENT );
503         if (!isAmbiguous(sParaIndent))
504         {
505             sal_Int16 IndentLevel = 0;
506             if ( mxPropertySet->getPropertyValue(sParaIndent) >>= IndentLevel )
507                 NRetIndentLevel <<= sal_Int32( rtl::math::round(static_cast<double>( IndentLevel ) / 352.8));
508             else
509                 NRetIndentLevel <<= sal_Int32(0);
510         }
511     }
512     catch (const uno::Exception&)
513     {
514         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
515     }
516     return NRetIndentLevel;
517 }
518 
519 template< typename... Ifc >
520 void SAL_CALL
setLocked(const uno::Any & _aLocked)521 ScVbaFormat< Ifc... >::setLocked( const uno::Any& _aLocked )
522 {
523     try
524     {
525         bool bIsLocked = false;
526         if ( !( _aLocked >>= bIsLocked ) )
527             throw uno::RuntimeException();
528         util::CellProtection aCellProtection;
529         OUString sCellProt( SC_UNONAME_CELLPRO );
530         mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection;
531         aCellProtection.IsLocked = bIsLocked;
532         mxPropertySet->setPropertyValue(sCellProt, uno::makeAny( aCellProtection ) );
533     }
534     catch (const uno::Exception&)
535     {
536         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
537     }
538 }
539 
540 template< typename... Ifc >
541 void SAL_CALL
setFormulaHidden(const uno::Any & FormulaHidden)542 ScVbaFormat< Ifc... >::setFormulaHidden( const uno::Any& FormulaHidden )
543 {
544     try
545     {
546         bool bIsFormulaHidden = false;
547         FormulaHidden >>= bIsFormulaHidden;
548         util::CellProtection aCellProtection;
549         OUString sCellProt( SC_UNONAME_CELLPRO );
550         mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection;
551         aCellProtection.IsFormulaHidden = bIsFormulaHidden;
552         mxPropertySet->setPropertyValue(sCellProt,uno::makeAny(aCellProtection));
553     }
554     catch (const uno::Exception&)
555     {
556         DebugHelper::basicexception( ERRCODE_BASIC_METHOD_FAILED, {} );
557     }
558 }
559 
560 template< typename... Ifc >
561 uno::Any SAL_CALL
getLocked()562 ScVbaFormat< Ifc... >::getLocked(  )
563 {
564     uno::Any aCellProtection = aNULL();
565     try
566     {
567         OUString sCellProt( SC_UNONAME_CELLPRO );
568 
569         if (!isAmbiguous(sCellProt))
570         {
571             SfxItemSet* pDataSet = getCurrentDataSet();
572             if ( pDataSet )
573             {
574                 const ScProtectionAttr& rProtAttr = pDataSet->Get(ATTR_PROTECTION);
575                 SfxItemState eState = pDataSet->GetItemState(ATTR_PROTECTION);
576                 if(eState != SfxItemState::DONTCARE)
577                     aCellProtection <<= rProtAttr.GetProtection();
578             }
579             else // fallback to propertyset
580             {
581                 util::CellProtection cellProtection;
582                 mxPropertySet->getPropertyValue(sCellProt) >>= cellProtection;
583                 aCellProtection <<= cellProtection.IsLocked;
584             }
585         }
586     }
587     catch (const uno::Exception&)
588     {
589         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
590     }
591     return aCellProtection;
592 }
593 
594 template< typename... Ifc >
595 uno::Any SAL_CALL
getFormulaHidden()596 ScVbaFormat< Ifc... >::getFormulaHidden(  )
597 {
598     uno::Any aBoolRet = aNULL();
599     try
600     {
601         OUString sCellProt( SC_UNONAME_CELLPRO );
602         if (!isAmbiguous(sCellProt))
603         {
604             SfxItemSet* pDataSet = getCurrentDataSet();
605             if ( pDataSet )
606             {
607                 const ScProtectionAttr& rProtAttr = pDataSet->Get(ATTR_PROTECTION);
608                 SfxItemState eState = pDataSet->GetItemState(ATTR_PROTECTION);
609                 if(eState != SfxItemState::DONTCARE)
610                     aBoolRet <<= rProtAttr.GetHideFormula();
611             }
612             else
613             {
614                 util::CellProtection aCellProtection;
615                 mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection;
616                 aBoolRet <<= aCellProtection.IsFormulaHidden;
617             }
618         }
619     }
620     catch (const uno::Exception&)
621     {
622         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
623     }
624     return aBoolRet;
625 }
626 
627 template< typename... Ifc >
628 void SAL_CALL
setShrinkToFit(const uno::Any & ShrinkToFit)629 ScVbaFormat< Ifc... >::setShrinkToFit( const uno::Any& ShrinkToFit )
630 {
631     try
632     {
633         mxPropertySet->setPropertyValue( SC_UNONAME_SHRINK_TO_FIT, ShrinkToFit);
634     }
635     catch (const uno::Exception& )
636     {
637         DebugHelper::basicexception(ERRCODE_BASIC_NOT_IMPLEMENTED, {} );
638     }
639 
640 }
641 
642 template< typename... Ifc >
643 uno::Any SAL_CALL
getShrinkToFit()644 ScVbaFormat< Ifc... >::getShrinkToFit(  )
645 {
646     uno::Any aRet = aNULL();
647     try
648     {
649         OUString sShrinkToFit( SC_UNONAME_SHRINK_TO_FIT );
650         if (!isAmbiguous(sShrinkToFit))
651             aRet = mxPropertySet->getPropertyValue(sShrinkToFit);
652     }
653     catch (const uno::Exception& )
654     {
655         DebugHelper::basicexception(ERRCODE_BASIC_NOT_IMPLEMENTED, {});
656     }
657     return aRet;
658 }
659 
660 template< typename... Ifc >
661 void SAL_CALL
setReadingOrder(const uno::Any & ReadingOrder)662 ScVbaFormat< Ifc... >::setReadingOrder( const uno::Any& ReadingOrder )
663 {
664     try
665     {
666         sal_Int32 nReadingOrder = 0;
667         if ( !(ReadingOrder >>= nReadingOrder ))
668             throw uno::RuntimeException();
669         uno::Any aVal = aNULL();
670         switch(nReadingOrder)
671         {
672             case excel::Constants::xlLTR:
673                 aVal <<= sal_Int16(text::WritingMode_LR_TB);
674                 break;
675             case excel::Constants::xlRTL:
676                 aVal <<= sal_Int16(text::WritingMode_RL_TB);
677                 break;
678             case excel::Constants::xlContext:
679                 // TODO implement xlContext
680                 // Reading order has to depend on the language of the first letter
681                 // written.
682                 aVal <<= sal_Int16(text::WritingMode_LR_TB);
683                 break;
684             default:
685                 DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
686         }
687         mxPropertySet->setPropertyValue( SC_UNONAME_WRITING, aVal );
688     }
689     catch (const uno::Exception& )
690     {
691         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
692     }
693 
694 }
695 
696 template< typename... Ifc >
697 uno::Any SAL_CALL
getReadingOrder()698 ScVbaFormat< Ifc... >::getReadingOrder(  )
699 {
700     uno::Any NRetReadingOrder = aNULL();
701     try
702     {
703         OUString sWritingMode( SC_UNONAME_WRITING );
704         if (!isAmbiguous(sWritingMode))
705         {
706             text::WritingMode aWritingMode = text::WritingMode_LR_TB;
707             if ( ( mxPropertySet->getPropertyValue(sWritingMode) ) >>= aWritingMode )
708                 switch (aWritingMode)
709                 {
710                     case text::WritingMode_LR_TB:
711                         NRetReadingOrder <<= excel::Constants::xlLTR;
712                         break;
713                     case text::WritingMode_RL_TB:
714                         NRetReadingOrder <<= excel::Constants::xlRTL;
715                         break;
716                     default:
717                         NRetReadingOrder <<= excel::Constants::xlRTL;
718                 }
719         }
720     }
721     catch (const uno::Exception& )
722     {
723         DebugHelper::basicexception(ERRCODE_BASIC_NOT_IMPLEMENTED, {});
724     }
725     return NRetReadingOrder;
726 
727 }
728 
729 template< typename... Ifc >
730 uno::Any SAL_CALL
getNumberFormat()731 ScVbaFormat< Ifc... >::getNumberFormat(  )
732 {
733     uno::Any aFormat = aNULL();
734     try
735     {
736         sal_Int32 nFormat = -1;
737         OUString sNumFormat( SC_UNO_DP_NUMBERFO );
738         if (!isAmbiguous(sNumFormat) &&
739             ( mxPropertySet->getPropertyValue(sNumFormat) >>= nFormat) )
740         {
741             initializeNumberFormats();
742 
743             sal_Int32 nNewFormat = xNumberFormatTypes->getFormatForLocale(nFormat, m_aDefaultLocale );
744             OUString sFormat;
745             xNumberFormats->getByKey(nNewFormat)->getPropertyValue( FORMATSTRING ) >>= sFormat;
746             aFormat <<= sFormat;
747         }
748     }
749     catch (const uno::Exception& )
750     {
751         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
752     }
753     return aFormat;
754 }
755 
756 template< typename... Ifc >
757 bool
isAmbiguous(const OUString & _sPropertyName)758 ScVbaFormat< Ifc... >::isAmbiguous(const OUString& _sPropertyName)
759 {
760     bool bResult = false;
761     try
762     {
763         if (mbCheckAmbiguoity)
764             bResult = ( getXPropertyState()->getPropertyState(_sPropertyName) == beans::PropertyState_AMBIGUOUS_VALUE );
765     }
766     catch (const uno::Exception& )
767     {
768         DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
769     }
770     return bResult;
771 }
772 
773 template< typename... Ifc >
774 void
initializeNumberFormats()775 ScVbaFormat< Ifc... >::initializeNumberFormats()
776 {
777     if ( !xNumberFormats.is() )
778     {
779         mxNumberFormatsSupplier.set( mxModel, uno::UNO_QUERY_THROW );
780         xNumberFormats = mxNumberFormatsSupplier->getNumberFormats();
781         xNumberFormatTypes.set( xNumberFormats, uno::UNO_QUERY ); // _THROW?
782     }
783 }
784 
785 template< typename... Ifc >
786 uno::Reference< beans::XPropertyState > const &
getXPropertyState()787 ScVbaFormat< Ifc... >::getXPropertyState()
788 {
789     if ( !xPropertyState.is() )
790         xPropertyState.set( mxPropertySet, uno::UNO_QUERY_THROW );
791     return xPropertyState;
792 }
793 
794 template< typename... Ifc >
795 ScCellRangesBase*
getCellRangesBase()796 ScVbaFormat< Ifc... >::getCellRangesBase()
797 {
798     return comphelper::getUnoTunnelImplementation<ScCellRangesBase>( mxPropertySet );
799 }
800 
801 template< typename... Ifc >
802 SfxItemSet*
getCurrentDataSet()803 ScVbaFormat< Ifc... >::getCurrentDataSet()
804 {
805     SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( getCellRangesBase() );
806     if ( !pDataSet )
807         throw uno::RuntimeException("Can't access Itemset for XPropertySet" );
808     return pDataSet;
809 }
810 
811 template class ScVbaFormat< excel::XStyle >;
812 template class ScVbaFormat< excel::XRange >;
813 
814 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
815