2010-10-12 15:59:00 +02:00
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2009-09-18 15:35:47 +00:00
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
2010-02-12 15:01:35 +01:00
* Copyright 2000 , 2010 Oracle and / or its affiliates .
2009-09-18 15:35:47 +00:00
*
* OpenOffice . org - a multi - platform office productivity suite
*
* This file is part of OpenOffice . org .
*
* OpenOffice . org is free software : you can redistribute it and / or modify
* it under the terms of the GNU Lesser General Public License version 3
* only , as published by the Free Software Foundation .
*
* OpenOffice . org is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Lesser General Public License version 3 for more details
* ( a copy is included in the LICENSE file that accompanied this code ) .
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice . org . If not , see
* < http : //www.openoffice.org/license.html>
* for a copy of the LGPLv3 License .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-09-17 18:42:00 +02:00
2009-09-18 15:35:47 +00:00
# include "excelvbahelper.hxx"
2010-09-17 18:42:00 +02:00
# include <comphelper/processfactory.hxx>
# include <com/sun/star/sheet/XSheetCellRange.hpp>
# include "docuno.hxx"
2009-09-18 15:35:47 +00:00
# include "tabvwsh.hxx"
# include "transobj.hxx"
# include "scmod.hxx"
# include "cellsuno.hxx"
2011-04-26 09:32:22 +01:00
# include <com/sun/star/script/vba/VBAEventId.hpp>
# include <com/sun/star/script/vba/XVBACompatibility.hpp>
# include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
# include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
# include <com/sun/star/script/ModuleInfo.hpp>
# include <com/sun/star/script/ModuleType.hpp>
2009-09-18 15:35:47 +00:00
using namespace : : com : : sun : : star ;
using namespace : : ooo : : vba ;
2011-03-15 01:58:39 -04:00
namespace ooo {
namespace vba {
namespace excel {
2010-09-17 18:42:00 +02:00
// ============================================================================
2010-07-01 16:23:26 +02:00
2011-05-05 17:59:58 +02:00
uno : : Reference < sheet : : XUnnamedDatabaseRanges >
GetUnnamedDataBaseRanges ( ScDocShell * pShell ) throw ( uno : : RuntimeException )
{
uno : : Reference < frame : : XModel > xModel ;
if ( pShell )
xModel . set ( pShell - > GetModel ( ) , uno : : UNO_QUERY_THROW ) ;
uno : : Reference < beans : : XPropertySet > xModelProps ( xModel , uno : : UNO_QUERY_THROW ) ;
uno : : Reference < sheet : : XUnnamedDatabaseRanges > xUnnamedDBRanges ( xModelProps - > getPropertyValue ( rtl : : OUString ( RTL_CONSTASCII_USTRINGPARAM ( " UnnamedDatabaseRanges " ) ) ) , uno : : UNO_QUERY_THROW ) ;
return xUnnamedDBRanges ;
}
2010-10-06 10:15:43 +01:00
// returns the XDatabaseRange for the autofilter on sheet (nSheet)
// also populates sName with the name of range
uno : : Reference < sheet : : XDatabaseRange >
2011-05-05 17:59:58 +02:00
GetAutoFiltRange ( ScDocShell * pShell , sal_Int16 nSheet ) throw ( uno : : RuntimeException )
2010-10-06 10:15:43 +01:00
{
2011-05-05 17:59:58 +02:00
uno : : Reference < sheet : : XUnnamedDatabaseRanges > xUnnamedDBRanges ( GetUnnamedDataBaseRanges ( pShell ) , uno : : UNO_QUERY_THROW ) ;
2010-10-06 10:15:43 +01:00
uno : : Reference < sheet : : XDatabaseRange > xDataBaseRange ;
2011-05-05 17:59:58 +02:00
if ( xUnnamedDBRanges - > hasByTable ( nSheet ) )
2010-10-06 10:15:43 +01:00
{
2011-05-05 17:59:58 +02:00
uno : : Reference < sheet : : XDatabaseRange > xDBRange ( xUnnamedDBRanges - > getByTable ( nSheet ) , uno : : UNO_QUERY_THROW ) ;
sal_Bool bHasAuto = false ;
uno : : Reference < beans : : XPropertySet > xProps ( xDBRange , uno : : UNO_QUERY_THROW ) ;
xProps - > getPropertyValue ( rtl : : OUString ( RTL_CONSTASCII_USTRINGPARAM ( " AutoFilter " ) ) ) > > = bHasAuto ;
if ( bHasAuto )
2010-10-06 10:15:43 +01:00
{
2011-05-05 17:59:58 +02:00
xDataBaseRange = xDBRange ;
2010-10-06 10:15:43 +01:00
}
}
return xDataBaseRange ;
}
2010-07-01 16:23:26 +02:00
ScDocShell * GetDocShellFromRange ( const uno : : Reference < uno : : XInterface > & xRange ) throw ( uno : : RuntimeException )
{
ScCellRangesBase * pScCellRangesBase = ScCellRangesBase : : getImplementation ( xRange ) ;
if ( ! pScCellRangesBase )
{
throw uno : : RuntimeException ( rtl : : OUString ( RTL_CONSTASCII_USTRINGPARAM ( " Failed to access underlying doc shell uno range object " ) ) , uno : : Reference < uno : : XInterface > ( ) ) ;
}
return pScCellRangesBase - > GetDocShell ( ) ;
}
2011-03-15 09:56:18 +00:00
uno : : Reference < XHelperInterface >
getUnoSheetModuleObj ( const uno : : Reference < table : : XCellRange > & xRange ) throw ( uno : : RuntimeException )
{
uno : : Reference < sheet : : XSheetCellRange > xSheetRange ( xRange , uno : : UNO_QUERY_THROW ) ;
uno : : Reference < sheet : : XSpreadsheet > xSheet ( xSheetRange - > getSpreadsheet ( ) , uno : : UNO_SET_THROW ) ;
return getUnoSheetModuleObj ( xSheet ) ;
}
2009-09-18 15:35:47 +00:00
void implSetZoom ( const uno : : Reference < frame : : XModel > & xModel , sal_Int16 nZoom , std : : vector < SCTAB > & nTabs )
{
ScTabViewShell * pViewSh = excel : : getBestViewShell ( xModel ) ;
Fraction aFract ( nZoom , 100 ) ;
pViewSh - > GetViewData ( ) - > SetZoom ( aFract , aFract , nTabs ) ;
pViewSh - > RefreshZoom ( ) ;
}
const : : rtl : : OUString REPLACE_CELLS_WARNING ( RTL_CONSTASCII_USTRINGPARAM ( " ReplaceCellsWarning " ) ) ;
class PasteCellsWarningReseter
{
private :
bool bInitialWarningState ;
static uno : : Reference < beans : : XPropertySet > getGlobalSheetSettings ( ) throw ( uno : : RuntimeException )
{
static uno : : Reference < beans : : XPropertySet > xTmpProps ( : : comphelper : : getProcessServiceFactory ( ) , uno : : UNO_QUERY_THROW ) ;
static uno : : Reference < uno : : XComponentContext > xContext ( xTmpProps - > getPropertyValue ( rtl : : OUString ( RTL_CONSTASCII_USTRINGPARAM ( " DefaultContext " ) ) ) , uno : : UNO_QUERY_THROW ) ;
static uno : : Reference < lang : : XMultiComponentFactory > xServiceManager (
xContext - > getServiceManager ( ) , uno : : UNO_QUERY_THROW ) ;
static uno : : Reference < beans : : XPropertySet > xProps ( xServiceManager - > createInstanceWithContext ( rtl : : OUString ( RTL_CONSTASCII_USTRINGPARAM ( " com.sun.star.sheet.GlobalSheetSettings " ) ) , xContext ) , uno : : UNO_QUERY_THROW ) ;
return xProps ;
}
bool getReplaceCellsWarning ( ) throw ( uno : : RuntimeException )
{
2011-03-10 16:55:21 -05:00
sal_Bool res = false ;
2009-09-18 15:35:47 +00:00
getGlobalSheetSettings ( ) - > getPropertyValue ( REPLACE_CELLS_WARNING ) > > = res ;
return ( res = = sal_True ) ;
}
void setReplaceCellsWarning ( bool bState ) throw ( uno : : RuntimeException )
{
getGlobalSheetSettings ( ) - > setPropertyValue ( REPLACE_CELLS_WARNING , uno : : makeAny ( bState ) ) ;
}
public :
PasteCellsWarningReseter ( ) throw ( uno : : RuntimeException )
{
bInitialWarningState = getReplaceCellsWarning ( ) ;
if ( bInitialWarningState )
setReplaceCellsWarning ( false ) ;
}
~ PasteCellsWarningReseter ( )
{
if ( bInitialWarningState )
{
// don't allow dtor to throw
try
{
setReplaceCellsWarning ( true ) ;
}
catch ( uno : : Exception & /*e*/ ) { }
}
}
} ;
void
implnPaste ( const uno : : Reference < frame : : XModel > & xModel )
{
PasteCellsWarningReseter resetWarningBox ;
ScTabViewShell * pViewShell = getBestViewShell ( xModel ) ;
if ( pViewShell )
{
pViewShell - > PasteFromSystem ( ) ;
pViewShell - > CellContentChanged ( ) ;
}
}
void
implnCopy ( const uno : : Reference < frame : : XModel > & xModel )
{
ScTabViewShell * pViewShell = getBestViewShell ( xModel ) ;
if ( pViewShell )
2010-09-15 18:01:02 +02:00
{
2009-09-18 15:35:47 +00:00
pViewShell - > CopyToClip ( NULL , false , false , true ) ;
2010-09-15 18:01:02 +02:00
// mark the copied transfer object so it is used in ScVbaRange::Insert
ScTransferObj * pClipObj = ScTransferObj : : GetOwnClipboard ( NULL ) ;
if ( pClipObj )
pClipObj - > SetUseInApi ( true ) ;
}
2009-09-18 15:35:47 +00:00
}
void
implnCut ( const uno : : Reference < frame : : XModel > & xModel )
{
ScTabViewShell * pViewShell = getBestViewShell ( xModel ) ;
if ( pViewShell )
2010-09-15 18:01:02 +02:00
{
2011-01-17 13:20:22 +01:00
pViewShell - > CutToClip ( NULL , sal_True ) ;
2010-09-15 18:01:02 +02:00
// mark the copied transfer object so it is used in ScVbaRange::Insert
ScTransferObj * pClipObj = ScTransferObj : : GetOwnClipboard ( NULL ) ;
if ( pClipObj )
pClipObj - > SetUseInApi ( true ) ;
}
2009-09-18 15:35:47 +00:00
}
2011-01-17 13:20:22 +01:00
void implnPasteSpecial ( const uno : : Reference < frame : : XModel > & xModel , sal_uInt16 nFlags , sal_uInt16 nFunction , sal_Bool bSkipEmpty , sal_Bool bTranspose )
2009-09-18 15:35:47 +00:00
{
PasteCellsWarningReseter resetWarningBox ;
2011-03-10 16:55:21 -05:00
sal_Bool bAsLink ( false ) , bOtherDoc ( false ) ;
2009-09-18 15:35:47 +00:00
InsCellCmd eMoveMode = INS_NONE ;
ScTabViewShell * pTabViewShell = getBestViewShell ( xModel ) ;
if ( pTabViewShell )
{
ScViewData * pView = pTabViewShell - > GetViewData ( ) ;
Window * pWin = ( pView ! = NULL ) ? pView - > GetActiveWin ( ) : NULL ;
if ( pView & & pWin )
{
if ( bAsLink & & bOtherDoc )
pTabViewShell - > PasteFromSystem ( 0 ) ; //SOT_FORMATSTR_ID_LINK
else
{
ScTransferObj * pOwnClip = ScTransferObj : : GetOwnClipboard ( pWin ) ;
ScDocument * pDoc = NULL ;
if ( pOwnClip )
pDoc = pOwnClip - > GetDocument ( ) ;
pTabViewShell - > PasteFromClip ( nFlags , pDoc ,
nFunction , bSkipEmpty , bTranspose , bAsLink ,
2011-01-17 13:20:22 +01:00
eMoveMode , IDF_NONE , sal_True ) ;
2009-09-18 15:35:47 +00:00
pTabViewShell - > CellContentChanged ( ) ;
}
}
}
}
ScDocShell *
getDocShell ( const css : : uno : : Reference < css : : frame : : XModel > & xModel )
{
uno : : Reference < uno : : XInterface > xIf ( xModel , uno : : UNO_QUERY_THROW ) ;
ScModelObj * pModel = dynamic_cast < ScModelObj * > ( xIf . get ( ) ) ;
ScDocShell * pDocShell = NULL ;
if ( pModel )
pDocShell = ( ScDocShell * ) pModel - > GetEmbeddedObject ( ) ;
return pDocShell ;
}
ScTabViewShell *
getBestViewShell ( const css : : uno : : Reference < css : : frame : : XModel > & xModel )
{
ScDocShell * pDocShell = getDocShell ( xModel ) ;
if ( pDocShell )
return pDocShell - > GetBestViewShell ( ) ;
return NULL ;
}
ScTabViewShell *
getCurrentBestViewShell ( const uno : : Reference < uno : : XComponentContext > & xContext )
{
uno : : Reference < frame : : XModel > xModel = getCurrentExcelDoc ( xContext ) ;
return getBestViewShell ( xModel ) ;
}
2012-09-11 08:48:02 +01:00
SfxViewFrame *
getViewFrame ( const uno : : Reference < frame : : XModel > & xModel )
2010-10-06 10:15:43 +01:00
{
2012-09-11 08:48:02 +01:00
ScTabViewShell * pViewShell = getBestViewShell ( xModel ) ;
if ( pViewShell )
return pViewShell - > GetViewFrame ( ) ;
return NULL ;
2010-10-06 10:15:43 +01:00
}
2011-03-15 01:58:39 -04:00
uno : : Reference < vba : : XHelperInterface >
getUnoSheetModuleObj ( const uno : : Reference < sheet : : XSpreadsheet > & xSheet ) throw ( uno : : RuntimeException )
2010-07-01 16:23:26 +02:00
{
2010-09-17 18:42:00 +02:00
uno : : Reference < beans : : XPropertySet > xProps ( xSheet , uno : : UNO_QUERY_THROW ) ;
2010-07-01 16:23:26 +02:00
rtl : : OUString sCodeName ;
xProps - > getPropertyValue ( rtl : : OUString ( RTL_CONSTASCII_USTRINGPARAM ( " CodeName " ) ) ) > > = sCodeName ;
// #TODO #FIXME ideally we should 'throw' here if we don't get a valid parent, but... it is possible
// to create a module ( and use 'Option VBASupport 1' ) for a calc document, in this scenario there
// are *NO* special document module objects ( of course being able to switch between vba/non vba mode at
// the document in the future could fix this, especially IF the switching of the vba mode takes care to
// create the special document module objects if they don't exist.
2010-09-17 18:42:00 +02:00
uno : : Reference < XHelperInterface > xParent ( ov : : getUnoDocModule ( sCodeName , GetDocShellFromRange ( xSheet ) ) , uno : : UNO_QUERY ) ;
2010-07-01 16:23:26 +02:00
return xParent ;
}
uno : : Reference < XHelperInterface >
getUnoSheetModuleObj ( const uno : : Reference < sheet : : XSheetCellRangeContainer > & xRanges ) throw ( uno : : RuntimeException )
{
uno : : Reference < container : : XEnumerationAccess > xEnumAccess ( xRanges , uno : : UNO_QUERY_THROW ) ;
uno : : Reference < container : : XEnumeration > xEnum = xEnumAccess - > createEnumeration ( ) ;
uno : : Reference < table : : XCellRange > xRange ( xEnum - > nextElement ( ) , uno : : UNO_QUERY_THROW ) ;
return getUnoSheetModuleObj ( xRange ) ;
}
2010-09-17 18:42:00 +02:00
uno : : Reference < XHelperInterface >
getUnoSheetModuleObj ( const uno : : Reference < table : : XCell > & xCell ) throw ( uno : : RuntimeException )
{
uno : : Reference < sheet : : XSheetCellRange > xSheetRange ( xCell , uno : : UNO_QUERY_THROW ) ;
uno : : Reference < sheet : : XSpreadsheet > xSheet ( xSheetRange - > getSpreadsheet ( ) , uno : : UNO_SET_THROW ) ;
return getUnoSheetModuleObj ( xSheet ) ;
}
uno : : Reference < XHelperInterface >
getUnoSheetModuleObj ( const uno : : Reference < frame : : XModel > & xModel , SCTAB nTab ) throw ( uno : : RuntimeException )
{
uno : : Reference < sheet : : XSpreadsheetDocument > xDoc ( xModel , uno : : UNO_QUERY_THROW ) ;
uno : : Reference < container : : XIndexAccess > xSheets ( xDoc - > getSheets ( ) , uno : : UNO_QUERY_THROW ) ;
uno : : Reference < sheet : : XSpreadsheet > xSheet ( xSheets - > getByIndex ( nTab ) , uno : : UNO_QUERY_THROW ) ;
return getUnoSheetModuleObj ( xSheet ) ;
}
2011-04-26 09:32:22 +01:00
void setUpDocumentModules ( const uno : : Reference < sheet : : XSpreadsheetDocument > & xDoc )
{
uno : : Reference < frame : : XModel > xModel ( xDoc , uno : : UNO_QUERY ) ;
ScDocShell * pShell = excel : : getDocShell ( xModel ) ;
if ( pShell )
{
String aPrjName ( RTL_CONSTASCII_USTRINGPARAM ( " Standard " ) ) ;
pShell - > GetBasicManager ( ) - > SetName ( aPrjName ) ;
/* Set library container to VBA compatibility mode. This will create
the VBA Globals object and store it in the Basic manager of the
document . */
uno : : Reference < script : : XLibraryContainer > xLibContainer = pShell - > GetBasicContainer ( ) ;
uno : : Reference < script : : vba : : XVBACompatibility > xVBACompat ( xLibContainer , uno : : UNO_QUERY_THROW ) ;
xVBACompat - > setVBACompatibilityMode ( sal_True ) ;
if ( xLibContainer . is ( ) )
{
if ( ! xLibContainer - > hasByName ( aPrjName ) )
xLibContainer - > createLibrary ( aPrjName ) ;
uno : : Any aLibAny = xLibContainer - > getByName ( aPrjName ) ;
uno : : Reference < container : : XNameContainer > xLib ;
aLibAny > > = xLib ;
if ( xLib . is ( ) )
{
uno : : Reference < script : : vba : : XVBAModuleInfo > xVBAModuleInfo ( xLib , uno : : UNO_QUERY_THROW ) ;
uno : : Reference < lang : : XMultiServiceFactory > xSF ( pShell - > GetModel ( ) , uno : : UNO_QUERY_THROW ) ;
uno : : Reference < container : : XNameAccess > xVBACodeNamedObjectAccess ( xSF - > createInstance ( rtl : : OUString ( RTL_CONSTASCII_USTRINGPARAM ( " ooo.vba.VBAObjectModuleObjectProvider " ) ) ) , uno : : UNO_QUERY_THROW ) ;
// set up the module info for the workbook and sheets in the nealy created
// spreadsheet
ScDocument * pDoc = pShell - > GetDocument ( ) ;
String sCodeName = pDoc - > GetCodeName ( ) ;
if ( sCodeName . Len ( ) = = 0 )
{
sCodeName = String ( RTL_CONSTASCII_USTRINGPARAM ( " ThisWorkbook " ) ) ;
pDoc - > SetCodeName ( sCodeName ) ;
}
std : : vector < rtl : : OUString > sDocModuleNames ;
sDocModuleNames . push_back ( sCodeName ) ;
for ( SCTAB index = 0 ; index < pDoc - > GetTableCount ( ) ; index + + )
{
2011-08-26 19:33:59 -04:00
rtl : : OUString aName ;
2011-04-26 09:32:22 +01:00
pDoc - > GetCodeName ( index , aName ) ;
sDocModuleNames . push_back ( aName ) ;
}
std : : vector < rtl : : OUString > : : iterator it_end = sDocModuleNames . end ( ) ;
for ( std : : vector < rtl : : OUString > : : iterator it = sDocModuleNames . begin ( ) ; it ! = it_end ; + + it )
{
script : : ModuleInfo sModuleInfo ;
uno : : Any aName = xVBACodeNamedObjectAccess - > getByName ( * it ) ;
sModuleInfo . ModuleObject . set ( aName , uno : : UNO_QUERY ) ;
sModuleInfo . ModuleType = script : : ModuleType : : DOCUMENT ;
xVBAModuleInfo - > insertModuleInfo ( * it , sModuleInfo ) ;
if ( xLib - > hasByName ( * it ) )
xLib - > replaceByName ( * it , uno : : makeAny ( rtl : : OUString ( RTL_CONSTASCII_USTRINGPARAM ( " Option VBASupport 1 \n " ) ) ) ) ;
else
xLib - > insertByName ( * it , uno : : makeAny ( rtl : : OUString ( RTL_CONSTASCII_USTRINGPARAM ( " Option VBASupport 1 \n " ) ) ) ) ;
}
}
}
/* Trigger the Workbook_Open event, event processor will register
itself as listener for specific events . */
try
{
uno : : Reference < script : : vba : : XVBAEventProcessor > xVbaEvents ( pShell - > GetDocument ( ) - > GetVbaEventProcessor ( ) , uno : : UNO_SET_THROW ) ;
uno : : Sequence < uno : : Any > aArgs ;
xVbaEvents - > processVbaEvent ( script : : vba : : VBAEventId : : WORKBOOK_OPEN , aArgs ) ;
}
catch ( uno : : Exception & )
{
}
}
}
2009-09-18 15:35:47 +00:00
SfxItemSet *
2010-04-13 19:44:24 +01:00
ScVbaCellRangeAccess : : GetDataSet ( ScCellRangesBase * pRangeObj )
2009-09-18 15:35:47 +00:00
{
2010-04-13 19:44:24 +01:00
return pRangeObj ? pRangeObj - > GetCurrentDataSet ( true ) : 0 ;
2009-09-18 15:35:47 +00:00
}
2010-04-13 19:44:24 +01:00
2010-09-17 18:42:00 +02:00
// ============================================================================
2010-07-01 16:23:26 +02:00
2011-03-15 01:58:39 -04:00
} // namespace excel
} // namespace vba
} // namespace ooo