LCOV - code coverage report
Current view: top level - sc/source/ui/unoobj - linkuno.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 572 962 59.5 %
Date: 2014-04-11 Functions: 98 167 58.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include <svl/smplhint.hxx>
      21             : #include <sfx2/linkmgr.hxx>
      22             : #include <vcl/svapp.hxx>
      23             : #include <svl/sharedstringpool.hxx>
      24             : 
      25             : #include "linkuno.hxx"
      26             : #include "miscuno.hxx"
      27             : #include "convuno.hxx"
      28             : #include "docsh.hxx"
      29             : #include "docfunc.hxx"
      30             : #include "tablink.hxx"
      31             : #include "arealink.hxx"
      32             : #include "hints.hxx"
      33             : #include "unonames.hxx"
      34             : #include "rangeseq.hxx"
      35             : #include "token.hxx"
      36             : #include "scmatrix.hxx"
      37             : #include <documentlinkmgr.hxx>
      38             : 
      39             : #include <vector>
      40             : #include <climits>
      41             : 
      42             : using namespace com::sun::star;
      43             : using namespace formula;
      44             : using ::com::sun::star::uno::Any;
      45             : using ::com::sun::star::uno::Reference;
      46             : using ::com::sun::star::uno::Sequence;
      47             : using ::com::sun::star::uno::UNO_QUERY;
      48             : using ::com::sun::star::uno::UNO_QUERY_THROW;
      49             : using ::com::sun::star::lang::IllegalArgumentException;
      50             : using ::com::sun::star::uno::RuntimeException;
      51             : using ::std::vector;
      52             : 
      53             : //  fuer Sheet- und Area-Links benutzt:
      54          10 : static const SfxItemPropertyMapEntry* lcl_GetSheetLinkMap()
      55             : {
      56             :     static const SfxItemPropertyMapEntry aSheetLinkMap_Impl[] =
      57             :     {
      58           1 :         {OUString(SC_UNONAME_FILTER),   0,  getCppuType((OUString*)0),    0, 0 },
      59           1 :         {OUString(SC_UNONAME_FILTOPT),  0,  getCppuType((OUString*)0),    0, 0 },
      60           1 :         {OUString(SC_UNONAME_LINKURL),  0,  getCppuType((OUString*)0),    0, 0 },
      61           1 :         {OUString(SC_UNONAME_REFDELAY), 0,  getCppuType((sal_Int32*)0),        0, 0 },
      62           1 :         {OUString(SC_UNONAME_REFPERIOD),    0,  getCppuType((sal_Int32*)0),        0, 0 },
      63             :         { OUString(), 0, css::uno::Type(), 0, 0 }
      64          16 :     };
      65          10 :     return aSheetLinkMap_Impl;
      66             : }
      67             : 
      68           2 : SC_SIMPLE_SERVICE_INFO( ScAreaLinkObj, "ScAreaLinkObj", "com.sun.star.sheet.CellAreaLink" )
      69           0 : SC_SIMPLE_SERVICE_INFO( ScAreaLinksObj, "ScAreaLinksObj", "com.sun.star.sheet.CellAreaLinks" )
      70           0 : SC_SIMPLE_SERVICE_INFO( ScDDELinkObj, "ScDDELinkObj", "com.sun.star.sheet.DDELink" )
      71           0 : SC_SIMPLE_SERVICE_INFO( ScDDELinksObj, "ScDDELinksObj", "com.sun.star.sheet.DDELinks" )
      72           0 : SC_SIMPLE_SERVICE_INFO( ScSheetLinkObj, "ScSheetLinkObj", "com.sun.star.sheet.SheetLink" )
      73           0 : SC_SIMPLE_SERVICE_INFO( ScSheetLinksObj, "ScSheetLinksObj", "com.sun.star.sheet.SheetLinks" )
      74             : 
      75           5 : ScSheetLinkObj::ScSheetLinkObj(ScDocShell* pDocSh, const OUString& rName) :
      76             :     aPropSet( lcl_GetSheetLinkMap() ),
      77             :     pDocShell( pDocSh ),
      78           5 :     aFileName( rName )
      79             : {
      80           5 :     pDocShell->GetDocument()->AddUnoObject(*this);
      81           5 : }
      82             : 
      83          15 : ScSheetLinkObj::~ScSheetLinkObj()
      84             : {
      85           5 :     if (pDocShell)
      86           0 :         pDocShell->GetDocument()->RemoveUnoObject(*this);
      87          10 : }
      88             : 
      89           5 : void ScSheetLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
      90             : {
      91             :     //! notify if links in document are changed
      92             :     //  UpdateRef is not needed here
      93             : 
      94           5 :     if ( rHint.ISA( SfxSimpleHint ) )
      95             :     {
      96           5 :         if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
      97           5 :             pDocShell = NULL;       // pointer is invalid
      98             :     }
      99           0 :     else if ( rHint.ISA( ScLinkRefreshedHint ) )
     100             :     {
     101           0 :         const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
     102           0 :         if ( rLH.GetLinkType() == SC_LINKREFTYPE_SHEET && rLH.GetUrl() == aFileName )
     103           0 :             Refreshed_Impl();
     104             :     }
     105           5 : }
     106             : 
     107           0 : ScTableLink* ScSheetLinkObj::GetLink_Impl() const
     108             : {
     109           0 :     if (pDocShell)
     110             :     {
     111           0 :         sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
     112           0 :         size_t nCount = pLinkManager->GetLinks().size();
     113           0 :         for (size_t i=0; i<nCount; i++)
     114             :         {
     115           0 :             ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
     116           0 :             if (pBase->ISA(ScTableLink))
     117             :             {
     118           0 :                 ScTableLink* pTabLink = (ScTableLink*)pBase;
     119           0 :                 if ( pTabLink->GetFileName().equals(aFileName) )
     120           0 :                     return pTabLink;
     121             :             }
     122             :         }
     123             :     }
     124           0 :     return NULL;    // nicht gefunden
     125             : }
     126             : 
     127             : // XNamed
     128             : 
     129           0 : OUString SAL_CALL ScSheetLinkObj::getName() throw(uno::RuntimeException, std::exception)
     130             : {
     131           0 :     SolarMutexGuard aGuard;
     132           0 :     return getFileName();   // Name ist der Dateiname (URL)
     133             : }
     134             : 
     135           0 : void SAL_CALL ScSheetLinkObj::setName( const OUString& aName ) throw(uno::RuntimeException, std::exception)
     136             : {
     137           0 :     SolarMutexGuard aGuard;
     138           0 :     setFileName(aName);     // Name ist der Dateiname (URL)
     139           0 : }
     140             : 
     141             : // XRefreshable
     142             : 
     143           0 : void SAL_CALL ScSheetLinkObj::refresh()
     144             :     throw (uno::RuntimeException, std::exception)
     145             : {
     146           0 :     SolarMutexGuard aGuard;
     147           0 :     ScTableLink* pLink = GetLink_Impl();
     148           0 :     if (pLink)
     149           0 :         pLink->Refresh( pLink->GetFileName(), pLink->GetFilterName(), NULL, pLink->GetRefreshDelay() );
     150           0 : }
     151             : 
     152           0 : void SAL_CALL ScSheetLinkObj::addRefreshListener(
     153             :     const uno::Reference<util::XRefreshListener >& xListener )
     154             :         throw (uno::RuntimeException, std::exception)
     155             : {
     156           0 :     SolarMutexGuard aGuard;
     157             :     uno::Reference<util::XRefreshListener>* pObj =
     158           0 :             new uno::Reference<util::XRefreshListener>( xListener );
     159           0 :     aRefreshListeners.push_back( pObj );
     160             : 
     161             :     //  hold one additional ref to keep this object alive as long as there are listeners
     162           0 :     if ( aRefreshListeners.size() == 1 )
     163           0 :         acquire();
     164           0 : }
     165             : 
     166           0 : void SAL_CALL ScSheetLinkObj::removeRefreshListener(
     167             :                                 const uno::Reference<util::XRefreshListener >& xListener )
     168             :                                                 throw(uno::RuntimeException, std::exception)
     169             : {
     170           0 :     SolarMutexGuard aGuard;
     171           0 :     size_t nCount = aRefreshListeners.size();
     172           0 :     for ( size_t n=nCount; n--; )
     173             :     {
     174           0 :         uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n];
     175           0 :         if ( rObj == xListener )
     176             :         {
     177           0 :             aRefreshListeners.erase( aRefreshListeners.begin() + n );
     178           0 :             if ( aRefreshListeners.empty() )
     179           0 :                 release();                          // release ref for listeners
     180           0 :             break;
     181             :         }
     182           0 :     }
     183           0 : }
     184             : 
     185           0 : void ScSheetLinkObj::Refreshed_Impl()
     186             : {
     187           0 :     lang::EventObject aEvent;
     188           0 :     aEvent.Source.set((cppu::OWeakObject*)this);
     189           0 :     for ( size_t n=0; n<aRefreshListeners.size(); n++ )
     190           0 :         aRefreshListeners[n]->refreshed( aEvent );
     191           0 : }
     192             : 
     193           0 : void ScSheetLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh )
     194             : {
     195           0 :     ScTableLink* pLink = GetLink_Impl();
     196           0 :     if( pLink )
     197           0 :         pLink->SetRefreshDelay( (sal_uLong) nRefresh );
     198           0 : }
     199             : 
     200             : // XPropertySet
     201             : 
     202           0 : uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSheetLinkObj::getPropertySetInfo()
     203             :                                                         throw(uno::RuntimeException, std::exception)
     204             : {
     205           0 :     SolarMutexGuard aGuard;
     206             :     static uno::Reference<beans::XPropertySetInfo> aRef(
     207           0 :         new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
     208           0 :     return aRef;
     209             : }
     210             : 
     211           0 : void SAL_CALL ScSheetLinkObj::setPropertyValue(
     212             :                         const OUString& aPropertyName, const uno::Any& aValue )
     213             :                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
     214             :                         lang::IllegalArgumentException, lang::WrappedTargetException,
     215             :                         uno::RuntimeException, std::exception)
     216             : {
     217           0 :     SolarMutexGuard aGuard;
     218           0 :     OUString aNameString(aPropertyName);
     219           0 :     OUString aValStr;
     220           0 :     if ( aNameString.equalsAscii( SC_UNONAME_LINKURL ) )
     221             :     {
     222           0 :         if ( aValue >>= aValStr )
     223           0 :             setFileName( aValStr );
     224             :     }
     225           0 :     else if ( aNameString.equalsAscii( SC_UNONAME_FILTER ) )
     226             :     {
     227           0 :         if ( aValue >>= aValStr )
     228           0 :             setFilter( aValStr );
     229             :     }
     230           0 :     else if ( aNameString.equalsAscii( SC_UNONAME_FILTOPT ) )
     231             :     {
     232           0 :         if ( aValue >>= aValStr )
     233           0 :             setFilterOptions( aValStr );
     234             :     }
     235           0 :     else if ( aNameString.equalsAscii( SC_UNONAME_REFPERIOD ) )
     236             :     {
     237           0 :         sal_Int32 nRefresh = 0;
     238           0 :         if ( aValue >>= nRefresh )
     239           0 :             setRefreshDelay( nRefresh );
     240             :     }
     241           0 :     else if ( aNameString.equalsAscii( SC_UNONAME_REFDELAY ) )
     242             :     {
     243           0 :         sal_Int32 nRefresh = 0;
     244           0 :         if ( aValue >>= nRefresh )
     245           0 :             setRefreshDelay( nRefresh );
     246           0 :     }
     247           0 : }
     248             : 
     249           0 : uno::Any SAL_CALL ScSheetLinkObj::getPropertyValue( const OUString& aPropertyName )
     250             :                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
     251             :                         uno::RuntimeException, std::exception)
     252             : {
     253           0 :     SolarMutexGuard aGuard;
     254           0 :     OUString aNameString(aPropertyName);
     255           0 :     uno::Any aRet;
     256           0 :     if ( aNameString.equalsAscii( SC_UNONAME_LINKURL ) )
     257           0 :         aRet <<= getFileName();
     258           0 :     else if ( aNameString.equalsAscii( SC_UNONAME_FILTER ) )
     259           0 :         aRet <<= getFilter();
     260           0 :     else if ( aNameString.equalsAscii( SC_UNONAME_FILTOPT ) )
     261           0 :         aRet <<= getFilterOptions();
     262           0 :     else if ( aNameString.equalsAscii( SC_UNONAME_REFPERIOD ) )
     263           0 :         aRet <<= getRefreshDelay();
     264           0 :     else if ( aNameString.equalsAscii( SC_UNONAME_REFDELAY ) )
     265           0 :         aRet <<= getRefreshDelay();
     266           0 :     return aRet;
     267             : }
     268             : 
     269           0 : SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSheetLinkObj )
     270             : 
     271             : // internal:
     272             : 
     273           0 : OUString ScSheetLinkObj::getFileName(void) const
     274             : {
     275           0 :     SolarMutexGuard aGuard;
     276           0 :     return aFileName;
     277             : }
     278             : 
     279           0 : void ScSheetLinkObj::setFileName(const OUString& rNewName)
     280             : {
     281           0 :     SolarMutexGuard aGuard;
     282           0 :     ScTableLink* pLink = GetLink_Impl();
     283           0 :     if (pLink)
     284             :     {
     285             :         //  pLink->Refresh mit neuem Dateinamen bringt sfx2::LinkManager durcheinander
     286             :         //  darum per Hand die Tabellen umsetzen und Link per UpdateLinks neu erzeugen
     287             : 
     288           0 :         OUString aNewStr(ScGlobal::GetAbsDocName( rNewName, pDocShell ));
     289             : 
     290             :         //  zuerst Tabellen umsetzen
     291             : 
     292           0 :         ScDocument* pDoc = pDocShell->GetDocument();
     293           0 :         SCTAB nTabCount = pDoc->GetTableCount();
     294           0 :         for (SCTAB nTab=0; nTab<nTabCount; nTab++)
     295           0 :             if ( pDoc->IsLinked(nTab) && pDoc->GetLinkDoc(nTab) == aFileName )  // alte Datei
     296           0 :                 pDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), aNewStr,
     297             :                                 pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
     298             :                                 pDoc->GetLinkTab(nTab),
     299           0 :                                 pDoc->GetLinkRefreshDelay(nTab) );  // nur Datei aendern
     300             : 
     301             :         //  Links updaten
     302             :         //! Undo !!!
     303             : 
     304           0 :         pLink = NULL;               // wird bei UpdateLinks ungueltig
     305           0 :         pDocShell->UpdateLinks();   // alter Link raus, evtl. neuen Link anlegen
     306             : 
     307             :         //  Daten kopieren
     308             : 
     309           0 :         aFileName = aNewStr;
     310           0 :         pLink = GetLink_Impl();     // neuer Link mit neuem Namen
     311           0 :         if (pLink)
     312           0 :             pLink->Update();        // inkl. Paint & Undo fuer Daten
     313           0 :     }
     314           0 : }
     315             : 
     316           0 : OUString ScSheetLinkObj::getFilter(void) const
     317             : {
     318           0 :     SolarMutexGuard aGuard;
     319           0 :     OUString aRet;
     320           0 :     ScTableLink* pLink = GetLink_Impl();
     321           0 :     if (pLink)
     322           0 :         aRet = pLink->GetFilterName();
     323           0 :     return aRet;
     324             : }
     325             : 
     326           0 : void ScSheetLinkObj::setFilter(const OUString& Filter)
     327             : {
     328           0 :     SolarMutexGuard aGuard;
     329           0 :     ScTableLink* pLink = GetLink_Impl();
     330           0 :     if (pLink)
     331             :     {
     332           0 :         OUString aFilterStr(Filter);
     333           0 :         pLink->Refresh( aFileName, aFilterStr, NULL, pLink->GetRefreshDelay() );
     334           0 :     }
     335           0 : }
     336             : 
     337           0 : OUString ScSheetLinkObj::getFilterOptions(void) const
     338             : {
     339           0 :     SolarMutexGuard aGuard;
     340           0 :     OUString aRet;
     341           0 :     ScTableLink* pLink = GetLink_Impl();
     342           0 :     if (pLink)
     343           0 :         aRet = pLink->GetOptions();
     344           0 :     return aRet;
     345             : }
     346             : 
     347           0 : void ScSheetLinkObj::setFilterOptions(const OUString& FilterOptions)
     348             : {
     349           0 :     SolarMutexGuard aGuard;
     350           0 :     ScTableLink* pLink = GetLink_Impl();
     351           0 :     if (pLink)
     352             :     {
     353           0 :         OUString aOptStr(FilterOptions);
     354           0 :         pLink->Refresh( aFileName, pLink->GetFilterName(), &aOptStr, pLink->GetRefreshDelay() );
     355           0 :     }
     356           0 : }
     357             : 
     358           0 : sal_Int32 ScSheetLinkObj::getRefreshDelay(void) const
     359             : {
     360           0 :     SolarMutexGuard aGuard;
     361           0 :     sal_Int32 nRet = 0;
     362           0 :     ScTableLink* pLink = GetLink_Impl();
     363           0 :     if (pLink)
     364           0 :         nRet = (sal_Int32) pLink->GetRefreshDelay();
     365           0 :     return nRet;
     366             : }
     367             : 
     368           0 : void ScSheetLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay)
     369             : {
     370           0 :     SolarMutexGuard aGuard;
     371           0 :     ModifyRefreshDelay_Impl( nRefreshDelay );
     372           0 : }
     373             : 
     374           6 : ScSheetLinksObj::ScSheetLinksObj(ScDocShell* pDocSh) :
     375           6 :     pDocShell( pDocSh )
     376             : {
     377           6 :     pDocShell->GetDocument()->AddUnoObject(*this);
     378           6 : }
     379             : 
     380          18 : ScSheetLinksObj::~ScSheetLinksObj()
     381             : {
     382           6 :     if (pDocShell)
     383           0 :         pDocShell->GetDocument()->RemoveUnoObject(*this);
     384          12 : }
     385             : 
     386         164 : void ScSheetLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
     387             : {
     388             :     //  Referenz-Update interessiert hier nicht
     389             : 
     390         328 :     if ( rHint.ISA( SfxSimpleHint ) &&
     391         164 :             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
     392             :     {
     393           6 :         pDocShell = NULL;       // ungueltig geworden
     394             :     }
     395         164 : }
     396             : 
     397             : // XSheetLinks
     398             : 
     399           6 : ScSheetLinkObj* ScSheetLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
     400             : {
     401           6 :     if (!pDocShell)
     402           0 :         return NULL;
     403             : 
     404             :     typedef boost::unordered_set<OUString, OUStringHash> StrSetType;
     405           6 :     StrSetType aNames;
     406           6 :     ScDocument* pDoc = pDocShell->GetDocument();
     407           6 :     SCTAB nTabCount = pDoc->GetTableCount();
     408           6 :     sal_Int32 nCount = 0;
     409           8 :     for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
     410             :     {
     411           6 :         if (!pDoc->IsLinked(nTab))
     412           0 :             continue;
     413             : 
     414           6 :         OUString aLinkDoc = pDoc->GetLinkDoc(nTab);
     415           6 :         if (aNames.insert(aLinkDoc).second)
     416             :         {
     417             :             // unique document name.
     418           6 :             if (nCount == nIndex)
     419           4 :                 return new ScSheetLinkObj( pDocShell, aLinkDoc );
     420           2 :             ++nCount;
     421             :         }
     422           2 :     }
     423             : 
     424           2 :     return NULL;    // kein Dokument oder Index zu gross
     425             : }
     426             : 
     427           2 : ScSheetLinkObj* ScSheetLinksObj::GetObjectByName_Impl(const OUString& aName)
     428             : {
     429             :     //  Name ist der Dateiname
     430             : 
     431           2 :     if (pDocShell)
     432             :     {
     433           2 :         OUString aNameStr(aName);
     434             : 
     435           2 :         ScDocument* pDoc = pDocShell->GetDocument();
     436           2 :         SCTAB nTabCount = pDoc->GetTableCount();
     437           3 :         for (SCTAB nTab=0; nTab<nTabCount; nTab++)
     438           2 :             if (pDoc->IsLinked(nTab))
     439             :             {
     440             :                 //! case-insensitiv ???
     441           2 :                 OUString aLinkDoc = pDoc->GetLinkDoc( nTab );
     442           2 :                 if ( aLinkDoc == aNameStr )
     443           1 :                     return new ScSheetLinkObj( pDocShell, aNameStr );
     444           1 :             }
     445             :     }
     446             : 
     447           1 :     return NULL;
     448             : }
     449             : 
     450             : // XEnumerationAccess
     451             : 
     452           2 : uno::Reference<container::XEnumeration> SAL_CALL ScSheetLinksObj::createEnumeration()
     453             :                                                     throw(uno::RuntimeException, std::exception)
     454             : {
     455           2 :     SolarMutexGuard aGuard;
     456           2 :     return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.SheetLinksEnumeration"));
     457             : }
     458             : 
     459             : // XIndexAccess
     460             : 
     461           5 : sal_Int32 SAL_CALL ScSheetLinksObj::getCount() throw(uno::RuntimeException, std::exception)
     462             : {
     463             :     typedef boost::unordered_set<OUString, OUStringHash> StrSetType;
     464             : 
     465           5 :     SolarMutexGuard aGuard;
     466           5 :     if (!pDocShell)
     467           0 :         return 0;
     468             : 
     469           5 :     sal_Int32 nCount = 0;
     470             : 
     471          10 :     StrSetType aNames;
     472           5 :     ScDocument* pDoc = pDocShell->GetDocument();
     473           5 :     SCTAB nTabCount = pDoc->GetTableCount();
     474          10 :     for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
     475             :     {
     476           5 :         if (!pDoc->IsLinked(nTab))
     477           0 :             continue;
     478             : 
     479           5 :         OUString aLinkDoc = pDoc->GetLinkDoc(nTab);
     480           5 :         if (aNames.insert(aLinkDoc).second)
     481           5 :             ++nCount;
     482           5 :     }
     483          10 :     return nCount;
     484             : }
     485             : 
     486           6 : uno::Any SAL_CALL ScSheetLinksObj::getByIndex( sal_Int32 nIndex )
     487             :                             throw(lang::IndexOutOfBoundsException,
     488             :                                     lang::WrappedTargetException, uno::RuntimeException, std::exception)
     489             : {
     490           6 :     SolarMutexGuard aGuard;
     491          12 :     uno::Reference<beans::XPropertySet> xLink(GetObjectByIndex_Impl(nIndex));
     492           6 :     if (xLink.is())
     493           8 :         return uno::makeAny(xLink);
     494             :     else
     495           8 :         throw lang::IndexOutOfBoundsException();
     496             : }
     497             : 
     498           1 : uno::Type SAL_CALL ScSheetLinksObj::getElementType() throw(uno::RuntimeException, std::exception)
     499             : {
     500           1 :     SolarMutexGuard aGuard;
     501           1 :     return getCppuType((uno::Reference<beans::XPropertySet>*)0);
     502             : }
     503             : 
     504           1 : sal_Bool SAL_CALL ScSheetLinksObj::hasElements() throw(uno::RuntimeException, std::exception)
     505             : {
     506           1 :     SolarMutexGuard aGuard;
     507           1 :     return ( getCount() != 0 );
     508             : }
     509             : 
     510           2 : uno::Any SAL_CALL ScSheetLinksObj::getByName( const OUString& aName )
     511             :             throw(container::NoSuchElementException,
     512             :                     lang::WrappedTargetException, uno::RuntimeException, std::exception)
     513             : {
     514           2 :     SolarMutexGuard aGuard;
     515           4 :     uno::Reference<beans::XPropertySet> xLink(GetObjectByName_Impl(aName));
     516           2 :     if (xLink.is())
     517           2 :         return uno::makeAny(xLink);
     518             :     else
     519           3 :         throw container::NoSuchElementException();
     520             : //    return uno::Any();
     521             : }
     522             : 
     523           2 : sal_Bool SAL_CALL ScSheetLinksObj::hasByName( const OUString& aName )
     524             :                                         throw(uno::RuntimeException, std::exception)
     525             : {
     526           2 :     SolarMutexGuard aGuard;
     527             :     //  Name ist der Dateiname
     528             : 
     529           2 :     if (pDocShell)
     530             :     {
     531           2 :         OUString aNameStr(aName);
     532             : 
     533           2 :         ScDocument* pDoc = pDocShell->GetDocument();
     534           2 :         SCTAB nTabCount = pDoc->GetTableCount();
     535           3 :         for (SCTAB nTab=0; nTab<nTabCount; nTab++)
     536           2 :             if (pDoc->IsLinked(nTab))
     537             :             {
     538             :                 //! case-insensitiv ???
     539           2 :                 OUString aLinkDoc(pDoc->GetLinkDoc( nTab ));
     540           2 :                 if ( aLinkDoc == aNameStr )
     541           1 :                     return sal_True;
     542           1 :             }
     543             :     }
     544           1 :     return false;
     545             : }
     546             : 
     547           1 : uno::Sequence<OUString> SAL_CALL ScSheetLinksObj::getElementNames() throw(uno::RuntimeException, std::exception)
     548             : {
     549             :     typedef boost::unordered_set<OUString, OUStringHash> StrSetType;
     550             : 
     551           1 :     SolarMutexGuard aGuard;
     552             :     //  Name ist der Dateiname
     553             : 
     554           1 :     if (!pDocShell)
     555           0 :         return uno::Sequence<OUString>();
     556             : 
     557           2 :     StrSetType aNames;
     558           1 :     ScDocument* pDoc = pDocShell->GetDocument();
     559           1 :     SCTAB nTabCount = pDoc->GetTableCount();
     560             : 
     561           1 :     sal_Int32 nLinkCount = getCount();
     562           2 :     uno::Sequence<OUString> aSeq(nLinkCount);
     563           1 :     OUString* pAry = aSeq.getArray();
     564           1 :     size_t nPos = 0;
     565           2 :     for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
     566             :     {
     567           1 :         if (!pDoc->IsLinked(nTab))
     568           0 :             continue;
     569             : 
     570           1 :         OUString aLinkDoc = pDoc->GetLinkDoc(nTab);
     571           1 :         if (aNames.insert(aLinkDoc).second)
     572           1 :             pAry[nPos++] = aLinkDoc;
     573           1 :     }
     574             :     OSL_ENSURE( nPos==static_cast<size_t>(nLinkCount), "verzaehlt" );
     575           2 :     return aSeq;
     576             : }
     577             : 
     578          61 : static ScAreaLink* lcl_GetAreaLink( ScDocShell* pDocShell, size_t nPos )
     579             : {
     580          61 :     if (pDocShell)
     581             :     {
     582          61 :         sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
     583          61 :         size_t nTotalCount = pLinkManager->GetLinks().size();
     584          61 :         size_t nAreaCount = 0;
     585          61 :         for (size_t i=0; i<nTotalCount; i++)
     586             :         {
     587          61 :             ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
     588          61 :             if (pBase->ISA(ScAreaLink))
     589             :             {
     590          61 :                 if ( nAreaCount == nPos )
     591          61 :                     return static_cast<ScAreaLink*>(pBase);
     592           0 :                 ++nAreaCount;
     593             :             }
     594             :         }
     595             :     }
     596           0 :     return NULL;    // nicht gefunden
     597             : }
     598             : 
     599           5 : ScAreaLinkObj::ScAreaLinkObj(ScDocShell* pDocSh, size_t nP) :
     600             :     aPropSet( lcl_GetSheetLinkMap() ),
     601             :     pDocShell( pDocSh ),
     602           5 :     nPos( nP )
     603             : {
     604           5 :     pDocShell->GetDocument()->AddUnoObject(*this);
     605           5 : }
     606             : 
     607          15 : ScAreaLinkObj::~ScAreaLinkObj()
     608             : {
     609           5 :     if (pDocShell)
     610           0 :         pDocShell->GetDocument()->RemoveUnoObject(*this);
     611          10 : }
     612             : 
     613           7 : void ScAreaLinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
     614             : {
     615             :     //! notify if links in document are changed
     616             :     //  UpdateRef is not needed here
     617             : 
     618           7 :     if ( rHint.ISA( SfxSimpleHint ) )
     619             :     {
     620           6 :         if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
     621           5 :             pDocShell = NULL;       // pointer is invalid
     622             :     }
     623           1 :     else if ( rHint.ISA( ScLinkRefreshedHint ) )
     624             :     {
     625           1 :         const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
     626           1 :         if ( rLH.GetLinkType() == SC_LINKREFTYPE_AREA )
     627             :         {
     628             :             //  get this link to compare dest position
     629           1 :             ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
     630           1 :             if ( pLink && pLink->GetDestArea().aStart == rLH.GetDestPos() )
     631           1 :                 Refreshed_Impl();
     632             :         }
     633             :     }
     634           7 : }
     635             : 
     636             : // XFileLink
     637             : 
     638          13 : void ScAreaLinkObj::Modify_Impl( const OUString* pNewFile, const OUString* pNewFilter,
     639             :                                  const OUString* pNewOptions, const OUString* pNewSource,
     640             :                                  const table::CellRangeAddress* pNewDest )
     641             : {
     642          13 :     ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
     643          13 :     if (pLink)
     644             :     {
     645          13 :         OUString aFile    (pLink->GetFile());
     646          26 :         OUString aFilter  (pLink->GetFilter());
     647          26 :         OUString aOptions (pLink->GetOptions());
     648          26 :         OUString aSource  (pLink->GetSource());
     649          13 :         ScRange aDest   (pLink->GetDestArea());
     650          13 :         sal_uLong nRefresh  = pLink->GetRefreshDelay();
     651             : 
     652             :         //! Undo fuer Loeschen
     653             :         //! Undo zusammenfassen
     654             : 
     655          13 :         sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
     656          13 :         pLinkManager->Remove( pLink );
     657          13 :         pLink = NULL;   // bei Remove geloescht
     658             : 
     659          13 :         sal_Bool bFitBlock = sal_True;          // verschieben, wenn durch Update Groesse geaendert
     660          13 :         if (pNewFile)
     661             :         {
     662           3 :             aFile = *pNewFile;
     663           3 :             aFile = ScGlobal::GetAbsDocName( aFile, pDocShell );    //! in InsertAreaLink?
     664             :         }
     665          13 :         if (pNewFilter)
     666           3 :             aFilter = *pNewFilter;
     667          13 :         if (pNewOptions)
     668           3 :             aOptions = *pNewOptions;
     669          13 :         if (pNewSource)
     670           2 :             aSource = *pNewSource;
     671          13 :         if (pNewDest)
     672             :         {
     673           2 :             ScUnoConversion::FillScRange( aDest, *pNewDest );
     674           2 :             bFitBlock = false;  // neuer Bereich angegeben -> keine Inhalte verschieben
     675             :         }
     676          13 :         pDocShell->GetDocFunc().InsertAreaLink( aFile, aFilter, aOptions, aSource,
     677          39 :                                                 aDest, nRefresh, bFitBlock, true );
     678             :     }
     679          13 : }
     680             : 
     681           6 : void ScAreaLinkObj::ModifyRefreshDelay_Impl( sal_Int32 nRefresh )
     682             : {
     683           6 :     ScAreaLink* pLink = lcl_GetAreaLink( pDocShell, nPos );
     684           6 :     if( pLink )
     685           6 :         pLink->SetRefreshDelay( (sal_uLong) nRefresh );
     686           6 : }
     687             : 
     688             : // XRefreshable
     689             : 
     690           0 : void SAL_CALL ScAreaLinkObj::refresh()
     691             :     throw(uno::RuntimeException, std::exception)
     692             : {
     693           0 :     SolarMutexGuard aGuard;
     694           0 :     ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
     695           0 :     if (pLink)
     696           0 :         pLink->Refresh( pLink->GetFile(), pLink->GetFilter(), pLink->GetSource(), pLink->GetRefreshDelay() );
     697           0 : }
     698             : 
     699           0 : void SAL_CALL ScAreaLinkObj::addRefreshListener(
     700             :     const uno::Reference<util::XRefreshListener >& xListener )
     701             :         throw (uno::RuntimeException, std::exception)
     702             : {
     703           0 :     SolarMutexGuard aGuard;
     704             :     uno::Reference<util::XRefreshListener>* pObj =
     705           0 :             new uno::Reference<util::XRefreshListener>( xListener );
     706           0 :     aRefreshListeners.push_back( pObj );
     707             : 
     708             :     //  hold one additional ref to keep this object alive as long as there are listeners
     709           0 :     if ( aRefreshListeners.size() == 1 )
     710           0 :         acquire();
     711           0 : }
     712             : 
     713           0 : void SAL_CALL ScAreaLinkObj::removeRefreshListener(
     714             :                                 const uno::Reference<util::XRefreshListener >& xListener )
     715             :                                                 throw(uno::RuntimeException, std::exception)
     716             : {
     717           0 :     SolarMutexGuard aGuard;
     718           0 :     size_t nCount = aRefreshListeners.size();
     719           0 :     for ( size_t n=nCount; n--; )
     720             :     {
     721           0 :         uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n];
     722           0 :         if ( rObj == xListener )
     723             :         {
     724           0 :             aRefreshListeners.erase( aRefreshListeners.begin() + n );
     725           0 :             if ( aRefreshListeners.empty() )
     726           0 :                 release();                          // release ref for listeners
     727           0 :             break;
     728             :         }
     729             : 
     730           0 :         if(n == 0)
     731           0 :             break;
     732           0 :     }
     733           0 : }
     734             : 
     735           1 : void ScAreaLinkObj::Refreshed_Impl()
     736             : {
     737           1 :     lang::EventObject aEvent;
     738           1 :     aEvent.Source.set((cppu::OWeakObject*)this);
     739           1 :     for ( size_t n=0; n<aRefreshListeners.size(); n++ )
     740           1 :         aRefreshListeners[n]->refreshed( aEvent );
     741           1 : }
     742             : 
     743             : // XPropertySet
     744             : 
     745          11 : uno::Reference<beans::XPropertySetInfo> SAL_CALL ScAreaLinkObj::getPropertySetInfo()
     746             :                                                         throw(uno::RuntimeException, std::exception)
     747             : {
     748          11 :     SolarMutexGuard aGuard;
     749             :     static uno::Reference<beans::XPropertySetInfo> aRef(
     750          11 :         new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
     751          11 :     return aRef;
     752             : }
     753             : 
     754          15 : void SAL_CALL ScAreaLinkObj::setPropertyValue(
     755             :                         const OUString& aPropertyName, const uno::Any& aValue )
     756             :                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
     757             :                         lang::IllegalArgumentException, lang::WrappedTargetException,
     758             :                         uno::RuntimeException, std::exception)
     759             : {
     760          15 :     SolarMutexGuard aGuard;
     761          30 :     OUString aNameString(aPropertyName);
     762          30 :     OUString aValStr;
     763          15 :     if ( aNameString.equalsAscii( SC_UNONAME_LINKURL ) )
     764             :     {
     765           3 :         if ( aValue >>= aValStr )
     766           3 :             setFileName( aValStr );
     767             :     }
     768          12 :     else if ( aNameString.equalsAscii( SC_UNONAME_FILTER ) )
     769             :     {
     770           3 :         if ( aValue >>= aValStr )
     771           3 :             setFilter( aValStr );
     772             :     }
     773           9 :     else if ( aNameString.equalsAscii( SC_UNONAME_FILTOPT ) )
     774             :     {
     775           3 :         if ( aValue >>= aValStr )
     776           3 :             setFilterOptions( aValStr );
     777             :     }
     778           6 :     else if ( aNameString.equalsAscii( SC_UNONAME_REFPERIOD ) )
     779             :     {
     780           3 :         sal_Int32 nRefresh = 0;
     781           3 :         if ( aValue >>= nRefresh )
     782           3 :             setRefreshDelay( nRefresh );
     783             :     }
     784           3 :     else if ( aNameString.equalsAscii( SC_UNONAME_REFDELAY ) )
     785             :     {
     786           3 :         sal_Int32 nRefresh = 0;
     787           3 :         if ( aValue >>= nRefresh )
     788           3 :             setRefreshDelay( nRefresh );
     789          15 :     }
     790          15 : }
     791             : 
     792          35 : uno::Any SAL_CALL ScAreaLinkObj::getPropertyValue( const OUString& aPropertyName )
     793             :                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
     794             :                         uno::RuntimeException, std::exception)
     795             : {
     796          35 :     SolarMutexGuard aGuard;
     797          70 :     OUString aNameString(aPropertyName);
     798          35 :     uno::Any aRet;
     799          35 :     if ( aNameString.equalsAscii( SC_UNONAME_LINKURL ) )
     800           7 :         aRet <<= getFileName();
     801          28 :     else if ( aNameString.equalsAscii( SC_UNONAME_FILTER ) )
     802           7 :         aRet <<= getFilter();
     803          21 :     else if ( aNameString.equalsAscii( SC_UNONAME_FILTOPT ) )
     804           7 :         aRet <<= getFilterOptions();
     805          14 :     else if ( aNameString.equalsAscii( SC_UNONAME_REFPERIOD ) )
     806           7 :         aRet <<= getRefreshDelay();
     807           7 :     else if ( aNameString.equalsAscii( SC_UNONAME_REFDELAY ) )
     808           7 :         aRet <<= getRefreshDelay();
     809          70 :     return aRet;
     810             : }
     811             : 
     812           0 : SC_IMPL_DUMMY_PROPERTY_LISTENER( ScAreaLinkObj )
     813             : 
     814             : //  internal:
     815             : 
     816           7 : OUString ScAreaLinkObj::getFileName(void) const
     817             : {
     818           7 :     SolarMutexGuard aGuard;
     819           7 :     OUString aRet;
     820           7 :     ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
     821           7 :     if (pLink)
     822           7 :         aRet = pLink->GetFile();
     823           7 :     return aRet;
     824             : }
     825             : 
     826           3 : void ScAreaLinkObj::setFileName(const OUString& rNewName)
     827             : {
     828           3 :     SolarMutexGuard aGuard;
     829           3 :     Modify_Impl( &rNewName, NULL, NULL, NULL, NULL );
     830           3 : }
     831             : 
     832           7 : OUString ScAreaLinkObj::getFilter(void) const
     833             : {
     834           7 :     SolarMutexGuard aGuard;
     835           7 :     OUString aRet;
     836           7 :     ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
     837           7 :     if (pLink)
     838           7 :         aRet = pLink->GetFilter();
     839           7 :     return aRet;
     840             : }
     841             : 
     842           3 : void ScAreaLinkObj::setFilter(const OUString& Filter)
     843             : {
     844           3 :     SolarMutexGuard aGuard;
     845           3 :     Modify_Impl( NULL, &Filter, NULL, NULL, NULL );
     846           3 : }
     847             : 
     848           7 : OUString ScAreaLinkObj::getFilterOptions(void) const
     849             : {
     850           7 :     SolarMutexGuard aGuard;
     851           7 :     OUString aRet;
     852           7 :     ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
     853           7 :     if (pLink)
     854           7 :         aRet = pLink->GetOptions();
     855           7 :     return aRet;
     856             : }
     857             : 
     858           3 : void ScAreaLinkObj::setFilterOptions(const OUString& FilterOptions)
     859             : {
     860           3 :     SolarMutexGuard aGuard;
     861           3 :     Modify_Impl( NULL, NULL, &FilterOptions, NULL, NULL );
     862           3 : }
     863             : 
     864          14 : sal_Int32 ScAreaLinkObj::getRefreshDelay(void) const
     865             : {
     866          14 :     SolarMutexGuard aGuard;
     867          14 :     sal_Int32 nRet = 0;
     868          14 :     ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
     869          14 :     if (pLink)
     870          14 :         nRet = (sal_Int32) pLink->GetRefreshDelay();
     871          14 :     return nRet;
     872             : }
     873             : 
     874           6 : void ScAreaLinkObj::setRefreshDelay(sal_Int32 nRefreshDelay)
     875             : {
     876           6 :     SolarMutexGuard aGuard;
     877           6 :     ModifyRefreshDelay_Impl( nRefreshDelay );
     878           6 : }
     879             : 
     880             : // XAreaLink
     881             : 
     882           3 : OUString SAL_CALL ScAreaLinkObj::getSourceArea() throw(uno::RuntimeException, std::exception)
     883             : {
     884           3 :     SolarMutexGuard aGuard;
     885           3 :     OUString aRet;
     886           3 :     ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
     887           3 :     if (pLink)
     888           3 :         aRet = pLink->GetSource();
     889           3 :     return aRet;
     890             : }
     891             : 
     892           2 : void SAL_CALL ScAreaLinkObj::setSourceArea( const OUString& aSourceArea )
     893             :                                             throw(uno::RuntimeException, std::exception)
     894             : {
     895           2 :     SolarMutexGuard aGuard;
     896           2 :     Modify_Impl( NULL, NULL, NULL, &aSourceArea, NULL );
     897           2 : }
     898             : 
     899           3 : table::CellRangeAddress SAL_CALL ScAreaLinkObj::getDestArea() throw(uno::RuntimeException, std::exception)
     900             : {
     901           3 :     SolarMutexGuard aGuard;
     902           3 :     table::CellRangeAddress aRet;
     903           3 :     ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, nPos);
     904           3 :     if (pLink)
     905           3 :         ScUnoConversion::FillApiRange( aRet, pLink->GetDestArea() );
     906           3 :     return aRet;
     907             : }
     908             : 
     909           2 : void SAL_CALL ScAreaLinkObj::setDestArea( const table::CellRangeAddress& aDestArea )
     910             :                                             throw(uno::RuntimeException, std::exception)
     911             : {
     912           2 :     SolarMutexGuard aGuard;
     913           2 :     Modify_Impl( NULL, NULL, NULL, NULL, &aDestArea );
     914           2 : }
     915             : 
     916          51 : ScAreaLinksObj::ScAreaLinksObj(ScDocShell* pDocSh) :
     917          51 :     pDocShell( pDocSh )
     918             : {
     919          51 :     pDocShell->GetDocument()->AddUnoObject(*this);
     920          51 : }
     921             : 
     922         153 : ScAreaLinksObj::~ScAreaLinksObj()
     923             : {
     924          51 :     if (pDocShell)
     925          44 :         pDocShell->GetDocument()->RemoveUnoObject(*this);
     926         102 : }
     927             : 
     928         135 : void ScAreaLinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
     929             : {
     930             :     //  Referenz-Update interessiert hier nicht
     931             : 
     932         266 :     if ( rHint.ISA( SfxSimpleHint ) &&
     933         131 :             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
     934             :     {
     935           7 :         pDocShell = NULL;       // ungueltig geworden
     936             :     }
     937         135 : }
     938             : 
     939             : // XAreaLinks
     940             : 
     941           7 : ScAreaLinkObj* ScAreaLinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
     942             : {
     943           7 :     if ( pDocShell && nIndex >= 0 && nIndex < getCount() )
     944           5 :         return new ScAreaLinkObj( pDocShell, (size_t)nIndex );
     945             : 
     946           2 :     return NULL;    // nicht gefunden
     947             : }
     948             : 
     949           3 : void SAL_CALL ScAreaLinksObj::insertAtPosition( const table::CellAddress& aDestPos,
     950             :                                                 const OUString& aFileName,
     951             :                                                 const OUString& aSourceArea,
     952             :                                                 const OUString& aFilter,
     953             :                                                 const OUString& aFilterOptions )
     954             :                                             throw(uno::RuntimeException, std::exception)
     955             : {
     956           3 :     SolarMutexGuard aGuard;
     957           3 :     if (pDocShell)
     958             :     {
     959           3 :         OUString aFileStr   (aFileName);
     960           6 :         OUString aFilterStr (aFilter);
     961           6 :         OUString aOptionStr (aFilterOptions);
     962           6 :         OUString aSourceStr (aSourceArea);
     963           3 :         ScAddress aDestAddr( (SCCOL)aDestPos.Column, (SCROW)aDestPos.Row, aDestPos.Sheet );
     964             : 
     965           3 :         aFileStr = ScGlobal::GetAbsDocName( aFileStr, pDocShell );  //! in InsertAreaLink ???
     966           3 :         pDocShell->GetDocFunc().InsertAreaLink( aFileStr, aFilterStr, aOptionStr,
     967             :                                                 aSourceStr, ScRange(aDestAddr),
     968           9 :                                                 0, false, true ); // don't move contents
     969           3 :     }
     970           3 : }
     971             : 
     972           0 : void SAL_CALL ScAreaLinksObj::removeByIndex( sal_Int32 nIndex ) throw(uno::RuntimeException, std::exception)
     973             : {
     974           0 :     SolarMutexGuard aGuard;
     975           0 :     ScAreaLink* pLink = lcl_GetAreaLink(pDocShell, (size_t)nIndex);
     976           0 :     if (pLink)
     977             :     {
     978             :         //! SetAddUndo oder so
     979             : 
     980           0 :         sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
     981           0 :         pLinkManager->Remove( pLink );
     982           0 :     }
     983           0 : }
     984             : 
     985             : // XEnumerationAccess
     986             : 
     987           2 : uno::Reference<container::XEnumeration> SAL_CALL ScAreaLinksObj::createEnumeration()
     988             :                                                     throw(uno::RuntimeException, std::exception)
     989             : {
     990           2 :     SolarMutexGuard aGuard;
     991           2 :     return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.CellAreaLinksEnumeration"));
     992             : }
     993             : 
     994             : // XIndexAccess
     995             : 
     996          55 : sal_Int32 SAL_CALL ScAreaLinksObj::getCount() throw(uno::RuntimeException, std::exception)
     997             : {
     998          55 :     SolarMutexGuard aGuard;
     999          55 :     sal_Int32 nAreaCount = 0;
    1000          55 :     if (pDocShell)
    1001             :     {
    1002          55 :         sfx2::LinkManager* pLinkManager = pDocShell->GetDocument()->GetLinkManager();
    1003          55 :         size_t nTotalCount = pLinkManager->GetLinks().size();
    1004          66 :         for (size_t i=0; i<nTotalCount; i++)
    1005             :         {
    1006          11 :             ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
    1007          11 :             if (pBase->ISA(ScAreaLink))
    1008          11 :                 ++nAreaCount;
    1009             :         }
    1010             :     }
    1011          55 :     return nAreaCount;
    1012             : }
    1013             : 
    1014           7 : uno::Any SAL_CALL ScAreaLinksObj::getByIndex( sal_Int32 nIndex )
    1015             :                             throw(lang::IndexOutOfBoundsException,
    1016             :                                     lang::WrappedTargetException, uno::RuntimeException, std::exception)
    1017             : {
    1018           7 :     SolarMutexGuard aGuard;
    1019          14 :     uno::Reference<sheet::XAreaLink> xLink(GetObjectByIndex_Impl(nIndex));
    1020           7 :     if (xLink.is())
    1021          10 :         return uno::makeAny(xLink);
    1022             :     else
    1023           9 :         throw lang::IndexOutOfBoundsException();
    1024             : }
    1025             : 
    1026           1 : uno::Type SAL_CALL ScAreaLinksObj::getElementType() throw(uno::RuntimeException, std::exception)
    1027             : {
    1028           1 :     SolarMutexGuard aGuard;
    1029           1 :     return getCppuType((uno::Reference<sheet::XAreaLink>*)0);
    1030             : }
    1031             : 
    1032           1 : sal_Bool SAL_CALL ScAreaLinksObj::hasElements() throw(uno::RuntimeException, std::exception)
    1033             : {
    1034           1 :     SolarMutexGuard aGuard;
    1035           1 :     return ( getCount() != 0 );
    1036             : }
    1037             : 
    1038           6 : ScDDELinkObj::ScDDELinkObj(ScDocShell* pDocSh, const OUString& rA,
    1039             :                             const OUString& rT, const OUString& rI) :
    1040             :     pDocShell( pDocSh ),
    1041             :     aAppl( rA ),
    1042             :     aTopic( rT ),
    1043           6 :     aItem( rI )
    1044             : {
    1045           6 :     pDocShell->GetDocument()->AddUnoObject(*this);
    1046           6 : }
    1047             : 
    1048          18 : ScDDELinkObj::~ScDDELinkObj()
    1049             : {
    1050           6 :     if (pDocShell)
    1051           0 :         pDocShell->GetDocument()->RemoveUnoObject(*this);
    1052          12 : }
    1053             : 
    1054           8 : void ScDDELinkObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
    1055             : {
    1056             :     //! notify if links in document are changed
    1057             :     //  UpdateRef is not needed here
    1058             : 
    1059           8 :     if ( rHint.ISA( SfxSimpleHint ) )
    1060             :     {
    1061           6 :         if ( ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
    1062           6 :             pDocShell = NULL;       // pointer is invalid
    1063             :     }
    1064           2 :     else if ( rHint.ISA( ScLinkRefreshedHint ) )
    1065             :     {
    1066           2 :         const ScLinkRefreshedHint& rLH = (const ScLinkRefreshedHint&) rHint;
    1067           6 :         if ( rLH.GetLinkType() == SC_LINKREFTYPE_DDE &&
    1068           4 :              rLH.GetDdeAppl()  == aAppl &&
    1069           6 :              rLH.GetDdeTopic() == aTopic &&
    1070           2 :              rLH.GetDdeItem()  == aItem )       //! mode is ignored
    1071           2 :             Refreshed_Impl();
    1072             :     }
    1073           8 : }
    1074             : 
    1075             : // XNamed
    1076             : 
    1077           9 : static OUString lcl_BuildDDEName( const OUString& rAppl, const OUString& rTopic, const OUString& rItem )
    1078             : {
    1079             :     //  Appl|Topic!Item (wie Excel)
    1080           9 :     OUString aRet = rAppl + "|" + rTopic + "!" + rItem;
    1081           9 :     return aRet;
    1082             : }
    1083             : 
    1084           2 : OUString SAL_CALL ScDDELinkObj::getName() throw(uno::RuntimeException, std::exception)
    1085             : {
    1086           2 :     SolarMutexGuard aGuard;
    1087           2 :     return lcl_BuildDDEName( aAppl, aTopic, aItem );
    1088             : }
    1089             : 
    1090           0 : void SAL_CALL ScDDELinkObj::setName( const OUString& /* aName */ ) throw(uno::RuntimeException, std::exception)
    1091             : {
    1092             :     //  name can't be changed (formulas wouldn't find the link)
    1093           0 :     throw uno::RuntimeException();
    1094             : }
    1095             : 
    1096             : // XDDELink
    1097             : 
    1098           1 : OUString SAL_CALL ScDDELinkObj::getApplication() throw(uno::RuntimeException, std::exception)
    1099             : {
    1100           1 :     SolarMutexGuard aGuard;
    1101             :     //! Test, ob Link noch im Dokument enthalten?
    1102             : 
    1103           1 :     return aAppl;
    1104             : }
    1105             : 
    1106           1 : OUString SAL_CALL ScDDELinkObj::getTopic() throw(uno::RuntimeException, std::exception)
    1107             : {
    1108           1 :     SolarMutexGuard aGuard;
    1109             :     //! Test, ob Link noch im Dokument enthalten?
    1110             : 
    1111           1 :     return aTopic;
    1112             : }
    1113             : 
    1114           1 : OUString SAL_CALL ScDDELinkObj::getItem() throw(uno::RuntimeException, std::exception)
    1115             : {
    1116           1 :     SolarMutexGuard aGuard;
    1117             :     //! Test, ob Link noch im Dokument enthalten?
    1118             : 
    1119           1 :     return aItem;
    1120             : }
    1121             : 
    1122             : // XRefreshable
    1123             : 
    1124           2 : void SAL_CALL ScDDELinkObj::refresh() throw(uno::RuntimeException, std::exception)
    1125             : {
    1126           2 :     SolarMutexGuard aGuard;
    1127           2 :     if (pDocShell)
    1128             :     {
    1129           2 :         sc::DocumentLinkManager& rMgr = pDocShell->GetDocument()->GetDocLinkManager();
    1130           2 :         rMgr.updateDdeLink(aAppl, aTopic, aItem);
    1131           2 :     }
    1132           2 : }
    1133             : 
    1134           1 : void SAL_CALL ScDDELinkObj::addRefreshListener(
    1135             :     const uno::Reference<util::XRefreshListener >& xListener )
    1136             :         throw (uno::RuntimeException, std::exception)
    1137             : {
    1138           1 :     SolarMutexGuard aGuard;
    1139             :     uno::Reference<util::XRefreshListener>* pObj =
    1140           1 :             new uno::Reference<util::XRefreshListener>( xListener );
    1141           1 :     aRefreshListeners.push_back( pObj );
    1142             : 
    1143             :     //  hold one additional ref to keep this object alive as long as there are listeners
    1144           1 :     if ( aRefreshListeners.size() == 1 )
    1145           1 :         acquire();
    1146           1 : }
    1147             : 
    1148           1 : void SAL_CALL ScDDELinkObj::removeRefreshListener(
    1149             :                                 const uno::Reference<util::XRefreshListener >& xListener )
    1150             :                                                 throw(uno::RuntimeException, std::exception)
    1151             : {
    1152           1 :     SolarMutexGuard aGuard;
    1153           1 :     size_t nCount = aRefreshListeners.size();
    1154           2 :     for ( size_t n=nCount; n--; )
    1155             :     {
    1156           1 :         uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n];
    1157           1 :         if ( rObj == xListener )
    1158             :         {
    1159           1 :             aRefreshListeners.erase( aRefreshListeners.begin() + n );
    1160           1 :             if ( aRefreshListeners.empty() )
    1161           1 :                 release();                          // release ref for listeners
    1162           1 :             break;
    1163             :         }
    1164           1 :     }
    1165           1 : }
    1166             : 
    1167             : // XDDELinkResults
    1168             : 
    1169           0 : uno::Sequence< uno::Sequence< uno::Any > > ScDDELinkObj::getResults(  )
    1170             :     throw (uno::RuntimeException, std::exception)
    1171             : {
    1172           0 :     SolarMutexGuard aGuard;
    1173           0 :     uno::Sequence< uno::Sequence< uno::Any > > aReturn;
    1174           0 :     bool bSuccess = false;
    1175             : 
    1176           0 :     if ( pDocShell )
    1177             :     {
    1178           0 :         ScDocument* pDoc = pDocShell->GetDocument();
    1179           0 :         if ( pDoc )
    1180             :         {
    1181           0 :             size_t nPos = 0;
    1182           0 :             if ( pDoc->FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) )
    1183             :             {
    1184           0 :                 const ScMatrix* pMatrix = pDoc->GetDdeLinkResultMatrix( nPos );
    1185           0 :                 if ( pMatrix )
    1186             :                 {
    1187           0 :                     uno::Any aAny;
    1188           0 :                     if ( ScRangeToSequence::FillMixedArray( aAny, pMatrix, true ) )
    1189             :                     {
    1190           0 :                         aAny >>= aReturn;
    1191           0 :                     }
    1192             :                 }
    1193           0 :                 bSuccess = true;
    1194             :             }
    1195             :         }
    1196             :     }
    1197             : 
    1198           0 :     if ( !bSuccess )
    1199             :     {
    1200             :         throw uno::RuntimeException( OUString(
    1201             :             "ScDDELinkObj::getResults: failed to get results!" ),
    1202           0 :             uno::Reference< uno::XInterface >() );
    1203             :     }
    1204             : 
    1205           0 :     return aReturn;
    1206             : }
    1207             : 
    1208           0 : void ScDDELinkObj::setResults( const uno::Sequence< uno::Sequence< uno::Any > >& aResults )
    1209             :     throw (uno::RuntimeException, std::exception)
    1210             : {
    1211           0 :     SolarMutexGuard aGuard;
    1212           0 :     bool bSuccess = false;
    1213             : 
    1214           0 :     if ( pDocShell )
    1215             :     {
    1216           0 :         ScDocument* pDoc = pDocShell->GetDocument();
    1217           0 :         if ( pDoc )
    1218             :         {
    1219           0 :             size_t nPos = 0;
    1220           0 :             if ( pDoc->FindDdeLink( aAppl, aTopic, aItem, SC_DDE_IGNOREMODE, nPos ) )
    1221             :             {
    1222           0 :                 uno::Any aAny;
    1223           0 :                 aAny <<= aResults;
    1224           0 :                 ScMatrixRef xMatrix = ScSequenceToMatrix::CreateMixedMatrix( aAny );
    1225           0 :                 bSuccess = pDoc->SetDdeLinkResultMatrix( nPos, xMatrix );
    1226             :             }
    1227             :         }
    1228             :     }
    1229             : 
    1230           0 :     if ( !bSuccess )
    1231             :     {
    1232             :         throw uno::RuntimeException( OUString(
    1233             :             "ScDDELinkObj::setResults: failed to set results!" ),
    1234           0 :             uno::Reference< uno::XInterface >() );
    1235           0 :     }
    1236           0 : }
    1237             : 
    1238           2 : void ScDDELinkObj::Refreshed_Impl()
    1239             : {
    1240           2 :     lang::EventObject aEvent;
    1241           2 :     aEvent.Source.set((cppu::OWeakObject*)this);
    1242           3 :     for ( size_t n=0; n<aRefreshListeners.size(); n++ )
    1243           3 :         aRefreshListeners[n]->refreshed( aEvent );
    1244           2 : }
    1245             : 
    1246          25 : ScDDELinksObj::ScDDELinksObj(ScDocShell* pDocSh) :
    1247          25 :     pDocShell( pDocSh )
    1248             : {
    1249          25 :     pDocShell->GetDocument()->AddUnoObject(*this);
    1250          25 : }
    1251             : 
    1252          75 : ScDDELinksObj::~ScDDELinksObj()
    1253             : {
    1254          25 :     if (pDocShell)
    1255          18 :         pDocShell->GetDocument()->RemoveUnoObject(*this);
    1256          50 : }
    1257             : 
    1258         159 : void ScDDELinksObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
    1259             : {
    1260             :     //  Referenz-Update interessiert hier nicht
    1261             : 
    1262         316 :     if ( rHint.ISA( SfxSimpleHint ) &&
    1263         157 :             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
    1264             :     {
    1265           7 :         pDocShell = NULL;       // ungueltig geworden
    1266             :     }
    1267         159 : }
    1268             : 
    1269             : // XDDELinks
    1270             : 
    1271           6 : ScDDELinkObj* ScDDELinksObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
    1272             : {
    1273           6 :     if (pDocShell)
    1274             :     {
    1275           8 :         OUString aAppl, aTopic, aItem;
    1276           6 :         if ( pDocShell->GetDocument()->GetDdeLinkData( (size_t)nIndex, aAppl, aTopic, aItem ) )
    1277           6 :             return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
    1278             :     }
    1279           2 :     return NULL;
    1280             : }
    1281             : 
    1282           3 : ScDDELinkObj* ScDDELinksObj::GetObjectByName_Impl(const OUString& aName)
    1283             : {
    1284           3 :     if (pDocShell)
    1285             :     {
    1286           3 :         OUString aNamStr(aName);
    1287           4 :         OUString aAppl, aTopic, aItem;
    1288             : 
    1289           3 :         ScDocument* pDoc = pDocShell->GetDocument();
    1290           3 :         size_t nCount = pDoc->GetDocLinkManager().getDdeLinkCount();
    1291           4 :         for (size_t i=0; i<nCount; i++)
    1292             :         {
    1293           3 :             pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
    1294           3 :             if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
    1295           2 :                 return new ScDDELinkObj( pDocShell, aAppl, aTopic, aItem );
    1296           1 :         }
    1297             :     }
    1298           1 :     return NULL;
    1299             : }
    1300             : 
    1301             : // XEnumerationAccess
    1302             : 
    1303           2 : uno::Reference<container::XEnumeration> SAL_CALL ScDDELinksObj::createEnumeration()
    1304             :                                                     throw(uno::RuntimeException, std::exception)
    1305             : {
    1306           2 :     SolarMutexGuard aGuard;
    1307           2 :     return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DDELinksEnumeration"));
    1308             : }
    1309             : 
    1310             : // XIndexAccess
    1311             : 
    1312          22 : sal_Int32 SAL_CALL ScDDELinksObj::getCount() throw(uno::RuntimeException, std::exception)
    1313             : {
    1314          22 :     SolarMutexGuard aGuard;
    1315          22 :     sal_Int32 nAreaCount = 0;
    1316          22 :     if (pDocShell)
    1317          22 :         nAreaCount = pDocShell->GetDocument()->GetDocLinkManager().getDdeLinkCount();
    1318          22 :     return nAreaCount;
    1319             : }
    1320             : 
    1321           6 : uno::Any SAL_CALL ScDDELinksObj::getByIndex( sal_Int32 nIndex )
    1322             :                             throw(lang::IndexOutOfBoundsException,
    1323             :                                     lang::WrappedTargetException, uno::RuntimeException, std::exception)
    1324             : {
    1325           6 :     SolarMutexGuard aGuard;
    1326          12 :     uno::Reference<sheet::XDDELink> xLink(GetObjectByIndex_Impl(nIndex));
    1327           6 :     if (xLink.is())
    1328           8 :         return uno::makeAny(xLink);
    1329             :     else
    1330           8 :         throw lang::IndexOutOfBoundsException();
    1331             : }
    1332             : 
    1333           1 : uno::Type SAL_CALL ScDDELinksObj::getElementType() throw(uno::RuntimeException, std::exception)
    1334             : {
    1335           1 :     SolarMutexGuard aGuard;
    1336           1 :     return getCppuType((uno::Reference<sheet::XDDELink>*)0);
    1337             : }
    1338             : 
    1339           1 : sal_Bool SAL_CALL ScDDELinksObj::hasElements() throw(uno::RuntimeException, std::exception)
    1340             : {
    1341           1 :     SolarMutexGuard aGuard;
    1342           1 :     return ( getCount() != 0 );
    1343             : }
    1344             : 
    1345           3 : uno::Any SAL_CALL ScDDELinksObj::getByName( const OUString& aName )
    1346             :             throw(container::NoSuchElementException,
    1347             :                     lang::WrappedTargetException, uno::RuntimeException, std::exception)
    1348             : {
    1349           3 :     SolarMutexGuard aGuard;
    1350           6 :     uno::Reference<sheet::XDDELink> xLink(GetObjectByName_Impl(aName));
    1351           3 :     if (xLink.is())
    1352           4 :         return uno::makeAny(xLink);
    1353             :     else
    1354           4 :         throw container::NoSuchElementException();
    1355             : }
    1356             : 
    1357           2 : uno::Sequence<OUString> SAL_CALL ScDDELinksObj::getElementNames() throw(uno::RuntimeException, std::exception)
    1358             : {
    1359           2 :     SolarMutexGuard aGuard;
    1360           2 :     if (pDocShell)
    1361             :     {
    1362           4 :         OUString aAppl, aTopic, aItem;
    1363             : 
    1364           2 :         ScDocument* pDoc = pDocShell->GetDocument();
    1365           2 :         size_t nCount = pDocShell->GetDocument()->GetDocLinkManager().getDdeLinkCount();
    1366           4 :         uno::Sequence<OUString> aSeq(nCount);
    1367           2 :         OUString* pAry = aSeq.getArray();
    1368             : 
    1369           4 :         for (size_t i=0; i<nCount; i++)
    1370             :         {
    1371           2 :             pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
    1372           2 :             pAry[i] = lcl_BuildDDEName(aAppl, aTopic, aItem);
    1373             :         }
    1374           4 :         return aSeq;
    1375             :     }
    1376           0 :     return uno::Sequence<OUString>();
    1377             : }
    1378             : 
    1379           2 : sal_Bool SAL_CALL ScDDELinksObj::hasByName( const OUString& aName )
    1380             :                                         throw(uno::RuntimeException, std::exception)
    1381             : {
    1382           2 :     SolarMutexGuard aGuard;
    1383           2 :     if (pDocShell)
    1384             :     {
    1385           2 :         OUString aNamStr(aName);
    1386           3 :         OUString aAppl, aTopic, aItem;
    1387             : 
    1388           2 :         ScDocument* pDoc = pDocShell->GetDocument();
    1389           2 :         size_t nCount = pDocShell->GetDocument()->GetDocLinkManager().getDdeLinkCount();
    1390           3 :         for (size_t i=0; i<nCount; i++)
    1391             :         {
    1392           2 :             pDoc->GetDdeLinkData( i, aAppl, aTopic, aItem );
    1393           2 :             if ( lcl_BuildDDEName(aAppl, aTopic, aItem) == aNamStr )
    1394           1 :                 return sal_True;
    1395           1 :         }
    1396             :     }
    1397           1 :     return false;
    1398             : }
    1399             : 
    1400             : // XDDELinks
    1401             : 
    1402           0 : uno::Reference< sheet::XDDELink > ScDDELinksObj::addDDELink(
    1403             :     const OUString& aApplication, const OUString& aTopic,
    1404             :     const OUString& aItem, ::com::sun::star::sheet::DDELinkMode nMode )
    1405             :     throw (uno::RuntimeException, std::exception)
    1406             : {
    1407           0 :     SolarMutexGuard aGuard;
    1408           0 :     uno::Reference< sheet::XDDELink > xLink;
    1409             : 
    1410           0 :     if ( pDocShell )
    1411             :     {
    1412           0 :         ScDocument* pDoc = pDocShell->GetDocument();
    1413           0 :         if ( pDoc )
    1414             :         {
    1415           0 :             sal_uInt8 nMod = SC_DDE_DEFAULT;
    1416           0 :             switch ( nMode )
    1417             :             {
    1418             :                 case sheet::DDELinkMode_DEFAULT:
    1419             :                     {
    1420           0 :                         nMod = SC_DDE_DEFAULT;
    1421             :                     }
    1422           0 :                     break;
    1423             :                 case sheet::DDELinkMode_ENGLISH:
    1424             :                     {
    1425           0 :                         nMod = SC_DDE_ENGLISH;
    1426             :                     }
    1427           0 :                     break;
    1428             :                 case sheet::DDELinkMode_TEXT:
    1429             :                     {
    1430           0 :                         nMod = SC_DDE_TEXT;
    1431             :                     }
    1432           0 :                     break;
    1433             :                 default:
    1434             :                     {
    1435             :                     }
    1436           0 :                     break;
    1437             :             }
    1438             : 
    1439           0 :             if ( pDoc->CreateDdeLink( aApplication, aTopic, aItem, nMod, ScMatrixRef() ) )
    1440             :             {
    1441           0 :                 const OUString aName( lcl_BuildDDEName( aApplication, aTopic, aItem ) );
    1442           0 :                 xLink.set( GetObjectByName_Impl( aName ) );
    1443             :             }
    1444             :         }
    1445             :     }
    1446             : 
    1447           0 :     if ( !xLink.is() )
    1448             :     {
    1449             :         throw uno::RuntimeException( OUString(
    1450             :             "ScDDELinksObj::addDDELink: cannot add DDE link!" ),
    1451           0 :             uno::Reference< uno::XInterface >() );
    1452             :     }
    1453             : 
    1454           0 :     return xLink;
    1455             : }
    1456             : 
    1457           6 : ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScDocShell* pDocShell, ScExternalRefCache::TableTypeRef pTable, size_t nIndex) :
    1458             :     mpDocShell(pDocShell),
    1459             :     mpTable(pTable),
    1460           6 :     mnIndex(nIndex)
    1461             : {
    1462           6 : }
    1463             : 
    1464          12 : ScExternalSheetCacheObj::~ScExternalSheetCacheObj()
    1465             : {
    1466          12 : }
    1467             : 
    1468           4 : void SAL_CALL ScExternalSheetCacheObj::setCellValue(sal_Int32 nCol, sal_Int32 nRow, const Any& rValue)
    1469             :     throw (IllegalArgumentException, RuntimeException, std::exception)
    1470             : {
    1471           4 :     SolarMutexGuard aGuard;
    1472           4 :     if (nRow < 0 || nCol < 0)
    1473           0 :         throw IllegalArgumentException();
    1474             : 
    1475           8 :     ScExternalRefCache::TokenRef pToken;
    1476           4 :     double fVal = 0.0;
    1477           8 :     OUString aVal;
    1478           4 :     if (rValue >>= fVal)
    1479           0 :         pToken.reset(new FormulaDoubleToken(fVal));
    1480           4 :     else if (rValue >>= aVal)
    1481             :     {
    1482           4 :         svl::SharedStringPool& rPool = mpDocShell->GetDocument()->GetSharedStringPool();
    1483           4 :         svl::SharedString aSS = rPool.intern(aVal);
    1484           4 :         pToken.reset(new FormulaStringToken(aSS));
    1485             :     }
    1486             :     else
    1487             :         // unidentified value type.
    1488           4 :         return;
    1489             : 
    1490           8 :     mpTable->setCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), pToken);
    1491             : }
    1492             : 
    1493           0 : Any SAL_CALL ScExternalSheetCacheObj::getCellValue(sal_Int32 nCol, sal_Int32 nRow)
    1494             :     throw (IllegalArgumentException, RuntimeException, std::exception)
    1495             : {
    1496           0 :     SolarMutexGuard aGuard;
    1497           0 :     if (nRow < 0 || nCol < 0)
    1498           0 :         throw IllegalArgumentException();
    1499             : 
    1500           0 :     FormulaToken* pToken = mpTable->getCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow)).get();
    1501           0 :     if (!pToken)
    1502           0 :         throw IllegalArgumentException();
    1503             : 
    1504           0 :     Any aValue;
    1505           0 :     switch (pToken->GetType())
    1506             :     {
    1507             :         case svDouble:
    1508             :         {
    1509           0 :             double fVal = pToken->GetDouble();
    1510           0 :             aValue <<= fVal;
    1511             :         }
    1512           0 :         break;
    1513             :         case svString:
    1514             :         {
    1515           0 :             OUString aVal = pToken->GetString().getString();
    1516           0 :             aValue <<= aVal;
    1517             :         }
    1518           0 :         break;
    1519             :         default:
    1520           0 :             throw IllegalArgumentException();
    1521             :     }
    1522           0 :     return aValue;
    1523             : }
    1524             : 
    1525           0 : Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllRows()
    1526             :     throw (RuntimeException, std::exception)
    1527             : {
    1528           0 :     SolarMutexGuard aGuard;
    1529           0 :     vector<SCROW> aRows;
    1530           0 :     mpTable->getAllRows(aRows);
    1531           0 :     size_t nSize = aRows.size();
    1532           0 :     Sequence<sal_Int32> aRowsSeq(nSize);
    1533           0 :     for (size_t i = 0; i < nSize; ++i)
    1534           0 :         aRowsSeq[i] = aRows[i];
    1535             : 
    1536           0 :     return aRowsSeq;
    1537             : }
    1538             : 
    1539           0 : Sequence< sal_Int32 > SAL_CALL ScExternalSheetCacheObj::getAllColumns(sal_Int32 nRow)
    1540             :     throw (IllegalArgumentException, RuntimeException, std::exception)
    1541             : {
    1542           0 :     SolarMutexGuard aGuard;
    1543           0 :     if (nRow < 0)
    1544           0 :         throw IllegalArgumentException();
    1545             : 
    1546           0 :     vector<SCCOL> aCols;
    1547           0 :     mpTable->getAllCols(static_cast<SCROW>(nRow), aCols);
    1548           0 :     size_t nSize = aCols.size();
    1549           0 :     Sequence<sal_Int32> aColsSeq(nSize);
    1550           0 :     for (size_t i = 0; i < nSize; ++i)
    1551           0 :         aColsSeq[i] = aCols[i];
    1552             : 
    1553           0 :     return aColsSeq;
    1554             : }
    1555             : 
    1556           3 : sal_Int32 SAL_CALL ScExternalSheetCacheObj::getTokenIndex()
    1557             :         throw (RuntimeException, std::exception)
    1558             : {
    1559           3 :     return static_cast< sal_Int32 >( mnIndex );
    1560             : }
    1561             : 
    1562           1 : ScExternalDocLinkObj::ScExternalDocLinkObj(ScDocShell* pDocShell, ScExternalRefManager* pRefMgr, sal_uInt16 nFileId) :
    1563           1 :     mpDocShell(pDocShell), mpRefMgr(pRefMgr), mnFileId(nFileId)
    1564             : {
    1565           1 : }
    1566             : 
    1567           2 : ScExternalDocLinkObj::~ScExternalDocLinkObj()
    1568             : {
    1569           2 : }
    1570             : 
    1571           3 : Reference< sheet::XExternalSheetCache > SAL_CALL ScExternalDocLinkObj::addSheetCache(
    1572             :     const OUString& aSheetName, sal_Bool bDynamicCache )
    1573             :         throw (RuntimeException, std::exception)
    1574             : {
    1575           3 :     SolarMutexGuard aGuard;
    1576           3 :     size_t nIndex = 0;
    1577           6 :     ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true, &nIndex);
    1578           3 :     if (!bDynamicCache)
    1579             :         // Set the whole table cached to prevent access to the source document.
    1580           3 :         pTable->setWholeTableCached();
    1581             : 
    1582           3 :     Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(mpDocShell, pTable, nIndex));
    1583           6 :     return aSheetCache;
    1584             : }
    1585             : 
    1586           0 : Any SAL_CALL ScExternalDocLinkObj::getByName(const OUString &aName)
    1587             :         throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException, std::exception)
    1588             : {
    1589           0 :     SolarMutexGuard aGuard;
    1590           0 :     size_t nIndex = 0;
    1591           0 :     ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false, &nIndex);
    1592           0 :     if (!pTable)
    1593           0 :         throw container::NoSuchElementException();
    1594             : 
    1595           0 :     Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(mpDocShell, pTable, nIndex));
    1596             : 
    1597           0 :     Any aAny;
    1598           0 :     aAny <<= aSheetCache;
    1599           0 :     return aAny;
    1600             : }
    1601             : 
    1602           3 : Sequence< OUString > SAL_CALL ScExternalDocLinkObj::getElementNames()
    1603             :         throw (RuntimeException, std::exception)
    1604             : {
    1605           3 :     SolarMutexGuard aGuard;
    1606           6 :     vector<OUString> aTabNames;
    1607           3 :     mpRefMgr->getAllCachedTableNames(mnFileId, aTabNames);
    1608             : 
    1609             :     // #i116940# be consistent with getByName: include only table names which have a cache already
    1610           6 :     vector<OUString> aValidNames;
    1611          12 :     for (vector<OUString>::iterator aIter = aTabNames.begin(); aIter != aTabNames.end(); ++aIter)
    1612           9 :         if (mpRefMgr->getCacheTable(mnFileId, *aIter, false))
    1613           9 :             aValidNames.push_back(*aIter);
    1614             : 
    1615           3 :     size_t n = aValidNames.size();
    1616           3 :     Sequence<OUString> aSeq(n);
    1617          12 :     for (size_t i = 0; i < n; ++i)
    1618           9 :         aSeq[i] = aValidNames[i];
    1619           6 :     return aSeq;
    1620             : }
    1621             : 
    1622           0 : sal_Bool SAL_CALL ScExternalDocLinkObj::hasByName(const OUString &aName)
    1623             :         throw (RuntimeException, std::exception)
    1624             : {
    1625           0 :     SolarMutexGuard aGuard;
    1626             : 
    1627             :     // #i116940# be consistent with getByName: allow only table names which have a cache already
    1628           0 :     ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false);
    1629           0 :     return (pTable.get() != NULL);
    1630             : }
    1631             : 
    1632           0 : sal_Int32 SAL_CALL ScExternalDocLinkObj::getCount()
    1633             :         throw (RuntimeException, std::exception)
    1634             : {
    1635           0 :     SolarMutexGuard aGuard;
    1636             : 
    1637             :     // #i116940# be consistent with getByName: count only table names which have a cache already
    1638           0 :     return getElementNames().getLength();
    1639             : }
    1640             : 
    1641           3 : Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nApiIndex)
    1642             :         throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException, std::exception)
    1643             : {
    1644           3 :     SolarMutexGuard aGuard;
    1645             : 
    1646             :     // #i116940# Can't use nApiIndex as index for the ref manager, because the API counts only
    1647             :     // the entries which have a cache already. Quick solution: Use getElementNames.
    1648           6 :     Sequence< OUString > aNames( getElementNames() );
    1649           3 :     if (nApiIndex < 0 || nApiIndex >= aNames.getLength())
    1650           0 :         throw lang::IndexOutOfBoundsException();
    1651             : 
    1652           3 :     size_t nIndex = 0;
    1653           6 :     ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aNames[nApiIndex], false, &nIndex);
    1654           3 :     if (!pTable)
    1655           0 :         throw lang::IndexOutOfBoundsException();
    1656             : 
    1657           6 :     Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(mpDocShell, pTable, nIndex));
    1658             : 
    1659           3 :     Any aAny;
    1660           3 :     aAny <<= aSheetCache;
    1661           6 :     return aAny;
    1662             : }
    1663             : 
    1664           0 : Reference< container::XEnumeration > SAL_CALL ScExternalDocLinkObj::createEnumeration()
    1665             :         throw (RuntimeException, std::exception)
    1666             : {
    1667           0 :     SolarMutexGuard aGuard;
    1668             :     Reference< container::XEnumeration > aRef(
    1669             :         new ScIndexEnumeration(this, OUString(
    1670           0 :             "com.sun.star.sheet.ExternalDocLink")));
    1671           0 :     return aRef;
    1672             : }
    1673             : 
    1674           0 : uno::Type SAL_CALL ScExternalDocLinkObj::getElementType()
    1675             :         throw (RuntimeException, std::exception)
    1676             : {
    1677           0 :     SolarMutexGuard aGuard;
    1678           0 :     return getCppuType(static_cast<Reference<sheet::XExternalDocLink>*>(0));
    1679             : }
    1680             : 
    1681           0 : sal_Bool SAL_CALL ScExternalDocLinkObj::hasElements()
    1682             :         throw (RuntimeException, std::exception)
    1683             : {
    1684           0 :     SolarMutexGuard aGuard;
    1685             : 
    1686             :     // #i116940# be consistent with getByName: count only table names which have a cache already
    1687           0 :     return ( getElementNames().getLength() > 0 );
    1688             : }
    1689             : 
    1690           0 : sal_Int32 SAL_CALL ScExternalDocLinkObj::getTokenIndex()
    1691             :         throw (RuntimeException, std::exception)
    1692             : {
    1693           0 :     return static_cast<sal_Int32>(mnFileId);
    1694             : }
    1695             : 
    1696           3 : ScExternalDocLinksObj::ScExternalDocLinksObj(ScDocShell* pDocShell) :
    1697             :     mpDocShell(pDocShell),
    1698           3 :     mpRefMgr(pDocShell->GetDocument()->GetExternalRefManager())
    1699             : {
    1700           3 : }
    1701             : 
    1702           6 : ScExternalDocLinksObj::~ScExternalDocLinksObj()
    1703             : {
    1704           6 : }
    1705             : 
    1706           1 : Reference< sheet::XExternalDocLink > SAL_CALL ScExternalDocLinksObj::addDocLink(
    1707             :     const OUString& aDocName )
    1708             :         throw (RuntimeException, std::exception)
    1709             : {
    1710           1 :     SolarMutexGuard aGuard;
    1711           1 :     sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aDocName);
    1712           1 :     Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpDocShell, mpRefMgr, nFileId));
    1713           1 :     return aDocLink;
    1714             : }
    1715             : 
    1716           0 : Any SAL_CALL ScExternalDocLinksObj::getByName(const OUString &aName)
    1717             :         throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException, std::exception)
    1718             : {
    1719           0 :     SolarMutexGuard aGuard;
    1720           0 :     if (!mpRefMgr->hasExternalFile(aName))
    1721           0 :         throw container::NoSuchElementException();
    1722             : 
    1723           0 :     sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aName);
    1724           0 :     Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpDocShell, mpRefMgr, nFileId));
    1725             : 
    1726           0 :     Any aAny;
    1727           0 :     aAny <<= aDocLink;
    1728           0 :     return aAny;
    1729             : }
    1730             : 
    1731           0 : Sequence< OUString > SAL_CALL ScExternalDocLinksObj::getElementNames()
    1732             :         throw (RuntimeException, std::exception)
    1733             : {
    1734           0 :     SolarMutexGuard aGuard;
    1735           0 :     sal_uInt16 n = mpRefMgr->getExternalFileCount();
    1736           0 :     Sequence<OUString> aSeq(n);
    1737           0 :     for (sal_uInt16 i = 0; i < n; ++i)
    1738             :     {
    1739           0 :         const OUString* pName = mpRefMgr->getExternalFileName(i);
    1740           0 :         aSeq[i] = pName ? *pName : OUString();
    1741             :     }
    1742             : 
    1743           0 :     return aSeq;
    1744             : }
    1745             : 
    1746           0 : sal_Bool SAL_CALL ScExternalDocLinksObj::hasByName(const OUString &aName)
    1747             :         throw (RuntimeException, std::exception)
    1748             : {
    1749           0 :     SolarMutexGuard aGuard;
    1750           0 :     return mpRefMgr->hasExternalFile(aName);
    1751             : }
    1752             : 
    1753           0 : sal_Int32 SAL_CALL ScExternalDocLinksObj::getCount()
    1754             :         throw (RuntimeException, std::exception)
    1755             : {
    1756           0 :     SolarMutexGuard aGuard;
    1757           0 :     return mpRefMgr->getExternalFileCount();
    1758             : }
    1759             : 
    1760           0 : Any SAL_CALL ScExternalDocLinksObj::getByIndex(sal_Int32 nIndex)
    1761             :         throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException, std::exception)
    1762             : {
    1763           0 :     SolarMutexGuard aGuard;
    1764           0 :     if (nIndex > ::std::numeric_limits<sal_uInt16>::max() || nIndex < ::std::numeric_limits<sal_uInt16>::min())
    1765           0 :         throw lang::IndexOutOfBoundsException();
    1766             : 
    1767           0 :     sal_uInt16 nFileId = static_cast<sal_uInt16>(nIndex);
    1768             : 
    1769           0 :     if (!mpRefMgr->hasExternalFile(nFileId))
    1770           0 :         throw lang::IndexOutOfBoundsException();
    1771             : 
    1772           0 :     Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpDocShell, mpRefMgr, nFileId));
    1773           0 :     Any aAny;
    1774           0 :     aAny <<= aDocLink;
    1775           0 :     return aAny;
    1776             : }
    1777             : 
    1778           0 : Reference< container::XEnumeration > SAL_CALL ScExternalDocLinksObj::createEnumeration()
    1779             :         throw (RuntimeException, std::exception)
    1780             : {
    1781           0 :     SolarMutexGuard aGuard;
    1782             :     Reference< container::XEnumeration > aRef(
    1783             :         new ScIndexEnumeration(this, OUString(
    1784           0 :             "com.sun.star.sheet.ExternalDocLinks")));
    1785           0 :     return aRef;
    1786             : }
    1787             : 
    1788           0 : uno::Type SAL_CALL ScExternalDocLinksObj::getElementType()
    1789             :         throw (RuntimeException, std::exception)
    1790             : {
    1791           0 :     SolarMutexGuard aGuard;
    1792           0 :     return getCppuType(static_cast<Reference<sheet::XExternalDocLinks>*>(0));
    1793             : }
    1794             : 
    1795           0 : sal_Bool SAL_CALL ScExternalDocLinksObj::hasElements()
    1796             :         throw (RuntimeException, std::exception)
    1797             : {
    1798           0 :     SolarMutexGuard aGuard;
    1799           0 :     return mpRefMgr->getExternalFileCount() > 0;
    1800             : }
    1801             : 
    1802             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10