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() throw(uno::RuntimeException)
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 throw(uno::RuntimeException)
234 {
235 ScUnoGuard aGuard;
236 //! Formeln anpassen ?????
237
238 String aNewStr(aNewName);
239 // GRAM_PODF_A1 for API compatibility.
240 Modify_Impl( &aNewStr, NULL, NULL, NULL, NULL,formula::FormulaGrammar::GRAM_PODF_A1 );
241
242 if ( aName != aNewStr ) // some error occured...
243 throw uno::RuntimeException(); // no other exceptions specified
244 }
getScopeName()245 rtl::OUString SAL_CALL ScNamedRangeObj::getScopeName() throw(uno::RuntimeException)
246 {
247 ScUnoGuard aGuard;
248 return aScopeName;
249 }
250
setScopeAndRangeName(const rtl::OUString & aNewScopeName,const rtl::OUString & aNewRangeName)251 void SAL_CALL ScNamedRangeObj::setScopeAndRangeName( const rtl::OUString& aNewScopeName, const rtl::OUString& aNewRangeName )
252 throw(uno::RuntimeException)
253 {
254 ScUnoGuard aGuard;
255 //! Formeln anpassen ?????
256
257 String aNewRangeStr(aNewRangeName);
258 String aNewScopeStr(aNewScopeName);
259 // GRAM_PODF_A1 for API compatibility.
260 Modify_Impl( &aNewRangeStr, NULL, NULL, NULL, NULL,formula::FormulaGrammar::GRAM_PODF_A1, aNewScopeName.getLength() == 0 ? NULL : &aNewScopeStr);
261
262 if ( aScopeName != aNewScopeStr || aName != aNewRangeStr ) // some error occured...
263 throw uno::RuntimeException(); // no other exceptions specified
264 }
265
266
getContent()267 rtl::OUString SAL_CALL ScNamedRangeObj::getContent() throw(uno::RuntimeException)
268 {
269 ScUnoGuard aGuard;
270 String aContent;
271 ScRangeData* pData = GetRangeData_Impl();
272 if (pData)
273 // GRAM_PODF_A1 for API compatibility.
274 pData->GetSymbol( aContent,formula::FormulaGrammar::GRAM_PODF_A1);
275 return aContent;
276 }
277
setContent(const rtl::OUString & aContent)278 void SAL_CALL ScNamedRangeObj::setContent( const rtl::OUString& aContent )
279 throw(uno::RuntimeException)
280 {
281 ScUnoGuard aGuard;
282 String aContStr(aContent);
283 // GRAM_PODF_A1 for API compatibility.
284 Modify_Impl( NULL, NULL, &aContStr, NULL, NULL,formula::FormulaGrammar::GRAM_PODF_A1 );
285 }
286
SetContentWithGrammar(const::rtl::OUString & aContent,const formula::FormulaGrammar::Grammar eGrammar)287 void ScNamedRangeObj::SetContentWithGrammar( const ::rtl::OUString& aContent,
288 const formula::FormulaGrammar::Grammar eGrammar )
289 throw(::com::sun::star::uno::RuntimeException)
290 {
291 String aContStr(aContent);
292 Modify_Impl( NULL, NULL, &aContStr, NULL, NULL, eGrammar );
293 }
294
getReferencePosition()295 table::CellAddress SAL_CALL ScNamedRangeObj::getReferencePosition()
296 throw(uno::RuntimeException)
297 {
298 ScUnoGuard aGuard;
299 ScAddress aPos;
300 ScRangeData* pData = GetRangeData_Impl();
301 if (pData)
302 aPos = pData->GetPos();
303 table::CellAddress aAddress;
304 aAddress.Column = aPos.Col();
305 aAddress.Row = aPos.Row();
306 aAddress.Sheet = aPos.Tab();
307 if (pDocShell)
308 {
309 SCTAB nDocTabs = pDocShell->GetDocument()->GetTableCount();
310 if ( aAddress.Sheet >= nDocTabs && nDocTabs > 0 )
311 {
312 // Even after ValidateTabRefs, the position can be invalid if
313 // the content points to preceding tables. The resulting string
314 // is invalid in any case, so the position is just shifted.
315 aAddress.Sheet = nDocTabs - 1;
316 }
317 }
318 return aAddress;
319 }
320
setReferencePosition(const table::CellAddress & aReferencePosition)321 void SAL_CALL ScNamedRangeObj::setReferencePosition( const table::CellAddress& aReferencePosition )
322 throw(uno::RuntimeException)
323 {
324 ScUnoGuard aGuard;
325 ScAddress aPos( (SCCOL)aReferencePosition.Column, (SCROW)aReferencePosition.Row, aReferencePosition.Sheet );
326 // GRAM_PODF_A1 for API compatibility.
327 Modify_Impl( NULL, NULL, NULL, &aPos, NULL,formula::FormulaGrammar::GRAM_PODF_A1 );
328 }
329
getType()330 sal_Int32 SAL_CALL ScNamedRangeObj::getType() throw(uno::RuntimeException)
331 {
332 ScUnoGuard aGuard;
333 sal_Int32 nType=0;
334 ScRangeData* pData = GetRangeData_Impl();
335 if (pData)
336 {
337 // do not return internal RT_* flags
338 // see property 'IsSharedFormula' for RT_SHARED
339 if ( pData->HasType(RT_CRITERIA) ) nType |= sheet::NamedRangeFlag::FILTER_CRITERIA;
340 if ( pData->HasType(RT_PRINTAREA) ) nType |= sheet::NamedRangeFlag::PRINT_AREA;
341 if ( pData->HasType(RT_COLHEADER) ) nType |= sheet::NamedRangeFlag::COLUMN_HEADER;
342 if ( pData->HasType(RT_ROWHEADER) ) nType |= sheet::NamedRangeFlag::ROW_HEADER;
343 }
344 return nType;
345 }
346
setType(sal_Int32 nUnoType)347 void SAL_CALL ScNamedRangeObj::setType( sal_Int32 nUnoType ) throw(uno::RuntimeException)
348 {
349 // see property 'IsSharedFormula' for RT_SHARED
350 ScUnoGuard aGuard;
351 sal_uInt16 nNewType = RT_NAME;
352 if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA ) nNewType |= RT_CRITERIA;
353 if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA ) nNewType |= RT_PRINTAREA;
354 if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER ) nNewType |= RT_COLHEADER;
355 if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER ) nNewType |= RT_ROWHEADER;
356
357 // GRAM_PODF_A1 for API compatibility.
358 Modify_Impl( NULL, NULL, NULL, NULL, &nNewType,formula::FormulaGrammar::GRAM_PODF_A1 );
359 }
360
361 // XFormulaTokens
362
getTokens()363 uno::Sequence<sheet::FormulaToken> SAL_CALL ScNamedRangeObj::getTokens() throw(uno::RuntimeException)
364 {
365 ScUnoGuard aGuard;
366 uno::Sequence<sheet::FormulaToken> aSequence;
367 ScRangeData* pData = GetRangeData_Impl();
368 if (pData && pDocShell)
369 {
370 ScTokenArray* pTokenArray = pData->GetCode();
371 if ( pTokenArray )
372 (void)ScTokenConversion::ConvertToTokenSequence( *pDocShell->GetDocument(), aSequence, *pTokenArray );
373 }
374 return aSequence;
375 }
376
setTokens(const uno::Sequence<sheet::FormulaToken> & rTokens)377 void SAL_CALL ScNamedRangeObj::setTokens( const uno::Sequence<sheet::FormulaToken>& rTokens ) throw(uno::RuntimeException)
378 {
379 ScUnoGuard aGuard;
380 if( pDocShell )
381 {
382 ScTokenArray aTokenArray;
383 (void)ScTokenConversion::ConvertToTokenArray( *pDocShell->GetDocument(), aTokenArray, rTokens );
384 // GRAM_PODF_A1 for API compatibility.
385 Modify_Impl( NULL, &aTokenArray, NULL, NULL, NULL, formula::FormulaGrammar::GRAM_PODF_A1 );
386 }
387 }
388
389
390 // XCellRangeSource
391
getReferredCells()392 uno::Reference<table::XCellRange> SAL_CALL ScNamedRangeObj::getReferredCells()
393 throw(uno::RuntimeException)
394 {
395 ScUnoGuard aGuard;
396 ScRange aRange;
397 ScRangeData* pData = GetRangeData_Impl();
398 if ( pData && pData->IsValidReference( aRange ) )
399 {
400 //! static Funktion um ScCellObj/ScCellRangeObj zu erzeugen am ScCellRangeObj ???
401
402 if ( aRange.aStart == aRange.aEnd )
403 return new ScCellObj( pDocShell, aRange.aStart );
404 else
405 return new ScCellRangeObj( pDocShell, aRange );
406 }
407 return NULL;
408 }
409
410 // beans::XPropertySet
411
getPropertySetInfo()412 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScNamedRangeObj::getPropertySetInfo()
413 throw(uno::RuntimeException)
414 {
415 ScUnoGuard aGuard;
416 static uno::Reference< beans::XPropertySetInfo > aRef(new SfxItemPropertySetInfo( lcl_GetNamedRangeMap() ));
417 return aRef;
418 }
419
setPropertyValue(const rtl::OUString & rPropertyName,const uno::Any & aValue)420 void SAL_CALL ScNamedRangeObj::setPropertyValue(
421 const rtl::OUString& rPropertyName, const uno::Any& aValue )
422 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
423 lang::IllegalArgumentException, lang::WrappedTargetException,
424 uno::RuntimeException)
425 {
426 ScUnoGuard aGuard;
427 if ( rPropertyName.equalsAscii( SC_UNONAME_ISSHAREDFMLA ) )
428 {
429 bool bIsShared = false;
430 if( aValue >>= bIsShared )
431 {
432 sal_uInt16 nNewType = bIsShared ? RT_SHARED : RT_NAME;
433 Modify_Impl( NULL, NULL, NULL, NULL, &nNewType,formula::FormulaGrammar::GRAM_PODF_A1 );
434 }
435 }
436 }
437
getPropertyValue(const rtl::OUString & rPropertyName)438 uno::Any SAL_CALL ScNamedRangeObj::getPropertyValue( const rtl::OUString& rPropertyName )
439 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
440 uno::RuntimeException)
441 {
442 ScUnoGuard aGuard;
443 uno::Any aRet;
444 if ( rPropertyName.equalsAscii( SC_UNO_LINKDISPBIT ) )
445 {
446 // no target bitmaps for individual entries (would be all equal)
447 // ScLinkTargetTypeObj::SetLinkTargetBitmap( aRet, SC_LINKTARGETTYPE_RANGENAME );
448 }
449 else if ( rPropertyName.equalsAscii( SC_UNO_LINKDISPNAME ) )
450 aRet <<= rtl::OUString( aName );
451 else if ( rPropertyName.equalsAscii( SC_UNONAME_TOKENINDEX ) )
452 {
453 // get index for use in formula tokens (read-only)
454 ScRangeData* pData = GetRangeData_Impl();
455 if (pData)
456 aRet <<= static_cast<sal_Int32>(pData->GetIndex());
457 }
458 else if ( rPropertyName.equalsAscii( SC_UNONAME_ISSHAREDFMLA ) )
459 {
460 if( ScRangeData* pData = GetRangeData_Impl() )
461 aRet <<= static_cast< bool >( pData->HasType( RT_SHARED ) );
462 }
463 return aRet;
464 }
465
SC_IMPL_DUMMY_PROPERTY_LISTENER(ScNamedRangeObj)466 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScNamedRangeObj )
467
468 // lang::XServiceInfo
469
470 rtl::OUString SAL_CALL ScNamedRangeObj::getImplementationName() throw(uno::RuntimeException)
471 {
472 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScNamedRangeObj" ) );
473 }
474
supportsService(const rtl::OUString & rServiceName)475 sal_Bool SAL_CALL ScNamedRangeObj::supportsService( const rtl::OUString& rServiceName )
476 throw(uno::RuntimeException)
477 {
478 return rServiceName.equalsAscii( SCNAMEDRANGEOBJ_SERVICE ) ||
479 rServiceName.equalsAscii( SCLINKTARGET_SERVICE );
480 }
481
getSupportedServiceNames()482 uno::Sequence<rtl::OUString> SAL_CALL ScNamedRangeObj::getSupportedServiceNames()
483 throw(uno::RuntimeException)
484 {
485 uno::Sequence<rtl::OUString> aRet(2);
486 aRet[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SCNAMEDRANGEOBJ_SERVICE ) );
487 aRet[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SCLINKTARGET_SERVICE ) );
488 return aRet;
489 }
490
491
492 // XUnoTunnel
493
getSomething(const uno::Sequence<sal_Int8> & rId)494 sal_Int64 SAL_CALL ScNamedRangeObj::getSomething(
495 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
496 {
497 if ( rId.getLength() == 16 &&
498 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
499 rId.getConstArray(), 16 ) )
500 {
501 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
502 }
503 return 0;
504 }
505
506 // static
getUnoTunnelId()507 const uno::Sequence<sal_Int8>& ScNamedRangeObj::getUnoTunnelId()
508 {
509 static uno::Sequence<sal_Int8> * pSeq = 0;
510 if( !pSeq )
511 {
512 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
513 if( !pSeq )
514 {
515 static uno::Sequence< sal_Int8 > aSeq( 16 );
516 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
517 pSeq = &aSeq;
518 }
519 }
520 return *pSeq;
521 }
522
523 // static
getImplementation(const uno::Reference<uno::XInterface> xObj)524 ScNamedRangeObj* ScNamedRangeObj::getImplementation( const uno::Reference<uno::XInterface> xObj )
525 {
526 ScNamedRangeObj* pRet = NULL;
527 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
528 if (xUT.is())
529 pRet = reinterpret_cast<ScNamedRangeObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
530 return pRet;
531 }
532
533 //------------------------------------------------------------------------
534
ScNamedRangesObj(ScDocShell * pDocSh)535 ScNamedRangesObj::ScNamedRangesObj(ScDocShell* pDocSh) :
536 pDocShell( pDocSh )
537 {
538 pDocShell->GetDocument()->AddUnoObject(*this);
539 }
540
~ScNamedRangesObj()541 ScNamedRangesObj::~ScNamedRangesObj()
542 {
543 if (pDocShell)
544 pDocShell->GetDocument()->RemoveUnoObject(*this);
545 }
546
Notify(SfxBroadcaster &,const SfxHint & rHint)547 void ScNamedRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
548 {
549 // Referenz-Update interessiert hier nicht
550
551 if ( rHint.ISA( SfxSimpleHint ) &&
552 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
553 {
554 pDocShell = NULL; // ungueltig geworden
555 }
556 }
557
558 // sheet::XNamedRanges
559
GetObjectByIndex_Impl(sal_uInt16 nIndex)560 ScNamedRangeObj* ScNamedRangesObj::GetObjectByIndex_Impl(sal_uInt16 nIndex)
561 {
562 if (pDocShell)
563 {
564 ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
565 if (pNames)
566 {
567 sal_uInt16 nCount = pNames->GetCount();
568 sal_uInt16 nPos = 0;
569 for (sal_uInt16 i=0; i<nCount; i++)
570 {
571 ScRangeData* pData = (*pNames)[i];
572 if (lcl_UserVisibleName(pData)) // interne weglassen
573 {
574 if ( nPos == nIndex )
575 return new ScNamedRangeObj( pDocShell, pData->GetName(), pData->GetScopeSheetName() );
576 ++nPos;
577 }
578 }
579 }
580 }
581 return NULL;
582 }
583
GetObjectByName_Impl(const rtl::OUString & aName)584 ScNamedRangeObj* ScNamedRangesObj::GetObjectByName_Impl(const rtl::OUString& aName)
585 {
586 if ( pDocShell && hasByName(aName) )
587 return new ScNamedRangeObj( pDocShell, String(aName) );
588 return NULL;
589 }
590
GetObjectByScopeName_Impl(const::rtl::OUString & aScopeName,const::rtl::OUString & aRangeName)591 ScNamedRangeObj* ScNamedRangesObj::GetObjectByScopeName_Impl(const ::rtl::OUString& aScopeName, const ::rtl::OUString& aRangeName)
592 {
593 if ( pDocShell && hasByScopeName(aScopeName, aRangeName) )
594 return new ScNamedRangeObj( pDocShell, String(aRangeName),String(aScopeName) );
595 return NULL;
596 }
ImplAddNewByScopeAndName(SCTAB aScope,const::rtl::OUString & aRangeName,const::rtl::OUString & aContent,const::com::sun::star::table::CellAddress & aPosition,sal_Int32 nUnoType)597 void ScNamedRangesObj::ImplAddNewByScopeAndName(SCTAB aScope, const ::rtl::OUString& aRangeName, const ::rtl::OUString& aContent,
598 const ::com::sun::star::table::CellAddress& aPosition, sal_Int32 nUnoType) throw(uno::RuntimeException)
599 {
600 ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, aPosition.Sheet );
601
602 sal_uInt16 nNewType = RT_NAME;
603 if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA ) nNewType |= RT_CRITERIA;
604 if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA ) nNewType |= RT_PRINTAREA;
605 if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER ) nNewType |= RT_COLHEADER;
606 if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER ) nNewType |= RT_ROWHEADER;
607
608 bool bDone = false;
609 if (pDocShell)
610 {
611 ScDocument* pDoc = pDocShell->GetDocument();
612 ScRangeName* pNames = pDoc->GetRangeName();
613 sal_uInt16 nIndex = 0;
614 String aNameStr(aRangeName);
615 String aContStr(aContent);
616 if (pNames && !pNames->SearchName(aNameStr, nIndex,aScope))
617 {
618
619 // GRAM_PODF_A1 for API compatibility.
620 ScRangeData* pNew = new ScRangeData( pDoc, aNameStr, aContStr,
621 aPos, nNewType,formula::FormulaGrammar::GRAM_PODF_A1 );//GRAM_ODFF,//
622
623 pNew->SetRangeScope(aScope);
624
625 const bool bSupportUndo(!pDoc->IsImportingXML());
626 if ( bSupportUndo )
627 {
628 ScRangeName* pNewRanges = new ScRangeName( *pNames );
629 if ( pNewRanges->Insert(pNew) )
630 {
631 ScDocFunc aFunc(*pDocShell);
632 aFunc.SetNewRangeNames( pNewRanges, sal_True );
633 bDone = true;
634 }
635 else
636 {
637 delete pNew;
638 delete pNewRanges;
639 }
640 }
641 else
642 {
643 if ( pNames->Insert(pNew) )
644 {
645 ScDocFunc aFunc(*pDocShell);
646 aFunc.SetNewRangeNames( pNames, sal_True );
647 bDone = true;
648 }
649 else
650 {
651 delete pNew;
652 }
653 }
654 }
655 }
656
657 if (!bDone)
658 throw uno::RuntimeException(); // no other exceptions specified
659 }
660
addNewByName(const rtl::OUString & aName,const rtl::OUString & aContent,const table::CellAddress & aPosition,sal_Int32 nUnoType)661 void SAL_CALL ScNamedRangesObj::addNewByName( const rtl::OUString& aName,
662 const rtl::OUString& aContent, const table::CellAddress& aPosition,
663 sal_Int32 nUnoType ) throw(uno::RuntimeException)
664 {
665 ScUnoGuard aGuard;
666 ImplAddNewByScopeAndName(MAXTABCOUNT, aName, aContent, aPosition, nUnoType);
667 }
668
669
addNewByScopeName(const rtl::OUString & aScopeName,const rtl::OUString & aRangeName,const rtl::OUString & aContent,const table::CellAddress & aPosition,sal_Int32 nUnoType)670 void SAL_CALL ScNamedRangesObj::addNewByScopeName( const rtl::OUString& aScopeName,const rtl::OUString& aRangeName,
671 const rtl::OUString& aContent, const table::CellAddress& aPosition,
672 sal_Int32 nUnoType ) throw(uno::RuntimeException)
673 {
674 ScUnoGuard aGuard;
675 SCTAB scope = MAXTABCOUNT;
676 if (aScopeName.getLength() != 0 && pDocShell &&
677 !pDocShell->GetDocument()->GetTable( String(aScopeName), scope ) )
678 throw uno::RuntimeException();
679 ImplAddNewByScopeAndName(scope, aRangeName, aContent, aPosition, nUnoType);
680
681
682 }
683
addNewFromTitles(const table::CellRangeAddress & aSource,sheet::Border aBorder)684 void SAL_CALL ScNamedRangesObj::addNewFromTitles( const table::CellRangeAddress& aSource,
685 sheet::Border aBorder ) throw(uno::RuntimeException)
686 {
687 ScUnoGuard aGuard;
688 //! das darf kein enum sein, weil mehrere Bits gesetzt sein koennen !!!
689
690 sal_Bool bTop = ( aBorder == sheet::Border_TOP );
691 sal_Bool bLeft = ( aBorder == sheet::Border_LEFT );
692 sal_Bool bBottom = ( aBorder == sheet::Border_BOTTOM );
693 sal_Bool bRight = ( aBorder == sheet::Border_RIGHT );
694
695 ScRange aRange;
696 ScUnoConversion::FillScRange( aRange, aSource );
697
698 sal_uInt16 nFlags = 0;
699 if (bTop) nFlags |= NAME_TOP;
700 if (bLeft) nFlags |= NAME_LEFT;
701 if (bBottom) nFlags |= NAME_BOTTOM;
702 if (bRight) nFlags |= NAME_RIGHT;
703
704 if (nFlags)
705 {
706 ScDocFunc aFunc(*pDocShell);
707 aFunc.CreateNames( aRange, nFlags, sal_True );
708 }
709 }
710
ImplRemoveByScopeAndName(SCTAB aScope,const::rtl::OUString & aRangeName)711 void ScNamedRangesObj::ImplRemoveByScopeAndName(SCTAB aScope, const ::rtl::OUString& aRangeName)
712 throw(uno::RuntimeException)
713 {
714 bool bDone = false;
715 if (pDocShell)
716 {
717 ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
718 if (pNames)
719 {
720 sal_uInt16 nPos = 0;
721 if (pNames->SearchName( String(aRangeName), nPos, aScope ))
722 if ( lcl_UserVisibleName((*pNames)[nPos]) )
723 {
724 ScRangeName* pNewRanges = new ScRangeName(*pNames);
725 pNewRanges->AtFree(nPos);
726 ScDocFunc aFunc(*pDocShell);
727 aFunc.SetNewRangeNames( pNewRanges, sal_True );
728 bDone = true;
729 }
730 }
731 }
732
733 if (!bDone)
734 throw uno::RuntimeException(); // no other exceptions specified
735 }
736
removeByName(const rtl::OUString & aName)737 void SAL_CALL ScNamedRangesObj::removeByName( const rtl::OUString& aName )
738 throw(uno::RuntimeException)
739 {
740 ScUnoGuard aGuard;
741 ImplRemoveByScopeAndName(MAXTABCOUNT, aName);
742 }
743
744
removeByScopeName(const::rtl::OUString & aScopeName,const::rtl::OUString & aRangeName)745 void SAL_CALL ScNamedRangesObj::removeByScopeName( const ::rtl::OUString& aScopeName, const ::rtl::OUString& aRangeName )
746 throw(uno::RuntimeException)
747 {
748 ScUnoGuard aGuard;
749 SCTAB scope = MAXTABCOUNT;
750 if (aScopeName.getLength() != 0 && pDocShell &&
751 !pDocShell->GetDocument()->GetTable( String(aScopeName), scope ))
752 throw uno::RuntimeException();
753 ImplRemoveByScopeAndName(scope, aRangeName);
754 }
755
756
outputList(const table::CellAddress & aOutputPosition)757 void SAL_CALL ScNamedRangesObj::outputList( const table::CellAddress& aOutputPosition )
758 throw(uno::RuntimeException)
759 {
760 ScUnoGuard aGuard;
761 ScAddress aPos( (SCCOL)aOutputPosition.Column, (SCROW)aOutputPosition.Row, aOutputPosition.Sheet );
762 if (pDocShell)
763 {
764 ScDocFunc aFunc(*pDocShell);
765 aFunc.InsertNameList( aPos, sal_True );
766 }
767 }
768
769 // container::XEnumerationAccess
770
createEnumeration()771 uno::Reference<container::XEnumeration> SAL_CALL ScNamedRangesObj::createEnumeration()
772 throw(uno::RuntimeException)
773 {
774 ScUnoGuard aGuard;
775 return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.NamedRangesEnumeration")));
776 }
777
778 // container::XIndexAccess
779
getCount()780 sal_Int32 SAL_CALL ScNamedRangesObj::getCount() throw(uno::RuntimeException)
781 {
782 ScUnoGuard aGuard;
783 long nRet = 0;
784 if (pDocShell)
785 {
786 ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
787 if (pNames)
788 {
789 sal_uInt16 nCount = pNames->GetCount();
790 for (sal_uInt16 i=0; i<nCount; i++)
791 if (lcl_UserVisibleName( (*pNames)[i] )) // interne weglassen
792 ++nRet;
793 }
794 }
795 return nRet;
796 }
797
getByIndex(sal_Int32 nIndex)798 uno::Any SAL_CALL ScNamedRangesObj::getByIndex( sal_Int32 nIndex )
799 throw(lang::IndexOutOfBoundsException,
800 lang::WrappedTargetException, uno::RuntimeException)
801 {
802 ScUnoGuard aGuard;
803 uno::Reference< sheet::XNamedRange2 > xRange(GetObjectByIndex_Impl((sal_uInt16)nIndex));
804 if ( xRange.is() )
805 return uno::makeAny(xRange);
806 else
807 throw lang::IndexOutOfBoundsException();
808 // return uno::Any();
809 }
810
getElementType()811 uno::Type SAL_CALL ScNamedRangesObj::getElementType() throw(uno::RuntimeException)
812 {
813 ScUnoGuard aGuard;
814 return ::getCppuType((const uno::Reference< sheet::XNamedRange2 >*)0); // muss zu getByIndex passen
815 }
816
hasElements()817 sal_Bool SAL_CALL ScNamedRangesObj::hasElements() throw(uno::RuntimeException)
818 {
819 ScUnoGuard aGuard;
820 return ( getCount() != 0 );
821 }
822
getByName(const rtl::OUString & aName)823 uno::Any SAL_CALL ScNamedRangesObj::getByName( const rtl::OUString& aName )
824 throw(container::NoSuchElementException,
825 lang::WrappedTargetException, uno::RuntimeException)
826 {
827 ScUnoGuard aGuard;
828 uno::Reference< sheet::XNamedRange2 > xRange(GetObjectByName_Impl(aName));
829 if ( xRange.is() )
830 return uno::makeAny(xRange);
831 else
832 throw container::NoSuchElementException();
833 // return uno::Any();
834 }
835
getByScopeName(const rtl::OUString & aScopeName,const rtl::OUString & aRangeName)836 uno::Any SAL_CALL ScNamedRangesObj::getByScopeName( const rtl::OUString& aScopeName, const rtl::OUString& aRangeName )
837 throw(container::NoSuchElementException,
838 lang::WrappedTargetException, uno::RuntimeException)
839 {
840 ScUnoGuard aGuard;
841 uno::Reference< sheet::XNamedRange2 > xRange(GetObjectByScopeName_Impl(aScopeName, aRangeName));
842 if ( xRange.is() )
843 return uno::makeAny(xRange);
844 else
845 throw container::NoSuchElementException();
846 // return uno::Any();
847 }
getElementNames()848 uno::Sequence<rtl::OUString> SAL_CALL ScNamedRangesObj::getElementNames()
849 throw(uno::RuntimeException)
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<rtl::OUString> aSeq(nVisCount);
859 rtl::OUString* 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 pAry[nVisPos++] = pData->GetName();
868 }
869 // DBG_ASSERT(nVisPos == nVisCount, "huch, verzaehlt?");
870 return aSeq;
871 }
872 }
873 return uno::Sequence<rtl::OUString>(0);
874 }
875
getElementScopeNames()876 uno::Sequence< sheet::RangeScopeName > SAL_CALL ScNamedRangesObj::getElementScopeNames()
877 throw(uno::RuntimeException)
878 {
879 ScUnoGuard aGuard;
880 if (pDocShell)
881 {
882 ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
883 if (pNames)
884 {
885 long nVisCount = getCount(); // Namen mit lcl_UserVisibleName
886 uno::Sequence<sheet::RangeScopeName> aSeq(nVisCount);
887 sheet::RangeScopeName * pAry = aSeq.getArray();
888
889 sal_uInt16 nCount = pNames->GetCount();
890 sal_uInt16 nVisPos = 0;
891 for (sal_uInt16 i=0; i<nCount; i++)
892 {
893 ScRangeData* pData = (*pNames)[i];
894 if ( lcl_UserVisibleName(pData) )
895 {
896 pAry[nVisPos].RangeName = pData->GetName();
897 pAry[nVisPos++].ScopeName = pData->GetScopeSheetName();
898 }
899 }
900 // DBG_ASSERT(nVisPos == nVisCount, "huch, verzaehlt?");
901 return aSeq;
902 }
903 }
904 return uno::Sequence< sheet::RangeScopeName >(0);
905 }
hasByName(const rtl::OUString & aName)906 sal_Bool SAL_CALL ScNamedRangesObj::hasByName( const rtl::OUString& aName )
907 throw(uno::RuntimeException)
908 {
909 ScUnoGuard aGuard;
910 if (pDocShell)
911 {
912 ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
913 if (pNames)
914 {
915 sal_uInt16 nPos = 0;
916 if (pNames->SearchName( String(aName), nPos ))
917 if ( lcl_UserVisibleName((*pNames)[nPos]) )
918 return sal_True;
919 }
920 }
921 return sal_False;
922 }
923
hasByScopeName(const::rtl::OUString & aScopeName,const::rtl::OUString & aRangeName)924 sal_Bool SAL_CALL ScNamedRangesObj::hasByScopeName( const ::rtl::OUString& aScopeName, const ::rtl::OUString& aRangeName)
925 throw(uno::RuntimeException)
926 {
927 ScUnoGuard aGuard;
928 if (pDocShell)
929 {
930 SCTAB scope = MAXTABCOUNT;
931 if (aScopeName.getLength() != 0 && !pDocShell->GetDocument()->GetTable( String(aScopeName), scope ) )
932 return sal_False;
933
934 ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
935 if (pNames)
936 {
937 sal_uInt16 nPos = 0;
938 if (pNames->SearchName( String(aRangeName), nPos, scope ))
939 if ( lcl_UserVisibleName((*pNames)[nPos]) )
940 return sal_True;
941 }
942 }
943 return sal_False;
944 }
945 /** called from the XActionLockable interface methods on initial locking */
lock()946 void ScNamedRangesObj::lock()
947 {
948 pDocShell->GetDocument()->CompileNameFormula( sal_True ); // CreateFormulaString
949 }
950
951 /** called from the XActionLockable interface methods on final unlock */
unlock()952 void ScNamedRangesObj::unlock()
953 {
954 pDocShell->GetDocument()->CompileNameFormula( sal_False ); // CompileFormulaString
955 }
956
957 // document::XActionLockable
958
isActionLocked()959 sal_Bool ScNamedRangesObj::isActionLocked() throw(uno::RuntimeException)
960 {
961 ScUnoGuard aGuard;
962 return pDocShell->GetDocument()->GetNamedRangesLockCount() != 0;
963 }
964
addActionLock()965 void ScNamedRangesObj::addActionLock() throw(uno::RuntimeException)
966 {
967 ScUnoGuard aGuard;
968 ScDocument* pDoc = pDocShell->GetDocument();
969 sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
970 ++nLockCount;
971 if ( nLockCount == 1 )
972 {
973 lock();
974 }
975 pDoc->SetNamedRangesLockCount( nLockCount );
976 }
977
removeActionLock()978 void ScNamedRangesObj::removeActionLock() throw(uno::RuntimeException)
979 {
980 ScUnoGuard aGuard;
981 ScDocument* pDoc = pDocShell->GetDocument();
982 sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
983 if ( nLockCount > 0 )
984 {
985 --nLockCount;
986 if ( nLockCount == 0 )
987 {
988 unlock();
989 }
990 pDoc->SetNamedRangesLockCount( nLockCount );
991 }
992 }
993
setActionLocks(sal_Int16 nLock)994 void ScNamedRangesObj::setActionLocks( sal_Int16 nLock ) throw(uno::RuntimeException)
995 {
996 ScUnoGuard aGuard;
997 if ( nLock >= 0 )
998 {
999 ScDocument* pDoc = pDocShell->GetDocument();
1000 sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
1001 if ( nLock == 0 && nLockCount > 0 )
1002 {
1003 unlock();
1004 }
1005 if ( nLock > 0 && nLockCount == 0 )
1006 {
1007 lock();
1008 }
1009 pDoc->SetNamedRangesLockCount( nLock );
1010 }
1011 }
1012
resetActionLocks()1013 sal_Int16 ScNamedRangesObj::resetActionLocks() throw(uno::RuntimeException)
1014 {
1015 ScUnoGuard aGuard;
1016 ScDocument* pDoc = pDocShell->GetDocument();
1017 sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
1018 if ( nLockCount > 0 )
1019 {
1020 unlock();
1021 }
1022 pDoc->SetNamedRangesLockCount( 0 );
1023 return nLockCount;
1024 }
1025
1026 //------------------------------------------------------------------------
1027
ScLabelRangeObj(ScDocShell * pDocSh,sal_Bool bCol,const ScRange & rR)1028 ScLabelRangeObj::ScLabelRangeObj(ScDocShell* pDocSh, sal_Bool bCol, const ScRange& rR) :
1029 pDocShell( pDocSh ),
1030 bColumn( bCol ),
1031 aRange( rR )
1032 {
1033 pDocShell->GetDocument()->AddUnoObject(*this);
1034 }
1035
~ScLabelRangeObj()1036 ScLabelRangeObj::~ScLabelRangeObj()
1037 {
1038 if (pDocShell)
1039 pDocShell->GetDocument()->RemoveUnoObject(*this);
1040 }
1041
Notify(SfxBroadcaster &,const SfxHint & rHint)1042 void ScLabelRangeObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
1043 {
1044 //! Ref-Update !!!
1045
1046 if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
1047 pDocShell = NULL; // ungueltig geworden
1048 }
1049
1050 // Hilfsfuntionen
1051
GetData_Impl()1052 ScRangePair* ScLabelRangeObj::GetData_Impl()
1053 {
1054 ScRangePair* pRet = NULL;
1055 if (pDocShell)
1056 {
1057 ScDocument* pDoc = pDocShell->GetDocument();
1058 ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
1059 if (pList)
1060 pRet = pList->Find( aRange );
1061 }
1062 return pRet;
1063 }
1064
Modify_Impl(const ScRange * pLabel,const ScRange * pData)1065 void ScLabelRangeObj::Modify_Impl( const ScRange* pLabel, const ScRange* pData )
1066 {
1067 if (pDocShell)
1068 {
1069 ScDocument* pDoc = pDocShell->GetDocument();
1070 ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
1071 if (pOldList)
1072 {
1073 ScRangePairListRef xNewList(pOldList->Clone());
1074 ScRangePair* pEntry = xNewList->Find( aRange );
1075 if (pEntry)
1076 {
1077 xNewList->Remove( pEntry ); // nur aus der Liste entfernt, nicht geloescht
1078
1079 if ( pLabel )
1080 pEntry->GetRange(0) = *pLabel;
1081 if ( pData )
1082 pEntry->GetRange(1) = *pData;
1083
1084 xNewList->Join( *pEntry );
1085 delete pEntry;
1086
1087 if (bColumn)
1088 pDoc->GetColNameRangesRef() = xNewList;
1089 else
1090 pDoc->GetRowNameRangesRef() = xNewList;
1091
1092 pDoc->CompileColRowNameFormula();
1093 pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
1094 pDocShell->SetDocumentModified();
1095
1096 //! Undo ?!?! (hier und aus Dialog)
1097
1098 if ( pLabel )
1099 aRange = *pLabel; // Objekt anpassen, um Range wiederzufinden
1100 }
1101 }
1102 }
1103 }
1104
1105 // sheet::XLabelRange
1106
getLabelArea()1107 table::CellRangeAddress SAL_CALL ScLabelRangeObj::getLabelArea()
1108 throw(uno::RuntimeException)
1109 {
1110 ScUnoGuard aGuard;
1111 table::CellRangeAddress aRet;
1112 ScRangePair* pData = GetData_Impl();
1113 if (pData)
1114 ScUnoConversion::FillApiRange( aRet, pData->GetRange(0) );
1115 return aRet;
1116 }
1117
setLabelArea(const table::CellRangeAddress & aLabelArea)1118 void SAL_CALL ScLabelRangeObj::setLabelArea( const table::CellRangeAddress& aLabelArea )
1119 throw(uno::RuntimeException)
1120 {
1121 ScUnoGuard aGuard;
1122 ScRange aLabelRange;
1123 ScUnoConversion::FillScRange( aLabelRange, aLabelArea );
1124 Modify_Impl( &aLabelRange, NULL );
1125 }
1126
getDataArea()1127 table::CellRangeAddress SAL_CALL ScLabelRangeObj::getDataArea()
1128 throw(uno::RuntimeException)
1129 {
1130 ScUnoGuard aGuard;
1131 table::CellRangeAddress aRet;
1132 ScRangePair* pData = GetData_Impl();
1133 if (pData)
1134 ScUnoConversion::FillApiRange( aRet, pData->GetRange(1) );
1135 return aRet;
1136 }
1137
setDataArea(const table::CellRangeAddress & aDataArea)1138 void SAL_CALL ScLabelRangeObj::setDataArea( const table::CellRangeAddress& aDataArea )
1139 throw(uno::RuntimeException)
1140 {
1141 ScUnoGuard aGuard;
1142 ScRange aDataRange;
1143 ScUnoConversion::FillScRange( aDataRange, aDataArea );
1144 Modify_Impl( NULL, &aDataRange );
1145 }
1146
1147 //------------------------------------------------------------------------
1148
ScLabelRangesObj(ScDocShell * pDocSh,sal_Bool bCol)1149 ScLabelRangesObj::ScLabelRangesObj(ScDocShell* pDocSh, sal_Bool bCol) :
1150 pDocShell( pDocSh ),
1151 bColumn( bCol )
1152 {
1153 pDocShell->GetDocument()->AddUnoObject(*this);
1154 }
1155
~ScLabelRangesObj()1156 ScLabelRangesObj::~ScLabelRangesObj()
1157 {
1158 if (pDocShell)
1159 pDocShell->GetDocument()->RemoveUnoObject(*this);
1160 }
1161
Notify(SfxBroadcaster &,const SfxHint & rHint)1162 void ScLabelRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
1163 {
1164 // Referenz-Update interessiert hier nicht
1165
1166 if ( rHint.ISA( SfxSimpleHint ) &&
1167 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
1168 {
1169 pDocShell = NULL; // ungueltig geworden
1170 }
1171 }
1172
1173 // sheet::XLabelRanges
1174
GetObjectByIndex_Impl(sal_uInt16 nIndex)1175 ScLabelRangeObj* ScLabelRangesObj::GetObjectByIndex_Impl(sal_uInt16 nIndex)
1176 {
1177 if (pDocShell)
1178 {
1179 ScDocument* pDoc = pDocShell->GetDocument();
1180 ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
1181 if ( pList && nIndex < pList->Count() )
1182 {
1183 ScRangePair* pData = pList->GetObject(nIndex);
1184 if (pData)
1185 return new ScLabelRangeObj( pDocShell, bColumn, pData->GetRange(0) );
1186 }
1187 }
1188 return NULL;
1189 }
1190
addNew(const table::CellRangeAddress & aLabelArea,const table::CellRangeAddress & aDataArea)1191 void SAL_CALL ScLabelRangesObj::addNew( const table::CellRangeAddress& aLabelArea,
1192 const table::CellRangeAddress& aDataArea )
1193 throw(uno::RuntimeException)
1194 {
1195 ScUnoGuard aGuard;
1196 if (pDocShell)
1197 {
1198 ScDocument* pDoc = pDocShell->GetDocument();
1199 ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
1200 if (pOldList)
1201 {
1202 ScRangePairListRef xNewList(pOldList->Clone());
1203
1204 ScRange aLabelRange;
1205 ScRange aDataRange;
1206 ScUnoConversion::FillScRange( aLabelRange, aLabelArea );
1207 ScUnoConversion::FillScRange( aDataRange, aDataArea );
1208 xNewList->Join( ScRangePair( aLabelRange, aDataRange ) );
1209
1210 if (bColumn)
1211 pDoc->GetColNameRangesRef() = xNewList;
1212 else
1213 pDoc->GetRowNameRangesRef() = xNewList;
1214
1215 pDoc->CompileColRowNameFormula();
1216 pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
1217 pDocShell->SetDocumentModified();
1218
1219 //! Undo ?!?! (hier und aus Dialog)
1220 }
1221 }
1222 }
1223
removeByIndex(sal_Int32 nIndex)1224 void SAL_CALL ScLabelRangesObj::removeByIndex( sal_Int32 nIndex )
1225 throw(uno::RuntimeException)
1226 {
1227 ScUnoGuard aGuard;
1228 sal_Bool bDone = sal_False;
1229 if (pDocShell)
1230 {
1231 ScDocument* pDoc = pDocShell->GetDocument();
1232 ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
1233
1234 if ( pOldList && nIndex >= 0 && nIndex < (sal_Int32)pOldList->Count() )
1235 {
1236 ScRangePairListRef xNewList(pOldList->Clone());
1237
1238 ScRangePair* pEntry = xNewList->GetObject( nIndex );
1239 if (pEntry)
1240 {
1241 xNewList->Remove( pEntry );
1242 delete pEntry;
1243
1244 if (bColumn)
1245 pDoc->GetColNameRangesRef() = xNewList;
1246 else
1247 pDoc->GetRowNameRangesRef() = xNewList;
1248
1249 pDoc->CompileColRowNameFormula();
1250 pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
1251 pDocShell->SetDocumentModified();
1252 bDone = sal_True;
1253
1254 //! Undo ?!?! (hier und aus Dialog)
1255 }
1256 }
1257 }
1258 if (!bDone)
1259 throw uno::RuntimeException(); // no other exceptions specified
1260 }
1261
1262 // container::XEnumerationAccess
1263
createEnumeration()1264 uno::Reference<container::XEnumeration> SAL_CALL ScLabelRangesObj::createEnumeration()
1265 throw(uno::RuntimeException)
1266 {
1267 ScUnoGuard aGuard;
1268 return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.LabelRangesEnumeration")));
1269 }
1270
1271 // container::XIndexAccess
1272
getCount()1273 sal_Int32 SAL_CALL ScLabelRangesObj::getCount() throw(uno::RuntimeException)
1274 {
1275 ScUnoGuard aGuard;
1276 if (pDocShell)
1277 {
1278 ScDocument* pDoc = pDocShell->GetDocument();
1279 ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
1280 if (pList)
1281 return pList->Count();
1282 }
1283 return 0;
1284 }
1285
getByIndex(sal_Int32 nIndex)1286 uno::Any SAL_CALL ScLabelRangesObj::getByIndex( sal_Int32 nIndex )
1287 throw(lang::IndexOutOfBoundsException,
1288 lang::WrappedTargetException, uno::RuntimeException)
1289 {
1290 ScUnoGuard aGuard;
1291 uno::Reference< sheet::XLabelRange > xRange(GetObjectByIndex_Impl((sal_uInt16)nIndex));
1292 if ( xRange.is() )
1293 return uno::makeAny(xRange);
1294 else
1295 throw lang::IndexOutOfBoundsException();
1296 // return uno::Any();
1297 }
1298
getElementType()1299 uno::Type SAL_CALL ScLabelRangesObj::getElementType() throw(uno::RuntimeException)
1300 {
1301 ScUnoGuard aGuard;
1302 return ::getCppuType((const uno::Reference< sheet::XLabelRange >*)0); // muss zu getByIndex passen
1303
1304 }
1305
hasElements()1306 sal_Bool SAL_CALL ScLabelRangesObj::hasElements() throw(uno::RuntimeException)
1307 {
1308 ScUnoGuard aGuard;
1309 return ( getCount() != 0 );
1310 }
1311
1312 //------------------------------------------------------------------------
1313
1314
1315
1316