Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / sc / source / ui / unoobj / nameuno.cxx
blob14bcecac00d48f932fedf374be5083b0e84ba6d4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svl/smplhint.hxx>
21 #include <vcl/svapp.hxx>
23 #include <com/sun/star/sheet/NamedRangeFlag.hpp>
24 #include <com/sun/star/awt/XBitmap.hpp>
25 #include <com/sun/star/beans/PropertyAttribute.hpp>
27 #include <comphelper/servicehelper.hxx>
28 #include <cppuhelper/supportsservice.hxx>
30 using namespace ::com::sun::star;
31 using ::com::sun::star::uno::Reference;
32 using ::com::sun::star::uno::Any;
35 #include "nameuno.hxx"
36 #include "miscuno.hxx"
37 #include "cellsuno.hxx"
38 #include "convuno.hxx"
39 #include "targuno.hxx"
40 #include "tokenuno.hxx"
41 #include "tokenarray.hxx"
42 #include "docsh.hxx"
43 #include "docfunc.hxx"
44 #include "rangenam.hxx"
45 #include "unonames.hxx"
47 #include "scui_def.hxx"
49 static const SfxItemPropertyMapEntry* lcl_GetNamedRangeMap()
51 static const SfxItemPropertyMapEntry aNamedRangeMap_Impl[] =
53 {OUString(SC_UNO_LINKDISPBIT), 0, cppu::UnoType<awt::XBitmap>::get(), beans::PropertyAttribute::READONLY, 0 },
54 {OUString(SC_UNO_LINKDISPNAME), 0, cppu::UnoType<OUString>::get(), beans::PropertyAttribute::READONLY, 0 },
55 {OUString(SC_UNONAME_TOKENINDEX), 0, cppu::UnoType<sal_Int32>::get(), beans::PropertyAttribute::READONLY, 0 },
56 {OUString(SC_UNONAME_ISSHAREDFMLA), 0, getBooleanCppuType(), 0, 0 },
57 { OUString(), 0, css::uno::Type(), 0, 0 }
59 return aNamedRangeMap_Impl;
62 static const SfxItemPropertyMapEntry* lcl_GetNamedRangesMap()
64 static const SfxItemPropertyMapEntry aNamedRangesMap_Impl[] =
66 {OUString(SC_UNO_MODIFY_BROADCAST), 0, getBooleanCppuType(), 0, 0 },
67 { OUString(), 0, css::uno::Type(), 0, 0 }
69 return aNamedRangesMap_Impl;
72 #define SCNAMEDRANGEOBJ_SERVICE "com.sun.star.sheet.NamedRange"
74 SC_SIMPLE_SERVICE_INFO( ScLabelRangeObj, "ScLabelRangeObj", "com.sun.star.sheet.LabelRange" )
75 SC_SIMPLE_SERVICE_INFO( ScLabelRangesObj, "ScLabelRangesObj", "com.sun.star.sheet.LabelRanges" )
76 SC_SIMPLE_SERVICE_INFO( ScNamedRangesObj, "ScNamedRangesObj", "com.sun.star.sheet.NamedRanges" )
78 static bool lcl_UserVisibleName(const ScRangeData& rData)
80 //! as method to ScRangeData
82 return !rData.HasType(RT_DATABASE);
85 ScNamedRangeObj::ScNamedRangeObj( rtl::Reference< ScNamedRangesObj > xParent, ScDocShell* pDocSh, const OUString& rNm, Reference<container::XNamed> xSheet):
86 mxParent(xParent),
87 pDocShell( pDocSh ),
88 aName( rNm ),
89 mxSheet( xSheet )
91 pDocShell->GetDocument()->AddUnoObject(*this);
94 ScNamedRangeObj::~ScNamedRangeObj()
96 if (pDocShell)
97 pDocShell->GetDocument()->RemoveUnoObject(*this);
100 void ScNamedRangeObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
102 // reference update is of no interest
104 if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
105 pDocShell = NULL; // became invalid
108 // Helper functions
110 ScRangeData* ScNamedRangeObj::GetRangeData_Impl()
112 ScRangeData* pRet = NULL;
113 if (pDocShell)
115 ScRangeName* pNames;
116 SCTAB nTab = GetTab_Impl();
117 if (nTab >= 0)
118 pNames = pDocShell->GetDocument()->GetRangeName(nTab);
119 else
120 pNames = pDocShell->GetDocument()->GetRangeName();
121 if (pNames)
123 pRet = pNames->findByUpperName(ScGlobal::pCharClass->uppercase(aName));
124 if (pRet)
125 pRet->ValidateTabRefs(); // adjust relative tab refs to valid tables
128 return pRet;
131 SCTAB ScNamedRangeObj::GetTab_Impl()
133 if (mxSheet.is())
135 if (!pDocShell)
136 return -2;
137 ScDocument* pDoc = pDocShell->GetDocument();
138 SCTAB nTab;
139 OUString sName = mxSheet->getName();
140 pDoc->GetTable(sName, nTab);
141 return nTab;
143 else
144 return -1;//global range name
147 // sheet::XNamedRange
149 void ScNamedRangeObj::Modify_Impl( const OUString* pNewName, const ScTokenArray* pNewTokens, const OUString* pNewContent,
150 const ScAddress* pNewPos, const sal_uInt16* pNewType,
151 const formula::FormulaGrammar::Grammar eGrammar )
153 if (!pDocShell)
154 return;
156 ScDocument* pDoc = pDocShell->GetDocument();
157 ScRangeName* pNames;
158 SCTAB nTab = GetTab_Impl();
159 if (nTab >= 0)
160 pNames = pDoc->GetRangeName(nTab);
161 else
162 pNames = pDoc->GetRangeName();
163 if (!pNames)
164 return;
166 const ScRangeData* pOld = pNames->findByUpperName(ScGlobal::pCharClass->uppercase(aName));
167 if (!pOld)
168 return;
170 ScRangeName* pNewRanges = new ScRangeName(*pNames);
172 OUString aInsName = pOld->GetName();
173 if (pNewName)
174 aInsName = *pNewName;
176 OUString aContent; // Content string based =>
177 pOld->GetSymbol( aContent, eGrammar); // no problems with changed positions and such.
178 if (pNewContent)
179 aContent = *pNewContent;
181 ScAddress aPos = pOld->GetPos();
182 if (pNewPos)
183 aPos = *pNewPos;
185 sal_uInt16 nType = pOld->GetType();
186 if (pNewType)
187 nType = *pNewType;
189 ScRangeData* pNew = NULL;
190 if (pNewTokens)
191 pNew = new ScRangeData( pDoc, aInsName, *pNewTokens, aPos, nType );
192 else
193 pNew = new ScRangeData( pDoc, aInsName, aContent, aPos, nType, eGrammar );
195 pNew->SetIndex( pOld->GetIndex() );
197 pNewRanges->erase(*pOld);
198 if (pNewRanges->insert(pNew))
200 pDocShell->GetDocFunc().SetNewRangeNames(pNewRanges, mxParent->IsModifyAndBroadcast(), nTab);
202 aName = aInsName; //! broadcast?
204 else
206 pNew = NULL; //! uno::Exception/Error or something
207 delete pNewRanges;
212 OUString SAL_CALL ScNamedRangeObj::getName() throw(uno::RuntimeException, std::exception)
214 SolarMutexGuard aGuard;
215 return aName;
218 void SAL_CALL ScNamedRangeObj::setName( const OUString& aNewName )
219 throw (uno::RuntimeException, std::exception)
221 SolarMutexGuard aGuard;
222 //! adapt formulas ?????
224 OUString aNewStr(aNewName);
225 // GRAM_PODF_A1 for API compatibility.
226 Modify_Impl( &aNewStr, NULL, NULL, NULL, NULL,formula::FormulaGrammar::GRAM_PODF_A1 );
228 if ( aName != aNewStr ) // some error occurred...
229 throw uno::RuntimeException(); // no other exceptions specified
232 OUString SAL_CALL ScNamedRangeObj::getContent() throw(uno::RuntimeException, std::exception)
234 SolarMutexGuard aGuard;
235 OUString aContent;
236 ScRangeData* pData = GetRangeData_Impl();
237 if (pData)
238 // GRAM_PODF_A1 for API compatibility.
239 pData->GetSymbol( aContent,formula::FormulaGrammar::GRAM_PODF_A1);
240 return aContent;
243 void SAL_CALL ScNamedRangeObj::setContent( const OUString& aContent )
244 throw (uno::RuntimeException, std::exception)
246 SolarMutexGuard aGuard;
247 OUString aContStr(aContent);
248 // GRAM_PODF_A1 for API compatibility.
249 Modify_Impl( NULL, NULL, &aContStr, NULL, NULL,formula::FormulaGrammar::GRAM_PODF_A1 );
252 table::CellAddress SAL_CALL ScNamedRangeObj::getReferencePosition()
253 throw(uno::RuntimeException, std::exception)
255 SolarMutexGuard aGuard;
256 ScAddress aPos;
257 ScRangeData* pData = GetRangeData_Impl();
258 if (pData)
259 aPos = pData->GetPos();
260 table::CellAddress aAddress;
261 aAddress.Column = aPos.Col();
262 aAddress.Row = aPos.Row();
263 aAddress.Sheet = aPos.Tab();
264 if (pDocShell)
266 SCTAB nDocTabs = pDocShell->GetDocument()->GetTableCount();
267 if ( aAddress.Sheet >= nDocTabs && nDocTabs > 0 )
269 // Even after ValidateTabRefs, the position can be invalid if
270 // the content points to preceding tables. The resulting string
271 // is invalid in any case, so the position is just shifted.
272 aAddress.Sheet = nDocTabs - 1;
275 return aAddress;
278 void SAL_CALL ScNamedRangeObj::setReferencePosition( const table::CellAddress& aReferencePosition )
279 throw (uno::RuntimeException, std::exception)
281 SolarMutexGuard aGuard;
282 ScAddress aPos( (SCCOL)aReferencePosition.Column, (SCROW)aReferencePosition.Row, aReferencePosition.Sheet );
283 // GRAM_PODF_A1 for API compatibility.
284 Modify_Impl( NULL, NULL, NULL, &aPos, NULL,formula::FormulaGrammar::GRAM_PODF_A1 );
287 sal_Int32 SAL_CALL ScNamedRangeObj::getType() throw(uno::RuntimeException, std::exception)
289 SolarMutexGuard aGuard;
290 sal_Int32 nType=0;
291 ScRangeData* pData = GetRangeData_Impl();
292 if (pData)
294 // do not return internal RT_* flags
295 // see property 'IsSharedFormula' for RT_SHARED
296 if ( pData->HasType(RT_CRITERIA) ) nType |= sheet::NamedRangeFlag::FILTER_CRITERIA;
297 if ( pData->HasType(RT_PRINTAREA) ) nType |= sheet::NamedRangeFlag::PRINT_AREA;
298 if ( pData->HasType(RT_COLHEADER) ) nType |= sheet::NamedRangeFlag::COLUMN_HEADER;
299 if ( pData->HasType(RT_ROWHEADER) ) nType |= sheet::NamedRangeFlag::ROW_HEADER;
301 return nType;
304 void SAL_CALL ScNamedRangeObj::setType( sal_Int32 nUnoType )
305 throw (uno::RuntimeException, std::exception)
307 // see property 'IsSharedFormula' for RT_SHARED
308 SolarMutexGuard aGuard;
309 sal_uInt16 nNewType = RT_NAME;
310 if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA ) nNewType |= RT_CRITERIA;
311 if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA ) nNewType |= RT_PRINTAREA;
312 if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER ) nNewType |= RT_COLHEADER;
313 if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER ) nNewType |= RT_ROWHEADER;
315 // GRAM_PODF_A1 for API compatibility.
316 Modify_Impl( NULL, NULL, NULL, NULL, &nNewType,formula::FormulaGrammar::GRAM_PODF_A1 );
319 // XFormulaTokens
321 uno::Sequence<sheet::FormulaToken> SAL_CALL ScNamedRangeObj::getTokens()
322 throw (uno::RuntimeException, std::exception)
324 SolarMutexGuard aGuard;
325 uno::Sequence<sheet::FormulaToken> aSequence;
326 ScRangeData* pData = GetRangeData_Impl();
327 if (pData && pDocShell)
329 ScTokenArray* pTokenArray = pData->GetCode();
330 if ( pTokenArray )
331 (void)ScTokenConversion::ConvertToTokenSequence( *pDocShell->GetDocument(), aSequence, *pTokenArray );
333 return aSequence;
336 void SAL_CALL ScNamedRangeObj::setTokens( const uno::Sequence<sheet::FormulaToken>& rTokens )
337 throw (uno::RuntimeException, std::exception)
339 SolarMutexGuard aGuard;
340 if( pDocShell )
342 ScTokenArray aTokenArray;
343 (void)ScTokenConversion::ConvertToTokenArray( *pDocShell->GetDocument(), aTokenArray, rTokens );
344 // GRAM_PODF_A1 for API compatibility.
345 Modify_Impl( NULL, &aTokenArray, NULL, NULL, NULL, formula::FormulaGrammar::GRAM_PODF_A1 );
350 // XCellRangeSource
352 uno::Reference<table::XCellRange> SAL_CALL ScNamedRangeObj::getReferredCells()
353 throw(uno::RuntimeException, std::exception)
355 SolarMutexGuard aGuard;
356 ScRange aRange;
357 ScRangeData* pData = GetRangeData_Impl();
358 if ( pData && pData->IsValidReference( aRange ) )
360 //! static function to create ScCellObj/ScCellRangeObj at ScCellRangeObj ???
362 if ( aRange.aStart == aRange.aEnd )
363 return new ScCellObj( pDocShell, aRange.aStart );
364 else
365 return new ScCellRangeObj( pDocShell, aRange );
367 return NULL;
370 // beans::XPropertySet
372 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScNamedRangeObj::getPropertySetInfo()
373 throw(uno::RuntimeException, std::exception)
375 SolarMutexGuard aGuard;
376 static uno::Reference< beans::XPropertySetInfo > aRef(new SfxItemPropertySetInfo( lcl_GetNamedRangeMap() ));
377 return aRef;
380 void SAL_CALL ScNamedRangeObj::setPropertyValue(
381 const OUString& rPropertyName, const uno::Any& /*aValue*/ )
382 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
383 lang::IllegalArgumentException, lang::WrappedTargetException,
384 uno::RuntimeException, std::exception)
386 SolarMutexGuard aGuard;
387 if ( rPropertyName == SC_UNONAME_ISSHAREDFMLA )
389 // Ignore this.
393 uno::Any SAL_CALL ScNamedRangeObj::getPropertyValue( const OUString& rPropertyName )
394 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
395 uno::RuntimeException, std::exception)
397 SolarMutexGuard aGuard;
398 uno::Any aRet;
399 if ( rPropertyName == SC_UNO_LINKDISPBIT )
401 // no target bitmaps for individual entries (would be all equal)
402 // ScLinkTargetTypeObj::SetLinkTargetBitmap( aRet, SC_LINKTARGETTYPE_RANGENAME );
404 else if ( rPropertyName == SC_UNO_LINKDISPNAME )
405 aRet <<= OUString( aName );
406 else if ( rPropertyName == SC_UNONAME_TOKENINDEX )
408 // get index for use in formula tokens (read-only)
409 ScRangeData* pData = GetRangeData_Impl();
410 if (pData)
411 aRet <<= static_cast<sal_Int32>(pData->GetIndex());
413 else if ( rPropertyName == SC_UNONAME_ISSHAREDFMLA )
415 if (GetRangeData_Impl())
416 aRet <<= false;
418 return aRet;
421 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScNamedRangeObj )
423 // lang::XServiceInfo
425 OUString SAL_CALL ScNamedRangeObj::getImplementationName() throw(uno::RuntimeException, std::exception)
427 return OUString( "ScNamedRangeObj" );
430 sal_Bool SAL_CALL ScNamedRangeObj::supportsService( const OUString& rServiceName )
431 throw(uno::RuntimeException, std::exception)
433 return cppu::supportsService(this, rServiceName);
436 uno::Sequence<OUString> SAL_CALL ScNamedRangeObj::getSupportedServiceNames()
437 throw(uno::RuntimeException, std::exception)
439 uno::Sequence<OUString> aRet(2);
440 aRet[0] = OUString( SCNAMEDRANGEOBJ_SERVICE );
441 aRet[1] = OUString( SCLINKTARGET_SERVICE );
442 return aRet;
446 // XUnoTunnel
448 sal_Int64 SAL_CALL ScNamedRangeObj::getSomething(
449 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException, std::exception)
451 if ( rId.getLength() == 16 &&
452 0 == memcmp( getUnoTunnelId().getConstArray(),
453 rId.getConstArray(), 16 ) )
455 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
457 return 0;
460 namespace
462 class theScNamedRangeObjUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScNamedRangeObjUnoTunnelId> {};
465 const uno::Sequence<sal_Int8>& ScNamedRangeObj::getUnoTunnelId()
467 return theScNamedRangeObjUnoTunnelId::get().getSeq();
470 ScNamedRangesObj::ScNamedRangesObj(ScDocShell* pDocSh) :
471 mbModifyAndBroadcast(true),
472 pDocShell( pDocSh )
474 pDocShell->GetDocument()->AddUnoObject(*this);
477 ScNamedRangesObj::~ScNamedRangesObj()
479 if (pDocShell)
480 pDocShell->GetDocument()->RemoveUnoObject(*this);
483 void ScNamedRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
485 // reference update is of no interest
487 if ( rHint.ISA( SfxSimpleHint ) &&
488 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
490 pDocShell = NULL; // became invalid
494 bool ScNamedRangesObj::IsModifyAndBroadcast() const
496 return mbModifyAndBroadcast;
499 // sheet::XNamedRanges
501 void SAL_CALL ScNamedRangesObj::addNewByName( const OUString& aName,
502 const OUString& aContent, const table::CellAddress& aPosition,
503 sal_Int32 nUnoType )
504 throw (uno::RuntimeException, std::exception)
506 SolarMutexGuard aGuard;
507 ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, aPosition.Sheet );
509 sal_uInt16 nNewType = RT_NAME;
510 if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA ) nNewType |= RT_CRITERIA;
511 if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA ) nNewType |= RT_PRINTAREA;
512 if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER ) nNewType |= RT_COLHEADER;
513 if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER ) nNewType |= RT_ROWHEADER;
515 bool bDone = false;
516 if (pDocShell)
518 ScDocument* pDoc = pDocShell->GetDocument();
519 ScRangeName* pNames = GetRangeName_Impl();
520 if (pNames && !pNames->findByUpperName(ScGlobal::pCharClass->uppercase(aName)))
522 ScRangeName* pNewRanges = new ScRangeName( *pNames );
523 // GRAM_PODF_A1 for API compatibility.
524 ScRangeData* pNew = new ScRangeData( pDoc, aName, aContent,
525 aPos, nNewType,formula::FormulaGrammar::GRAM_PODF_A1 );
526 if ( pNewRanges->insert(pNew) )
528 pDocShell->GetDocFunc().SetNewRangeNames(pNewRanges, mbModifyAndBroadcast, GetTab_Impl());
529 bDone = true;
531 else
533 pNew = NULL;
534 delete pNewRanges;
539 if (!bDone)
540 throw uno::RuntimeException(); // no other exceptions specified
543 void SAL_CALL ScNamedRangesObj::addNewFromTitles( const table::CellRangeAddress& aSource,
544 sheet::Border aBorder ) throw(uno::RuntimeException, std::exception)
546 SolarMutexGuard aGuard;
547 //! this cannot be an enum, because multiple bits can be set !!!
549 bool bTop = ( aBorder == sheet::Border_TOP );
550 bool bLeft = ( aBorder == sheet::Border_LEFT );
551 bool bBottom = ( aBorder == sheet::Border_BOTTOM );
552 bool bRight = ( aBorder == sheet::Border_RIGHT );
554 ScRange aRange;
555 ScUnoConversion::FillScRange( aRange, aSource );
557 sal_uInt16 nFlags = 0;
558 if (bTop) nFlags |= NAME_TOP;
559 if (bLeft) nFlags |= NAME_LEFT;
560 if (bBottom) nFlags |= NAME_BOTTOM;
561 if (bRight) nFlags |= NAME_RIGHT;
563 if (nFlags)
564 pDocShell->GetDocFunc().CreateNames( aRange, nFlags, true, GetTab_Impl() );
567 void SAL_CALL ScNamedRangesObj::removeByName( const OUString& aName )
568 throw(uno::RuntimeException, std::exception)
570 SolarMutexGuard aGuard;
571 bool bDone = false;
572 if (pDocShell)
574 ScRangeName* pNames = GetRangeName_Impl();
575 if (pNames)
577 const ScRangeData* pData = pNames->findByUpperName(ScGlobal::pCharClass->uppercase(aName));
578 if (pData && lcl_UserVisibleName(*pData))
580 ScRangeName* pNewRanges = new ScRangeName(*pNames);
581 pNewRanges->erase(*pData);
582 pDocShell->GetDocFunc().SetNewRangeNames( pNewRanges, mbModifyAndBroadcast, GetTab_Impl());
583 bDone = true;
588 if (!bDone)
589 throw uno::RuntimeException(); // no other exceptions specified
592 void SAL_CALL ScNamedRangesObj::outputList( const table::CellAddress& aOutputPosition )
593 throw(uno::RuntimeException, std::exception)
595 SolarMutexGuard aGuard;
596 ScAddress aPos( (SCCOL)aOutputPosition.Column, (SCROW)aOutputPosition.Row, aOutputPosition.Sheet );
597 if (pDocShell)
598 pDocShell->GetDocFunc().InsertNameList( aPos, true );
601 // container::XEnumerationAccess
603 uno::Reference<container::XEnumeration> SAL_CALL ScNamedRangesObj::createEnumeration()
604 throw(uno::RuntimeException, std::exception)
606 SolarMutexGuard aGuard;
607 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.NamedRangesEnumeration"));
610 // container::XIndexAccess
612 sal_Int32 SAL_CALL ScNamedRangesObj::getCount() throw(uno::RuntimeException, std::exception)
614 SolarMutexGuard aGuard;
615 long nRet = 0;
616 if (pDocShell)
618 ScRangeName* pNames = GetRangeName_Impl();
619 if (pNames)
621 ScRangeName::const_iterator itr = pNames->begin(), itrEnd = pNames->end();
622 for (; itr != itrEnd; ++itr)
623 if (lcl_UserVisibleName(*itr->second))
624 ++nRet;
627 return nRet;
630 uno::Any SAL_CALL ScNamedRangesObj::getByIndex( sal_Int32 nIndex )
631 throw(lang::IndexOutOfBoundsException,
632 lang::WrappedTargetException, uno::RuntimeException, std::exception)
634 SolarMutexGuard aGuard;
635 uno::Reference< sheet::XNamedRange > xRange(GetObjectByIndex_Impl((sal_uInt16)nIndex));
636 if ( xRange.is() )
637 return uno::makeAny(xRange);
638 else
639 throw lang::IndexOutOfBoundsException();
642 uno::Type SAL_CALL ScNamedRangesObj::getElementType() throw(uno::RuntimeException, std::exception)
644 SolarMutexGuard aGuard;
645 return cppu::UnoType<sheet::XNamedRange>::get(); // must be suitable for getByIndex
648 sal_Bool SAL_CALL ScNamedRangesObj::hasElements() throw(uno::RuntimeException, std::exception)
650 SolarMutexGuard aGuard;
651 return ( getCount() != 0 );
654 Reference<beans::XPropertySetInfo> SAL_CALL ScNamedRangesObj::getPropertySetInfo()
655 throw(uno::RuntimeException, std::exception)
657 static Reference<beans::XPropertySetInfo> aRef(
658 new SfxItemPropertySetInfo(lcl_GetNamedRangesMap()));
659 return aRef;
662 void SAL_CALL ScNamedRangesObj::setPropertyValue(
663 const OUString& rPropertyName, const uno::Any& aValue )
664 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
665 lang::IllegalArgumentException, lang::WrappedTargetException,
666 uno::RuntimeException, std::exception)
668 if ( rPropertyName == SC_UNO_MODIFY_BROADCAST )
670 aValue >>= mbModifyAndBroadcast;
674 Any SAL_CALL ScNamedRangesObj::getPropertyValue( const OUString& rPropertyName )
675 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
676 uno::RuntimeException, std::exception)
678 Any aRet;
679 if ( rPropertyName == SC_UNO_MODIFY_BROADCAST )
681 aRet <<= mbModifyAndBroadcast;
684 return aRet;
687 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScNamedRangesObj )
689 uno::Any SAL_CALL ScNamedRangesObj::getByName( const OUString& aName )
690 throw(container::NoSuchElementException,
691 lang::WrappedTargetException, uno::RuntimeException, std::exception)
693 SolarMutexGuard aGuard;
694 uno::Reference< sheet::XNamedRange > xRange(GetObjectByName_Impl(aName));
695 if ( xRange.is() )
696 return uno::makeAny(xRange);
697 else
698 throw container::NoSuchElementException();
701 uno::Sequence<OUString> SAL_CALL ScNamedRangesObj::getElementNames()
702 throw(uno::RuntimeException, std::exception)
704 SolarMutexGuard aGuard;
705 if (pDocShell)
707 ScRangeName* pNames = GetRangeName_Impl();
708 if (pNames)
710 long nVisCount = getCount(); // names with lcl_UserVisibleName
711 uno::Sequence<OUString> aSeq(nVisCount);
712 OUString* pAry = aSeq.getArray();
713 sal_uInt16 nVisPos = 0;
714 ScRangeName::const_iterator itr = pNames->begin(), itrEnd = pNames->end();
715 for (; itr != itrEnd; ++itr)
717 if (lcl_UserVisibleName(*itr->second))
718 pAry[nVisPos++] = itr->second->GetName();
720 return aSeq;
723 return uno::Sequence<OUString>(0);
726 sal_Bool SAL_CALL ScNamedRangesObj::hasByName( const OUString& aName )
727 throw(uno::RuntimeException, std::exception)
729 SolarMutexGuard aGuard;
730 if (pDocShell)
732 ScRangeName* pNames = GetRangeName_Impl();
733 if (pNames)
735 const ScRangeData* pData = pNames->findByUpperName(ScGlobal::pCharClass->uppercase(aName));
736 if (pData && lcl_UserVisibleName(*pData))
737 return sal_True;
740 return false;
743 /** called from the XActionLockable interface methods on initial locking */
744 void ScNamedRangesObj::lock()
746 pDocShell->GetDocument()->PreprocessRangeNameUpdate();
749 /** called from the XActionLockable interface methods on final unlock */
750 void ScNamedRangesObj::unlock()
752 pDocShell->GetDocument()->PostprocessRangeNameUpdate();
755 // document::XActionLockable
757 sal_Bool ScNamedRangesObj::isActionLocked() throw(uno::RuntimeException, std::exception)
759 SolarMutexGuard aGuard;
760 return pDocShell->GetDocument()->GetNamedRangesLockCount() != 0;
763 void ScNamedRangesObj::addActionLock() throw(uno::RuntimeException, std::exception)
765 SolarMutexGuard aGuard;
766 ScDocument* pDoc = pDocShell->GetDocument();
767 sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
768 ++nLockCount;
769 if ( nLockCount == 1 )
771 lock();
773 pDoc->SetNamedRangesLockCount( nLockCount );
776 void ScNamedRangesObj::removeActionLock() throw(uno::RuntimeException, std::exception)
778 SolarMutexGuard aGuard;
779 ScDocument* pDoc = pDocShell->GetDocument();
780 sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
781 if ( nLockCount > 0 )
783 --nLockCount;
784 if ( nLockCount == 0 )
786 unlock();
788 pDoc->SetNamedRangesLockCount( nLockCount );
792 void ScNamedRangesObj::setActionLocks( sal_Int16 nLock ) throw(uno::RuntimeException, std::exception)
794 SolarMutexGuard aGuard;
795 if ( nLock >= 0 )
797 ScDocument* pDoc = pDocShell->GetDocument();
798 sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
799 if ( nLock == 0 && nLockCount > 0 )
801 unlock();
803 if ( nLock > 0 && nLockCount == 0 )
805 lock();
807 pDoc->SetNamedRangesLockCount( nLock );
811 sal_Int16 ScNamedRangesObj::resetActionLocks() throw(uno::RuntimeException, std::exception)
813 SolarMutexGuard aGuard;
814 ScDocument* pDoc = pDocShell->GetDocument();
815 sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount();
816 if ( nLockCount > 0 )
818 unlock();
820 pDoc->SetNamedRangesLockCount( 0 );
821 return nLockCount;
824 ScGlobalNamedRangesObj::ScGlobalNamedRangesObj(ScDocShell* pDocSh)
825 : ScNamedRangesObj(pDocSh)
830 ScGlobalNamedRangesObj::~ScGlobalNamedRangesObj()
835 ScNamedRangeObj* ScGlobalNamedRangesObj::GetObjectByIndex_Impl(sal_uInt16 nIndex)
837 if (!pDocShell)
838 return NULL;
840 ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName();
841 if (!pNames)
842 return NULL;
844 ScRangeName::const_iterator itr = pNames->begin(), itrEnd = pNames->end();
845 sal_uInt16 nPos = 0;
846 for (; itr != itrEnd; ++itr)
848 if (lcl_UserVisibleName(*itr->second))
850 if (nPos == nIndex)
851 return new ScNamedRangeObj(this, pDocShell, itr->second->GetName());
853 ++nPos;
855 return NULL;
858 ScNamedRangeObj* ScGlobalNamedRangesObj::GetObjectByName_Impl(const OUString& aName)
860 if ( pDocShell && hasByName(aName) )
861 return new ScNamedRangeObj(this, pDocShell, aName);
862 return NULL;
865 ScRangeName* ScGlobalNamedRangesObj::GetRangeName_Impl()
867 return pDocShell->GetDocument()->GetRangeName();
870 SCTAB ScGlobalNamedRangesObj::GetTab_Impl()
872 return -1;
875 ScLocalNamedRangesObj::ScLocalNamedRangesObj( ScDocShell* pDocSh, uno::Reference<container::XNamed> xSheet )
876 : ScNamedRangesObj(pDocSh),
877 mxSheet(xSheet)
882 ScLocalNamedRangesObj::~ScLocalNamedRangesObj()
887 ScNamedRangeObj* ScLocalNamedRangesObj::GetObjectByName_Impl(const OUString& aName)
889 if ( pDocShell && hasByName( aName ) )
890 return new ScNamedRangeObj( this, pDocShell, aName, mxSheet);
891 return NULL;
895 ScNamedRangeObj* ScLocalNamedRangesObj::GetObjectByIndex_Impl( sal_uInt16 nIndex )
897 if (!pDocShell)
898 return NULL;
900 OUString aName = mxSheet->getName();
901 ScDocument* pDoc = pDocShell->GetDocument();
902 SCTAB nTab;
903 pDoc->GetTable( aName, nTab );
905 ScRangeName* pNames = pDoc->GetRangeName( nTab );
906 if (!pNames)
907 return NULL;
909 ScRangeName::const_iterator itr = pNames->begin(), itrEnd = pNames->end();
910 sal_uInt16 nPos = 0;
911 for (; itr != itrEnd; ++itr)
913 if (lcl_UserVisibleName(*itr->second))
915 if (nPos == nIndex)
916 return new ScNamedRangeObj(this, pDocShell, itr->second->GetName(), mxSheet);
918 ++nPos;
920 return NULL;
923 ScRangeName* ScLocalNamedRangesObj::GetRangeName_Impl()
925 SCTAB nTab = GetTab_Impl();
926 return pDocShell->GetDocument()->GetRangeName( nTab );
929 SCTAB ScLocalNamedRangesObj::GetTab_Impl()
931 SCTAB nTab;
932 pDocShell->GetDocument()->GetTable(mxSheet->getName(), nTab);
933 return nTab;
936 ScLabelRangeObj::ScLabelRangeObj(ScDocShell* pDocSh, bool bCol, const ScRange& rR) :
937 pDocShell( pDocSh ),
938 bColumn( bCol ),
939 aRange( rR )
941 pDocShell->GetDocument()->AddUnoObject(*this);
944 ScLabelRangeObj::~ScLabelRangeObj()
946 if (pDocShell)
947 pDocShell->GetDocument()->RemoveUnoObject(*this);
950 void ScLabelRangeObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
952 //! Ref-Update !!!
954 if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
955 pDocShell = NULL; // became invalid
958 // Helper functions
960 ScRangePair* ScLabelRangeObj::GetData_Impl()
962 ScRangePair* pRet = NULL;
963 if (pDocShell)
965 ScDocument* pDoc = pDocShell->GetDocument();
966 ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
967 if (pList)
968 pRet = pList->Find( aRange );
970 return pRet;
973 void ScLabelRangeObj::Modify_Impl( const ScRange* pLabel, const ScRange* pData )
975 if (pDocShell)
977 ScDocument* pDoc = pDocShell->GetDocument();
978 ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
979 if (pOldList)
981 ScRangePairListRef xNewList(pOldList->Clone());
982 ScRangePair* pEntry = xNewList->Find( aRange );
983 if (pEntry)
985 xNewList->Remove( pEntry ); // only removed from list, not deleted
987 if ( pLabel )
988 pEntry->GetRange(0) = *pLabel;
989 if ( pData )
990 pEntry->GetRange(1) = *pData;
992 xNewList->Join( *pEntry );
993 delete pEntry;
995 if (bColumn)
996 pDoc->GetColNameRangesRef() = xNewList;
997 else
998 pDoc->GetRowNameRangesRef() = xNewList;
1000 pDoc->CompileColRowNameFormula();
1001 pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
1002 pDocShell->SetDocumentModified();
1004 //! Undo ?!?! (here and from dialog)
1006 if ( pLabel )
1007 aRange = *pLabel; // adapt object to find range again
1013 // sheet::XLabelRange
1015 table::CellRangeAddress SAL_CALL ScLabelRangeObj::getLabelArea()
1016 throw(uno::RuntimeException, std::exception)
1018 SolarMutexGuard aGuard;
1019 table::CellRangeAddress aRet;
1020 ScRangePair* pData = GetData_Impl();
1021 if (pData)
1022 ScUnoConversion::FillApiRange( aRet, pData->GetRange(0) );
1023 return aRet;
1026 void SAL_CALL ScLabelRangeObj::setLabelArea( const table::CellRangeAddress& aLabelArea )
1027 throw(uno::RuntimeException, std::exception)
1029 SolarMutexGuard aGuard;
1030 ScRange aLabelRange;
1031 ScUnoConversion::FillScRange( aLabelRange, aLabelArea );
1032 Modify_Impl( &aLabelRange, NULL );
1035 table::CellRangeAddress SAL_CALL ScLabelRangeObj::getDataArea()
1036 throw(uno::RuntimeException, std::exception)
1038 SolarMutexGuard aGuard;
1039 table::CellRangeAddress aRet;
1040 ScRangePair* pData = GetData_Impl();
1041 if (pData)
1042 ScUnoConversion::FillApiRange( aRet, pData->GetRange(1) );
1043 return aRet;
1046 void SAL_CALL ScLabelRangeObj::setDataArea( const table::CellRangeAddress& aDataArea )
1047 throw(uno::RuntimeException, std::exception)
1049 SolarMutexGuard aGuard;
1050 ScRange aDataRange;
1051 ScUnoConversion::FillScRange( aDataRange, aDataArea );
1052 Modify_Impl( NULL, &aDataRange );
1055 ScLabelRangesObj::ScLabelRangesObj(ScDocShell* pDocSh, bool bCol) :
1056 pDocShell( pDocSh ),
1057 bColumn( bCol )
1059 pDocShell->GetDocument()->AddUnoObject(*this);
1062 ScLabelRangesObj::~ScLabelRangesObj()
1064 if (pDocShell)
1065 pDocShell->GetDocument()->RemoveUnoObject(*this);
1068 void ScLabelRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
1070 // reference update is of no interest
1072 if ( rHint.ISA( SfxSimpleHint ) &&
1073 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
1075 pDocShell = NULL; // became invalid
1079 // sheet::XLabelRanges
1081 ScLabelRangeObj* ScLabelRangesObj::GetObjectByIndex_Impl(size_t nIndex)
1083 if (pDocShell)
1085 ScDocument* pDoc = pDocShell->GetDocument();
1086 ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
1087 if ( pList && nIndex < pList->size() )
1089 ScRangePair* pData = (*pList)[nIndex];
1090 if (pData)
1091 return new ScLabelRangeObj( pDocShell, bColumn, pData->GetRange(0) );
1094 return NULL;
1097 void SAL_CALL ScLabelRangesObj::addNew( const table::CellRangeAddress& aLabelArea,
1098 const table::CellRangeAddress& aDataArea )
1099 throw(uno::RuntimeException, std::exception)
1101 SolarMutexGuard aGuard;
1102 if (pDocShell)
1104 ScDocument* pDoc = pDocShell->GetDocument();
1105 ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
1106 if (pOldList)
1108 ScRangePairListRef xNewList(pOldList->Clone());
1110 ScRange aLabelRange;
1111 ScRange aDataRange;
1112 ScUnoConversion::FillScRange( aLabelRange, aLabelArea );
1113 ScUnoConversion::FillScRange( aDataRange, aDataArea );
1114 xNewList->Join( ScRangePair( aLabelRange, aDataRange ) );
1116 if (bColumn)
1117 pDoc->GetColNameRangesRef() = xNewList;
1118 else
1119 pDoc->GetRowNameRangesRef() = xNewList;
1121 pDoc->CompileColRowNameFormula();
1122 pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
1123 pDocShell->SetDocumentModified();
1125 //! Undo ?!?! (here and from dialog)
1130 void SAL_CALL ScLabelRangesObj::removeByIndex( sal_Int32 nIndex )
1131 throw(uno::RuntimeException, std::exception)
1133 SolarMutexGuard aGuard;
1134 bool bDone = false;
1135 if (pDocShell)
1137 ScDocument* pDoc = pDocShell->GetDocument();
1138 ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
1140 if ( pOldList && nIndex >= 0 && nIndex < (sal_Int32)pOldList->size() )
1142 ScRangePairListRef xNewList(pOldList->Clone());
1144 ScRangePair* pEntry = (*xNewList)[nIndex];
1145 if (pEntry)
1147 xNewList->Remove( pEntry );
1148 delete pEntry;
1150 if (bColumn)
1151 pDoc->GetColNameRangesRef() = xNewList;
1152 else
1153 pDoc->GetRowNameRangesRef() = xNewList;
1155 pDoc->CompileColRowNameFormula();
1156 pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
1157 pDocShell->SetDocumentModified();
1158 bDone = true;
1160 //! Undo ?!?! (here and from dialog)
1164 if (!bDone)
1165 throw uno::RuntimeException(); // no other exceptions specified
1168 // container::XEnumerationAccess
1170 uno::Reference<container::XEnumeration> SAL_CALL ScLabelRangesObj::createEnumeration()
1171 throw(uno::RuntimeException, std::exception)
1173 SolarMutexGuard aGuard;
1174 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.LabelRangesEnumeration"));
1177 // container::XIndexAccess
1179 sal_Int32 SAL_CALL ScLabelRangesObj::getCount() throw(uno::RuntimeException, std::exception)
1181 SolarMutexGuard aGuard;
1182 if (pDocShell)
1184 ScDocument* pDoc = pDocShell->GetDocument();
1185 ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges();
1186 if (pList)
1187 return pList->size();
1189 return 0;
1192 uno::Any SAL_CALL ScLabelRangesObj::getByIndex( sal_Int32 nIndex )
1193 throw(lang::IndexOutOfBoundsException,
1194 lang::WrappedTargetException, uno::RuntimeException, std::exception)
1196 SolarMutexGuard aGuard;
1197 uno::Reference< sheet::XLabelRange > xRange(GetObjectByIndex_Impl((sal_uInt16)nIndex));
1198 if ( xRange.is() )
1199 return uno::makeAny(xRange);
1200 else
1201 throw lang::IndexOutOfBoundsException();
1204 uno::Type SAL_CALL ScLabelRangesObj::getElementType() throw(uno::RuntimeException, std::exception)
1206 SolarMutexGuard aGuard;
1207 return cppu::UnoType<sheet::XLabelRange>::get(); // must be suitable for getByIndex
1211 sal_Bool SAL_CALL ScLabelRangesObj::hasElements() throw(uno::RuntimeException, std::exception)
1213 SolarMutexGuard aGuard;
1214 return ( getCount() != 0 );
1219 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */