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