xref: /trunk/main/sc/source/ui/unoobj/nameuno.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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 <svl/smplhint.hxx>
34 
35 #include <com/sun/star/sheet/NamedRangeFlag.hpp>
36 #include <com/sun/star/awt/XBitmap.hpp>
37 #include <com/sun/star/beans/PropertyAttribute.hpp>
38 
39 using namespace ::com::sun::star;
40 
41 
42 #include "nameuno.hxx"
43 #include "miscuno.hxx"
44 #include "cellsuno.hxx"
45 #include "convuno.hxx"
46 #include "targuno.hxx"
47 #include "tokenuno.hxx"
48 #include "tokenarray.hxx"
49 #include "docsh.hxx"
50 #include "docfunc.hxx"
51 #include "rangenam.hxx"
52 //CHINA001 #include "namecrea.hxx"      // NAME_TOP etc.
53 #include "unoguard.hxx"
54 #include "unonames.hxx"
55 
56 #include "scui_def.hxx" //CHINA001
57 
58 //------------------------------------------------------------------------
59 
60 const SfxItemPropertyMapEntry* lcl_GetNamedRangeMap()
61 {
62     static SfxItemPropertyMapEntry aNamedRangeMap_Impl[] =
63     {
64         {MAP_CHAR_LEN(SC_UNO_LINKDISPBIT),      0,  &getCppuType((uno::Reference<awt::XBitmap>*)0), beans::PropertyAttribute::READONLY, 0 },
65         {MAP_CHAR_LEN(SC_UNO_LINKDISPNAME),     0,  &getCppuType((rtl::OUString*)0),                beans::PropertyAttribute::READONLY, 0 },
66         {MAP_CHAR_LEN(SC_UNONAME_TOKENINDEX),   0,  &getCppuType((sal_Int32*)0),                    beans::PropertyAttribute::READONLY, 0 },
67         {MAP_CHAR_LEN(SC_UNONAME_ISSHAREDFMLA), 0,  &getBooleanCppuType(),                          0, 0 },
68         {0,0,0,0,0,0}
69     };
70     return aNamedRangeMap_Impl;
71 }
72 
73 //------------------------------------------------------------------------
74 
75 #define SCNAMEDRANGEOBJ_SERVICE     "com.sun.star.sheet.NamedRange"
76 
77 SC_SIMPLE_SERVICE_INFO( ScLabelRangeObj, "ScLabelRangeObj", "com.sun.star.sheet.LabelRange" )
78 SC_SIMPLE_SERVICE_INFO( ScLabelRangesObj, "ScLabelRangesObj", "com.sun.star.sheet.LabelRanges" )
79 SC_SIMPLE_SERVICE_INFO( ScNamedRangesObj, "ScNamedRangesObj", "com.sun.star.sheet.NamedRanges" )
80 
81 //------------------------------------------------------------------------
82 
83 sal_Bool lcl_UserVisibleName( const ScRangeData* pData )
84 {
85     //! als Methode an ScRangeData
86 
87     return ( pData && !pData->HasType( RT_DATABASE ) && !pData->HasType( RT_SHARED ) );
88 }
89 
90 //------------------------------------------------------------------------
91 
92 ScNamedRangeObj::ScNamedRangeObj(ScDocShell* pDocSh, const String& rNm) :
93     pDocShell( pDocSh ),
94     aName( rNm )
95 {
96     pDocShell->GetDocument()->AddUnoObject(*this);
97 }
98 
99 ScNamedRangeObj::~ScNamedRangeObj()
100 {
101     if (pDocShell)
102         pDocShell->GetDocument()->RemoveUnoObject(*this);
103 }
104 
105 void ScNamedRangeObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
106 {
107     //  Ref-Update interessiert nicht
108 
109     if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
110         pDocShell = NULL;       // ungueltig geworden
111 }
112 
113 // Hilfsfuntionen
114 
115 ScRangeData* ScNamedRangeObj::GetRangeData_Impl()
116 {
117     ScRangeData* pRet = NULL;
118     if (pDocShell)
119     {
120         ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
121         if (pNames)
122         {
123             sal_uInt16 nPos = 0;
124             if (pNames->SearchName( aName, nPos ))
125             {
126                 pRet = (*pNames)[nPos];
127                 pRet->ValidateTabRefs();        // adjust relative tab refs to valid tables
128             }
129         }
130     }
131     return pRet;
132 }
133 
134 // sheet::XNamedRange
135 
136 void ScNamedRangeObj::Modify_Impl( const String* pNewName, const ScTokenArray* pNewTokens, const String* pNewContent,
137                                     const ScAddress* pNewPos, const sal_uInt16* pNewType,
138                                     const formula::FormulaGrammar::Grammar eGrammar )
139 {
140     if (pDocShell)
141     {
142         ScDocument* pDoc = pDocShell->GetDocument();
143         ScRangeName* pNames = pDoc->GetRangeName();
144         if (pNames)
145         {
146             sal_uInt16 nPos = 0;
147             if (pNames->SearchName( aName, nPos ))
148             {
149                 ScRangeName* pNewRanges = new ScRangeName( *pNames );
150                 ScRangeData* pOld = (*pNames)[nPos];
151 
152                 String aInsName(pOld->GetName());
153                 if (pNewName)
154                     aInsName = *pNewName;
155                 String aContent;                            // Content string based =>
156                 pOld->GetSymbol( aContent, eGrammar);   // no problems with changed positions and such.
157                 if (pNewContent)
158                     aContent = *pNewContent;
159                 ScAddress aPos(pOld->GetPos());
160                 if (pNewPos)
161                     aPos = *pNewPos;
162                 sal_uInt16 nType = pOld->GetType();
163                 if (pNewType)
164                     nType = *pNewType;
165 
166                 ScRangeData* pNew = NULL;
167                 if ( pNewTokens )
168                     pNew = new ScRangeData( pDoc, aInsName, *pNewTokens, aPos, nType );
169                 else
170                     pNew = new ScRangeData( pDoc, aInsName, aContent, aPos, nType, eGrammar );
171                 pNew->SetIndex( pOld->GetIndex() );
172 
173                 pNewRanges->AtFree( nPos );
174                 if ( pNewRanges->Insert(pNew) )
175                 {
176                     ScDocFunc aFunc(*pDocShell);
177                     aFunc.SetNewRangeNames( pNewRanges, sal_True );
178 
179                     aName = aInsName;   //! broadcast?
180                 }
181                 else
182                 {
183                     delete pNew;        //! uno::Exception/Fehler oder so
184                     delete pNewRanges;
185                 }
186             }
187         }
188     }
189 }
190 
191 
192 rtl::OUString SAL_CALL ScNamedRangeObj::getName() throw(uno::RuntimeException)
193 {
194     ScUnoGuard aGuard;
195     return aName;
196 }
197 
198 void SAL_CALL ScNamedRangeObj::setName( const rtl::OUString& aNewName )
199                                                 throw(uno::RuntimeException)
200 {
201     ScUnoGuard aGuard;
202     //! Formeln anpassen ?????
203 
204     String aNewStr(aNewName);
205     // GRAM_PODF_A1 for API compatibility.
206     Modify_Impl( &aNewStr, NULL, NULL, NULL, NULL,formula::FormulaGrammar::GRAM_PODF_A1 );
207 
208     if ( aName != aNewStr )                 // some error occured...
209         throw uno::RuntimeException();      // no other exceptions specified
210 }
211 
212 rtl::OUString SAL_CALL ScNamedRangeObj::getContent() throw(uno::RuntimeException)
213 {
214     ScUnoGuard aGuard;
215     String aContent;
216     ScRangeData* pData = GetRangeData_Impl();
217     if (pData)
218         // GRAM_PODF_A1 for API compatibility.
219         pData->GetSymbol( aContent,formula::FormulaGrammar::GRAM_PODF_A1);
220     return aContent;
221 }
222 
223 void SAL_CALL ScNamedRangeObj::setContent( const rtl::OUString& aContent )
224                                                 throw(uno::RuntimeException)
225 {
226     ScUnoGuard aGuard;
227     String aContStr(aContent);
228     // GRAM_PODF_A1 for API compatibility.
229     Modify_Impl( NULL, NULL, &aContStr, NULL, NULL,formula::FormulaGrammar::GRAM_PODF_A1 );
230 }
231 
232 void ScNamedRangeObj::SetContentWithGrammar( const ::rtl::OUString& aContent,
233                                     const formula::FormulaGrammar::Grammar eGrammar )
234                                 throw(::com::sun::star::uno::RuntimeException)
235 {
236     String aContStr(aContent);
237     Modify_Impl( NULL, NULL, &aContStr, NULL, NULL, eGrammar );
238 }
239 
240 table::CellAddress SAL_CALL ScNamedRangeObj::getReferencePosition()
241                                                 throw(uno::RuntimeException)
242 {
243     ScUnoGuard aGuard;
244     ScAddress aPos;
245     ScRangeData* pData = GetRangeData_Impl();
246     if (pData)
247         aPos = pData->GetPos();
248     table::CellAddress aAddress;
249     aAddress.Column = aPos.Col();
250     aAddress.Row    = aPos.Row();
251     aAddress.Sheet  = aPos.Tab();
252     if (pDocShell)
253     {
254         SCTAB nDocTabs = pDocShell->GetDocument()->GetTableCount();
255         if ( aAddress.Sheet >= nDocTabs && nDocTabs > 0 )
256         {
257             //  Even after ValidateTabRefs, the position can be invalid if
258             //  the content points to preceding tables. The resulting string
259             //  is invalid in any case, so the position is just shifted.
260             aAddress.Sheet = nDocTabs - 1;
261         }
262     }
263     return aAddress;
264 }
265 
266 void SAL_CALL ScNamedRangeObj::setReferencePosition( const table::CellAddress& aReferencePosition )
267                                                 throw(uno::RuntimeException)
268 {
269     ScUnoGuard aGuard;
270     ScAddress aPos( (SCCOL)aReferencePosition.Column, (SCROW)aReferencePosition.Row, aReferencePosition.Sheet );
271     // GRAM_PODF_A1 for API compatibility.
272     Modify_Impl( NULL, NULL, NULL, &aPos, NULL,formula::FormulaGrammar::GRAM_PODF_A1 );
273 }
274 
275 sal_Int32 SAL_CALL ScNamedRangeObj::getType() throw(uno::RuntimeException)
276 {
277     ScUnoGuard aGuard;
278     sal_Int32 nType=0;
279     ScRangeData* pData = GetRangeData_Impl();
280     if (pData)
281     {
282         // do not return internal RT_* flags
283         // see property 'IsSharedFormula' for RT_SHARED
284         if ( pData->HasType(RT_CRITERIA) )  nType |= sheet::NamedRangeFlag::FILTER_CRITERIA;
285         if ( pData->HasType(RT_PRINTAREA) ) nType |= sheet::NamedRangeFlag::PRINT_AREA;
286         if ( pData->HasType(RT_COLHEADER) ) nType |= sheet::NamedRangeFlag::COLUMN_HEADER;
287         if ( pData->HasType(RT_ROWHEADER) ) nType |= sheet::NamedRangeFlag::ROW_HEADER;
288     }
289     return nType;
290 }
291 
292 void SAL_CALL ScNamedRangeObj::setType( sal_Int32 nUnoType ) throw(uno::RuntimeException)
293 {
294     // see property 'IsSharedFormula' for RT_SHARED
295     ScUnoGuard aGuard;
296     sal_uInt16 nNewType = RT_NAME;
297     if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA )    nNewType |= RT_CRITERIA;
298     if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA )         nNewType |= RT_PRINTAREA;
299     if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER )      nNewType |= RT_COLHEADER;
300     if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER )         nNewType |= RT_ROWHEADER;
301 
302     // GRAM_PODF_A1 for API compatibility.
303     Modify_Impl( NULL, NULL, NULL, NULL, &nNewType,formula::FormulaGrammar::GRAM_PODF_A1 );
304 }
305 
306 // XFormulaTokens
307 
308 uno::Sequence<sheet::FormulaToken> SAL_CALL ScNamedRangeObj::getTokens() throw(uno::RuntimeException)
309 {
310     ScUnoGuard aGuard;
311     uno::Sequence<sheet::FormulaToken> aSequence;
312     ScRangeData* pData = GetRangeData_Impl();
313     if (pData && pDocShell)
314     {
315         ScTokenArray* pTokenArray = pData->GetCode();
316         if ( pTokenArray )
317             (void)ScTokenConversion::ConvertToTokenSequence( *pDocShell->GetDocument(), aSequence, *pTokenArray );
318     }
319     return aSequence;
320 }
321 
322 void SAL_CALL ScNamedRangeObj::setTokens( const uno::Sequence<sheet::FormulaToken>& rTokens ) throw(uno::RuntimeException)
323 {
324     ScUnoGuard aGuard;
325     if( pDocShell )
326     {
327         ScTokenArray aTokenArray;
328         (void)ScTokenConversion::ConvertToTokenArray( *pDocShell->GetDocument(), aTokenArray, rTokens );
329         // GRAM_PODF_A1 for API compatibility.
330         Modify_Impl( NULL, &aTokenArray, NULL, NULL, NULL, formula::FormulaGrammar::GRAM_PODF_A1 );
331     }
332 }
333 
334 
335 // XCellRangeSource
336 
337 uno::Reference<table::XCellRange> SAL_CALL ScNamedRangeObj::getReferredCells()
338                                                 throw(uno::RuntimeException)
339 {
340     ScUnoGuard aGuard;
341     ScRange aRange;
342     ScRangeData* pData = GetRangeData_Impl();
343     if ( pData && pData->IsValidReference( aRange ) )
344     {
345         //! static Funktion um ScCellObj/ScCellRangeObj zu erzeugen am ScCellRangeObj ???
346 
347         if ( aRange.aStart == aRange.aEnd )
348             return new ScCellObj( pDocShell, aRange.aStart );
349         else
350             return new ScCellRangeObj( pDocShell, aRange );
351     }
352     return NULL;
353 }
354 
355 // beans::XPropertySet
356 
357 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScNamedRangeObj::getPropertySetInfo()
358                                                         throw(uno::RuntimeException)
359 {
360     ScUnoGuard aGuard;
361     static uno::Reference< beans::XPropertySetInfo >  aRef(new SfxItemPropertySetInfo( lcl_GetNamedRangeMap() ));
362     return aRef;
363 }
364 
365 void SAL_CALL ScNamedRangeObj::setPropertyValue(
366                         const rtl::OUString& rPropertyName, const uno::Any& aValue )
367                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
368                         lang::IllegalArgumentException, lang::WrappedTargetException,
369                         uno::RuntimeException)
370 {
371     ScUnoGuard aGuard;
372     if ( rPropertyName.equalsAscii( SC_UNONAME_ISSHAREDFMLA ) )
373     {
374         bool bIsShared = false;
375         if( aValue >>= bIsShared )
376         {
377             sal_uInt16 nNewType = bIsShared ? RT_SHARED : RT_NAME;
378             Modify_Impl( NULL, NULL, NULL, NULL, &nNewType,formula::FormulaGrammar::GRAM_PODF_A1 );
379         }
380     }
381 }
382 
383 uno::Any SAL_CALL ScNamedRangeObj::getPropertyValue( const rtl::OUString& rPropertyName )
384                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
385                         uno::RuntimeException)
386 {
387     ScUnoGuard aGuard;
388     uno::Any aRet;
389     if ( rPropertyName.equalsAscii( SC_UNO_LINKDISPBIT ) )
390     {
391         //  no target bitmaps for individual entries (would be all equal)
392         // ScLinkTargetTypeObj::SetLinkTargetBitmap( aRet, SC_LINKTARGETTYPE_RANGENAME );
393     }
394     else if ( rPropertyName.equalsAscii( SC_UNO_LINKDISPNAME ) )
395         aRet <<= rtl::OUString( aName );
396     else if ( rPropertyName.equalsAscii( SC_UNONAME_TOKENINDEX ) )
397     {
398         // get index for use in formula tokens (read-only)
399         ScRangeData* pData = GetRangeData_Impl();
400         if (pData)
401             aRet <<= static_cast<sal_Int32>(pData->GetIndex());
402     }
403     else if ( rPropertyName.equalsAscii( SC_UNONAME_ISSHAREDFMLA ) )
404     {
405         if( ScRangeData* pData = GetRangeData_Impl() )
406             aRet <<= static_cast< bool >( pData->HasType( RT_SHARED ) );
407     }
408     return aRet;
409 }
410 
411 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScNamedRangeObj )
412 
413 // lang::XServiceInfo
414 
415 rtl::OUString SAL_CALL ScNamedRangeObj::getImplementationName() throw(uno::RuntimeException)
416 {
417     return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScNamedRangeObj" ) );
418 }
419 
420 sal_Bool SAL_CALL ScNamedRangeObj::supportsService( const rtl::OUString& rServiceName )
421                                                     throw(uno::RuntimeException)
422 {
423     return rServiceName.equalsAscii( SCNAMEDRANGEOBJ_SERVICE ) ||
424            rServiceName.equalsAscii( SCLINKTARGET_SERVICE );
425 }
426 
427 uno::Sequence<rtl::OUString> SAL_CALL ScNamedRangeObj::getSupportedServiceNames()
428                                                     throw(uno::RuntimeException)
429 {
430     uno::Sequence<rtl::OUString> aRet(2);
431     aRet[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SCNAMEDRANGEOBJ_SERVICE ) );
432     aRet[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SCLINKTARGET_SERVICE ) );
433     return aRet;
434 }
435 
436 
437 // XUnoTunnel
438 
439 sal_Int64 SAL_CALL ScNamedRangeObj::getSomething(
440                 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
441 {
442     if ( rId.getLength() == 16 &&
443           0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
444                                     rId.getConstArray(), 16 ) )
445     {
446         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
447     }
448     return 0;
449 }
450 
451 // static
452 const uno::Sequence<sal_Int8>& ScNamedRangeObj::getUnoTunnelId()
453 {
454     static uno::Sequence<sal_Int8> * pSeq = 0;
455     if( !pSeq )
456     {
457         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
458         if( !pSeq )
459         {
460             static uno::Sequence< sal_Int8 > aSeq( 16 );
461             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
462             pSeq = &aSeq;
463         }
464     }
465     return *pSeq;
466 }
467 
468 // static
469 ScNamedRangeObj* ScNamedRangeObj::getImplementation( const uno::Reference<uno::XInterface> xObj )
470 {
471     ScNamedRangeObj* pRet = NULL;
472     uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
473     if (xUT.is())
474         pRet = reinterpret_cast<ScNamedRangeObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
475     return pRet;
476 }
477 
478 //------------------------------------------------------------------------
479 
480 ScNamedRangesObj::ScNamedRangesObj(ScDocShell* pDocSh) :
481     pDocShell( pDocSh )
482 {
483     pDocShell->GetDocument()->AddUnoObject(*this);
484 }
485 
486 ScNamedRangesObj::~ScNamedRangesObj()
487 {
488     if (pDocShell)
489         pDocShell->GetDocument()->RemoveUnoObject(*this);
490 }
491 
492 void ScNamedRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
493 {
494     //  Referenz-Update interessiert hier nicht
495 
496     if ( rHint.ISA( SfxSimpleHint ) &&
497             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
498     {
499         pDocShell = NULL;       // ungueltig geworden
500     }
501 }
502 
503 // sheet::XNamedRanges
504 
505 ScNamedRangeObj* ScNamedRangesObj::GetObjectByIndex_Impl(sal_uInt16 nIndex)
506 {
507     if (pDocShell)
508     {
509         ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
510         if (pNames)
511         {
512             sal_uInt16 nCount = pNames->GetCount();
513             sal_uInt16 nPos = 0;
514             for (sal_uInt16 i=0; i<nCount; i++)
515             {
516                 ScRangeData* pData = (*pNames)[i];
517                 if (lcl_UserVisibleName(pData))         // interne weglassen
518                 {
519                     if ( nPos == nIndex )
520                         return new ScNamedRangeObj( pDocShell, pData->GetName() );
521                     ++nPos;
522                 }
523             }
524         }
525     }
526     return NULL;
527 }
528 
529 ScNamedRangeObj* ScNamedRangesObj::GetObjectByName_Impl(const rtl::OUString& aName)
530 {
531     if ( pDocShell && hasByName(aName) )
532         return new ScNamedRangeObj( pDocShell, String(aName) );
533     return NULL;
534 }
535 
536 void SAL_CALL ScNamedRangesObj::addNewByName( const rtl::OUString& aName,
537         const rtl::OUString& aContent, const table::CellAddress& aPosition,
538         sal_Int32 nUnoType ) throw(uno::RuntimeException)
539 {
540     ScUnoGuard aGuard;
541     String aNameStr(aName);
542     String aContStr(aContent);
543     ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, aPosition.Sheet );
544 
545     sal_uInt16 nNewType = RT_NAME;
546     if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA )    nNewType |= RT_CRITERIA;
547     if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA )         nNewType |= RT_PRINTAREA;
548     if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER )      nNewType |= RT_COLHEADER;
549     if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER )         nNewType |= RT_ROWHEADER;
550 
551     sal_Bool bDone = sal_False;
552     if (pDocShell)
553     {
554         ScDocument* pDoc = pDocShell->GetDocument();
555         ScRangeName* pNames = pDoc->GetRangeName();
556         sal_uInt16 nIndex = 0;
557         if (pNames && !pNames->SearchName(aNameStr, nIndex))
558         {
559             ScRangeName* pNewRanges = new ScRangeName( *pNames );
560             // GRAM_PODF_A1 for API compatibility.
561             ScRangeData* pNew = new ScRangeData( pDoc, aNameStr, aContStr,
562                                                 aPos, nNewType,formula::FormulaGrammar::GRAM_PODF_A1 );
563             if ( pNewRanges->Insert(pNew) )
564             {
565                 ScDocFunc aFunc(*pDocShell);
566                 aFunc.SetNewRangeNames( pNewRanges, sal_True );
567                 bDone = sal_True;
568             }
569             else
570             {
571                 delete pNew;
572                 delete pNewRanges;
573             }
574         }
575     }
576 
577     if (!bDone)
578         throw uno::RuntimeException();      // no other exceptions specified
579 }
580 
581 void SAL_CALL ScNamedRangesObj::addNewFromTitles( const table::CellRangeAddress& aSource,
582                                     sheet::Border aBorder ) throw(uno::RuntimeException)
583 {
584     ScUnoGuard aGuard;
585     //! das darf kein enum sein, weil mehrere Bits gesetzt sein koennen !!!
586 
587     sal_Bool bTop    = ( aBorder == sheet::Border_TOP );
588     sal_Bool bLeft   = ( aBorder == sheet::Border_LEFT );
589     sal_Bool bBottom = ( aBorder == sheet::Border_BOTTOM );
590     sal_Bool bRight  = ( aBorder == sheet::Border_RIGHT );
591 
592     ScRange aRange;
593     ScUnoConversion::FillScRange( aRange, aSource );
594 
595     sal_uInt16 nFlags = 0;
596     if (bTop)    nFlags |= NAME_TOP;
597     if (bLeft)   nFlags |= NAME_LEFT;
598     if (bBottom) nFlags |= NAME_BOTTOM;
599     if (bRight)  nFlags |= NAME_RIGHT;
600 
601     if (nFlags)
602     {
603         ScDocFunc aFunc(*pDocShell);
604         aFunc.CreateNames( aRange, nFlags, sal_True );
605     }
606 }
607 
608 void SAL_CALL ScNamedRangesObj::removeByName( const rtl::OUString& aName )
609                                                 throw(uno::RuntimeException)
610 {
611     ScUnoGuard aGuard;
612     sal_Bool bDone = sal_False;
613     if (pDocShell)
614     {
615         ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
616         if (pNames)
617         {
618             String aString(aName);
619             sal_uInt16 nPos = 0;
620             if (pNames->SearchName( aString, nPos ))
621                 if ( lcl_UserVisibleName((*pNames)[nPos]) )
622                 {
623                     ScRangeName* pNewRanges = new ScRangeName(*pNames);
624                     pNewRanges->AtFree(nPos);
625                     ScDocFunc aFunc(*pDocShell);
626                     aFunc.SetNewRangeNames( pNewRanges, sal_True );
627                     bDone = sal_True;
628                 }
629         }
630     }
631 
632     if (!bDone)
633         throw uno::RuntimeException();      // no other exceptions specified
634 }
635 
636 void SAL_CALL ScNamedRangesObj::outputList( const table::CellAddress& aOutputPosition )
637                                                 throw(uno::RuntimeException)
638 {
639     ScUnoGuard aGuard;
640     ScAddress aPos( (SCCOL)aOutputPosition.Column, (SCROW)aOutputPosition.Row, aOutputPosition.Sheet );
641     if (pDocShell)
642     {
643         ScDocFunc aFunc(*pDocShell);
644         aFunc.InsertNameList( aPos, sal_True );
645     }
646 }
647 
648 // container::XEnumerationAccess
649 
650 uno::Reference<container::XEnumeration> SAL_CALL ScNamedRangesObj::createEnumeration()
651                                                     throw(uno::RuntimeException)
652 {
653     ScUnoGuard aGuard;
654     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.NamedRangesEnumeration")));
655 }
656 
657 // container::XIndexAccess
658 
659 sal_Int32 SAL_CALL ScNamedRangesObj::getCount() throw(uno::RuntimeException)
660 {
661     ScUnoGuard aGuard;
662     long nRet = 0;
663     if (pDocShell)
664     {
665         ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
666         if (pNames)
667         {
668             sal_uInt16 nCount = pNames->GetCount();
669             for (sal_uInt16 i=0; i<nCount; i++)
670                 if (lcl_UserVisibleName( (*pNames)[i] ))    // interne weglassen
671                     ++nRet;
672         }
673     }
674     return nRet;
675 }
676 
677 uno::Any SAL_CALL ScNamedRangesObj::getByIndex( sal_Int32 nIndex )
678                             throw(lang::IndexOutOfBoundsException,
679                                     lang::WrappedTargetException, uno::RuntimeException)
680 {
681     ScUnoGuard aGuard;
682     uno::Reference< sheet::XNamedRange >  xRange(GetObjectByIndex_Impl((sal_uInt16)nIndex));
683     if ( xRange.is() )
684         return uno::makeAny(xRange);
685     else
686         throw lang::IndexOutOfBoundsException();
687 //    return uno::Any();
688 }
689 
690 uno::Type SAL_CALL ScNamedRangesObj::getElementType() throw(uno::RuntimeException)
691 {
692     ScUnoGuard aGuard;
693     return ::getCppuType((const uno::Reference< sheet::XNamedRange >*)0);   // muss zu getByIndex passen
694 }
695 
696 sal_Bool SAL_CALL ScNamedRangesObj::hasElements() throw(uno::RuntimeException)
697 {
698     ScUnoGuard aGuard;
699     return ( getCount() != 0 );
700 }
701 
702 uno::Any SAL_CALL ScNamedRangesObj::getByName( const rtl::OUString& aName )
703             throw(container::NoSuchElementException,
704                     lang::WrappedTargetException, uno::RuntimeException)
705 {
706     ScUnoGuard aGuard;
707     uno::Reference< sheet::XNamedRange >  xRange(GetObjectByName_Impl(aName));
708     if ( xRange.is() )
709         return uno::makeAny(xRange);
710     else
711         throw container::NoSuchElementException();
712 //    return uno::Any();
713 }
714 
715 uno::Sequence<rtl::OUString> SAL_CALL ScNamedRangesObj::getElementNames()
716                                                 throw(uno::RuntimeException)
717 {
718     ScUnoGuard aGuard;
719     if (pDocShell)
720     {
721         ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
722         if (pNames)
723         {
724             long nVisCount = getCount();            // Namen mit lcl_UserVisibleName
725             uno::Sequence<rtl::OUString> aSeq(nVisCount);
726             rtl::OUString* pAry = aSeq.getArray();
727 
728             sal_uInt16 nCount = pNames->GetCount();
729             sal_uInt16 nVisPos = 0;
730             for (sal_uInt16 i=0; i<nCount; i++)
731             {
732                 ScRangeData* pData = (*pNames)[i];
733                 if ( lcl_UserVisibleName(pData) )
734                     pAry[nVisPos++] = pData->GetName();
735             }
736 //          DBG_ASSERT(nVisPos == nVisCount, "huch, verzaehlt?");
737             return aSeq;
738         }
739     }
740     return uno::Sequence<rtl::OUString>(0);
741 }
742 
743 sal_Bool SAL_CALL ScNamedRangesObj::hasByName( const rtl::OUString& aName )
744                                         throw(uno::RuntimeException)
745 {
746     ScUnoGuard aGuard;
747     if (pDocShell)
748     {
749         ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
750         if (pNames)
751         {
752             sal_uInt16 nPos = 0;
753             if (pNames->SearchName( String(aName), nPos ))
754                 if ( lcl_UserVisibleName((*pNames)[nPos]) )
755                     return sal_True;
756         }
757     }
758     return sal_False;
759 }
760 
761 /** called from the XActionLockable interface methods on initial locking */
762 void ScNamedRangesObj::lock()
763 {
764     pDocShell->GetDocument()->CompileNameFormula( sal_True ); // CreateFormulaString
765 }
766 
767 /** called from the XActionLockable interface methods on final unlock */
768 void ScNamedRangesObj::unlock()
769 {
770     pDocShell->GetDocument()->CompileNameFormula( sal_False ); // CompileFormulaString
771 }
772 
773 // document::XActionLockable
774 
775 sal_Bool ScNamedRangesObj::isActionLocked() throw(uno::RuntimeException)
776 {
777     ScUnoGuard aGuard;
778     return pDocShell->GetDocument()->GetNamedRangesLockCount() != 0;
779 }
780 
781 void ScNamedRangesObj::addActionLock() throw(uno::RuntimeException)
782 {
783     ScUnoGuard aGuard;
784     ScDocument* pDoc = pDocShell->GetDocument();
785     sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
786     ++nLockCount;
787     if ( nLockCount == 1 )
788     {
789         lock();
790     }
791     pDoc->SetNamedRangesLockCount( nLockCount );
792 }
793 
794 void ScNamedRangesObj::removeActionLock() throw(uno::RuntimeException)
795 {
796     ScUnoGuard aGuard;
797     ScDocument* pDoc = pDocShell->GetDocument();
798     sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
799     if ( nLockCount > 0 )
800     {
801         --nLockCount;
802         if ( nLockCount == 0 )
803         {
804             unlock();
805         }
806         pDoc->SetNamedRangesLockCount( nLockCount );
807     }
808 }
809 
810 void ScNamedRangesObj::setActionLocks( sal_Int16 nLock ) throw(uno::RuntimeException)
811 {
812     ScUnoGuard aGuard;
813     if ( nLock >= 0 )
814     {
815         ScDocument* pDoc = pDocShell->GetDocument();
816         sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
817         if ( nLock == 0 && nLockCount > 0 )
818         {
819             unlock();
820         }
821         if ( nLock > 0 && nLockCount == 0 )
822         {
823             lock();
824         }
825         pDoc->SetNamedRangesLockCount( nLock );
826     }
827 }
828 
829 sal_Int16 ScNamedRangesObj::resetActionLocks() throw(uno::RuntimeException)
830 {
831     ScUnoGuard aGuard;
832     ScDocument* pDoc = pDocShell->GetDocument();
833     sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
834     if ( nLockCount > 0 )
835     {
836         unlock();
837     }
838     pDoc->SetNamedRangesLockCount( 0 );
839     return nLockCount;
840 }
841 
842 //------------------------------------------------------------------------
843 
844 ScLabelRangeObj::ScLabelRangeObj(ScDocShell* pDocSh, sal_Bool bCol, const ScRange& rR) :
845     pDocShell( pDocSh ),
846     bColumn( bCol ),
847     aRange( rR )
848 {
849     pDocShell->GetDocument()->AddUnoObject(*this);
850 }
851 
852 ScLabelRangeObj::~ScLabelRangeObj()
853 {
854     if (pDocShell)
855         pDocShell->GetDocument()->RemoveUnoObject(*this);
856 }
857 
858 void ScLabelRangeObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
859 {
860     //! Ref-Update !!!
861 
862     if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
863         pDocShell = NULL;       // ungueltig geworden
864 }
865 
866 // Hilfsfuntionen
867 
868 ScRangePair* ScLabelRangeObj::GetData_Impl()
869 {
870     ScRangePair* pRet = NULL;
871     if (pDocShell)
872     {
873         ScDocument* pDoc = pDocShell->GetDocument();
874         ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
875         if (pList)
876             pRet = pList->Find( aRange );
877     }
878     return pRet;
879 }
880 
881 void ScLabelRangeObj::Modify_Impl( const ScRange* pLabel, const ScRange* pData )
882 {
883     if (pDocShell)
884     {
885         ScDocument* pDoc = pDocShell->GetDocument();
886         ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
887         if (pOldList)
888         {
889             ScRangePairListRef xNewList(pOldList->Clone());
890             ScRangePair* pEntry = xNewList->Find( aRange );
891             if (pEntry)
892             {
893                 xNewList->Remove( pEntry );     // nur aus der Liste entfernt, nicht geloescht
894 
895                 if ( pLabel )
896                     pEntry->GetRange(0) = *pLabel;
897                 if ( pData )
898                     pEntry->GetRange(1) = *pData;
899 
900                 xNewList->Join( *pEntry );
901                 delete pEntry;
902 
903                 if (bColumn)
904                     pDoc->GetColNameRangesRef() = xNewList;
905                 else
906                     pDoc->GetRowNameRangesRef() = xNewList;
907 
908                 pDoc->CompileColRowNameFormula();
909                 pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
910                 pDocShell->SetDocumentModified();
911 
912                 //! Undo ?!?! (hier und aus Dialog)
913 
914                 if ( pLabel )
915                     aRange = *pLabel;   // Objekt anpassen, um Range wiederzufinden
916             }
917         }
918     }
919 }
920 
921 // sheet::XLabelRange
922 
923 table::CellRangeAddress SAL_CALL ScLabelRangeObj::getLabelArea()
924                                                 throw(uno::RuntimeException)
925 {
926     ScUnoGuard aGuard;
927     table::CellRangeAddress aRet;
928     ScRangePair* pData = GetData_Impl();
929     if (pData)
930         ScUnoConversion::FillApiRange( aRet, pData->GetRange(0) );
931     return aRet;
932 }
933 
934 void SAL_CALL ScLabelRangeObj::setLabelArea( const table::CellRangeAddress& aLabelArea )
935                                                 throw(uno::RuntimeException)
936 {
937     ScUnoGuard aGuard;
938     ScRange aLabelRange;
939     ScUnoConversion::FillScRange( aLabelRange, aLabelArea );
940     Modify_Impl( &aLabelRange, NULL );
941 }
942 
943 table::CellRangeAddress SAL_CALL ScLabelRangeObj::getDataArea()
944                                                 throw(uno::RuntimeException)
945 {
946     ScUnoGuard aGuard;
947     table::CellRangeAddress aRet;
948     ScRangePair* pData = GetData_Impl();
949     if (pData)
950         ScUnoConversion::FillApiRange( aRet, pData->GetRange(1) );
951     return aRet;
952 }
953 
954 void SAL_CALL ScLabelRangeObj::setDataArea( const table::CellRangeAddress& aDataArea )
955                                                 throw(uno::RuntimeException)
956 {
957     ScUnoGuard aGuard;
958     ScRange aDataRange;
959     ScUnoConversion::FillScRange( aDataRange, aDataArea );
960     Modify_Impl( NULL, &aDataRange );
961 }
962 
963 //------------------------------------------------------------------------
964 
965 ScLabelRangesObj::ScLabelRangesObj(ScDocShell* pDocSh, sal_Bool bCol) :
966     pDocShell( pDocSh ),
967     bColumn( bCol )
968 {
969     pDocShell->GetDocument()->AddUnoObject(*this);
970 }
971 
972 ScLabelRangesObj::~ScLabelRangesObj()
973 {
974     if (pDocShell)
975         pDocShell->GetDocument()->RemoveUnoObject(*this);
976 }
977 
978 void ScLabelRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
979 {
980     //  Referenz-Update interessiert hier nicht
981 
982     if ( rHint.ISA( SfxSimpleHint ) &&
983             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
984     {
985         pDocShell = NULL;       // ungueltig geworden
986     }
987 }
988 
989 // sheet::XLabelRanges
990 
991 ScLabelRangeObj* ScLabelRangesObj::GetObjectByIndex_Impl(sal_uInt16 nIndex)
992 {
993     if (pDocShell)
994     {
995         ScDocument* pDoc = pDocShell->GetDocument();
996         ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
997         if ( pList && nIndex < pList->Count() )
998         {
999             ScRangePair* pData = pList->GetObject(nIndex);
1000             if (pData)
1001                 return new ScLabelRangeObj( pDocShell, bColumn, pData->GetRange(0) );
1002         }
1003     }
1004     return NULL;
1005 }
1006 
1007 void SAL_CALL ScLabelRangesObj::addNew( const table::CellRangeAddress& aLabelArea,
1008                                 const table::CellRangeAddress& aDataArea )
1009                                                 throw(uno::RuntimeException)
1010 {
1011     ScUnoGuard aGuard;
1012     if (pDocShell)
1013     {
1014         ScDocument* pDoc = pDocShell->GetDocument();
1015         ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
1016         if (pOldList)
1017         {
1018             ScRangePairListRef xNewList(pOldList->Clone());
1019 
1020             ScRange aLabelRange;
1021             ScRange aDataRange;
1022             ScUnoConversion::FillScRange( aLabelRange, aLabelArea );
1023             ScUnoConversion::FillScRange( aDataRange,  aDataArea );
1024             xNewList->Join( ScRangePair( aLabelRange, aDataRange ) );
1025 
1026             if (bColumn)
1027                 pDoc->GetColNameRangesRef() = xNewList;
1028             else
1029                 pDoc->GetRowNameRangesRef() = xNewList;
1030 
1031             pDoc->CompileColRowNameFormula();
1032             pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
1033             pDocShell->SetDocumentModified();
1034 
1035             //! Undo ?!?! (hier und aus Dialog)
1036         }
1037     }
1038 }
1039 
1040 void SAL_CALL ScLabelRangesObj::removeByIndex( sal_Int32 nIndex )
1041                                                 throw(uno::RuntimeException)
1042 {
1043     ScUnoGuard aGuard;
1044     sal_Bool bDone = sal_False;
1045     if (pDocShell)
1046     {
1047         ScDocument* pDoc = pDocShell->GetDocument();
1048         ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
1049 
1050         if ( pOldList && nIndex >= 0 && nIndex < (sal_Int32)pOldList->Count() )
1051         {
1052             ScRangePairListRef xNewList(pOldList->Clone());
1053 
1054             ScRangePair* pEntry = xNewList->GetObject( nIndex );
1055             if (pEntry)
1056             {
1057                 xNewList->Remove( pEntry );
1058                 delete pEntry;
1059 
1060                 if (bColumn)
1061                     pDoc->GetColNameRangesRef() = xNewList;
1062                 else
1063                     pDoc->GetRowNameRangesRef() = xNewList;
1064 
1065                 pDoc->CompileColRowNameFormula();
1066                 pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
1067                 pDocShell->SetDocumentModified();
1068                 bDone = sal_True;
1069 
1070                 //! Undo ?!?! (hier und aus Dialog)
1071             }
1072         }
1073     }
1074     if (!bDone)
1075         throw uno::RuntimeException();      // no other exceptions specified
1076 }
1077 
1078 // container::XEnumerationAccess
1079 
1080 uno::Reference<container::XEnumeration> SAL_CALL ScLabelRangesObj::createEnumeration()
1081                                                     throw(uno::RuntimeException)
1082 {
1083     ScUnoGuard aGuard;
1084     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.LabelRangesEnumeration")));
1085 }
1086 
1087 // container::XIndexAccess
1088 
1089 sal_Int32 SAL_CALL ScLabelRangesObj::getCount() throw(uno::RuntimeException)
1090 {
1091     ScUnoGuard aGuard;
1092     if (pDocShell)
1093     {
1094         ScDocument* pDoc = pDocShell->GetDocument();
1095         ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
1096         if (pList)
1097             return pList->Count();
1098     }
1099     return 0;
1100 }
1101 
1102 uno::Any SAL_CALL ScLabelRangesObj::getByIndex( sal_Int32 nIndex )
1103                             throw(lang::IndexOutOfBoundsException,
1104                                     lang::WrappedTargetException, uno::RuntimeException)
1105 {
1106     ScUnoGuard aGuard;
1107     uno::Reference< sheet::XLabelRange >  xRange(GetObjectByIndex_Impl((sal_uInt16)nIndex));
1108     if ( xRange.is() )
1109         return uno::makeAny(xRange);
1110     else
1111         throw lang::IndexOutOfBoundsException();
1112 //    return uno::Any();
1113 }
1114 
1115 uno::Type SAL_CALL ScLabelRangesObj::getElementType() throw(uno::RuntimeException)
1116 {
1117     ScUnoGuard aGuard;
1118     return ::getCppuType((const uno::Reference< sheet::XLabelRange >*)0);   // muss zu getByIndex passen
1119 
1120 }
1121 
1122 sal_Bool SAL_CALL ScLabelRangesObj::hasElements() throw(uno::RuntimeException)
1123 {
1124     ScUnoGuard aGuard;
1125     return ( getCount() != 0 );
1126 }
1127 
1128 //------------------------------------------------------------------------
1129 
1130 
1131 
1132