[Libreoffice-commits] .: Branch 'libreoffice-3-4' - sc/source

Noel Power noelp at kemper.freedesktop.org
Thu Apr 7 09:15:31 PDT 2011


 sc/source/ui/vba/excelvbahelper.hxx |   14 ++++++++++++++
 sc/source/ui/vba/vbaapplication.cxx |    3 +--
 sc/source/ui/vba/vbaworkbook.cxx    |   28 ++++++++++++++++++++++++++++
 sc/source/ui/vba/vbaworkbook.hxx    |    4 ++++
 sc/source/ui/vba/vbaworksheet.cxx   |   30 +++++++++++++++++++++++++++++-
 sc/source/ui/vba/vbaworksheet.hxx   |    3 +++
 sc/source/ui/vba/vbaworksheets.cxx  |   27 ++++++++++-----------------
 7 files changed, 89 insertions(+), 20 deletions(-)

New commits:
commit 38e8127d0184322a02d458974dfb49b52a0d34f7
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Thu Apr 7 17:14:41 2011 +0100

    fix cast to implementation objects failure from some vba objects
    
    old calls attempting to cast to implementation objects now fail ( and crash on access ) because we now wrap some objects via a aggregation proxy. This patch fixes this

diff --git a/sc/source/ui/vba/excelvbahelper.hxx b/sc/source/ui/vba/excelvbahelper.hxx
index 2100f4a..e8014fe 100644
--- a/sc/source/ui/vba/excelvbahelper.hxx
+++ b/sc/source/ui/vba/excelvbahelper.hxx
@@ -35,6 +35,7 @@
 #include <com/sun/star/table/XCellRange.hpp>
 #include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
 #include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
 #include <ooo/vba/XHelperInterface.hpp>
 #include <formula/grammar.hxx>
 
@@ -84,6 +85,19 @@ public:
     static SfxItemSet* GetDataSet( ScCellRangesBase* pRangeObj );
 };
 
+// Extracts a implementation object ( via XUnoTunnel ) from an uno object
+// by default will throw if unsuccessful.
+template < typename ImplObject >
+    ImplObject* getImplFromDocModuleWrapper( const css::uno::Reference< css::uno::XInterface >& rxWrapperIf, bool bThrow = true ) throw (css::uno::RuntimeException)
+    {
+        ImplObject* pObj = NULL;
+        css::uno::Reference< css::lang::XUnoTunnel >  xTunnel( rxWrapperIf, css::uno::UNO_QUERY );
+        if ( xTunnel.is() )
+            pObj = reinterpret_cast<ImplObject*>( xTunnel->getSomething(ImplObject::getUnoTunnelId()));
+        if ( bThrow && !pObj )
+            throw css::uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Internal error, can't exctract implementation object" ) ), rxWrapperIf );
+        return pObj;
+    }
 // ============================================================================
 
 } // namespace excel
diff --git a/sc/source/ui/vba/vbaapplication.cxx b/sc/source/ui/vba/vbaapplication.cxx
index 4c4dd44..ba27f71 100644
--- a/sc/source/ui/vba/vbaapplication.cxx
+++ b/sc/source/ui/vba/vbaapplication.cxx
@@ -924,8 +924,7 @@ ScVbaApplication::setIteration(sal_Bool bIteration) throw (uno::RuntimeException
         uno::Reference< ooo::vba::excel::XWorkbook > xWorkbook;
         uno::Any aWorkbook = xWorkbooks->Item(uno::makeAny(i), uno::Any());
         aWorkbook >>= xWorkbook;
-        ScVbaWorkbook* pWorkbook = static_cast< ScVbaWorkbook* > ( xWorkbook.get() );
-
+        ScVbaWorkbook* pWorkbook = excel::getImplFromDocModuleWrapper<ScVbaWorkbook>( xWorkbook );
         uno::Reference< frame::XModel > xModel( pWorkbook->getDocModel(), uno::UNO_QUERY_THROW );
         uno::Reference< beans::XPropertySet > xPropertySet( xModel, uno::UNO_QUERY_THROW );
         xPropertySet->setPropertyValue( aPropName, aIteration );
diff --git a/sc/source/ui/vba/vbaworkbook.cxx b/sc/source/ui/vba/vbaworkbook.cxx
index 1b1a740..963c70e 100644
--- a/sc/source/ui/vba/vbaworkbook.cxx
+++ b/sc/source/ui/vba/vbaworkbook.cxx
@@ -233,6 +233,23 @@ ScVbaWorkbook::ScVbaWorkbook( uno::Sequence< uno::Any> const & args,
     init();
 }
 
+const uno::Sequence<sal_Int8>&
+ScVbaWorkbook::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq;
+
+    if( !aSeq.getLength() )
+    {
+        static osl::Mutex           aCreateMutex;
+        osl::Guard< osl::Mutex >    aGuard( aCreateMutex );
+
+        aSeq.realloc( 16 );
+        rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True );
+    }
+
+    return aSeq;
+}
+
 uno::Reference< excel::XWorksheet >
 ScVbaWorkbook::getActiveSheet() throw (uno::RuntimeException)
 {
@@ -419,6 +436,17 @@ ScVbaWorkbook::getCodeName() throw (css::uno::RuntimeException)
     return xModelProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CodeName" ) ) ).get< ::rtl::OUString >();
 }
 
+sal_Int64
+ScVbaWorkbook::getSomething(const uno::Sequence<sal_Int8 >& rId ) throw(css::uno::RuntimeException)
+{
+    if (rId.getLength() == 16 &&
+        0 == rtl_compareMemory( ScVbaWorksheet::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ))
+    {
+        return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+    }
+    return 0;
+}
+
 namespace workbook
 {
 namespace sdecl = comphelper::service_decl;
diff --git a/sc/source/ui/vba/vbaworkbook.hxx b/sc/source/ui/vba/vbaworkbook.hxx
index 6bde08a..5b98702 100644
--- a/sc/source/ui/vba/vbaworkbook.hxx
+++ b/sc/source/ui/vba/vbaworkbook.hxx
@@ -53,6 +53,8 @@ public:
     ScVbaWorkbook( 	css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext );
     virtual ~ScVbaWorkbook() {}
 
+    static const com::sun::star::uno::Sequence<sal_Int8>& getUnoTunnelId();
+
     // Attributes
     virtual ::sal_Bool SAL_CALL getProtectStructure() throw (css::uno::RuntimeException);
     virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getActiveSheet() throw (css::uno::RuntimeException);
@@ -83,6 +85,8 @@ public:
     virtual css::uno::Sequence<rtl::OUString> getServiceNames();
 
     virtual css::uno::Reference< css::frame::XModel >  getDocModel() { return mxModel; }
+    // XUnoTunnel
+    virtual ::sal_Int64 getSomething(const css::uno::Sequence<sal_Int8 >& rId ) throw(css::uno::RuntimeException);
 };
 
 #endif /* SC_VBA_WORKBOOK_HXX */
diff --git a/sc/source/ui/vba/vbaworksheet.cxx b/sc/source/ui/vba/vbaworksheet.cxx
index 94f197d..9348f92 100644
--- a/sc/source/ui/vba/vbaworksheet.cxx
+++ b/sc/source/ui/vba/vbaworksheet.cxx
@@ -213,6 +213,22 @@ ScVbaWorksheet::~ScVbaWorksheet()
 {
 }
 
+const uno::Sequence<sal_Int8>& ScVbaWorksheet::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq;
+
+    if( !aSeq.getLength() )
+    {
+        static osl::Mutex           aCreateMutex;
+        osl::Guard< osl::Mutex >    aGuard( aCreateMutex );
+
+        aSeq.realloc( 16 );
+        rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True );
+    }
+
+    return aSeq;
+}
+
 ::rtl::OUString
 ScVbaWorksheet::getName() throw (uno::RuntimeException)
 {
@@ -573,7 +589,8 @@ ScVbaWorksheet::Copy( const uno::Any& Before, const uno::Any& After ) throw (uno
         return;
     }
 
-    ScVbaWorksheet* pDestSheet = static_cast< ScVbaWorksheet* >(xSheet.get());
+    ScVbaWorksheet* pDestSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSheet );
+
     uno::Reference <sheet::XSpreadsheetDocument> xDestDoc( pDestSheet->getModel(), uno::UNO_QUERY );
     uno::Reference <sheet::XSpreadsheetDocument> xSrcDoc( getModel(), uno::UNO_QUERY );
 
@@ -1118,6 +1135,17 @@ ScVbaWorksheet::PrintOut( const uno::Any& From, const uno::Any& To, const uno::A
     PrintOutHelper( excel::getBestViewShell( xModel ), From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName, bSelection );
 }
 
+sal_Int64 SAL_CALL
+ScVbaWorksheet::getSomething(const uno::Sequence<sal_Int8 > & rId) throw(uno::RuntimeException)
+{
+    if (rId.getLength() == 16 &&
+        0 == rtl_compareMemory( ScVbaWorksheet::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ))
+    {
+        return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+    }
+    return 0;
+}
+
 namespace worksheet
 {
 namespace sdecl = comphelper::service_decl;
diff --git a/sc/source/ui/vba/vbaworksheet.hxx b/sc/source/ui/vba/vbaworksheet.hxx
index 6ad6baf..1172d39 100644
--- a/sc/source/ui/vba/vbaworksheet.hxx
+++ b/sc/source/ui/vba/vbaworksheet.hxx
@@ -90,6 +90,7 @@ public:
     { return mxModel; }
     virtual css::uno::Reference< css::sheet::XSpreadsheet > getSheet()
     { return mxSheet; }
+    static const com::sun::star::uno::Sequence<sal_Int8>& getUnoTunnelId();
 
     // Attributes
     virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException);
@@ -171,6 +172,8 @@ public:
     // XHelperInterface
     virtual rtl::OUString& getServiceImplName();
     virtual css::uno::Sequence<rtl::OUString> getServiceNames();	
+    // XUnoTunnel
+    virtual ::sal_Int64 getSomething(const css::uno::Sequence<sal_Int8 >& rId ) throw(css::uno::RuntimeException);
 };
 
 #endif /* SC_VBA_WORKSHEET_HXX */
diff --git a/sc/source/ui/vba/vbaworksheets.cxx b/sc/source/ui/vba/vbaworksheets.cxx
index 1bac962..1a07848 100644
--- a/sc/source/ui/vba/vbaworksheets.cxx
+++ b/sc/source/ui/vba/vbaworksheets.cxx
@@ -407,18 +407,14 @@ ScVbaWorksheets::Select( const uno::Any& Replace ) throw (uno::RuntimeException)
     for ( sal_Int32 nItem = 1; nItem <= nElems; ++nItem )
     {
         uno::Reference< excel::XWorksheet > xSheet( Item( uno::makeAny( nItem ), uno::Any() ), uno::UNO_QUERY_THROW );
-        ScVbaWorksheet* pSheet = dynamic_cast< ScVbaWorksheet* >( xSheet.get() );
-        if ( pSheet )
+        ScVbaWorksheet* pSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSheet );
+        if ( bSelectSingle )
         {
-            if ( bSelectSingle )
-            {
-                rMarkData.SelectOneTable( static_cast< SCTAB >( pSheet->getSheetID() ) );
-                bSelectSingle = false;
-            }
-            else
-                rMarkData.SelectTable( static_cast< SCTAB >( pSheet->getSheetID() ), sal_True );
-            
+            rMarkData.SelectOneTable( static_cast< SCTAB >( pSheet->getSheetID() ) );
+            bSelectSingle = false;
         }
+        else
+            rMarkData.SelectTable( static_cast< SCTAB >( pSheet->getSheetID() ), sal_True );
     }
     
 
@@ -440,13 +436,10 @@ ScVbaWorksheets::Item( const uno::Any& Index, const uno::Any& Index2  ) throw (u
         for( sal_Int32 index = 0; index < nElems; ++index )
         {
             uno::Reference< excel::XWorksheet > xWorkSheet( ScVbaWorksheets_BASE::Item( sIndices[ index ], Index2 ), uno::UNO_QUERY_THROW );
-            ScVbaWorksheet* pWorkSheet = dynamic_cast< ScVbaWorksheet* >( xWorkSheet.get() );
-            if ( pWorkSheet )
-            {
-                uno::Reference< sheet::XSpreadsheet > xSheet( pWorkSheet->getSheet() , uno::UNO_QUERY_THROW );
-                uno::Reference< container::XNamed > xName( xSheet, uno::UNO_QUERY_THROW );
-                mSheets.push_back( xSheet );
-            }
+            ScVbaWorksheet* pWorkSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xWorkSheet );
+            uno::Reference< sheet::XSpreadsheet > xSheet( pWorkSheet->getSheet() , uno::UNO_QUERY_THROW );
+            uno::Reference< container::XNamed > xName( xSheet, uno::UNO_QUERY_THROW );
+            mSheets.push_back( xSheet );
         }  
         uno::Reference< container::XIndexAccess > xIndexAccess = new SheetCollectionHelper( mSheets );
         uno::Reference< XCollection > xSelectedSheets(  new ScVbaWorksheets( this->getParent(), mxContext, xIndexAccess, mxModel ) );


More information about the Libreoffice-commits mailing list