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