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

Generated by: LCOV version 1.10