xref: /trunk/main/sc/source/ui/unoobj/nameuno.cxx (revision 86e1cf34)
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 occurred...
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 occurred...
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