xref: /trunk/main/sc/source/ui/unoobj/afmtuno.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 
33 #include "scitems.hxx"
34 #include <editeng/memberids.hrc>
35 #include <tools/debug.hxx>
36 #include <tools/shl.hxx>
37 #include <svl/poolitem.hxx>
38 #include <svx/unomid.hxx>
39 #include "unowids.hxx"
40 #include <rtl/uuid.h>
41 #include <com/sun/star/table/BorderLine.hpp>
42 #include <com/sun/star/table/CellVertJustify.hpp>
43 #include <com/sun/star/table/ShadowLocation.hpp>
44 #include <com/sun/star/table/TableBorder.hpp>
45 #include <com/sun/star/table/ShadowFormat.hpp>
46 #include <com/sun/star/table/CellRangeAddress.hpp>
47 #include <com/sun/star/table/CellContentType.hpp>
48 #include <com/sun/star/table/TableOrientation.hpp>
49 #include <com/sun/star/table/CellHoriJustify.hpp>
50 #include <com/sun/star/util/SortField.hpp>
51 #include <com/sun/star/util/SortFieldType.hpp>
52 #include <com/sun/star/table/CellOrientation.hpp>
53 #include <com/sun/star/table/CellAddress.hpp>
54 #include <com/sun/star/awt/SimpleFontMetric.hpp>
55 #include <com/sun/star/awt/FontWeight.hpp>
56 #include <com/sun/star/awt/FontSlant.hpp>
57 #include <com/sun/star/awt/CharSet.hpp>
58 #include <com/sun/star/awt/FontDescriptor.hpp>
59 #include <com/sun/star/awt/FontWidth.hpp>
60 #include <com/sun/star/awt/XFont.hpp>
61 #include <com/sun/star/awt/FontType.hpp>
62 #include <com/sun/star/awt/FontUnderline.hpp>
63 #include <com/sun/star/awt/FontStrikeout.hpp>
64 #include <com/sun/star/awt/FontFamily.hpp>
65 #include <com/sun/star/awt/FontPitch.hpp>
66 
67 #include "afmtuno.hxx"
68 #include "miscuno.hxx"
69 #include "autoform.hxx"
70 #include "unoguard.hxx"
71 #include "scdll.hxx"
72 #include "unonames.hxx"
73 #include "cellsuno.hxx"
74 
75 using namespace ::com::sun::star;
76 
77 //------------------------------------------------------------------------
78 
79 //  ein AutoFormat hat immer 16 Eintraege
80 #define SC_AF_FIELD_COUNT 16
81 
82 //------------------------------------------------------------------------
83 
84 //  AutoFormat-Map nur fuer PropertySetInfo, ohne Which-IDs
85 
86 const SfxItemPropertyMapEntry* lcl_GetAutoFormatMap()
87 {
88     static SfxItemPropertyMapEntry aAutoFormatMap_Impl[] =
89     {
90         {MAP_CHAR_LEN(SC_UNONAME_INCBACK),  0,  &::getBooleanCppuType(),    0, 0 },
91         {MAP_CHAR_LEN(SC_UNONAME_INCBORD),  0,  &::getBooleanCppuType(),    0, 0 },
92         {MAP_CHAR_LEN(SC_UNONAME_INCFONT),  0,  &::getBooleanCppuType(),    0, 0 },
93         {MAP_CHAR_LEN(SC_UNONAME_INCJUST),  0,  &::getBooleanCppuType(),    0, 0 },
94         {MAP_CHAR_LEN(SC_UNONAME_INCNUM),   0,  &::getBooleanCppuType(),    0, 0 },
95         {MAP_CHAR_LEN(SC_UNONAME_INCWIDTH), 0,  &::getBooleanCppuType(),    0, 0 },
96         {0,0,0,0,0,0}
97     };
98     return aAutoFormatMap_Impl;
99 }
100 
101 //! Zahlformat (String/Language) ??? (in XNumberFormat nur ReadOnly)
102 //! table::TableBorder ??!?
103 
104 const SfxItemPropertyMapEntry* lcl_GetAutoFieldMap()
105 {
106     static SfxItemPropertyMapEntry aAutoFieldMap_Impl[] =
107     {
108         {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND,        &::getCppuType((const sal_Int32*)0),        0, MID_BACK_COLOR },
109         {MAP_CHAR_LEN(SC_UNONAME_CCOLOR),   ATTR_FONT_COLOR,        &::getCppuType((const sal_Int32*)0),        0, 0 },
110         {MAP_CHAR_LEN(SC_UNONAME_COUTL),    ATTR_FONT_CONTOUR,      &::getBooleanCppuType(),                    0, 0 },
111         {MAP_CHAR_LEN(SC_UNONAME_CCROSS),   ATTR_FONT_CROSSEDOUT,   &::getBooleanCppuType(),                    0, MID_CROSSED_OUT },
112         {MAP_CHAR_LEN(SC_UNONAME_CFONT),    ATTR_FONT,              &::getCppuType((const sal_Int16*)0),        0, MID_FONT_FAMILY },
113         {MAP_CHAR_LEN(SC_UNONAME_CFCHARS),  ATTR_FONT,              &::getCppuType((sal_Int16*)0),              0, MID_FONT_CHAR_SET },
114         {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS),  ATTR_CJK_FONT,          &::getCppuType((sal_Int16*)0),              0, MID_FONT_CHAR_SET },
115         {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS),  ATTR_CTL_FONT,          &::getCppuType((sal_Int16*)0),              0, MID_FONT_CHAR_SET },
116         {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL),  ATTR_FONT,              &::getCppuType((sal_Int16*)0),              0, MID_FONT_FAMILY },
117         {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL),  ATTR_CJK_FONT,          &::getCppuType((sal_Int16*)0),              0, MID_FONT_FAMILY },
118         {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL),  ATTR_CTL_FONT,          &::getCppuType((sal_Int16*)0),              0, MID_FONT_FAMILY },
119         {MAP_CHAR_LEN(SC_UNONAME_CFNAME),   ATTR_FONT,              &::getCppuType((rtl::OUString*)0),          0, MID_FONT_FAMILY_NAME },
120         {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME),   ATTR_CJK_FONT,          &::getCppuType((rtl::OUString*)0),          0, MID_FONT_FAMILY_NAME },
121         {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME),   ATTR_CTL_FONT,          &::getCppuType((rtl::OUString*)0),          0, MID_FONT_FAMILY_NAME },
122         {MAP_CHAR_LEN(SC_UNONAME_CFPITCH),  ATTR_FONT,              &::getCppuType((sal_Int16*)0),              0, MID_FONT_PITCH },
123         {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH),  ATTR_CJK_FONT,          &::getCppuType((sal_Int16*)0),              0, MID_FONT_PITCH },
124         {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH),  ATTR_CTL_FONT,          &::getCppuType((sal_Int16*)0),              0, MID_FONT_PITCH },
125         {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE),  ATTR_FONT,              &::getCppuType((rtl::OUString*)0),          0, MID_FONT_STYLE_NAME },
126         {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE),  ATTR_CJK_FONT,          &::getCppuType((rtl::OUString*)0),          0, MID_FONT_STYLE_NAME },
127         {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE),  ATTR_CTL_FONT,          &::getCppuType((rtl::OUString*)0),          0, MID_FONT_STYLE_NAME },
128         {MAP_CHAR_LEN(SC_UNONAME_CHEIGHT),  ATTR_FONT_HEIGHT,       &::getCppuType((float*)0),                  0, MID_FONTHEIGHT | CONVERT_TWIPS },
129         {MAP_CHAR_LEN(SC_UNO_CJK_CHEIGHT),  ATTR_CJK_FONT_HEIGHT,   &::getCppuType((float*)0),                  0, MID_FONTHEIGHT | CONVERT_TWIPS },
130         {MAP_CHAR_LEN(SC_UNO_CTL_CHEIGHT),  ATTR_CTL_FONT_HEIGHT,   &::getCppuType((float*)0),                  0, MID_FONTHEIGHT | CONVERT_TWIPS },
131         {MAP_CHAR_LEN(SC_UNONAME_COVER),    ATTR_FONT_OVERLINE,     &::getCppuType((const sal_Int16*)0),        0, MID_TL_STYLE },
132         {MAP_CHAR_LEN(SC_UNONAME_CPOST),    ATTR_FONT_POSTURE,      &::getCppuType((awt::FontSlant*)0),         0, MID_POSTURE },
133         {MAP_CHAR_LEN(SC_UNO_CJK_CPOST),    ATTR_CJK_FONT_POSTURE,  &::getCppuType((awt::FontSlant*)0),         0, MID_POSTURE },
134         {MAP_CHAR_LEN(SC_UNO_CTL_CPOST),    ATTR_CTL_FONT_POSTURE,  &::getCppuType((awt::FontSlant*)0),         0, MID_POSTURE },
135         {MAP_CHAR_LEN(SC_UNONAME_CSHADD),   ATTR_FONT_SHADOWED,     &::getBooleanCppuType(),                    0, 0 },
136         {MAP_CHAR_LEN(SC_UNONAME_TBLBORD),  SC_WID_UNO_TBLBORD,     &::getCppuType((table::TableBorder*)0),     0, 0 | CONVERT_TWIPS },
137         {MAP_CHAR_LEN(SC_UNONAME_CUNDER),   ATTR_FONT_UNDERLINE,    &::getCppuType((const sal_Int16*)0),        0, MID_TL_STYLE },
138         {MAP_CHAR_LEN(SC_UNONAME_CWEIGHT),  ATTR_FONT_WEIGHT,       &::getCppuType((float*)0),                  0, MID_WEIGHT },
139         {MAP_CHAR_LEN(SC_UNO_CJK_CWEIGHT),  ATTR_CJK_FONT_WEIGHT,   &::getCppuType((float*)0),                  0, MID_WEIGHT },
140         {MAP_CHAR_LEN(SC_UNO_CTL_CWEIGHT),  ATTR_CTL_FONT_WEIGHT,   &::getCppuType((float*)0),                  0, MID_WEIGHT },
141         {MAP_CHAR_LEN(SC_UNONAME_CELLHJUS), ATTR_HOR_JUSTIFY,       &::getCppuType((const table::CellHoriJustify*)0),   0, 0 },
142         {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND,        &::getBooleanCppuType(),                    0, MID_GRAPHIC_TRANSPARENT },
143         {MAP_CHAR_LEN(SC_UNONAME_WRAP),     ATTR_LINEBREAK,         &::getBooleanCppuType(),                    0, 0 },
144         {MAP_CHAR_LEN(SC_UNONAME_CELLORI),  ATTR_STACKED,           &::getCppuType((const table::CellOrientation*)0),   0, 0 },
145         {MAP_CHAR_LEN(SC_UNONAME_PBMARGIN), ATTR_MARGIN,            &::getCppuType((const sal_Int32*)0),        0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
146         {MAP_CHAR_LEN(SC_UNONAME_PLMARGIN), ATTR_MARGIN,            &::getCppuType((const sal_Int32*)0),        0, MID_MARGIN_L_MARGIN  | CONVERT_TWIPS },
147         {MAP_CHAR_LEN(SC_UNONAME_PRMARGIN), ATTR_MARGIN,            &::getCppuType((const sal_Int32*)0),        0, MID_MARGIN_R_MARGIN  | CONVERT_TWIPS },
148         {MAP_CHAR_LEN(SC_UNONAME_PTMARGIN), ATTR_MARGIN,            &::getCppuType((const sal_Int32*)0),        0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
149         {MAP_CHAR_LEN(SC_UNONAME_ROTANG),   ATTR_ROTATE_VALUE,      &::getCppuType((const sal_Int32*)0),        0, 0 },
150         {MAP_CHAR_LEN(SC_UNONAME_ROTREF),   ATTR_ROTATE_MODE,       &::getCppuType((const table::CellVertJustify*)0),   0, 0 },
151         {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY,       &::getCppuType((const table::CellVertJustify*)0),   0, 0 },
152         {0,0,0,0,0,0}
153     };
154     return aAutoFieldMap_Impl;
155 }
156 
157 //------------------------------------------------------------------------
158 
159 #define SCAUTOFORMATSOBJ_SERVICE    "com.sun.star.sheet.TableAutoFormats"
160 
161 SC_SIMPLE_SERVICE_INFO( ScAutoFormatFieldObj, "ScAutoFormatFieldObj", "com.sun.star.sheet.TableAutoFormatField" )
162 SC_SIMPLE_SERVICE_INFO( ScAutoFormatObj, "ScAutoFormatObj", "com.sun.star.sheet.TableAutoFormat" )
163 SC_SIMPLE_SERVICE_INFO( ScAutoFormatsObj, "ScAutoFormatsObj", SCAUTOFORMATSOBJ_SERVICE )
164 
165 //------------------------------------------------------------------------
166 
167 sal_Bool lcl_FindAutoFormatIndex( const ScAutoFormat& rFormats, const String& rName, sal_uInt16& rOutIndex )
168 {
169     String aEntryName;
170     sal_uInt16 nCount = rFormats.GetCount();
171     for( sal_uInt16 nPos=0; nPos<nCount; nPos++ )
172     {
173         ScAutoFormatData* pEntry = rFormats[nPos];
174         pEntry->GetName( aEntryName );
175         if ( aEntryName == rName )
176         {
177             rOutIndex = nPos;
178             return sal_True;
179         }
180     }
181     return sal_False;       // is nich
182 }
183 
184 //------------------------------------------------------------------------
185 
186 ScAutoFormatsObj::ScAutoFormatsObj()
187 {
188     //! Dieses Objekt darf es nur einmal geben, und es muss an den Auto-Format-Daten
189     //! bekannt sein, damit Aenderungen gebroadcasted werden koennen
190 }
191 
192 ScAutoFormatsObj::~ScAutoFormatsObj()
193 {
194 }
195 
196 // stuff for exService_...
197 
198 uno::Reference<uno::XInterface> SAL_CALL ScAutoFormatsObj_CreateInstance(
199                         const uno::Reference<lang::XMultiServiceFactory>& )
200 {
201     ScUnoGuard aGuard;
202     ScDLL::Init();
203     static uno::Reference< uno::XInterface > xInst((::cppu::OWeakObject*) new ScAutoFormatsObj);
204     return xInst;
205 }
206 
207 rtl::OUString ScAutoFormatsObj::getImplementationName_Static()
208 {
209     return rtl::OUString::createFromAscii( "stardiv.StarCalc.ScAutoFormatsObj" );
210 }
211 
212 uno::Sequence<rtl::OUString> ScAutoFormatsObj::getSupportedServiceNames_Static()
213 {
214     uno::Sequence<rtl::OUString> aRet(1);
215     rtl::OUString* pArray = aRet.getArray();
216     pArray[0] = rtl::OUString::createFromAscii( SCAUTOFORMATSOBJ_SERVICE );
217     return aRet;
218 }
219 
220 // XTableAutoFormats
221 
222 ScAutoFormatObj* ScAutoFormatsObj::GetObjectByIndex_Impl(sal_uInt16 nIndex)
223 {
224     ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
225     if (pFormats && nIndex < pFormats->GetCount())
226         return new ScAutoFormatObj(nIndex);
227 
228     return NULL;    // falscher Index
229 }
230 
231 ScAutoFormatObj* ScAutoFormatsObj::GetObjectByName_Impl(const rtl::OUString& aName)
232 {
233     ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
234     if (pFormats)
235     {
236         String aString(aName);
237         sal_uInt16 nIndex;
238         if (lcl_FindAutoFormatIndex( *pFormats, aString, nIndex ))
239             return GetObjectByIndex_Impl(nIndex);
240     }
241     return NULL;
242 }
243 
244 // container::XNameContainer
245 
246 void SAL_CALL ScAutoFormatsObj::insertByName( const rtl::OUString& aName, const uno::Any& aElement )
247                             throw(lang::IllegalArgumentException, container::ElementExistException,
248                                     lang::WrappedTargetException, uno::RuntimeException)
249 {
250     ScUnoGuard aGuard;
251     sal_Bool bDone = sal_False;
252     //  Reflection muss nicht uno::XInterface sein, kann auch irgendein Interface sein...
253     uno::Reference< uno::XInterface > xInterface(aElement, uno::UNO_QUERY);
254     if ( xInterface.is() )
255     {
256         ScAutoFormatObj* pFormatObj = ScAutoFormatObj::getImplementation( xInterface );
257         if ( pFormatObj && !pFormatObj->IsInserted() )  // noch nicht eingefuegt?
258         {
259             String aNameStr(aName);
260             ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
261 
262             sal_uInt16 nDummy;
263             if (pFormats && !lcl_FindAutoFormatIndex( *pFormats, aNameStr, nDummy ))
264             {
265                 ScAutoFormatData* pNew = new ScAutoFormatData();
266                 pNew->SetName( aNameStr );
267 
268                 if (pFormats->Insert( pNew ))
269                 {
270                     //! Notify fuer andere Objekte
271                     pFormats->Save();   // sofort speichern
272 
273                     sal_uInt16 nNewIndex;
274                     if (lcl_FindAutoFormatIndex( *pFormats, aNameStr, nNewIndex ))
275                     {
276                         pFormatObj->InitFormat( nNewIndex );    // kann jetzt benutzt werden
277                         bDone = sal_True;
278                     }
279                 }
280                 else
281                 {
282                     delete pNew;
283                     DBG_ERROR("AutoFormat konnte nicht eingefuegt werden");
284                     throw uno::RuntimeException();
285                 }
286             }
287             else
288             {
289                 throw container::ElementExistException();
290             }
291         }
292     }
293 
294     if (!bDone)
295     {
296         //  other errors are handled above
297         throw lang::IllegalArgumentException();
298     }
299 }
300 
301 void SAL_CALL ScAutoFormatsObj::replaceByName( const rtl::OUString& aName, const uno::Any& aElement )
302                             throw(lang::IllegalArgumentException, container::NoSuchElementException,
303                                     lang::WrappedTargetException, uno::RuntimeException)
304 {
305     ScUnoGuard aGuard;
306     //! zusammenfassen?
307     removeByName( aName );
308     insertByName( aName, aElement );
309 }
310 
311 void SAL_CALL ScAutoFormatsObj::removeByName( const rtl::OUString& aName )
312                                 throw(container::NoSuchElementException,
313                                     lang::WrappedTargetException, uno::RuntimeException)
314 {
315     ScUnoGuard aGuard;
316     String aNameStr(aName);
317     ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
318 
319     sal_uInt16 nIndex;
320     if (pFormats && lcl_FindAutoFormatIndex( *pFormats, aNameStr, nIndex ))
321     {
322         pFormats->AtFree( nIndex );
323 
324         //! Notify fuer andere Objekte
325         pFormats->Save();   // sofort speichern
326     }
327     else
328     {
329         throw container::NoSuchElementException();
330     }
331 }
332 
333 // container::XEnumerationAccess
334 
335 uno::Reference<container::XEnumeration> SAL_CALL ScAutoFormatsObj::createEnumeration()
336                                                     throw(uno::RuntimeException)
337 {
338     ScUnoGuard aGuard;
339     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.TableAutoFormatEnumeration")));
340 }
341 
342 // container::XIndexAccess
343 
344 sal_Int32 SAL_CALL ScAutoFormatsObj::getCount() throw(uno::RuntimeException)
345 {
346     ScUnoGuard aGuard;
347     ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
348     if (pFormats)
349         return pFormats->GetCount();
350 
351     return 0;
352 }
353 
354 uno::Any SAL_CALL ScAutoFormatsObj::getByIndex( sal_Int32 nIndex )
355                             throw(lang::IndexOutOfBoundsException,
356                                     lang::WrappedTargetException, uno::RuntimeException)
357 {
358     ScUnoGuard aGuard;
359     uno::Reference< container::XNamed >  xFormat(GetObjectByIndex_Impl((sal_uInt16)nIndex));
360     if (!xFormat.is())
361         throw lang::IndexOutOfBoundsException();
362     return uno::makeAny(xFormat);
363 }
364 
365 uno::Type SAL_CALL ScAutoFormatsObj::getElementType() throw(uno::RuntimeException)
366 {
367     ScUnoGuard aGuard;
368     return ::getCppuType((const uno::Reference< container::XNamed >*)0);    // muss zu getByIndex passen
369 }
370 
371 sal_Bool SAL_CALL ScAutoFormatsObj::hasElements() throw(uno::RuntimeException)
372 {
373     ScUnoGuard aGuard;
374     return ( getCount() != 0 );
375 }
376 
377 // container::XNameAccess
378 
379 uno::Any SAL_CALL ScAutoFormatsObj::getByName( const rtl::OUString& aName )
380             throw(container::NoSuchElementException,
381                     lang::WrappedTargetException, uno::RuntimeException)
382 {
383     ScUnoGuard aGuard;
384     uno::Reference< container::XNamed >  xFormat(GetObjectByName_Impl(aName));
385     if (!xFormat.is())
386         throw container::NoSuchElementException();
387     return uno::makeAny(xFormat);
388 }
389 
390 uno::Sequence<rtl::OUString> SAL_CALL ScAutoFormatsObj::getElementNames()
391                                                 throw(uno::RuntimeException)
392 {
393     ScUnoGuard aGuard;
394     ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
395     if (pFormats)
396     {
397         String aName;
398         sal_uInt16 nCount = pFormats->GetCount();
399         uno::Sequence<rtl::OUString> aSeq(nCount);
400         rtl::OUString* pAry = aSeq.getArray();
401         for (sal_uInt16 i=0; i<nCount; i++)
402         {
403             (*pFormats)[i]->GetName(aName);
404             pAry[i] = aName;
405         }
406         return aSeq;
407     }
408     return uno::Sequence<rtl::OUString>(0);
409 }
410 
411 sal_Bool SAL_CALL ScAutoFormatsObj::hasByName( const rtl::OUString& aName )
412                                         throw(uno::RuntimeException)
413 {
414     ScUnoGuard aGuard;
415     ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
416     if (pFormats)
417     {
418         String aString(aName);
419         sal_uInt16 nDummy;
420         return lcl_FindAutoFormatIndex( *pFormats, aString, nDummy );
421     }
422     return sal_False;
423 }
424 
425 //------------------------------------------------------------------------
426 
427 ScAutoFormatObj::ScAutoFormatObj(sal_uInt16 nIndex) :
428     aPropSet( lcl_GetAutoFormatMap() ),
429     nFormatIndex( nIndex )
430 {
431     //! Listening !!!
432 }
433 
434 ScAutoFormatObj::~ScAutoFormatObj()
435 {
436     //  Wenn ein AutoFormat-Objekt losgelassen wird, werden eventuelle Aenderungen
437     //  gespeichert, damit sie z.B. im Writer sichtbar sind
438 
439     if (IsInserted())
440     {
441         ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
442         if ( pFormats && pFormats->IsSaveLater() )
443             pFormats->Save();
444 
445         // Save() setzt SaveLater Flag zurueck
446     }
447 }
448 
449 void ScAutoFormatObj::InitFormat( sal_uInt16 nNewIndex )
450 {
451     DBG_ASSERT( nFormatIndex == SC_AFMTOBJ_INVALID, "ScAutoFormatObj::InitFormat mehrfach" );
452     nFormatIndex = nNewIndex;
453     //! Listening !!!
454 }
455 
456 // XUnoTunnel
457 
458 sal_Int64 SAL_CALL ScAutoFormatObj::getSomething(
459                 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
460 {
461     if ( rId.getLength() == 16 &&
462           0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
463                                     rId.getConstArray(), 16 ) )
464     {
465         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
466     }
467     return 0;
468 }
469 
470 // static
471 const uno::Sequence<sal_Int8>& ScAutoFormatObj::getUnoTunnelId()
472 {
473     static uno::Sequence<sal_Int8> * pSeq = 0;
474     if( !pSeq )
475     {
476         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
477         if( !pSeq )
478         {
479             static uno::Sequence< sal_Int8 > aSeq( 16 );
480             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
481             pSeq = &aSeq;
482         }
483     }
484     return *pSeq;
485 }
486 
487 // static
488 ScAutoFormatObj* ScAutoFormatObj::getImplementation(
489                         const uno::Reference<uno::XInterface> xObj )
490 {
491     ScAutoFormatObj* pRet = NULL;
492     uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
493     if (xUT.is())
494         pRet = reinterpret_cast<ScAutoFormatObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
495     return pRet;
496 }
497 
498 void ScAutoFormatObj::Notify( SfxBroadcaster& /* rBC */, const SfxHint& /* rHint */ )
499 {
500     //  spaeter...
501 }
502 
503 // XTableAutoFormat
504 
505 ScAutoFormatFieldObj* ScAutoFormatObj::GetObjectByIndex_Impl(sal_uInt16 nIndex)
506 {
507     if ( IsInserted() && nIndex < SC_AF_FIELD_COUNT )
508         return new ScAutoFormatFieldObj( nFormatIndex, nIndex );
509 
510     return NULL;
511 }
512 
513 // container::XEnumerationAccess
514 
515 uno::Reference<container::XEnumeration> SAL_CALL ScAutoFormatObj::createEnumeration()
516                                                     throw(uno::RuntimeException)
517 {
518     ScUnoGuard aGuard;
519     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.TableAutoFormatEnumeration")));
520 }
521 
522 // container::XIndexAccess
523 
524 sal_Int32 SAL_CALL ScAutoFormatObj::getCount() throw(uno::RuntimeException)
525 {
526     ScUnoGuard aGuard;
527     if (IsInserted())
528         return SC_AF_FIELD_COUNT;   // immer 16 Elemente
529     else
530         return 0;
531 }
532 
533 uno::Any SAL_CALL ScAutoFormatObj::getByIndex( sal_Int32 nIndex )
534                             throw(lang::IndexOutOfBoundsException,
535                                     lang::WrappedTargetException, uno::RuntimeException)
536 {
537     ScUnoGuard aGuard;
538 
539     if ( nIndex < 0 || nIndex >= getCount() )
540         throw lang::IndexOutOfBoundsException();
541 
542     if (IsInserted())
543         return uno::makeAny(uno::Reference< beans::XPropertySet >(GetObjectByIndex_Impl((sal_uInt16)nIndex)));
544     return uno::Any();
545 }
546 
547 uno::Type SAL_CALL ScAutoFormatObj::getElementType() throw(uno::RuntimeException)
548 {
549     ScUnoGuard aGuard;
550     return ::getCppuType((const uno::Reference< beans::XPropertySet >*)0);  // muss zu getByIndex passen
551 }
552 
553 sal_Bool SAL_CALL ScAutoFormatObj::hasElements() throw(uno::RuntimeException)
554 {
555     ScUnoGuard aGuard;
556     return ( getCount() != 0 );
557 }
558 
559 // container::XNamed
560 
561 rtl::OUString SAL_CALL ScAutoFormatObj::getName() throw(uno::RuntimeException)
562 {
563     ScUnoGuard aGuard;
564     ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
565     if (pFormats && IsInserted() && nFormatIndex < pFormats->GetCount())
566     {
567         String aName;
568         (*pFormats)[nFormatIndex]->GetName(aName);
569         return aName;
570     }
571     return rtl::OUString();
572 }
573 
574 void SAL_CALL ScAutoFormatObj::setName( const rtl::OUString& aNewName )
575                                                 throw(uno::RuntimeException)
576 {
577     ScUnoGuard aGuard;
578     String aNewString(aNewName);
579     ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
580 
581     sal_uInt16 nDummy;
582     if (pFormats && IsInserted() && nFormatIndex < pFormats->GetCount() &&
583             !lcl_FindAutoFormatIndex( *pFormats, aNewString, nDummy ))
584     {
585         ScAutoFormatData* pData = (*pFormats)[nFormatIndex];
586         DBG_ASSERT(pData,"AutoFormat Daten nicht da");
587 
588         ScAutoFormatData* pNew = new ScAutoFormatData(*pData);
589         pNew->SetName( aNewString );
590 
591         pFormats->AtFree( nFormatIndex );
592         if (pFormats->Insert( pNew ))
593         {
594             nFormatIndex = pFormats->IndexOf( pNew );   // ist evtl. anders einsortiert...
595 
596             //! Notify fuer andere Objekte
597             pFormats->SetSaveLater(sal_True);
598         }
599         else
600         {
601             delete pNew;
602             DBG_ERROR("AutoFormat konnte nicht eingefuegt werden");
603             nFormatIndex = 0;       //! alter Index ist ungueltig
604         }
605     }
606     else
607     {
608         //  not inserted or name exists
609         throw uno::RuntimeException();
610     }
611 }
612 
613 // beans::XPropertySet
614 
615 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAutoFormatObj::getPropertySetInfo()
616                                                         throw(uno::RuntimeException)
617 {
618     ScUnoGuard aGuard;
619     static uno::Reference< beans::XPropertySetInfo > aRef(new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
620     return aRef;
621 }
622 
623 void SAL_CALL ScAutoFormatObj::setPropertyValue(
624                         const rtl::OUString& aPropertyName, const uno::Any& aValue )
625                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
626                         lang::IllegalArgumentException, lang::WrappedTargetException,
627                         uno::RuntimeException)
628 {
629     ScUnoGuard aGuard;
630     ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
631     if (pFormats && IsInserted() && nFormatIndex < pFormats->GetCount())
632     {
633         ScAutoFormatData* pData = (*pFormats)[nFormatIndex];
634         DBG_ASSERT(pData,"AutoFormat Daten nicht da");
635 
636         String aPropString(aPropertyName);
637         sal_Bool bBool = sal_Bool();
638         if (aPropString.EqualsAscii( SC_UNONAME_INCBACK ) && (aValue >>= bBool))
639             pData->SetIncludeBackground( bBool );
640         else if (aPropString.EqualsAscii( SC_UNONAME_INCBORD ) && (aValue >>= bBool))
641             pData->SetIncludeFrame( bBool );
642         else if (aPropString.EqualsAscii( SC_UNONAME_INCFONT ) && (aValue >>= bBool))
643             pData->SetIncludeFont( bBool );
644         else if (aPropString.EqualsAscii( SC_UNONAME_INCJUST ) && (aValue >>= bBool))
645             pData->SetIncludeJustify( bBool );
646         else if (aPropString.EqualsAscii( SC_UNONAME_INCNUM ) && (aValue >>= bBool))
647             pData->SetIncludeValueFormat( bBool );
648         else if (aPropString.EqualsAscii( SC_UNONAME_INCWIDTH ) && (aValue >>= bBool))
649             pData->SetIncludeWidthHeight( bBool );
650 
651         // else Fehler
652 
653         //! Notify fuer andere Objekte
654         pFormats->SetSaveLater(sal_True);
655     }
656 }
657 
658 uno::Any SAL_CALL ScAutoFormatObj::getPropertyValue( const rtl::OUString& aPropertyName )
659                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
660                         uno::RuntimeException)
661 {
662     ScUnoGuard aGuard;
663     uno::Any aAny;
664 
665     ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
666     if (pFormats && IsInserted() && nFormatIndex < pFormats->GetCount())
667     {
668         ScAutoFormatData* pData = (*pFormats)[nFormatIndex];
669         DBG_ASSERT(pData,"AutoFormat Daten nicht da");
670 
671         sal_Bool bValue;
672         sal_Bool bError = sal_False;
673 
674         String aPropString(aPropertyName);
675         if (aPropString.EqualsAscii( SC_UNONAME_INCBACK ))
676             bValue = pData->GetIncludeBackground();
677         else if (aPropString.EqualsAscii( SC_UNONAME_INCBORD ))
678             bValue = pData->GetIncludeFrame();
679         else if (aPropString.EqualsAscii( SC_UNONAME_INCFONT ))
680             bValue = pData->GetIncludeFont();
681         else if (aPropString.EqualsAscii( SC_UNONAME_INCJUST ))
682             bValue = pData->GetIncludeJustify();
683         else if (aPropString.EqualsAscii( SC_UNONAME_INCNUM ))
684             bValue = pData->GetIncludeValueFormat();
685         else if (aPropString.EqualsAscii( SC_UNONAME_INCWIDTH ))
686             bValue = pData->GetIncludeWidthHeight();
687         else
688             bError = sal_True;      // unbekannte Property
689 
690         if (!bError)
691             aAny <<= bValue;
692     }
693 
694     return aAny;
695 }
696 
697 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAutoFormatObj )
698 
699 //------------------------------------------------------------------------
700 
701 ScAutoFormatFieldObj::ScAutoFormatFieldObj(sal_uInt16 nFormat, sal_uInt16 nField) :
702     aPropSet( lcl_GetAutoFieldMap() ),
703     nFormatIndex( nFormat ),
704     nFieldIndex( nField )
705 {
706     //! Listening !!!
707 }
708 
709 ScAutoFormatFieldObj::~ScAutoFormatFieldObj()
710 {
711 }
712 
713 void ScAutoFormatFieldObj::Notify( SfxBroadcaster& /* rBC */, const SfxHint& /* rHint */ )
714 {
715     //  spaeter...
716 }
717 
718 // beans::XPropertySet
719 
720 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAutoFormatFieldObj::getPropertySetInfo()
721                                                         throw(uno::RuntimeException)
722 {
723     ScUnoGuard aGuard;
724     static uno::Reference< beans::XPropertySetInfo > aRef(new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
725     return aRef;
726 }
727 
728 void SAL_CALL ScAutoFormatFieldObj::setPropertyValue(
729                         const rtl::OUString& aPropertyName, const uno::Any& aValue )
730                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
731                         lang::IllegalArgumentException, lang::WrappedTargetException,
732                         uno::RuntimeException)
733 {
734     ScUnoGuard aGuard;
735     ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
736     const SfxItemPropertySimpleEntry* pEntry =
737             aPropSet.getPropertyMap()->getByName( aPropertyName );
738 
739     if ( pEntry && pEntry->nWID && pFormats && nFormatIndex < pFormats->GetCount() )
740     {
741         ScAutoFormatData* pData = (*pFormats)[nFormatIndex];
742 
743         if ( IsScItemWid( pEntry->nWID ) )
744         {
745             if( const SfxPoolItem* pItem = pData->GetItem( nFieldIndex, pEntry->nWID ) )
746             {
747                 sal_Bool bDone = sal_False;
748 
749                 switch( pEntry->nWID )
750                 {
751                     case ATTR_STACKED:
752                     {
753                         table::CellOrientation eOrient;
754                         if( aValue >>= eOrient )
755                         {
756                             switch( eOrient )
757                             {
758                                 case table::CellOrientation_STANDARD:
759                                     pData->PutItem( nFieldIndex, SfxBoolItem( ATTR_STACKED, sal_False ) );
760                                 break;
761                                 case table::CellOrientation_TOPBOTTOM:
762                                     pData->PutItem( nFieldIndex, SfxBoolItem( ATTR_STACKED, sal_False ) );
763                                     pData->PutItem( nFieldIndex, SfxInt32Item( ATTR_ROTATE_VALUE, 27000 ) );
764                                 break;
765                                 case table::CellOrientation_BOTTOMTOP:
766                                     pData->PutItem( nFieldIndex, SfxBoolItem( ATTR_STACKED, sal_False ) );
767                                     pData->PutItem( nFieldIndex, SfxInt32Item( ATTR_ROTATE_VALUE, 9000 ) );
768                                 break;
769                                 case table::CellOrientation_STACKED:
770                                     pData->PutItem( nFieldIndex, SfxBoolItem( ATTR_STACKED, sal_True ) );
771                                 break;
772                                 default:
773                                 {
774                                     // added to avoid warnings
775                                 }
776                             }
777                             bDone = sal_True;
778                         }
779                     }
780                     break;
781                     default:
782                         SfxPoolItem* pNewItem = pItem->Clone();
783                         bDone = pNewItem->PutValue( aValue, pEntry->nMemberId );
784                         if (bDone)
785                             pData->PutItem( nFieldIndex, *pNewItem );
786                         delete pNewItem;
787                 }
788 
789                 if (bDone)
790                     //! Notify fuer andere Objekte?
791                     pFormats->SetSaveLater(sal_True);
792             }
793         }
794         else
795         {
796             switch (pEntry->nWID)
797             {
798                 case SC_WID_UNO_TBLBORD:
799                     {
800                         table::TableBorder aBorder;
801                         if ( aValue >>= aBorder )   // empty = nothing to do
802                         {
803                             SvxBoxItem aOuter(ATTR_BORDER);
804                             SvxBoxInfoItem aInner(ATTR_BORDER_INNER);
805                             ScHelperFunctions::FillBoxItems( aOuter, aInner, aBorder );
806                             pData->PutItem( nFieldIndex, aOuter );
807 
808                             //! Notify fuer andere Objekte?
809                             pFormats->SetSaveLater(sal_True);
810                         }
811                     }
812                     break;
813             }
814         }
815     }
816 }
817 
818 uno::Any SAL_CALL ScAutoFormatFieldObj::getPropertyValue( const rtl::OUString& aPropertyName )
819                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
820                         uno::RuntimeException)
821 {
822     ScUnoGuard aGuard;
823     uno::Any aVal;
824 
825     ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
826     const SfxItemPropertySimpleEntry* pEntry =
827             aPropSet.getPropertyMap()->getByName( aPropertyName );
828 
829     if ( pEntry && pEntry->nWID && pFormats && nFormatIndex < pFormats->GetCount() )
830     {
831         const ScAutoFormatData* pData = (*pFormats)[nFormatIndex];
832 
833         if ( IsScItemWid( pEntry->nWID ) )
834         {
835             if( const SfxPoolItem* pItem = pData->GetItem( nFieldIndex, pEntry->nWID ) )
836             {
837                 switch( pEntry->nWID )
838                 {
839                     case ATTR_STACKED:
840                     {
841                         const SfxInt32Item* pRotItem = (const SfxInt32Item*)pData->GetItem( nFieldIndex, ATTR_ROTATE_VALUE );
842                         sal_Int32 nRot = pRotItem ? pRotItem->GetValue() : 0;
843                         sal_Bool bStacked = ((const SfxBoolItem*)pItem)->GetValue();
844                         SvxOrientationItem( nRot, bStacked, 0 ).QueryValue( aVal );
845                     }
846                     break;
847                     default:
848                         pItem->QueryValue( aVal, pEntry->nMemberId );
849                 }
850             }
851         }
852         else
853         {
854             switch (pEntry->nWID)
855             {
856                 case SC_WID_UNO_TBLBORD:
857                     {
858                         const SfxPoolItem* pItem = pData->GetItem(nFieldIndex, ATTR_BORDER);
859                         if (pItem)
860                         {
861                             SvxBoxItem aOuter(*(static_cast<const SvxBoxItem*>(pItem)));
862                             SvxBoxInfoItem aInner(ATTR_BORDER_INNER);
863 
864                             table::TableBorder aBorder;
865                             ScHelperFunctions::FillTableBorder( aBorder, aOuter, aInner );
866                             aVal <<= aBorder;
867                         }
868                     }
869                     break;
870             }
871         }
872     }
873 
874     return aVal;
875 }
876 
877 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAutoFormatFieldObj )
878 
879 //------------------------------------------------------------------------
880 
881 
882 
883