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