LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/ui/docshell - servobj.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 62 116 53.4 %
Date: 2013-07-09 Functions: 11 14 78.6 %
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 <sot/formats.hxx>
      21             : #include <sfx2/app.hxx>
      22             : #include <sfx2/linkmgr.hxx>
      23             : #include "servobj.hxx"
      24             : #include "docsh.hxx"
      25             : #include "impex.hxx"
      26             : #include "brdcst.hxx"
      27             : #include "rangenam.hxx"
      28             : #include "sc.hrc"               // SC_HINT_AREAS_CHANGED
      29             : 
      30             : using namespace formula;
      31             : 
      32             : // -----------------------------------------------------------------------
      33             : 
      34           8 : static sal_Bool lcl_FillRangeFromName( ScRange& rRange, ScDocShell* pDocSh, const String& rName )
      35             : {
      36           8 :     if (pDocSh)
      37             :     {
      38           8 :         ScDocument* pDoc = pDocSh->GetDocument();
      39           8 :         ScRangeName* pNames = pDoc->GetRangeName();
      40           8 :         if (pNames)
      41             :         {
      42           8 :             const ScRangeData* pData = pNames->findByUpperName(ScGlobal::pCharClass->uppercase(rName));
      43           8 :             if (pData)
      44             :             {
      45           0 :                 if ( pData->IsValidReference( rRange ) )
      46           0 :                     return sal_True;
      47             :             }
      48             :         }
      49             :     }
      50           8 :     return false;
      51             : }
      52             : 
      53           8 : ScServerObjectSvtListenerForwarder::ScServerObjectSvtListenerForwarder(
      54             :         ScServerObject* pObjP)
      55           8 :     : pObj(pObjP)
      56             : {
      57           8 : }
      58             : 
      59           8 : ScServerObjectSvtListenerForwarder::~ScServerObjectSvtListenerForwarder()
      60             : {
      61             :     //! do NOT access pObj
      62           8 : }
      63             : 
      64           0 : void ScServerObjectSvtListenerForwarder::Notify( SvtBroadcaster& /* rBC */, const SfxHint& rHint)
      65             : {
      66           0 :     pObj->Notify( aBroadcaster, rHint);
      67           0 : }
      68             : 
      69           8 : ScServerObject::ScServerObject( ScDocShell* pShell, const String& rItem ) :
      70             :     aForwarder( this ),
      71             :     pDocSh( pShell ),
      72           8 :     bRefreshListener( false )
      73             : {
      74             :     //  parse item string
      75             : 
      76           8 :     if ( lcl_FillRangeFromName( aRange, pDocSh, rItem ) )
      77             :     {
      78           0 :         aItemStr = rItem;               // must be parsed again on ref update
      79             :     }
      80             :     else
      81             :     {
      82             :         //  parse ref
      83           8 :         ScDocument* pDoc = pDocSh->GetDocument();
      84           8 :         SCTAB nTab = pDocSh->GetCurTab();
      85           8 :         aRange.aStart.SetTab( nTab );
      86             : 
      87             :         // For DDE link, we always must parse references using OOO A1 convention.
      88             : 
      89           8 :         if ( aRange.Parse( rItem, pDoc, FormulaGrammar::CONV_OOO ) & SCA_VALID )
      90             :         {
      91             :             // area reference
      92             :         }
      93           8 :         else if ( aRange.aStart.Parse( rItem, pDoc, FormulaGrammar::CONV_OOO ) & SCA_VALID )
      94             :         {
      95             :             // cell reference
      96           8 :             aRange.aEnd = aRange.aStart;
      97             :         }
      98             :         else
      99             :         {
     100             :             OSL_FAIL("ScServerObject: invalid item");
     101             :         }
     102             :     }
     103             : 
     104           8 :     pDocSh->GetDocument()->GetLinkManager()->InsertServer( this );
     105           8 :     pDocSh->GetDocument()->StartListeningArea( aRange, &aForwarder );
     106             : 
     107           8 :     StartListening(*pDocSh);        // um mitzubekommen, wenn die DocShell geloescht wird
     108           8 :     StartListening(*SFX_APP());     // for SC_HINT_AREAS_CHANGED
     109           8 : }
     110             : 
     111          24 : ScServerObject::~ScServerObject()
     112             : {
     113           8 :     Clear();
     114          16 : }
     115             : 
     116           8 : void ScServerObject::Clear()
     117             : {
     118           8 :     if (pDocSh)
     119             :     {
     120           8 :         ScDocShell* pTemp = pDocSh;
     121           8 :         pDocSh = NULL;
     122             : 
     123           8 :         pTemp->GetDocument()->EndListeningArea( aRange, &aForwarder );
     124           8 :         pTemp->GetDocument()->GetLinkManager()->RemoveServer( this );
     125           8 :         EndListening(*pTemp);
     126           8 :         EndListening(*SFX_APP());
     127             :     }
     128           8 : }
     129             : 
     130           0 : void ScServerObject::EndListeningAll()
     131             : {
     132           0 :     aForwarder.EndListeningAll();
     133           0 :     SfxListener::EndListeningAll();
     134           0 : }
     135             : 
     136           8 : sal_Bool ScServerObject::GetData(
     137             :         ::com::sun::star::uno::Any & rData /*out param*/,
     138             :         const String & rMimeType, sal_Bool /* bSynchron */ )
     139             : {
     140           8 :     if (!pDocSh)
     141           0 :         return false;
     142             : 
     143             :     // named ranges may have changed -> update aRange
     144           8 :     if ( aItemStr.Len() )
     145             :     {
     146           0 :         ScRange aNew;
     147           0 :         if ( lcl_FillRangeFromName( aNew, pDocSh, aItemStr ) && aNew != aRange )
     148             :         {
     149           0 :             aRange = aNew;
     150           0 :             bRefreshListener = sal_True;
     151             :         }
     152             :     }
     153             : 
     154           8 :     if ( bRefreshListener )
     155             :     {
     156             :         //  refresh the listeners now (this is called from a timer)
     157             : 
     158           0 :         EndListeningAll();
     159           0 :         pDocSh->GetDocument()->StartListeningArea( aRange, &aForwarder );
     160           0 :         StartListening(*pDocSh);
     161           0 :         StartListening(*SFX_APP());
     162           0 :         bRefreshListener = false;
     163             :     }
     164             : 
     165           8 :     String aDdeTextFmt = pDocSh->GetDdeTextFmt();
     166           8 :     ScDocument* pDoc = pDocSh->GetDocument();
     167             : 
     168           8 :     if( FORMAT_STRING == SotExchange::GetFormatIdFromMimeType( rMimeType ))
     169             :     {
     170           8 :         ScImportExport aObj( pDoc, aRange );
     171           8 :         if( aDdeTextFmt.GetChar(0) == 'F' )
     172           0 :             aObj.SetFormulas( sal_True );
     173          16 :         if( aDdeTextFmt.EqualsAscii( "SYLK" ) ||
     174           8 :             aDdeTextFmt.EqualsAscii( "FSYLK" ) )
     175             :         {
     176           0 :             OString aByteData;
     177           0 :             if( aObj.ExportByteString( aByteData, osl_getThreadTextEncoding(), SOT_FORMATSTR_ID_SYLK ) )
     178             :             {
     179           0 :                 rData <<= ::com::sun::star::uno::Sequence< sal_Int8 >(
     180           0 :                                         (const sal_Int8*)aByteData.getStr(),
     181           0 :                                         aByteData.getLength() + 1 );
     182           0 :                 return 1;
     183             :             }
     184           0 :             return 0;
     185             :         }
     186          16 :         if( aDdeTextFmt.EqualsAscii( "CSV" ) ||
     187           8 :             aDdeTextFmt.EqualsAscii( "FCSV" ) )
     188           0 :             aObj.SetSeparator( ',' );
     189           8 :         aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, ' ', false ) );
     190           8 :         return aObj.ExportData( rMimeType, rData ) ? 1 : 0;
     191             :     }
     192             : 
     193           0 :     ScImportExport aObj( pDoc, aRange );
     194           0 :     aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, ' ', false ) );
     195           0 :     if( aObj.IsRef() )
     196           0 :         return aObj.ExportData( rMimeType, rData ) ? 1 : 0;
     197           8 :     return 0;
     198             : }
     199             : 
     200          34 : void ScServerObject::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
     201             : {
     202          34 :     sal_Bool bDataChanged = false;
     203             : 
     204             :     //  DocShell can't be tested via type info, because SFX_HINT_DYING comes from the dtor
     205          34 :     if ( &rBC == pDocSh )
     206             :     {
     207             :         //  from DocShell, only SFX_HINT_DYING is interesting
     208           0 :         if ( rHint.ISA(SfxSimpleHint) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
     209             :         {
     210           0 :             pDocSh = NULL;
     211           0 :             EndListening(*SFX_APP());
     212             :             //  don't access DocShell anymore for EndListening etc.
     213             :         }
     214             :     }
     215          34 :     else if (rBC.ISA(SfxApplication))
     216             :     {
     217          34 :         if ( aItemStr.Len() && rHint.ISA(SfxSimpleHint) &&
     218           0 :                 ((const SfxSimpleHint&)rHint).GetId() == SC_HINT_AREAS_CHANGED )
     219             :         {
     220             :             //  check if named range was modified
     221           0 :             ScRange aNew;
     222           0 :             if ( lcl_FillRangeFromName( aNew, pDocSh, aItemStr ) && aNew != aRange )
     223           0 :                 bDataChanged = sal_True;
     224             :         }
     225             :     }
     226             :     else
     227             :     {
     228             :         //  must be from Area broadcasters
     229             : 
     230           0 :         const ScHint* pScHint = PTR_CAST( ScHint, &rHint );
     231           0 :         if (pScHint && (pScHint->GetId() & SC_HINT_DATACHANGED))
     232           0 :             bDataChanged = sal_True;
     233           0 :         else if (rHint.ISA(ScAreaChangedHint))      // position of broadcaster changed
     234             :         {
     235           0 :             ScRange aNewRange = ((const ScAreaChangedHint&)rHint).GetRange();
     236           0 :             if ( aRange != aNewRange )
     237             :             {
     238           0 :                 bRefreshListener = sal_True;
     239           0 :                 bDataChanged = sal_True;
     240             :             }
     241             :         }
     242           0 :         else if (rHint.ISA(SfxSimpleHint))
     243             :         {
     244           0 :             sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId();
     245           0 :             if (nId == SFX_HINT_DYING)
     246             :             {
     247             :                 //  If the range is being deleted, listening must be restarted
     248             :                 //  after the deletion is complete (done in GetData)
     249           0 :                 bRefreshListener = sal_True;
     250           0 :                 bDataChanged = sal_True;
     251             :             }
     252             :         }
     253             :     }
     254             : 
     255          34 :     if ( bDataChanged && HasDataLinks() )
     256           0 :         SvLinkSource::NotifyDataChanged();
     257         127 : }
     258             : 
     259             : 
     260             : 
     261             : 
     262             : 
     263             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10