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