LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/ui/vba - excelvbahelper.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 162 189 85.7 %
Date: 2013-07-09 Functions: 23 26 88.5 %
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 "excelvbahelper.hxx"
      21             : 
      22             : #include <comphelper/processfactory.hxx>
      23             : #include <com/sun/star/sheet/XSheetCellRange.hpp>
      24             : #include <com/sun/star/sheet/GlobalSheetSettings.hpp>
      25             : 
      26             : #include "docuno.hxx"
      27             : #include "tabvwsh.hxx"
      28             : #include "transobj.hxx"
      29             : #include "scmod.hxx"
      30             : #include "cellsuno.hxx"
      31             : 
      32             : #include <com/sun/star/script/vba/VBAEventId.hpp>
      33             : #include <com/sun/star/script/vba/XVBACompatibility.hpp>
      34             : #include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
      35             : #include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
      36             : #include <com/sun/star/script/ModuleInfo.hpp>
      37             : #include <com/sun/star/script/ModuleType.hpp>
      38             : 
      39             : using namespace ::com::sun::star;
      40             : using namespace ::ooo::vba;
      41             : 
      42             : namespace ooo {
      43             : namespace vba {
      44             : namespace excel {
      45             : 
      46             : // ============================================================================
      47             : 
      48             : uno::Reference< sheet::XUnnamedDatabaseRanges >
      49          13 : GetUnnamedDataBaseRanges( ScDocShell* pShell ) throw ( uno::RuntimeException )
      50             : {
      51          13 :     uno::Reference< frame::XModel > xModel;
      52          13 :     if ( pShell )
      53          13 :         xModel.set( pShell->GetModel(), uno::UNO_QUERY_THROW );
      54          26 :     uno::Reference< beans::XPropertySet > xModelProps( xModel, uno::UNO_QUERY_THROW );
      55          13 :     uno::Reference< sheet::XUnnamedDatabaseRanges > xUnnamedDBRanges( xModelProps->getPropertyValue("UnnamedDatabaseRanges"), uno::UNO_QUERY_THROW );
      56          26 :     return xUnnamedDBRanges;
      57             : }
      58             : 
      59             : // returns the XDatabaseRange for the autofilter on sheet (nSheet)
      60             : // also populates sName with the name of range
      61             : uno::Reference< sheet::XDatabaseRange >
      62          12 : GetAutoFiltRange( ScDocShell* pShell, sal_Int16 nSheet ) throw ( uno::RuntimeException )
      63             : {
      64          12 :     uno::Reference< sheet::XUnnamedDatabaseRanges > xUnnamedDBRanges( GetUnnamedDataBaseRanges( pShell ), uno::UNO_QUERY_THROW );
      65          12 :     uno::Reference< sheet::XDatabaseRange > xDataBaseRange;
      66          12 :     if (xUnnamedDBRanges->hasByTable( nSheet ) )
      67             :     {
      68          11 :         uno::Reference< sheet::XDatabaseRange > xDBRange( xUnnamedDBRanges->getByTable( nSheet ) , uno::UNO_QUERY_THROW );
      69          11 :         sal_Bool bHasAuto = false;
      70          22 :         uno::Reference< beans::XPropertySet > xProps( xDBRange, uno::UNO_QUERY_THROW );
      71          11 :         xProps->getPropertyValue("AutoFilter") >>= bHasAuto;
      72          11 :         if ( bHasAuto )
      73             :         {
      74          11 :             xDataBaseRange=xDBRange;
      75          11 :         }
      76             :     }
      77          12 :     return xDataBaseRange;
      78             : }
      79             : 
      80        1677 : ScDocShell* GetDocShellFromRange( const uno::Reference< uno::XInterface >& xRange ) throw ( uno::RuntimeException )
      81             : {
      82        1677 :     ScCellRangesBase* pScCellRangesBase = ScCellRangesBase::getImplementation( xRange );
      83        1677 :     if ( !pScCellRangesBase )
      84             :     {
      85           0 :         throw uno::RuntimeException("Failed to access underlying doc shell uno range object", uno::Reference< uno::XInterface >() );
      86             :     }
      87        1677 :     return pScCellRangesBase->GetDocShell();
      88             : }
      89             : 
      90             : uno::Reference< XHelperInterface >
      91        1454 : getUnoSheetModuleObj( const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException )
      92             : {
      93        1454 :     uno::Reference< sheet::XSheetCellRange > xSheetRange( xRange, uno::UNO_QUERY_THROW );
      94        2908 :     uno::Reference< sheet::XSpreadsheet > xSheet( xSheetRange->getSpreadsheet(), uno::UNO_SET_THROW );
      95        2908 :     return getUnoSheetModuleObj( xSheet );
      96             : }
      97             : 
      98           2 : void implSetZoom( const uno::Reference< frame::XModel >& xModel, sal_Int16 nZoom, std::vector< SCTAB >& nTabs )
      99             : {
     100           2 :     ScTabViewShell* pViewSh = excel::getBestViewShell( xModel );
     101           2 :     Fraction aFract( nZoom, 100 );
     102           2 :     pViewSh->GetViewData()->SetZoom( aFract, aFract, nTabs );
     103           2 :     pViewSh->RefreshZoom();
     104           2 : }
     105             : 
     106           2 : const OUString REPLACE_CELLS_WARNING( "ReplaceCellsWarning");
     107             : 
     108             : class PasteCellsWarningReseter
     109             : {
     110             : private:
     111             :     bool bInitialWarningState;
     112          45 :     static uno::Reference< sheet::XGlobalSheetSettings > getGlobalSheetSettings() throw ( uno::RuntimeException )
     113             :     {
     114          45 :         static uno::Reference< sheet::XGlobalSheetSettings > xProps = sheet::GlobalSheetSettings::create( comphelper::getProcessComponentContext() );
     115          45 :         return xProps;
     116             :     }
     117             : 
     118          15 :     bool getReplaceCellsWarning() throw ( uno::RuntimeException )
     119             :     {
     120          15 :         sal_Bool res = getGlobalSheetSettings()->getReplaceCellsWarning();
     121          15 :         return ( res == sal_True );
     122             :     }
     123             : 
     124          30 :     void setReplaceCellsWarning( bool bState ) throw ( uno::RuntimeException )
     125             :     {
     126          30 :         getGlobalSheetSettings()->setReplaceCellsWarning( bState );
     127          30 :     }
     128             : public:
     129          15 :     PasteCellsWarningReseter() throw ( uno::RuntimeException )
     130             :     {
     131          15 :         bInitialWarningState = getReplaceCellsWarning();
     132          15 :         if ( bInitialWarningState )
     133          15 :             setReplaceCellsWarning( false );
     134          15 :     }
     135          15 :     ~PasteCellsWarningReseter()
     136             :     {
     137          15 :         if ( bInitialWarningState )
     138             :         {
     139             :             // don't allow dtor to throw
     140             :             try
     141             :             {
     142          15 :                 setReplaceCellsWarning( true );
     143             :             }
     144           0 :             catch ( uno::Exception& /*e*/ ){}
     145             :         }
     146          15 :     }
     147             : };
     148             : 
     149             : void
     150           3 : implnPaste( const uno::Reference< frame::XModel>& xModel )
     151             : {
     152           3 :     PasteCellsWarningReseter resetWarningBox;
     153           3 :     ScTabViewShell* pViewShell = getBestViewShell( xModel );
     154           3 :     if ( pViewShell )
     155             :     {
     156           3 :         pViewShell->PasteFromSystem();
     157           3 :         pViewShell->CellContentChanged();
     158           3 :     }
     159           3 : }
     160             : 
     161             : 
     162             : void
     163          11 : implnCopy( const uno::Reference< frame::XModel>& xModel )
     164             : {
     165          11 :     ScTabViewShell* pViewShell = getBestViewShell( xModel );
     166          11 :     if ( pViewShell )
     167             :     {
     168          11 :         pViewShell->CopyToClip(NULL,false,false,true);
     169             : 
     170             :         // mark the copied transfer object so it is used in ScVbaRange::Insert
     171          11 :         ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( NULL );
     172          11 :         if (pClipObj)
     173           0 :             pClipObj->SetUseInApi( true );
     174             :     }
     175          11 : }
     176             : 
     177             : void
     178           0 : implnCut( const uno::Reference< frame::XModel>& xModel )
     179             : {
     180           0 :     ScTabViewShell* pViewShell =  getBestViewShell( xModel );
     181           0 :     if ( pViewShell )
     182             :     {
     183           0 :         pViewShell->CutToClip( NULL, sal_True );
     184             : 
     185             :         // mark the copied transfer object so it is used in ScVbaRange::Insert
     186           0 :         ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( NULL );
     187           0 :         if (pClipObj)
     188           0 :             pClipObj->SetUseInApi( true );
     189             :     }
     190           0 : }
     191             : 
     192          12 : void implnPasteSpecial( const uno::Reference< frame::XModel>& xModel, sal_uInt16 nFlags,sal_uInt16 nFunction,sal_Bool bSkipEmpty, sal_Bool bTranspose)
     193             : {
     194          12 :     PasteCellsWarningReseter resetWarningBox;
     195          12 :     sal_Bool bAsLink(false), bOtherDoc(false);
     196          12 :     InsCellCmd eMoveMode = INS_NONE;
     197             : 
     198          12 :     ScTabViewShell* pTabViewShell = getBestViewShell( xModel );
     199          12 :     if ( pTabViewShell )
     200             :     {
     201          12 :         ScViewData* pView = pTabViewShell->GetViewData();
     202          12 :         Window* pWin = ( pView != NULL ) ? pView->GetActiveWin() : NULL;
     203          12 :         if ( pView && pWin )
     204             :         {
     205          12 :             if ( bAsLink && bOtherDoc )
     206           0 :                 pTabViewShell->PasteFromSystem(0);//SOT_FORMATSTR_ID_LINK
     207             :             else
     208             :             {
     209          12 :                 ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
     210          12 :                 ScDocument* pDoc = NULL;
     211          12 :                 if ( pOwnClip )
     212           0 :                     pDoc = pOwnClip->GetDocument();
     213             :                 pTabViewShell->PasteFromClip( nFlags, pDoc,
     214             :                     nFunction, bSkipEmpty, bTranspose, bAsLink,
     215          12 :                     eMoveMode, IDF_NONE, sal_True );
     216          12 :                 pTabViewShell->CellContentChanged();
     217             :             }
     218             :         }
     219          12 :     }
     220             : 
     221          12 : }
     222             : 
     223             : ScDocShell*
     224         136 : getDocShell( const css::uno::Reference< css::frame::XModel>& xModel )
     225             : {
     226         136 :     uno::Reference< uno::XInterface > xIf( xModel, uno::UNO_QUERY_THROW );
     227         136 :     ScModelObj* pModel = dynamic_cast< ScModelObj* >( xIf.get() );
     228         136 :     ScDocShell* pDocShell = NULL;
     229         136 :     if ( pModel )
     230         136 :         pDocShell = (ScDocShell*)pModel->GetEmbeddedObject();
     231         136 :     return pDocShell;
     232             : 
     233             : }
     234             : 
     235             : ScTabViewShell*
     236         112 : getBestViewShell( const css::uno::Reference< css::frame::XModel>& xModel )
     237             : {
     238         112 :     ScDocShell* pDocShell = getDocShell( xModel );
     239         112 :     if ( pDocShell )
     240         112 :         return pDocShell->GetBestViewShell();
     241           0 :     return NULL;
     242             : }
     243             : 
     244             : ScTabViewShell*
     245          33 : getCurrentBestViewShell(  const uno::Reference< uno::XComponentContext >& xContext )
     246             : {
     247          33 :     uno::Reference< frame::XModel > xModel = getCurrentExcelDoc( xContext );
     248          33 :     return getBestViewShell( xModel );
     249             : }
     250             : 
     251             : SfxViewFrame*
     252          11 : getViewFrame( const uno::Reference< frame::XModel >& xModel )
     253             : {
     254          11 :     ScTabViewShell* pViewShell = getBestViewShell( xModel );
     255          11 :     if ( pViewShell )
     256          11 :         return pViewShell->GetViewFrame();
     257           0 :     return NULL;
     258             : }
     259             : 
     260             : uno::Reference< XHelperInterface >
     261        1677 : getUnoSheetModuleObj( const uno::Reference< sheet::XSpreadsheet >& xSheet ) throw ( uno::RuntimeException )
     262             : {
     263        1677 :     uno::Reference< beans::XPropertySet > xProps( xSheet, uno::UNO_QUERY_THROW );
     264        3354 :     OUString sCodeName;
     265        1677 :     xProps->getPropertyValue("CodeName") >>= sCodeName;
     266             :     // #TODO #FIXME ideally we should 'throw' here if we don't get a valid parent, but... it is possible
     267             :     // to create a module ( and use 'Option VBASupport 1' ) for a calc document, in this scenario there
     268             :     // are *NO* special document module objects ( of course being able to switch between vba/non vba mode at
     269             :     // the document in the future could fix this, especially IF the switching of the vba mode takes care to
     270             :     // create the special document module objects if they don't exist.
     271        3354 :     return getUnoDocModule( sCodeName, GetDocShellFromRange( xSheet ) );
     272             : }
     273             : 
     274             : uno::Reference< XHelperInterface >
     275          50 : getUnoSheetModuleObj( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges ) throw ( uno::RuntimeException )
     276             : {
     277          50 :     uno::Reference< container::XEnumerationAccess > xEnumAccess( xRanges, uno::UNO_QUERY_THROW );
     278         100 :     uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration();
     279         100 :     uno::Reference< table::XCellRange > xRange( xEnum->nextElement(), uno::UNO_QUERY_THROW );
     280         100 :     return getUnoSheetModuleObj( xRange );
     281             : }
     282             : 
     283             : uno::Reference< XHelperInterface >
     284           0 : getUnoSheetModuleObj( const uno::Reference< table::XCell >& xCell ) throw ( uno::RuntimeException )
     285             : {
     286           0 :     uno::Reference< sheet::XSheetCellRange > xSheetRange( xCell, uno::UNO_QUERY_THROW );
     287           0 :     uno::Reference< sheet::XSpreadsheet > xSheet( xSheetRange->getSpreadsheet(), uno::UNO_SET_THROW );
     288           0 :     return getUnoSheetModuleObj( xSheet );
     289             : }
     290             : 
     291             : uno::Reference< XHelperInterface >
     292           0 : getUnoSheetModuleObj( const uno::Reference< frame::XModel >& xModel, SCTAB nTab ) throw ( uno::RuntimeException )
     293             : {
     294           0 :     uno::Reference< sheet::XSpreadsheetDocument > xDoc( xModel, uno::UNO_QUERY_THROW );
     295           0 :     uno::Reference< container::XIndexAccess > xSheets( xDoc->getSheets(), uno::UNO_QUERY_THROW );
     296           0 :     uno::Reference< sheet::XSpreadsheet > xSheet( xSheets->getByIndex( nTab ), uno::UNO_QUERY_THROW );
     297           0 :     return getUnoSheetModuleObj( xSheet );
     298             : }
     299             : 
     300           1 : void setUpDocumentModules( const uno::Reference< sheet::XSpreadsheetDocument >& xDoc )
     301             : {
     302           1 :     uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY );
     303           1 :     ScDocShell* pShell = excel::getDocShell( xModel );
     304           1 :     if ( pShell )
     305             :     {
     306           1 :         String aPrjName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
     307           1 :         pShell->GetBasicManager()->SetName( aPrjName );
     308             : 
     309             :         /*  Set library container to VBA compatibility mode. This will create
     310             :             the VBA Globals object and store it in the Basic manager of the
     311             :             document. */
     312           2 :         uno::Reference<script::XLibraryContainer> xLibContainer = pShell->GetBasicContainer();
     313           2 :         uno::Reference<script::vba::XVBACompatibility> xVBACompat( xLibContainer, uno::UNO_QUERY_THROW );
     314           1 :         xVBACompat->setVBACompatibilityMode( sal_True );
     315             : 
     316           1 :         if( xLibContainer.is() )
     317             :         {
     318           1 :             if( !xLibContainer->hasByName( aPrjName ) )
     319           0 :                 xLibContainer->createLibrary( aPrjName );
     320           1 :             uno::Any aLibAny = xLibContainer->getByName( aPrjName );
     321           2 :             uno::Reference< container::XNameContainer > xLib;
     322           1 :             aLibAny >>= xLib;
     323           1 :             if( xLib.is()  )
     324             :             {
     325           1 :                 uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY_THROW );
     326           2 :                 uno::Reference< lang::XMultiServiceFactory> xSF( pShell->GetModel(), uno::UNO_QUERY_THROW);
     327           2 :                 uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess( xSF->createInstance("ooo.vba.VBAObjectModuleObjectProvider"), uno::UNO_QUERY_THROW );
     328             :                 // set up the module info for the workbook and sheets in the nealy created
     329             :                 // spreadsheet
     330           1 :                 ScDocument* pDoc = pShell->GetDocument();
     331           2 :                 String sCodeName = pDoc->GetCodeName();
     332           1 :                 if ( sCodeName.Len() == 0 )
     333             :                 {
     334           1 :                     sCodeName = String( RTL_CONSTASCII_USTRINGPARAM("ThisWorkbook") );
     335           1 :                     pDoc->SetCodeName( sCodeName );
     336             :                 }
     337             : 
     338           2 :                 std::vector< OUString > sDocModuleNames;
     339           1 :                 sDocModuleNames.push_back( sCodeName );
     340             : 
     341           2 :                 for ( SCTAB index = 0; index < pDoc->GetTableCount(); index++)
     342             :                 {
     343           1 :                     OUString aName;
     344           1 :                     pDoc->GetCodeName( index, aName );
     345           1 :                     sDocModuleNames.push_back( aName );
     346           1 :                 }
     347             : 
     348           1 :                 std::vector<OUString>::iterator it_end = sDocModuleNames.end();
     349             : 
     350           3 :                 for ( std::vector<OUString>::iterator it = sDocModuleNames.begin(); it != it_end; ++it )
     351             :                 {
     352           2 :                     script::ModuleInfo sModuleInfo;
     353             : 
     354           4 :                     uno::Any aName= xVBACodeNamedObjectAccess->getByName( *it );
     355           2 :                     sModuleInfo.ModuleObject.set( aName, uno::UNO_QUERY );
     356           2 :                     sModuleInfo.ModuleType = script::ModuleType::DOCUMENT;
     357           2 :                     xVBAModuleInfo->insertModuleInfo( *it, sModuleInfo );
     358           2 :                     if( xLib->hasByName( *it ) )
     359           0 :                         xLib->replaceByName( *it, uno::makeAny( OUString( "Option VBASupport 1\n") ) );
     360             :                     else
     361           2 :                         xLib->insertByName( *it, uno::makeAny( OUString( "Option VBASupport 1\n" ) ) );
     362           3 :                 }
     363           1 :             }
     364             :         }
     365             : 
     366             :         /*  Trigger the Workbook_Open event, event processor will register
     367             :             itself as listener for specific events. */
     368             :         try
     369             :         {
     370           1 :             uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pShell->GetDocument()->GetVbaEventProcessor(), uno::UNO_SET_THROW );
     371           2 :             uno::Sequence< uno::Any > aArgs;
     372           2 :             xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_OPEN, aArgs );
     373             :         }
     374           0 :         catch( uno::Exception& )
     375             :         {
     376           1 :         }
     377           1 :     }
     378           1 : }
     379             : 
     380             : SfxItemSet*
     381          72 : ScVbaCellRangeAccess::GetDataSet( ScCellRangesBase* pRangeObj )
     382             : {
     383          72 :     return pRangeObj ? pRangeObj->GetCurrentDataSet( true ) : 0;
     384             : }
     385             : 
     386             : // ============================================================================
     387             : 
     388             : } // namespace excel
     389             : } // namespace vba
     390           6 : } // namespace ooo

Generated by: LCOV version 1.10