summaryrefslogtreecommitdiff
path: root/basic/source/classes
diff options
context:
space:
mode:
Diffstat (limited to 'basic/source/classes')
-rw-r--r--basic/source/classes/disas.cxx687
-rw-r--r--basic/source/classes/errobject.cxx225
-rw-r--r--basic/source/classes/eventatt.cxx599
-rw-r--r--basic/source/classes/image.cxx544
-rw-r--r--basic/source/classes/makefile.mk76
-rw-r--r--basic/source/classes/propacc.cxx430
-rw-r--r--basic/source/classes/sb.cxx2135
-rw-r--r--basic/source/classes/sb.src681
-rw-r--r--basic/source/classes/sbintern.cxx82
-rwxr-xr-xbasic/source/classes/sbunoobj.cxx4855
-rwxr-xr-xbasic/source/classes/sbxmod.cxx2626
11 files changed, 12940 insertions, 0 deletions
diff --git a/basic/source/classes/disas.cxx b/basic/source/classes/disas.cxx
new file mode 100644
index 000000000000..37d777cb8da8
--- /dev/null
+++ b/basic/source/classes/disas.cxx
@@ -0,0 +1,687 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_basic.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <tools/stream.hxx>
+#include <basic/sbx.hxx>
+#include "sb.hxx"
+#include "iosys.hxx"
+#include "disas.hxx"
+#include "sbtrace.hxx"
+
+
+static const char* pOp1[] = {
+ "NOP",
+
+ // Operators
+ // the following operators have the same order as in
+ // enum SbxVarOp
+ "EXP", "MUL", "DIV", "MOD", "PLUS", "MINUS", "NEG",
+ "EQ", "NE", "LT", "GT", "LE", "GE",
+ "IDIV", "AND", "OR", "XOR", "EQV", "IMP", "NOT",
+ "CAT",
+ // End enum SbxVarOp
+ "LIKE", "IS",
+ // Load/Store
+ "ARGC", // Create new Argv
+ "ARGV", // TOS ==> current Argv
+ "INPUT", // Input ==> TOS
+ "LINPUT", // Line Input ==> TOS
+ "GET", // get TOS
+ "SET", // Save Object TOS ==> TOS-1
+ "PUT", // TOS ==> TOS-1
+ "CONST", // TOS ==> TOS-1, then ReadOnly
+ "DIM", // DIM
+ "REDIM", // REDIM
+ "REDIMP", // REDIM PRESERVE
+ "ERASE", // delete TOS
+ // Branch
+ "STOP", // End of program
+ "INITFOR", // FOR-Variable init
+ "NEXT", // FOR-Variable increment
+ "CASE", // Begin CASE
+ "ENDCASE", // End CASE
+ "STDERR", // Default error handling
+ "NOERROR", // No error handling
+ "LEAVE", // leave UP
+ // I/O
+ "CHANNEL", // TOS = Channelnumber
+ "PRINT", // print TOS
+ "PRINTF", // print TOS in field
+ "WRITE", // write TOS
+ "RENAME", // Rename Tos+1 to Tos
+ "PROMPT", // TOS = Prompt for Input
+ "RESTART", // Define restart point
+ "STDIO", // Switch to I/O channel 0
+ // Misc
+ "EMPTY", // Empty statement to stack
+ "ERROR", // TOS = error code
+ "LSET", // Save object TOS ==> TOS-1
+ "RSET", // Save object TOS ==> TOS-1 (TODO: Same as above?)
+ "REDIMP_ERASE",
+ "INITFOREACH",
+ "VBASET",
+ "ERASE_CLEAR",
+ "ARRAYACCESS",
+ "BYVAL"
+};
+
+static const char* pOp2[] = {
+ "NUMBER", // Load a numeric constant (+ID)
+ "STRING", // Load a string constant (+ID)
+ "CONSTANT", // Immediate Load (+value)
+ "ARGN", // Save named args in argv (+StringID)
+ "PAD", // Pad String to defined length (+length)
+ // Branches
+ "JUMP", // Jump to target (+Target)
+ "JUMP.T", // evaluate TOS, conditional jump (+Target)
+ "JUMP.F", // evaluate TOS, conditional jump (+Target)
+ "ONJUMP", // evaluate TOS, jump into JUMP-table (+MaxVal)
+ "GOSUB", // UP-Call (+Target)
+ "RETURN", // UP-Return (+0 or Target)
+ "TESTFOR", // Test FOR-Variable, increment (+Endlabel)
+ "CASETO", // Tos+1 <= Case <= Tos, 2xremove (+Target)
+ "ERRHDL", // Error-Handler (+Offset)
+ "RESUME", // Resume after errors (+0 or 1 or Label)
+ // I/O
+ "CLOSE", // (+channel/0)
+ "PRCHAR", // (+char)
+ // Objects
+ "SETCLASS", // Test Set + Classname (+StringId)
+ "TESTCLASS", // Check TOS class (+StringId)
+ "LIB", // Set Libname for Declare-Procs (+StringId)
+ // New since Beta 3 (TODO: Which Beta3?)
+ "BASED", // TOS is incremted about BASE, push BASE before
+ "ARGTYP", // Convert last parameter in argv (+Type)
+ "VBASETCLASS",
+};
+
+static const char* pOp3[] = {
+ // All opcodes with two operands
+ "RTL", // Load from RTL (+StringID+Typ)
+ "FIND", // Load (+StringID+Typ)
+ "ELEM", // Load element (+StringID+Typ)
+ "PARAM", // Parameter (+Offset+Typ)
+
+ // Branching
+ "CALL", // Call DECLARE method (+StringID+Typ)
+ "CALL.C", // Call Cdecl-DECLARE method (+StringID+Typ)
+ "CASEIS", // Case-Test (+Test-Opcode+False-Target)
+ "STMNT", // Start of a statement (+Line+Col)
+
+ // I/O
+ "OPEN", // (+SvStreamFlags+Flags)
+
+ // Objects and variables
+ "LOCAL", // Local variables (+StringID+Typ)
+ "PUBLIC", // Modul global var (+StringID+Typ)
+ "GLOBAL", // Global var (+StringID+Typ)
+ "CREATE", // Create object (+StringId+StringId)
+ "STATIC", // Create static object (+StringId+StringId)
+ "TCREATE", // Create User defined Object (+StringId+StringId)
+ "DCREATE", // Create User defined Object-Array kreieren (+StringId+StringId)
+ "GLOBAL_P", // Define persistent global var (existing after basic restart)
+ // P=PERSIST (+StringID+Typ)
+ "FIND_G", // Searches for global var with special handling due to _GLOBAL_P
+ "DCREATE_REDIMP", // Change dimensions of a user defined Object-Array (+StringId+StringId)
+ "FIND_CM", // Search inside a class module (CM) to enable global search in time
+ "PUBLIC_P", // Module global Variable (persisted between calls)(+StringID+Typ)
+ "FIND_STATIC", // local static var lookup (+StringID+Typ)
+};
+
+static const char** pOps[3] = { pOp1, pOp2, pOp3 };
+
+typedef void( SbiDisas::*Func )( String& ); // Processing routines
+
+static const Func pOperand2[] = {
+ &SbiDisas::StrOp, // Load a numeric constant (+ID)
+ &SbiDisas::StrOp, // Load a string constant (+ID)
+ &SbiDisas::ImmOp, // Immediate Load (+Wert)
+ &SbiDisas::StrOp, // Save a named argument (+ID)
+ &SbiDisas::ImmOp, // Strip String to fixed size (+length)
+
+ // Branches
+ &SbiDisas::LblOp, // Jump (+Target)
+ &SbiDisas::LblOp, // eval TOS, conditional jump (+Target)
+ &SbiDisas::LblOp, // eval TOS, conditional jump (+Target)
+ &SbiDisas::OnOp, // eval TOS, jump in JUMP table (+MaxVal)
+ &SbiDisas::LblOp, // UP call (+Target)
+ &SbiDisas::ReturnOp, // UP Return (+0 or Target)
+ &SbiDisas::LblOp, // test FOR-Variable, increment (+Endlabel)
+ &SbiDisas::LblOp, // Tos+1 <= Case <= Tos), 2xremove (+Target)
+ &SbiDisas::LblOp, // Error handler (+Offset)
+ &SbiDisas::ResumeOp, // Resume after errors (+0 or 1 or Label)
+
+ // I/O
+ &SbiDisas::CloseOp, // (+channel/0)
+ &SbiDisas::CharOp, // (+char)
+
+ // Objects
+ &SbiDisas::StrOp, // Test classname (+StringId)
+ &SbiDisas::StrOp, // TESTCLASS, Check TOS class (+StringId)
+ &SbiDisas::StrOp, // Set libname for declare procs (+StringId)
+ &SbiDisas::ImmOp, // TOS is incremented about BASE erhoeht, BASE pushed before
+ &SbiDisas::TypeOp, // Convert last parameter to/in(?) argv (+Typ)
+ &SbiDisas::StrOp, // VBASETCLASS (+StringId)
+};
+
+static const Func pOperand3[] = {
+ // All opcodes with two operands
+ &SbiDisas::VarOp, // Load from RTL (+StringID+Typ)
+ &SbiDisas::VarOp, // Load (+StringID+Typ)
+ &SbiDisas::VarOp, // Load Element (+StringID+Typ)
+ &SbiDisas::OffOp, // Parameter (+Offset+Typ)
+
+ // Branch
+ &SbiDisas::VarOp, // Call DECLARE-Method (+StringID+Typ)
+ &SbiDisas::VarOp, // Call CDecl-DECLARE-Methode (+StringID+Typ)
+ &SbiDisas::CaseOp, // Case-Test (+Test-Opcode+False-Target)
+ &SbiDisas::StmntOp, // Statement (+Row+Column)
+
+ // I/O
+ &SbiDisas::StrmOp, // (+SvStreamFlags+Flags)
+
+ // Objects
+ &SbiDisas::VarDefOp, // Define local var (+StringID+Typ)
+ &SbiDisas::VarDefOp, // Define Module global var (+StringID+Typ)
+ &SbiDisas::VarDefOp, // Define global var (+StringID+Typ)
+ &SbiDisas::Str2Op, // Create object (+StringId+StringId)
+ &SbiDisas::VarDefOp, // Define static object (+StringID+Typ)
+ &SbiDisas::Str2Op, // Create User defined Object (+StringId+StringId)
+ &SbiDisas::Str2Op, // Create User defined Object-Array (+StringId+StringId)
+ &SbiDisas::VarDefOp, // Define persistent global var P=PERSIST (+StringID+Typ)
+ &SbiDisas::VarOp, // Searches for global var with special handling due to _GLOBAL_P
+ &SbiDisas::Str2Op, // Redimensionate User defined Object-Array (+StringId+StringId)
+ &SbiDisas::VarOp, // FIND_CM
+ &SbiDisas::VarDefOp, // PUBLIC_P
+ &SbiDisas::VarOp, // FIND_STATIC
+};
+
+// TODO: Why as method? Isn't a simple define sufficient?
+static const char* _crlf()
+{
+#if defined (UNX) || defined( PM2 )
+ return "\n";
+#else
+ return "\r\n";
+#endif
+}
+
+// This method exists because we want to load the file as own segment
+sal_Bool SbModule::Disassemble( String& rText )
+{
+ rText.Erase();
+ if( pImage )
+ {
+ SbiDisas aDisas( this, pImage );
+ aDisas.Disas( rText );
+ }
+ return sal_Bool( rText.Len() != 0 );
+}
+
+SbiDisas::SbiDisas( SbModule* p, const SbiImage* q ) : rImg( *q ), pMod( p )
+{
+ memset( cLabels, 0, 8192 );
+ nLine = 0;
+ nOff = 0;
+ nPC = 0;
+ nOp1 = nOp2 = nParts = 0;
+ eOp = _NOP;
+ // Set Label-Bits
+ nOff = 0;
+ while( Fetch() )
+ {
+ switch( eOp )
+ {
+ case _RESUME: if( nOp1 <= 1 ) break;
+ case _RETURN: if( !nOp1 ) break;
+ case _JUMP:
+ case _JUMPT:
+ case _JUMPF:
+ case _GOSUB:
+ case _TESTFOR:
+ case _CASEIS:
+ case _CASETO:
+ case _ERRHDL:
+ cLabels[ (nOp1 & 0xffff) >> 3 ] |= ( 1 << ( nOp1 & 7 ) );
+ break;
+ default: break;
+ }
+ }
+ nOff = 0;
+ // Add the publics
+ for( sal_uInt16 i = 0; i < pMod->GetMethods()->Count(); i++ )
+ {
+ SbMethod* pMeth = PTR_CAST(SbMethod,pMod->GetMethods()->Get( i ));
+ if( pMeth )
+ {
+ sal_uInt16 nPos = (sal_uInt16) (pMeth->GetId());
+ cLabels[ nPos >> 3 ] |= ( 1 << ( nPos & 7 ) );
+ }
+ }
+}
+
+// Read current opcode
+sal_Bool SbiDisas::Fetch()
+{
+ nPC = nOff;
+ if( nOff >= rImg.GetCodeSize() )
+ return sal_False;
+ const unsigned char* p = (const unsigned char*)( rImg.GetCode() + nOff );
+ eOp = (SbiOpcode) ( *p++ & 0xFF );
+ if( eOp <= SbOP0_END )
+ {
+ nOp1 = nOp2 = 0;
+ nParts = 1;
+ nOff++;
+ return sal_True;
+ }
+ else if( eOp <= SbOP1_END )
+ {
+ nOff += 5;
+ if( nOff > rImg.GetCodeSize() )
+ return sal_False;
+ nOp1 = *p++; nOp1 |= *p++ << 8; nOp1 |= *p++ << 16; nOp1 |= *p++ << 24;
+ nParts = 2;
+ return sal_True;
+ }
+ else if( eOp <= SbOP2_END )
+ {
+ nOff += 9;
+ if( nOff > rImg.GetCodeSize() )
+ return sal_False;
+ nOp1 = *p++; nOp1 |= *p++ << 8; nOp1 |= *p++ << 16; nOp1 |= *p++ << 24;
+ nOp2 = *p++; nOp2 |= *p++ << 8; nOp2 |= *p++ << 16; nOp2 |= *p++ << 24;
+ nParts = 3;
+ return sal_True;
+ }
+ else
+ return sal_False;
+}
+
+void SbiDisas::Disas( SvStream& r )
+{
+ String aText;
+ nOff = 0;
+ while( DisasLine( aText ) )
+ {
+ ByteString aByteText( aText, gsl_getSystemTextEncoding() );
+ r.WriteLine( aByteText );
+ }
+}
+
+void SbiDisas::Disas( String& r )
+{
+ r.Erase();
+ String aText;
+ nOff = 0;
+ while( DisasLine( aText ) )
+ {
+ r += aText;
+ r.AppendAscii( _crlf() );
+ }
+ aText.ConvertLineEnd();
+}
+
+sal_Bool SbiDisas::DisasLine( String& rText )
+{
+ char cBuf[ 100 ];
+ const char* pMask[] = {
+ "%08" SAL_PRIXUINT32 " ",
+ "%08" SAL_PRIXUINT32 " %02X ",
+ "%08" SAL_PRIXUINT32 " %02X %08X ",
+ "%08" SAL_PRIXUINT32 " %02X %08X %08X " };
+ rText.Erase();
+ if( !Fetch() )
+ return sal_False;
+
+#ifdef DBG_TRACE_BASIC
+ String aTraceStr_STMNT;
+#endif
+
+ // New line?
+ if( eOp == _STMNT && nOp1 != nLine )
+ {
+ // Find line
+ String aSource = rImg.aOUSource;
+ nLine = nOp1;
+ sal_uInt16 n = 0;
+ sal_uInt16 l = (sal_uInt16)nLine;
+ while( --l ) {
+ n = aSource.SearchAscii( "\n", n );
+ if( n == STRING_NOTFOUND ) break;
+ else n++;
+ }
+ // Show position
+ if( n != STRING_NOTFOUND )
+ {
+ sal_uInt16 n2 = aSource.SearchAscii( "\n", n );
+ if( n2 == STRING_NOTFOUND ) n2 = aSource.Len() - n;
+ String s( aSource.Copy( n, n2 - n + 1 ) );
+ sal_Bool bDone;
+ do {
+ bDone = sal_True;
+ n = s.Search( '\r' );
+ if( n != STRING_NOTFOUND ) bDone = sal_False, s.Erase( n, 1 );
+ n = s.Search( '\n' );
+ if( n != STRING_NOTFOUND ) bDone = sal_False, s.Erase( n, 1 );
+ } while( !bDone );
+// snprintf( cBuf, sizeof(cBuf), pMask[ 0 ], nPC );
+// rText += cBuf;
+ rText.AppendAscii( "; " );
+ rText += s;
+ rText.AppendAscii( _crlf() );
+
+#ifdef DBG_TRACE_BASIC
+ aTraceStr_STMNT = s;
+#endif
+ }
+ }
+
+ // Label?
+ const char* p = "";
+ if( cLabels[ nPC >> 3 ] & ( 1 << ( nPC & 7 ) ) )
+ {
+ // Public?
+ ByteString aByteMethName;
+ for( sal_uInt16 i = 0; i < pMod->GetMethods()->Count(); i++ )
+ {
+ SbMethod* pMeth = PTR_CAST(SbMethod,pMod->GetMethods()->Get( i ));
+ if( pMeth )
+ {
+ aByteMethName = ByteString( pMeth->GetName(), gsl_getSystemTextEncoding() );
+ if( pMeth->GetId() == nPC )
+ {
+ p = aByteMethName.GetBuffer();
+ break;
+ }
+ if( pMeth->GetId() >= nPC )
+ break;
+ }
+ }
+ snprintf( cBuf, sizeof(cBuf), pMask[ 0 ], nPC );
+ rText.AppendAscii( cBuf );
+ if( p && *p )
+ {
+ rText.AppendAscii( p );
+ }
+ else
+ {
+ // fix warning (now error) for "Lbl%04lX" format
+ snprintf( cBuf, sizeof(cBuf), "Lbl%08" SAL_PRIXUINT32, nPC );
+ rText.AppendAscii( cBuf );
+ }
+ rText += ':';
+ rText.AppendAscii( _crlf() );
+ }
+ snprintf( cBuf, sizeof(cBuf), pMask[ nParts ], nPC, (sal_uInt16) eOp, nOp1, nOp2 );
+
+ String aPCodeStr;
+ aPCodeStr.AppendAscii( cBuf );
+ int n = eOp;
+ if( eOp >= SbOP2_START )
+ n -= SbOP2_START;
+ else if( eOp >= SbOP1_START )
+ n -= SbOP1_START;
+ aPCodeStr += '\t';
+ aPCodeStr.AppendAscii( pOps[ nParts-1 ][ n ] );
+ aPCodeStr += '\t';
+ switch( nParts )
+ {
+ case 2: (this->*( pOperand2[ n ] ) )( aPCodeStr ); break;
+ case 3: (this->*( pOperand3[ n ] ) )( aPCodeStr ); break;
+ }
+
+ rText += aPCodeStr;
+
+#ifdef DBG_TRACE_BASIC
+ dbg_RegisterTraceTextForPC( pMod, nPC, aTraceStr_STMNT, aPCodeStr );
+#endif
+
+ return sal_True;
+}
+
+// Read from StringPool
+void SbiDisas::StrOp( String& rText )
+{
+ String aStr = rImg.GetString( (sal_uInt16)nOp1 );
+ ByteString aByteString( aStr, RTL_TEXTENCODING_ASCII_US );
+ const char* p = aByteString.GetBuffer();
+ if( p )
+ {
+ rText += '"';
+ rText.AppendAscii( p );
+ rText += '"';
+ }
+ else
+ {
+ rText.AppendAscii( "?String? " );
+ rText += (sal_uInt16)nOp1;
+ }
+}
+
+void SbiDisas::Str2Op( String& rText )
+{
+ StrOp( rText );
+ rText += ',';
+ String s;
+ nOp1 = nOp2;
+ StrOp( s );
+ rText += s;
+}
+
+// Immediate Operand
+void SbiDisas::ImmOp( String& rText )
+{
+ rText += String::CreateFromInt32(nOp1);
+}
+
+// OnGoto Operand
+void SbiDisas::OnOp( String& rText )
+{
+ rText += String::CreateFromInt32(nOp1 & 0x7FFF);
+ if( nOp1 & 0x800 )
+ rText.AppendAscii( "\t; Gosub" );
+}
+
+// Label
+void SbiDisas::LblOp( String& rText )
+{
+ char cBuf[ 10 ];
+ snprintf( cBuf, sizeof(cBuf), "Lbl%04" SAL_PRIXUINT32, nOp1 );
+ rText.AppendAscii( cBuf );
+}
+
+// 0 or Label
+void SbiDisas::ReturnOp( String& rText )
+{
+ if( nOp1 )
+ LblOp( rText );
+}
+
+// 0, 1 or Label
+void SbiDisas::ResumeOp( String& rText )
+{
+ switch( nOp1 )
+ {
+ case 1: rText.AppendAscii( "NEXT" ); break;
+ case 2: LblOp( rText );
+ }
+}
+
+// print Prompt
+// sal_False/TRUE
+void SbiDisas::PromptOp( String& rText )
+{
+ if( nOp1 )
+ rText.AppendAscii( "\"? \"" );
+}
+
+// 0 or 1
+void SbiDisas::CloseOp( String& rText )
+{
+ rText.AppendAscii( nOp1 ? "Channel" : "All" );
+}
+
+// Print character
+void SbiDisas::CharOp( String& rText )
+{
+ const char* p = NULL;
+ switch( nOp1 )
+ {
+ case 7: p = "'\\a'"; break;
+ case 9: p = "'\\t'"; break;
+ case 10: p = "'\\n'"; break;
+ case 12: p = "'\\f'"; break;
+ case 13: p = "'\\r'"; break;
+ }
+ if( p ) rText.AppendAscii( p );
+ else if( nOp1 >= ' ' )
+ rText += '\'',
+ rText += (char) nOp1,
+ rText += '\'';
+ else
+ rText.AppendAscii( "char " ),
+ rText += (sal_uInt16)nOp1;
+}
+
+// Print var: String-ID and type
+void SbiDisas::VarOp( String& rText )
+{
+ rText += rImg.GetString( (sal_uInt16)(nOp1 & 0x7FFF) );
+ rText.AppendAscii( "\t; " );
+ // The type
+ sal_uInt32 n = nOp1;
+ nOp1 = nOp2;
+ TypeOp( rText );
+ if( n & 0x8000 )
+ rText.AppendAscii( ", Args" );
+}
+
+// Define variable: String-ID and type
+void SbiDisas::VarDefOp( String& rText )
+{
+ rText += rImg.GetString( (sal_uInt16)(nOp1 & 0x7FFF) );
+ rText.AppendAscii( "\t; " );
+ // The Typ
+ nOp1 = nOp2;
+ TypeOp( rText );
+}
+
+// Print variable: Offset and Typ
+void SbiDisas::OffOp( String& rText )
+{
+ rText += String::CreateFromInt32( nOp1 & 0x7FFF );
+ rText.AppendAscii( "\t; " );
+ // The type
+ sal_uInt32 n = nOp1;
+ nOp1 = nOp2;
+ TypeOp( rText );
+ if( n & 0x8000 )
+ rText.AppendAscii( ", Args" );
+}
+
+// Data type
+#ifdef HP9000 // TODO: remove this!
+static char* SbiDisas_TypeOp_pTypes[13] = {
+ "Empty","Null","Integer","Long","Single","Double",
+ "Currency","Date","String","Object","Error","Boolean",
+ "Variant" };
+#define pTypes SbiDisas_TypeOp_pTypes
+#endif
+void SbiDisas::TypeOp( String& rText )
+{
+ // AB 19.1.96: Typ kann Flag für BYVAL enthalten (StepARGTYP)
+ if( nOp1 & 0x8000 )
+ {
+ nOp1 &= 0x7FFF; // Flag wegfiltern
+ rText.AppendAscii( "BYVAL " );
+ }
+ if( nOp1 < 13 )
+ {
+#ifndef HP9000
+ static char pTypes[][13] = {
+ "Empty","Null","Integer","Long","Single","Double",
+ "Currency","Date","String","Object","Error","Boolean",
+ "Variant" };
+#endif
+ rText.AppendAscii( pTypes[ nOp1 ] );
+ }
+ else
+ {
+ rText.AppendAscii( "type " );
+ rText += (sal_uInt16)nOp1;
+ }
+}
+#ifdef HP9000
+#undef pTypes
+#endif
+
+// sal_True-Label, condition Opcode
+void SbiDisas::CaseOp( String& rText )
+{
+ LblOp( rText );
+ rText += ',';
+ rText.AppendAscii( pOp1[ nOp2 - SbxEQ + _EQ ] );
+}
+
+// Row, column
+void SbiDisas::StmntOp( String& rText )
+{
+ rText += String::CreateFromInt32( nOp1 );
+ rText += ',';
+ sal_uInt32 nCol = nOp2 & 0xFF;
+ sal_uInt32 nFor = nOp2 / 0x100;
+ rText += String::CreateFromInt32( nCol );
+ rText.AppendAscii( " (For-Level: " );
+ rText += String::CreateFromInt32( nFor );
+ rText += ')';
+}
+
+// open mode, flags
+void SbiDisas::StrmOp( String& rText )
+{
+ char cBuf[ 10 ];
+ snprintf( cBuf, sizeof(cBuf), "%04" SAL_PRIXUINT32, nOp1 );
+ rText.AppendAscii( cBuf );
+ if( nOp2 & SBSTRM_INPUT )
+ rText.AppendAscii( ", Input" );
+ if( nOp2 & SBSTRM_OUTPUT )
+ rText.AppendAscii( ", Output" );
+ if( nOp2 & SBSTRM_APPEND )
+ rText.AppendAscii( ", Append" );
+ if( nOp2 & SBSTRM_RANDOM )
+ rText.AppendAscii( ", Random" );
+ if( nOp2 & SBSTRM_BINARY )
+ rText.AppendAscii( ", Binary" );
+}
+
+
diff --git a/basic/source/classes/errobject.cxx b/basic/source/classes/errobject.cxx
new file mode 100644
index 000000000000..0ec0454e2bb5
--- /dev/null
+++ b/basic/source/classes/errobject.cxx
@@ -0,0 +1,225 @@
+/*************************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* 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.
+*
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_basic.hxx"
+#include "errobject.hxx"
+
+#include <cppuhelper/implbase2.hxx>
+#include <com/sun/star/script/XDefaultProperty.hpp>
+#include "sbintern.hxx"
+#include "runtime.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo;
+
+typedef ::cppu::WeakImplHelper2< vba::XErrObject, script::XDefaultProperty > ErrObjectImpl_BASE;
+
+class ErrObject : public ErrObjectImpl_BASE
+{
+ rtl::OUString m_sHelpFile;
+ rtl::OUString m_sSource;
+ rtl::OUString m_sDescription;
+ sal_Int32 m_nNumber;
+ sal_Int32 m_nHelpContext;
+
+public:
+ ErrObject();
+ ~ErrObject();
+ // Attributes
+ virtual ::sal_Int32 SAL_CALL getNumber() throw (uno::RuntimeException);
+ virtual void SAL_CALL setNumber( ::sal_Int32 _number ) throw (uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getHelpContext() throw (uno::RuntimeException);
+ virtual void SAL_CALL setHelpContext( ::sal_Int32 _helpcontext ) throw (uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getHelpFile() throw (uno::RuntimeException);
+ virtual void SAL_CALL setHelpFile( const ::rtl::OUString& _helpfile ) throw (uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getDescription() throw (uno::RuntimeException);
+ virtual void SAL_CALL setDescription( const ::rtl::OUString& _description ) throw (uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getSource() throw (uno::RuntimeException);
+ virtual void SAL_CALL setSource( const ::rtl::OUString& _source ) throw (uno::RuntimeException);
+
+ // Methods
+ virtual void SAL_CALL Clear( ) throw (uno::RuntimeException);
+ virtual void SAL_CALL Raise( const uno::Any& Number, const uno::Any& Source, const uno::Any& Description, const uno::Any& HelpFile, const uno::Any& HelpContext ) throw (uno::RuntimeException);
+ // XDefaultProperty
+ virtual ::rtl::OUString SAL_CALL getDefaultPropertyName( ) throw (uno::RuntimeException);
+
+ // Helper method
+ void setData( const uno::Any& Number, const uno::Any& Source, const uno::Any& Description,
+ const uno::Any& HelpFile, const uno::Any& HelpContext ) throw (uno::RuntimeException);
+};
+
+
+ErrObject::~ErrObject()
+{
+}
+
+ErrObject::ErrObject() : m_nNumber(0), m_nHelpContext(0)
+{
+}
+
+sal_Int32 SAL_CALL
+ErrObject::getNumber() throw (uno::RuntimeException)
+{
+ return m_nNumber;
+}
+
+void SAL_CALL
+ErrObject::setNumber( ::sal_Int32 _number ) throw (uno::RuntimeException)
+{
+ pINST->setErrorVB( _number, String() );
+ ::rtl::OUString _description = pINST->GetErrorMsg();
+ setData( uno::makeAny( _number ), uno::Any(), uno::makeAny( _description ), uno::Any(), uno::Any() );
+}
+
+::sal_Int32 SAL_CALL
+ErrObject::getHelpContext() throw (uno::RuntimeException)
+{
+ return m_nHelpContext;
+}
+void SAL_CALL
+ErrObject::setHelpContext( ::sal_Int32 _helpcontext ) throw (uno::RuntimeException)
+{
+ m_nHelpContext = _helpcontext;
+}
+
+::rtl::OUString SAL_CALL
+ErrObject::getHelpFile() throw (uno::RuntimeException)
+{
+ return m_sHelpFile;
+}
+
+void SAL_CALL
+ErrObject::setHelpFile( const ::rtl::OUString& _helpfile ) throw (uno::RuntimeException)
+{
+ m_sHelpFile = _helpfile;
+}
+
+::rtl::OUString SAL_CALL
+ErrObject::getDescription() throw (uno::RuntimeException)
+{
+ return m_sDescription;
+}
+
+void SAL_CALL
+ErrObject::setDescription( const ::rtl::OUString& _description ) throw (uno::RuntimeException)
+{
+ m_sDescription = _description;
+}
+
+::rtl::OUString SAL_CALL
+ErrObject::getSource() throw (uno::RuntimeException)
+{
+ return m_sSource;
+}
+
+void SAL_CALL
+ErrObject::setSource( const ::rtl::OUString& _source ) throw (uno::RuntimeException)
+{
+ m_sSource = _source;
+}
+
+// Methods
+void SAL_CALL
+ErrObject::Clear( ) throw (uno::RuntimeException)
+{
+ m_sHelpFile = rtl::OUString();
+ m_sSource = m_sHelpFile;
+ m_sDescription = m_sSource;
+ m_nNumber = 0;
+ m_nHelpContext = 0;
+}
+
+void SAL_CALL
+ErrObject::Raise( const uno::Any& Number, const uno::Any& Source, const uno::Any& Description, const uno::Any& HelpFile, const uno::Any& HelpContext ) throw (uno::RuntimeException)
+{
+ setData( Number, Source, Description, HelpFile, HelpContext );
+ if ( m_nNumber )
+ pINST->ErrorVB( m_nNumber, m_sDescription );
+}
+
+// XDefaultProperty
+::rtl::OUString SAL_CALL
+ErrObject::getDefaultPropertyName( ) throw (uno::RuntimeException)
+{
+ static rtl::OUString sDfltPropName( RTL_CONSTASCII_USTRINGPARAM("Number") );
+ return sDfltPropName;
+}
+
+void ErrObject::setData( const uno::Any& Number, const uno::Any& Source, const uno::Any& Description, const uno::Any& HelpFile, const uno::Any& HelpContext )
+ throw (uno::RuntimeException)
+{
+ if ( !Number.hasValue() )
+ throw uno::RuntimeException( rtl::OUString::createFromAscii("Missing Required Paramater"), uno::Reference< uno::XInterface >() );
+ Number >>= m_nNumber;
+ Description >>= m_sDescription;
+ Source >>= m_sSource;
+ HelpFile >>= m_sHelpFile;
+ HelpContext >>= m_nHelpContext;
+}
+
+// SbxErrObject
+SbxErrObject::SbxErrObject( const String& rName, const Any& rUnoObj )
+ : SbUnoObject( rName, rUnoObj )
+ , m_pErrObject( NULL )
+{
+ OSL_TRACE("SbxErrObject::SbxErrObject ctor");
+ rUnoObj >>= m_xErr;
+ if ( m_xErr.is() )
+ {
+ SetDfltProperty( uno::Reference< script::XDefaultProperty >( m_xErr, uno::UNO_QUERY_THROW )->getDefaultPropertyName() ) ;
+ m_pErrObject = static_cast< ErrObject* >( m_xErr.get() );
+ }
+}
+
+SbxErrObject::~SbxErrObject()
+{
+ OSL_TRACE("SbxErrObject::~SbxErrObject dtor");
+}
+
+uno::Reference< vba::XErrObject >
+SbxErrObject::getUnoErrObject()
+{
+ SbxVariable* pVar = getErrObject();
+ SbxErrObject* pGlobErr = static_cast< SbxErrObject* >( pVar );
+ return pGlobErr->m_xErr;
+}
+
+SbxVariableRef
+SbxErrObject::getErrObject()
+{
+ static SbxVariableRef pGlobErr = new SbxErrObject( String( RTL_CONSTASCII_USTRINGPARAM("Err")), uno::makeAny( uno::Reference< vba::XErrObject >( new ErrObject() ) ) );
+ return pGlobErr;
+}
+
+void SbxErrObject::setNumberAndDescription( ::sal_Int32 _number, const ::rtl::OUString& _description )
+ throw (uno::RuntimeException)
+{
+ if( m_pErrObject != NULL )
+ m_pErrObject->setData( uno::makeAny( _number ), uno::Any(), uno::makeAny( _description ), uno::Any(), uno::Any() );
+}
+
diff --git a/basic/source/classes/eventatt.cxx b/basic/source/classes/eventatt.cxx
new file mode 100644
index 000000000000..8d9f30e4982f
--- /dev/null
+++ b/basic/source/classes/eventatt.cxx
@@ -0,0 +1,599 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_basic.hxx"
+
+//#include <stl_queue.h>
+#include <osl/mutex.hxx>
+#include <comphelper/processfactory.hxx>
+
+
+#include <com/sun/star/script/XEventAttacher.hpp>
+#include <com/sun/star/script/XAllListener.hpp>
+#include <com/sun/star/script/XScriptEventsSupplier.hpp>
+#include <com/sun/star/script/XScriptEventsAttacher.hpp>
+#include <com/sun/star/script/ScriptEventDescriptor.hpp>
+#include <com/sun/star/script/XLibraryContainer.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/resource/XStringResourceSupplier.hpp>
+#include <com/sun/star/resource/XStringResourceManager.hpp>
+#include <com/sun/star/awt/XControlContainer.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/awt/XDialog.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
+
+#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
+#include <com/sun/star/script/provider/XScriptProvider.hpp>
+#include <com/sun/star/awt/XDialogProvider.hpp>
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <basic/basicmanagerrepository.hxx>
+#include <basic/basmgr.hxx>
+//==================================================================================================
+
+#include <xmlscript/xmldlg_imexp.hxx>
+#include <sbunoobj.hxx>
+#include <basic/sbstar.hxx>
+#include <basic/sbmeth.hxx>
+#include <basic/sbuno.hxx>
+#include <runtime.hxx>
+#include <sbintern.hxx>
+
+
+#include <cppuhelper/implbase1.hxx>
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::resource;
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::reflection;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::io;
+using namespace ::cppu;
+using namespace ::osl;
+
+
+void SFURL_firing_impl( const ScriptEvent& aScriptEvent, Any* pRet, const Reference< frame::XModel >& xModel )
+{
+ OSL_TRACE("SFURL_firing_impl() processing script url %s",
+ ::rtl::OUStringToOString( aScriptEvent.ScriptCode,
+ RTL_TEXTENCODING_ASCII_US ).pData->buffer );
+ try
+ {
+ Reference< provider::XScriptProvider > xScriptProvider;
+ if ( xModel.is() )
+ {
+ Reference< provider::XScriptProviderSupplier > xSupplier( xModel, UNO_QUERY );
+ OSL_ENSURE( xSupplier.is(), "SFURL_firing_impl: failed to get script provider supplier" );
+ if ( xSupplier.is() )
+ xScriptProvider.set( xSupplier->getScriptProvider() );
+ }
+ else
+ {
+ Reference< XComponentContext > xContext;
+ Reference< XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ OSL_VERIFY( xProps->getPropertyValue( ::rtl::OUString::createFromAscii( "DefaultContext" ) ) >>= xContext );
+ if ( xContext.is() )
+ {
+ Reference< provider::XScriptProviderFactory > xFactory(
+ xContext->getValueByName(
+ ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory" ) ),
+ UNO_QUERY );
+ OSL_ENSURE( xFactory.is(), "SFURL_firing_impl: failed to get master script provider factory" );
+ if ( xFactory.is() )
+ {
+ Any aCtx;
+ aCtx <<= ::rtl::OUString::createFromAscii( "user" );
+ xScriptProvider.set( xFactory->createScriptProvider( aCtx ), UNO_QUERY );
+ }
+ }
+ }
+
+ if ( !xScriptProvider.is() )
+ {
+ OSL_TRACE("SFURL_firing_impl() Failed to create msp");
+ return;
+ }
+ Sequence< Any > inArgs( 0 );
+ Sequence< Any > outArgs( 0 );
+ Sequence< sal_Int16 > outIndex;
+
+ // get Arguments for script
+ inArgs = aScriptEvent.Arguments;
+
+ Reference< provider::XScript > xScript = xScriptProvider->getScript( aScriptEvent.ScriptCode );
+
+ if ( !xScript.is() )
+ {
+ OSL_TRACE("SFURL_firing_impl() Failed to obtain XScript");
+ return;
+ }
+
+ Any result = xScript->invoke( inArgs, outIndex, outArgs );
+ if ( pRet )
+ {
+ *pRet = result;
+ }
+ }
+ catch ( RuntimeException& re )
+ {
+ OSL_TRACE("SFURL_firing_impl() Caught RuntimeException reason %s.",
+ ::rtl::OUStringToOString( re.Message,
+ RTL_TEXTENCODING_ASCII_US ).pData->buffer );
+ }
+ catch ( Exception& e )
+ {
+ OSL_TRACE("SFURL_firing_impl() Caught Exception reason %s.",
+ ::rtl::OUStringToOString( e.Message,
+ RTL_TEXTENCODING_ASCII_US ).pData->buffer );
+ }
+
+}
+
+
+class BasicScriptListener_Impl : public WeakImplHelper1< XScriptListener >
+{
+ StarBASICRef maBasicRef;
+ Reference< frame::XModel > m_xModel;
+
+ virtual void firing_impl(const ScriptEvent& aScriptEvent, Any* pRet);
+
+public:
+ BasicScriptListener_Impl( StarBASIC* pBasic, const Reference< frame::XModel >& xModel )
+ : maBasicRef( pBasic ), m_xModel( xModel ) {}
+
+ // Methods of XAllListener
+ virtual void SAL_CALL firing(const ScriptEvent& aScriptEvent)
+ throw( RuntimeException );
+ virtual Any SAL_CALL approveFiring(const ScriptEvent& aScriptEvent)
+ throw( InvocationTargetException, RuntimeException );
+
+ // Methods of XEventListener
+ virtual void SAL_CALL disposing(const EventObject& Source)
+ throw( RuntimeException );
+};
+
+// Methods XAllListener
+void BasicScriptListener_Impl::firing( const ScriptEvent& aScriptEvent ) throw ( RuntimeException )
+{
+ firing_impl( aScriptEvent, NULL );
+}
+
+Any BasicScriptListener_Impl::approveFiring( const ScriptEvent& aScriptEvent )
+ throw ( InvocationTargetException, RuntimeException )
+{
+ Any aRetAny;
+ firing_impl( aScriptEvent, &aRetAny );
+ return aRetAny;
+}
+
+// Methods XEventListener
+void BasicScriptListener_Impl::disposing(const EventObject& ) throw ( RuntimeException )
+{
+ // TODO: ???
+ //vos::OGuard guard( Application::GetSolarMutex() );
+ //xSbxObj.Clear();
+}
+
+
+void BasicScriptListener_Impl::firing_impl( const ScriptEvent& aScriptEvent, Any* pRet )
+{
+ //Guard< Mutex > aGuard( Mutex::getGlobalMutex() );
+ //{
+ if( aScriptEvent.ScriptType.compareToAscii( "StarBasic" ) == 0 )
+ {
+ // Full qualified name?
+ String aMacro( aScriptEvent.ScriptCode );
+ String aLibName;
+ String aLocation;
+ if( aMacro.GetTokenCount( '.' ) == 3 )
+ {
+ sal_uInt16 nLast = 0;
+ ::rtl::OUString aFullLibName = aMacro.GetToken( 0, '.', nLast );
+
+ sal_Int32 nIndex = aFullLibName.indexOf( (sal_Unicode)':' );
+ if (nIndex >= 0)
+ {
+ aLocation = aFullLibName.copy( 0, nIndex );
+ aLibName = aFullLibName.copy( nIndex + 1 );
+ }
+
+ String aModul = aMacro.GetToken( 0, '.', nLast );
+ aMacro.Erase( 0, nLast );
+ }
+
+ SbxObject* p = maBasicRef;
+ SbxObject* pParent = p->GetParent();
+ SbxObject* pParentParent = pParent ? pParent->GetParent() : NULL;
+
+ StarBASICRef xAppStandardBasic;
+ StarBASICRef xDocStandardBasic;
+ if( pParentParent )
+ {
+ // Own basic must be document library
+ xAppStandardBasic = (StarBASIC*)pParentParent;
+ xDocStandardBasic = (StarBASIC*)pParent;
+ }
+ else if( pParent )
+ {
+ String aName = p->GetName();
+ if( aName.EqualsAscii("Standard") )
+ {
+ // Own basic is doc standard lib
+ xDocStandardBasic = (StarBASIC*)p;
+ }
+ xAppStandardBasic = (StarBASIC*)pParent;
+ }
+ else
+ {
+ xAppStandardBasic = (StarBASIC*)p;
+ }
+
+ sal_Bool bSearchLib = true;
+ StarBASICRef xLibSearchBasic;
+ if( aLocation.EqualsAscii("application") )
+ xLibSearchBasic = xAppStandardBasic;
+ else if( aLocation.EqualsAscii("document") )
+ xLibSearchBasic = xDocStandardBasic;
+ else
+ bSearchLib = false;
+
+ SbxVariable* pMethVar = NULL;
+ // Be still tolerant and make default search if no search basic exists
+ if( bSearchLib && xLibSearchBasic.Is() )
+ {
+ StarBASICRef xLibBasic;
+ sal_Int16 nCount = xLibSearchBasic->GetObjects()->Count();
+ for( sal_Int16 nObj = -1; nObj < nCount ; nObj++ )
+ {
+ StarBASIC* pBasic;
+ if( nObj == -1 )
+ {
+ pBasic = (StarBASIC*)xLibSearchBasic;
+ }
+ else
+ {
+ SbxVariable* pVar = xLibSearchBasic->GetObjects()->Get( nObj );
+ pBasic = PTR_CAST(StarBASIC,pVar);
+ }
+ if( pBasic )
+ {
+ String aName = pBasic->GetName();
+ if( aName == aLibName )
+ {
+ // Search only in the lib, not automatically in application basic
+ sal_uInt16 nFlags = pBasic->GetFlags();
+ pBasic->ResetFlag( SBX_GBLSEARCH );
+ pMethVar = pBasic->Find( aMacro, SbxCLASS_DONTCARE );
+ pBasic->SetFlags( nFlags );
+ break;
+ }
+ }
+ }
+ }
+
+ // Default: Be tolerant and search everywhere
+ if( (!pMethVar || !pMethVar->ISA(SbMethod)) && maBasicRef.Is() )
+ pMethVar = maBasicRef->FindQualified( aMacro, SbxCLASS_DONTCARE );
+
+ SbMethod* pMeth = PTR_CAST(SbMethod,pMethVar);
+ if( !pMeth )
+ return;
+
+ // Setup parameters
+ SbxArrayRef xArray;
+ String aTmp;
+ sal_Int32 nCnt = aScriptEvent.Arguments.getLength();
+ if( nCnt )
+ {
+ xArray = new SbxArray;
+ const Any *pArgs = aScriptEvent.Arguments.getConstArray();
+ for( sal_Int32 i = 0; i < nCnt; i++ )
+ {
+ SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
+ unoToSbxValue( (SbxVariable*)xVar, pArgs[i] );
+ xArray->Put( xVar, sal::static_int_cast< sal_uInt16 >(i+1) );
+ }
+ }
+
+ // Call method
+ SbxVariableRef xValue = pRet ? new SbxVariable : 0;
+ if( xArray.Is() )
+ pMeth->SetParameters( xArray );
+ pMeth->Call( xValue );
+ if( pRet )
+ *pRet = sbxToUnoValue( xValue );
+ pMeth->SetParameters( NULL );
+ }
+ else // scripting framework script
+ {
+ //callBasic via scripting framework
+ SFURL_firing_impl( aScriptEvent, pRet, m_xModel );
+
+ }
+}
+
+Any implFindDialogLibForDialog( const Any& rDlgAny, SbxObject* pBasic )
+{
+ Any aRetDlgLibAny;
+
+ SbxVariable* pDlgLibContVar = pBasic->Find
+ ( String::CreateFromAscii("DialogLibraries"), SbxCLASS_OBJECT );
+ if( pDlgLibContVar && pDlgLibContVar->ISA(SbUnoObject) )
+ {
+ SbUnoObject* pDlgLibContUnoObj = (SbUnoObject*)(SbxBase*)pDlgLibContVar;
+ Any aDlgLibContAny = pDlgLibContUnoObj->getUnoAny();
+
+ Reference< XLibraryContainer > xDlgLibContNameAccess( aDlgLibContAny, UNO_QUERY );
+ OSL_ENSURE( xDlgLibContNameAccess.is(), "implFindDialogLibForDialog: no lib container for the given dialog!" );
+ if( xDlgLibContNameAccess.is() )
+ {
+ Sequence< ::rtl::OUString > aLibNames = xDlgLibContNameAccess->getElementNames();
+ const ::rtl::OUString* pLibNames = aLibNames.getConstArray();
+ sal_Int32 nLibNameCount = aLibNames.getLength();
+
+ for( sal_Int32 iLib = 0 ; iLib < nLibNameCount ; iLib++ )
+ {
+ if ( !xDlgLibContNameAccess->isLibraryLoaded( pLibNames[ iLib ] ) )
+ // if the library isn't loaded, then the dialog cannot originate from this lib
+ continue;
+
+ Any aDlgLibAny = xDlgLibContNameAccess->getByName( pLibNames[ iLib ] );
+
+ Reference< XNameAccess > xDlgLibNameAccess( aDlgLibAny, UNO_QUERY );
+ OSL_ENSURE( xDlgLibNameAccess.is(), "implFindDialogLibForDialog: invalid dialog lib!" );
+ if( xDlgLibNameAccess.is() )
+ {
+ Sequence< ::rtl::OUString > aDlgNames = xDlgLibNameAccess->getElementNames();
+ const ::rtl::OUString* pDlgNames = aDlgNames.getConstArray();
+ sal_Int32 nDlgNameCount = aDlgNames.getLength();
+
+ for( sal_Int32 iDlg = 0 ; iDlg < nDlgNameCount ; iDlg++ )
+ {
+ Any aDlgAny = xDlgLibNameAccess->getByName( pDlgNames[ iDlg ] );
+ if( aDlgAny == rDlgAny )
+ {
+ aRetDlgLibAny = aDlgLibAny;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return aRetDlgLibAny;
+}
+
+Any implFindDialogLibForDialogBasic( const Any& aAnyISP, SbxObject* pBasic, StarBASIC*& pFoundBasic )
+{
+ Any aDlgLibAny;
+ // Find dialog library for dialog, direct access is not possible here
+ StarBASIC* pStartedBasic = (StarBASIC*)pBasic;
+ SbxObject* pParentBasic = pStartedBasic ? pStartedBasic->GetParent() : NULL;
+ SbxObject* pParentParentBasic = pParentBasic ? pParentBasic->GetParent() : NULL;
+
+ SbxObject* pSearchBasic1 = NULL;
+ SbxObject* pSearchBasic2 = NULL;
+ if( pParentParentBasic )
+ {
+ pSearchBasic1 = pParentBasic;
+ pSearchBasic2 = pParentParentBasic;
+ }
+ else
+ {
+ pSearchBasic1 = pStartedBasic;
+ pSearchBasic2 = pParentBasic;
+ }
+ if( pSearchBasic1 )
+ {
+ aDlgLibAny = implFindDialogLibForDialog( aAnyISP, pSearchBasic1 );
+
+ if ( aDlgLibAny.hasValue() )
+ pFoundBasic = (StarBASIC*)pSearchBasic1;
+
+ else if( pSearchBasic2 )
+ {
+ aDlgLibAny = implFindDialogLibForDialog( aAnyISP, pSearchBasic2 );
+ if ( aDlgLibAny.hasValue() )
+ pFoundBasic = (StarBASIC*)pSearchBasic2;
+ }
+ }
+ return aDlgLibAny;
+}
+
+static ::rtl::OUString aDecorationPropName =
+ ::rtl::OUString::createFromAscii( "Decoration" );
+static ::rtl::OUString aTitlePropName =
+ ::rtl::OUString::createFromAscii( "Title" );
+
+void RTL_Impl_CreateUnoDialog( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
+{
+ static ::rtl::OUString aResourceResolverPropName = ::rtl::OUString::createFromAscii( "ResourceResolver" );
+
+ (void)pBasic;
+ (void)bWrite;
+
+ Reference< XMultiServiceFactory > xMSF( comphelper::getProcessServiceFactory() );
+ if( !xMSF.is() )
+ return;
+
+ // We need at least 1 parameter
+ if ( rPar.Count() < 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Get dialog
+ SbxBaseRef pObj = (SbxBase*)rPar.Get( 1 )->GetObject();
+ if( !(pObj && pObj->ISA(SbUnoObject)) )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ SbUnoObject* pUnoObj = (SbUnoObject*)(SbxBase*)pObj;
+ Any aAnyISP = pUnoObj->getUnoAny();
+ TypeClass eType = aAnyISP.getValueType().getTypeClass();
+
+ if( eType != TypeClass_INTERFACE )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Create new uno dialog
+ Reference< XNameContainer > xDialogModel( xMSF->createInstance
+ ( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlDialogModel" ) ) ),
+ UNO_QUERY );
+ if( !xDialogModel.is() )
+ return;
+
+ Reference< XInputStreamProvider > xISP;
+ aAnyISP >>= xISP;
+ if( !xISP.is() )
+ return;
+
+ Reference< XComponentContext > xContext;
+ Reference< XPropertySet > xProps( xMSF, UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ OSL_VERIFY( xProps->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")) ) >>= xContext );
+
+ // Import the DialogModel
+ Reference< XInputStream > xInput( xISP->createInputStream() );
+
+ // i83963 Force decoration
+ uno::Reference< beans::XPropertySet > xDlgModPropSet( xDialogModel, uno::UNO_QUERY );
+ if( xDlgModPropSet.is() )
+ {
+ bool bDecoration = true;
+ try
+ {
+ Any aDecorationAny = xDlgModPropSet->getPropertyValue( aDecorationPropName );
+ aDecorationAny >>= bDecoration;
+ if( !bDecoration )
+ {
+ xDlgModPropSet->setPropertyValue( aDecorationPropName, makeAny( true ) );
+ xDlgModPropSet->setPropertyValue( aTitlePropName, makeAny( ::rtl::OUString() ) );
+ }
+ }
+ catch( UnknownPropertyException& )
+ {}
+ }
+
+ Any aDlgLibAny;
+ bool bDocDialog = false;
+ StarBASIC* pFoundBasic = NULL;
+ OSL_TRACE("About to try get a hold of ThisComponent");
+ Reference< frame::XModel > xModel = StarBASIC::GetModelFromBasic( pINST->GetBasic() ) ;
+ aDlgLibAny = implFindDialogLibForDialogBasic( aAnyISP, pINST->GetBasic(), pFoundBasic );
+ // If we found the dialog then it belongs to the Search basic
+ if ( !pFoundBasic )
+ {
+ Reference< frame::XDesktop > xDesktop( xMSF->createInstance
+ ( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ) ),
+ UNO_QUERY );
+ Reference< container::XEnumeration > xModels;
+ if ( xDesktop.is() )
+ {
+ Reference< container::XEnumerationAccess > xComponents( xDesktop->getComponents(), UNO_QUERY );
+ if ( xComponents.is() )
+ xModels.set( xComponents->createEnumeration(), UNO_QUERY );
+ if ( xModels.is() )
+ {
+ while ( xModels->hasMoreElements() )
+ {
+ Reference< frame::XModel > xNextModel( xModels->nextElement(), UNO_QUERY );
+ if ( xNextModel.is() )
+ {
+ BasicManager* pMgr = basic::BasicManagerRepository::getDocumentBasicManager( xNextModel );
+ if ( pMgr )
+ aDlgLibAny = implFindDialogLibForDialogBasic( aAnyISP, pMgr->GetLib(0), pFoundBasic );
+ if ( aDlgLibAny.hasValue() )
+ {
+ bDocDialog = true;
+ xModel = xNextModel;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ if ( pFoundBasic )
+ bDocDialog = pFoundBasic->IsDocBasic();
+ Reference< XScriptListener > xScriptListener = new BasicScriptListener_Impl( pINST->GetBasic(), xModel );
+
+ Sequence< Any > aArgs( 4 );
+ if( bDocDialog )
+ aArgs[ 0 ] <<= xModel;
+ else
+ aArgs[ 0 ] <<= uno::Reference< uno::XInterface >();
+ aArgs[ 1 ] <<= xInput;
+ aArgs[ 2 ] = aDlgLibAny;
+ aArgs[ 3 ] <<= xScriptListener;
+ // Create a "living" Dialog
+ Reference< XControl > xCntrl;
+ try
+ {
+ Reference< XDialogProvider > xDlgProv( xMSF->createInstanceWithArguments( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.scripting.DialogProvider" ) ), aArgs ), UNO_QUERY );
+ xCntrl.set( xDlgProv->createDialog( rtl::OUString() ), UNO_QUERY_THROW );
+ // Add dialog model to dispose vector
+ Reference< XComponent > xDlgComponent( xCntrl->getModel(), UNO_QUERY );
+ pINST->getComponentVector().push_back( xDlgComponent );
+ // need ThisCompoent from calling script
+ }
+ // preserve existing bad behaviour, it's possible... but probably
+ // illegal to open 2 dialogs ( they ARE modal ) when this happens, sometimes
+ // create dialog fails. So, in this case let's not throw, just leave basic
+ // detect the unset object.
+ catch( uno::Exception& )
+ {
+ }
+
+ // Return dialog
+ Any aRetVal;
+ aRetVal <<= xCntrl;
+ SbxVariableRef refVar = rPar.Get(0);
+ unoToSbxValue( (SbxVariable*)refVar, aRetVal );
+}
+
+
+//===================================================================
+
diff --git a/basic/source/classes/image.cxx b/basic/source/classes/image.cxx
new file mode 100644
index 000000000000..fc6228d1aee9
--- /dev/null
+++ b/basic/source/classes/image.cxx
@@ -0,0 +1,544 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_basic.hxx"
+#include <tools/stream.hxx>
+#include <tools/tenccvt.hxx>
+#include <basic/sbx.hxx>
+#include "sb.hxx"
+#include <string.h> // memset() etc
+#include "image.hxx"
+#include <codegen.hxx>
+SbiImage::SbiImage()
+{
+ pStringOff = NULL;
+ pStrings = NULL;
+ pCode = NULL;
+ pLegacyPCode = NULL;
+ nFlags = 0;
+ nStrings = 0;
+ nStringSize= 0;
+ nCodeSize = 0;
+ nLegacyCodeSize =
+ nDimBase = 0;
+ bInit =
+ bError = sal_False;
+ bFirstInit = sal_True;
+ eCharSet = gsl_getSystemTextEncoding();
+}
+
+SbiImage::~SbiImage()
+{
+ Clear();
+}
+
+void SbiImage::Clear()
+{
+ delete[] pStringOff;
+ delete[] pStrings;
+ delete[] pCode;
+ ReleaseLegacyBuffer();
+ pStringOff = NULL;
+ pStrings = NULL;
+ pCode = NULL;
+ nFlags = 0;
+ nStrings = 0;
+ nStringSize= 0;
+ nLegacyCodeSize = 0;
+ nCodeSize = 0;
+ eCharSet = gsl_getSystemTextEncoding();
+ nDimBase = 0;
+ bError = sal_False;
+}
+
+/**************************************************************************
+*
+* Service-Routines for Load/Store
+*
+**************************************************************************/
+
+sal_Bool SbiGood( SvStream& r )
+{
+ return sal_Bool( !r.IsEof() && r.GetError() == SVSTREAM_OK );
+}
+
+// Open Record
+sal_uIntPtr SbiOpenRecord( SvStream& r, sal_uInt16 nSignature, sal_uInt16 nElem )
+{
+ sal_uIntPtr nPos = r.Tell();
+ r << nSignature << (sal_Int32) 0 << nElem;
+ return nPos;
+}
+
+// Close Record
+void SbiCloseRecord( SvStream& r, sal_uIntPtr nOff )
+{
+ sal_uIntPtr nPos = r.Tell();
+ r.Seek( nOff + 2 );
+ r << (sal_Int32) ( nPos - nOff - 8 );
+ r.Seek( nPos );
+}
+
+/**************************************************************************
+*
+* Load/Store
+*
+**************************************************************************/
+
+// If the version number does not find, binary parts are omitted, but not
+// source, comments and name
+sal_Bool SbiImage::Load( SvStream& r )
+{
+ sal_uInt32 nVersion = 0; // Versionsnumber
+ return Load( r, nVersion );
+}
+sal_Bool SbiImage::Load( SvStream& r, sal_uInt32& nVersion )
+{
+
+ sal_uInt16 nSign, nCount;
+ sal_uInt32 nLen, nOff;
+
+ Clear();
+ // Read Master-Record
+ r >> nSign >> nLen >> nCount;
+ sal_uIntPtr nLast = r.Tell() + nLen;
+ sal_uInt32 nCharSet; // System charset
+ sal_uInt32 lDimBase;
+ sal_uInt16 nReserved1;
+ sal_uInt32 nReserved2;
+ sal_uInt32 nReserved3;
+ sal_Bool bBadVer = sal_False;
+ if( nSign == B_MODULE )
+ {
+ r >> nVersion >> nCharSet >> lDimBase
+ >> nFlags >> nReserved1 >> nReserved2 >> nReserved3;
+ eCharSet = (CharSet) nCharSet;
+ eCharSet = GetSOLoadTextEncoding( eCharSet );
+ bBadVer = sal_Bool( nVersion > B_CURVERSION );
+ nDimBase = (sal_uInt16) lDimBase;
+ }
+
+ bool bLegacy = ( nVersion < B_EXT_IMG_VERSION );
+
+ sal_uIntPtr nNext;
+ while( ( nNext = r.Tell() ) < nLast )
+ {
+ short i;
+
+ r >> nSign >> nLen >> nCount;
+ nNext += nLen + 8;
+ if( r.GetError() == SVSTREAM_OK )
+ switch( nSign )
+ {
+ case B_NAME:
+ r.ReadByteString( aName, eCharSet );
+ //r >> aName;
+ break;
+ case B_COMMENT:
+ r.ReadByteString( aComment, eCharSet );
+ //r >> aComment;
+ break;
+ case B_SOURCE:
+ {
+ String aTmp;
+ r.ReadByteString( aTmp, eCharSet );
+ aOUSource = aTmp;
+ //r >> aSource;
+ break;
+ }
+#ifdef EXTENDED_BINARY_MODULES
+ case B_EXTSOURCE:
+ {
+ for( sal_uInt16 j = 0 ; j < nCount ; j++ )
+ {
+ String aTmp;
+ r.ReadByteString( aTmp, eCharSet );
+ aOUSource += aTmp;
+ }
+ break;
+ }
+#endif
+ case B_PCODE:
+ if( bBadVer ) break;
+ pCode = new char[ nLen ];
+ nCodeSize = nLen;
+ r.Read( pCode, nCodeSize );
+ if ( bLegacy )
+ {
+ ReleaseLegacyBuffer(); // release any previously held buffer
+ nLegacyCodeSize = (sal_uInt16) nCodeSize;
+ pLegacyPCode = pCode;
+
+ PCodeBuffConvertor< sal_uInt16, sal_uInt32 > aLegacyToNew( (sal_uInt8*)pLegacyPCode, nLegacyCodeSize );
+ aLegacyToNew.convert();
+ pCode = (char*)aLegacyToNew.GetBuffer();
+ nCodeSize = aLegacyToNew.GetSize();
+ // we don't release the legacy buffer
+ // right now, thats because the module
+ // needs it to fix up the method
+ // nStart members. When that is done
+ // the module can release the buffer
+ // or it can wait until this routine
+ // is called again or when this class // destructs all of which will trigger
+ // release of the buffer.
+ }
+ break;
+ case B_PUBLICS:
+ case B_POOLDIR:
+ case B_SYMPOOL:
+ case B_LINERANGES:
+ break;
+ case B_STRINGPOOL:
+ if( bBadVer ) break;
+ MakeStrings( nCount );
+ for( i = 0; i < nStrings && SbiGood( r ); i++ )
+ {
+ r >> nOff;
+ pStringOff[ i ] = (sal_uInt16) nOff;
+ }
+ r >> nLen;
+ if( SbiGood( r ) )
+ {
+ delete [] pStrings;
+ pStrings = new sal_Unicode[ nLen ];
+ nStringSize = (sal_uInt16) nLen;
+
+ char* pByteStrings = new char[ nLen ];
+ r.Read( pByteStrings, nStringSize );
+ for( short j = 0; j < nStrings; j++ )
+ {
+ sal_uInt16 nOff2 = (sal_uInt16) pStringOff[ j ];
+ String aStr( pByteStrings + nOff2, eCharSet );
+ memcpy( pStrings + nOff2, aStr.GetBuffer(), (aStr.Len() + 1) * sizeof( sal_Unicode ) );
+ }
+ delete[] pByteStrings;
+ } break;
+ case B_MODEND:
+ goto done;
+ default:
+ break;
+ }
+ else
+ break;
+ r.Seek( nNext );
+ }
+done:
+ r.Seek( nLast );
+ //if( eCharSet != ::GetSystemCharSet() )
+ //ConvertStrings();
+ if( !SbiGood( r ) )
+ bError = sal_True;
+ return sal_Bool( !bError );
+}
+
+sal_Bool SbiImage::Save( SvStream& r, sal_uInt32 nVer )
+{
+ bool bLegacy = ( nVer < B_EXT_IMG_VERSION );
+
+ // detect if old code exceeds legacy limits
+ // if so, then disallow save
+ if ( bLegacy && ExceedsLegacyLimits() )
+ {
+ SbiImage aEmptyImg;
+ aEmptyImg.aName = aName;
+ aEmptyImg.Save( r, B_LEGACYVERSION );
+ return sal_True;
+ }
+ // First of all the header
+ sal_uIntPtr nStart = SbiOpenRecord( r, B_MODULE, 1 );
+ sal_uIntPtr nPos;
+
+ eCharSet = GetSOStoreTextEncoding( eCharSet );
+ if ( bLegacy )
+ r << (sal_Int32) B_LEGACYVERSION;
+ else
+ r << (sal_Int32) B_CURVERSION;
+ r << (sal_Int32) eCharSet
+ << (sal_Int32) nDimBase
+ << (sal_Int16) nFlags
+ << (sal_Int16) 0
+ << (sal_Int32) 0
+ << (sal_Int32) 0;
+
+ // Name?
+ if( aName.Len() && SbiGood( r ) )
+ {
+ nPos = SbiOpenRecord( r, B_NAME, 1 );
+ r.WriteByteString( aName, eCharSet );
+ //r << aName;
+ SbiCloseRecord( r, nPos );
+ }
+ // Comment?
+ if( aComment.Len() && SbiGood( r ) )
+ {
+ nPos = SbiOpenRecord( r, B_COMMENT, 1 );
+ r.WriteByteString( aComment, eCharSet );
+ //r << aComment;
+ SbiCloseRecord( r, nPos );
+ }
+ // Source?
+ if( aOUSource.getLength() && SbiGood( r ) )
+ {
+ nPos = SbiOpenRecord( r, B_SOURCE, 1 );
+ String aTmp;
+ sal_Int32 nLen = aOUSource.getLength();
+ const sal_Int32 nMaxUnitSize = STRING_MAXLEN - 1;
+ if( nLen > STRING_MAXLEN )
+ aTmp = aOUSource.copy( 0, nMaxUnitSize );
+ else
+ aTmp = aOUSource;
+ r.WriteByteString( aTmp, eCharSet );
+ //r << aSource;
+ SbiCloseRecord( r, nPos );
+
+#ifdef EXTENDED_BINARY_MODULES
+ if( nLen > STRING_MAXLEN )
+ {
+ sal_Int32 nRemainingLen = nLen - nMaxUnitSize;
+ sal_uInt16 nUnitCount = sal_uInt16( (nRemainingLen + nMaxUnitSize - 1) / nMaxUnitSize );
+ nPos = SbiOpenRecord( r, B_EXTSOURCE, nUnitCount );
+ for( sal_uInt16 i = 0 ; i < nUnitCount ; i++ )
+ {
+ sal_Int32 nCopyLen =
+ (nRemainingLen > nMaxUnitSize) ? nMaxUnitSize : nRemainingLen;
+ String aTmp2 = aOUSource.copy( (i+1) * nMaxUnitSize, nCopyLen );
+ nRemainingLen -= nCopyLen;
+ r.WriteByteString( aTmp2, eCharSet );
+ }
+ SbiCloseRecord( r, nPos );
+ }
+#endif
+ }
+ // Binary data?
+ if( pCode && SbiGood( r ) )
+ {
+ nPos = SbiOpenRecord( r, B_PCODE, 1 );
+ if ( bLegacy )
+ {
+ ReleaseLegacyBuffer(); // release any previously held buffer
+ PCodeBuffConvertor< sal_uInt32, sal_uInt16 > aNewToLegacy( (sal_uInt8*)pCode, nCodeSize );
+ aNewToLegacy.convert();
+ pLegacyPCode = (char*)aNewToLegacy.GetBuffer();
+ nLegacyCodeSize = aNewToLegacy.GetSize();
+ r.Write( pLegacyPCode, nLegacyCodeSize );
+ }
+ else
+ r.Write( pCode, nCodeSize );
+ SbiCloseRecord( r, nPos );
+ }
+ // String-Pool?
+ if( nStrings )
+ {
+ nPos = SbiOpenRecord( r, B_STRINGPOOL, nStrings );
+ // For every String:
+ // sal_uInt32 Offset of the Strings in the Stringblock
+ short i;
+
+ for( i = 0; i < nStrings && SbiGood( r ); i++ )
+ r << (sal_uInt32) pStringOff[ i ];
+
+ // Then the String-Block
+ char* pByteStrings = new char[ nStringSize ];
+ for( i = 0; i < nStrings; i++ )
+ {
+ sal_uInt16 nOff = (sal_uInt16) pStringOff[ i ];
+ ByteString aStr( pStrings + nOff, eCharSet );
+ memcpy( pByteStrings + nOff, aStr.GetBuffer(), (aStr.Len() + 1) * sizeof( char ) );
+ }
+ r << (sal_uInt32) nStringSize;
+ r.Write( pByteStrings, nStringSize );
+
+ delete[] pByteStrings;
+ SbiCloseRecord( r, nPos );
+ }
+ // Set overall length
+ SbiCloseRecord( r, nStart );
+ if( !SbiGood( r ) )
+ bError = sal_True;
+ return sal_Bool( !bError );
+}
+
+/**************************************************************************
+*
+* Routines called by the compiler
+*
+**************************************************************************/
+
+void SbiImage::MakeStrings( short nSize )
+{
+ nStrings = 0;
+ nStringIdx = 0;
+ nStringOff = 0;
+ nStringSize = 1024;
+ pStrings = new sal_Unicode[ nStringSize ];
+ pStringOff = new sal_uInt32[ nSize ];
+ if( pStrings && pStringOff )
+ {
+ nStrings = nSize;
+ memset( pStringOff, 0, nSize * sizeof( sal_uInt32 ) );
+ memset( pStrings, 0, nStringSize * sizeof( sal_Unicode ) );
+ }
+ else
+ bError = sal_True;
+}
+
+// Hinzufuegen eines Strings an den StringPool. Der String-Puffer
+// waechst dynamisch in 1K-Schritten
+// Add a string to StringPool. The String buffer is dynamically
+// growing in 1K-Steps
+void SbiImage::AddString( const String& r )
+{
+ if( nStringIdx >= nStrings )
+ bError = sal_True;
+ if( !bError )
+ {
+ xub_StrLen len = r.Len() + 1;
+ sal_uInt32 needed = nStringOff + len;
+ if( needed > 0xFFFFFF00L )
+ bError = sal_True; // out of mem!
+ else if( needed > nStringSize )
+ {
+ sal_uInt32 nNewLen = needed + 1024;
+ nNewLen &= 0xFFFFFC00; // trim to 1K border
+ if( nNewLen > 0xFFFFFF00L )
+ nNewLen = 0xFFFFFF00L;
+ sal_Unicode* p = NULL;
+ if( (p = new sal_Unicode[ nNewLen ]) != NULL )
+ {
+ memcpy( p, pStrings, nStringSize * sizeof( sal_Unicode ) );
+ delete[] pStrings;
+ pStrings = p;
+ nStringSize = sal::static_int_cast< sal_uInt16 >(nNewLen);
+ }
+ else
+ bError = sal_True;
+ }
+ if( !bError )
+ {
+ pStringOff[ nStringIdx++ ] = nStringOff;
+ //ByteString aByteStr( r, eCharSet );
+ memcpy( pStrings + nStringOff, r.GetBuffer(), len * sizeof( sal_Unicode ) );
+ nStringOff = nStringOff + len;
+ // Last String? The update the size of the buffer
+ if( nStringIdx >= nStrings )
+ nStringSize = nStringOff;
+ }
+ }
+}
+
+// Add code block
+// The block was fetched by the compiler from class SbBuffer and
+// is already created with new. Additionally it contains all Integers
+// in Big Endian format, so can be directly read/written.
+void SbiImage::AddCode( char* p, sal_uInt32 s )
+{
+ pCode = p;
+ nCodeSize = s;
+}
+
+// Add user type
+void SbiImage::AddType(SbxObject* pObject)
+{
+ if( !rTypes.Is() )
+ rTypes = new SbxArray;
+ SbxObject *pCopyObject = new SbxObject(*pObject);
+ rTypes->Insert (pCopyObject,rTypes->Count());
+}
+
+void SbiImage::AddEnum(SbxObject* pObject) // Register enum type
+{
+ if( !rEnums.Is() )
+ rEnums = new SbxArray;
+ rEnums->Insert( pObject, rEnums->Count() );
+}
+
+
+/**************************************************************************
+*
+* Accessing the image
+*
+**************************************************************************/
+
+// Note: IDs start with 1
+String SbiImage::GetString( short nId ) const
+{
+ if( nId && nId <= nStrings )
+ {
+ sal_uInt32 nOff = pStringOff[ nId - 1 ];
+ sal_Unicode* pStr = pStrings + nOff;
+
+ // #i42467: Special treatment for vbNullChar
+ if( *pStr == 0 )
+ {
+ sal_uInt32 nNextOff = (nId < nStrings) ? pStringOff[ nId ] : nStringOff;
+ sal_uInt32 nLen = nNextOff - nOff - 1;
+ if( nLen == 1 )
+ {
+ // Force length 1 and make char 0 afterwards
+ String aNullCharStr( String::CreateFromAscii( " " ) );
+ aNullCharStr.SetChar( 0, 0 );
+ return aNullCharStr;
+ }
+ }
+ else
+ {
+ String aStr( pStr );
+ return aStr;
+ }
+ }
+ return String();
+}
+
+const SbxObject* SbiImage::FindType (String aTypeName) const
+{
+ return rTypes.Is() ? (SbxObject*)rTypes->Find(aTypeName,SbxCLASS_OBJECT) : NULL;
+}
+
+sal_uInt16 SbiImage::CalcLegacyOffset( sal_Int32 nOffset )
+{
+ return SbiCodeGen::calcLegacyOffSet( (sal_uInt8*)pCode, nOffset ) ;
+}
+
+sal_uInt32 SbiImage::CalcNewOffset( sal_Int16 nOffset )
+{
+ return SbiCodeGen::calcNewOffSet( (sal_uInt8*)pLegacyPCode, nOffset ) ;
+}
+
+void SbiImage::ReleaseLegacyBuffer()
+{
+ delete[] pLegacyPCode;
+ pLegacyPCode = NULL;
+ nLegacyCodeSize = 0;
+}
+
+sal_Bool SbiImage::ExceedsLegacyLimits()
+{
+ if ( ( nStringSize > 0xFF00L ) || ( CalcLegacyOffset( nCodeSize ) > 0xFF00L ) )
+ return sal_True;
+ return sal_False;
+}
diff --git a/basic/source/classes/makefile.mk b/basic/source/classes/makefile.mk
new file mode 100644
index 000000000000..e00ed4674cc1
--- /dev/null
+++ b/basic/source/classes/makefile.mk
@@ -0,0 +1,76 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=basic
+TARGET=classes
+LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+
+.INCLUDE : settings.mk
+
+ALLTAR .SEQUENTIAL : \
+ $(MISC)$/$(TARGET).don \
+ $(MISC)$/$(TARGET).slo
+
+$(MISC)$/$(TARGET).don : $(SOLARBINDIR)$/oovbaapi.rdb
+ +$(CPPUMAKER) -O$(OUT)$/inc -BUCR $(SOLARBINDIR)$/oovbaapi.rdb -X$(SOLARBINDIR)$/types.rdb && echo > $@
+ echo $@
+
+$(MISC)$/$(TARGET).slo : $(SLOTARGET)
+ echo $@
+
+# --- Allgemein -----------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/sb.obj \
+ $(SLO)$/sbxmod.obj \
+ $(SLO)$/image.obj \
+ $(SLO)$/sbintern.obj \
+ $(SLO)$/sbunoobj.obj \
+ $(SLO)$/propacc.obj \
+ $(SLO)$/disas.obj \
+ $(SLO)$/errobject.obj \
+ $(SLO)$/eventatt.obj
+
+OBJFILES= \
+ $(OBJ)$/sbintern.obj
+
+SRS1NAME=$(TARGET)
+SRC1FILES= sb.src
+
+LIB1TARGET= $(SLB)$/$(TARGET).lib
+LIB1OBJFILES = $(SLOFILES)
+
+# --- Targets -------------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/basic/source/classes/propacc.cxx b/basic/source/classes/propacc.cxx
new file mode 100644
index 000000000000..9168ef915770
--- /dev/null
+++ b/basic/source/classes/propacc.cxx
@@ -0,0 +1,430 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_basic.hxx"
+
+#include "propacc.hxx"
+
+#include <tools/urlobj.hxx>
+#include <tools/errcode.hxx>
+#include <svl/svarray.hxx>
+#include <basic/sbstar.hxx>
+#include <sbunoobj.hxx>
+
+using com::sun::star::uno::Reference;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace cppu;
+
+
+//========================================================================
+
+// Declaration conversion from Sbx to UNO with known target type
+Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty = NULL );
+
+//========================================================================
+
+#ifdef WNT
+#define CDECL _cdecl
+#endif
+#if defined(UNX) || defined(OS2)
+#define CDECL
+#endif
+
+int CDECL SbCompare_PropertyValues_Impl( const void *arg1, const void *arg2 )
+{
+ return ((PropertyValue*)arg1)->Name.compareTo( ((PropertyValue*)arg2)->Name );
+}
+
+extern "C" int CDECL SbCompare_UString_PropertyValue_Impl( const void *arg1, const void *arg2 )
+{
+ const ::rtl::OUString *pArg1 = (::rtl::OUString*) arg1;
+ const PropertyValue **pArg2 = (const PropertyValue**) arg2;
+ return pArg1->compareTo( (*pArg2)->Name );
+}
+
+int CDECL SbCompare_Properties_Impl( const void *arg1, const void *arg2 )
+{
+ return ((Property*)arg1)->Name.compareTo( ((Property*)arg2)->Name );
+}
+
+extern "C" int CDECL SbCompare_UString_Property_Impl( const void *arg1, const void *arg2 )
+{
+ const ::rtl::OUString *pArg1 = (::rtl::OUString*) arg1;
+ const Property *pArg2 = (Property*) arg2;
+ return pArg1->compareTo( pArg2->Name );
+}
+
+//----------------------------------------------------------------------------
+
+SbPropertyValues::SbPropertyValues()
+{
+}
+
+//----------------------------------------------------------------------------
+
+SbPropertyValues::~SbPropertyValues()
+{
+ _xInfo = Reference< XPropertySetInfo >();
+
+ for ( sal_uInt16 n = 0; n < _aPropVals.Count(); ++n )
+ delete _aPropVals.GetObject( n );
+}
+
+//----------------------------------------------------------------------------
+
+Reference< XPropertySetInfo > SbPropertyValues::getPropertySetInfo(void) throw( RuntimeException )
+{
+ // create on demand?
+ if ( !_xInfo.is() )
+ {
+ SbPropertySetInfo *pInfo = new SbPropertySetInfo( _aPropVals );
+ ((SbPropertyValues*)this)->_xInfo = (XPropertySetInfo*)pInfo;
+ }
+ return _xInfo;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Int32 SbPropertyValues::GetIndex_Impl( const ::rtl::OUString &rPropName ) const
+{
+ PropertyValue **ppPV;
+ ppPV = (PropertyValue **)
+ bsearch( &rPropName, _aPropVals.GetData(), _aPropVals.Count(),
+ sizeof( PropertyValue* ),
+ SbCompare_UString_PropertyValue_Impl );
+ return ppPV ? ( (ppPV-_aPropVals.GetData()) / sizeof(ppPV) ) : USHRT_MAX;
+}
+
+//----------------------------------------------------------------------------
+
+void SbPropertyValues::setPropertyValue(
+ const ::rtl::OUString& aPropertyName,
+ const Any& aValue)
+ throw (::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::beans::PropertyVetoException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ sal_Int32 nIndex = GetIndex_Impl( aPropertyName );
+ PropertyValue *pPropVal = _aPropVals.GetObject(
+ sal::static_int_cast< sal_uInt16 >(nIndex));
+ pPropVal->Value = aValue;
+}
+
+//----------------------------------------------------------------------------
+
+Any SbPropertyValues::getPropertyValue(
+ const ::rtl::OUString& aPropertyName)
+ throw(::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ sal_Int32 nIndex = GetIndex_Impl( aPropertyName );
+ if ( nIndex != USHRT_MAX )
+ return _aPropVals.GetObject(
+ sal::static_int_cast< sal_uInt16 >(nIndex))->Value;
+ return Any();
+}
+
+//----------------------------------------------------------------------------
+
+void SbPropertyValues::addPropertyChangeListener(
+ const ::rtl::OUString& aPropertyName,
+ const Reference< XPropertyChangeListener >& )
+ throw ()
+{
+ (void)aPropertyName;
+}
+
+//----------------------------------------------------------------------------
+
+void SbPropertyValues::removePropertyChangeListener(
+ const ::rtl::OUString& aPropertyName,
+ const Reference< XPropertyChangeListener >& )
+ throw ()
+{
+ (void)aPropertyName;
+}
+
+//----------------------------------------------------------------------------
+
+void SbPropertyValues::addVetoableChangeListener(
+ const ::rtl::OUString& aPropertyName,
+ const Reference< XVetoableChangeListener >& )
+ throw()
+{
+ (void)aPropertyName;
+}
+
+//----------------------------------------------------------------------------
+
+void SbPropertyValues::removeVetoableChangeListener(
+ const ::rtl::OUString& aPropertyName,
+ const Reference< XVetoableChangeListener >& )
+ throw()
+{
+ (void)aPropertyName;
+}
+
+//----------------------------------------------------------------------------
+
+Sequence< PropertyValue > SbPropertyValues::getPropertyValues(void) throw (::com::sun::star::uno::RuntimeException)
+{
+ Sequence<PropertyValue> aRet( _aPropVals.Count());
+ for ( sal_uInt16 n = 0; n < _aPropVals.Count(); ++n )
+ aRet.getArray()[n] = *_aPropVals.GetObject(n);
+ return aRet;
+}
+
+//----------------------------------------------------------------------------
+
+void SbPropertyValues::setPropertyValues(const Sequence< PropertyValue >& rPropertyValues )
+ throw (::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::beans::PropertyVetoException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ if ( _aPropVals.Count() )
+ throw PropertyExistException();
+
+ const PropertyValue *pPropVals = rPropertyValues.getConstArray();
+ for ( sal_Int16 n = 0; n < rPropertyValues.getLength(); ++n )
+ {
+ PropertyValue *pPropVal = new PropertyValue(pPropVals[n]);
+ _aPropVals.Insert( pPropVal, n );
+ }
+}
+
+//============================================================================
+//PropertySetInfoImpl
+
+PropertySetInfoImpl::PropertySetInfoImpl()
+{
+}
+
+sal_Int32 PropertySetInfoImpl::GetIndex_Impl( const ::rtl::OUString &rPropName ) const
+{
+ Property *pP;
+ pP = (Property*)
+ bsearch( &rPropName, _aProps.getConstArray(), _aProps.getLength(),
+ sizeof( Property ),
+ SbCompare_UString_Property_Impl );
+ return pP ? sal::static_int_cast<sal_Int32>( (pP-_aProps.getConstArray()) / sizeof(pP) ) : -1;
+}
+
+Sequence< Property > PropertySetInfoImpl::getProperties(void) throw()
+{
+ return _aProps;
+}
+
+Property PropertySetInfoImpl::getPropertyByName(const ::rtl::OUString& Name) throw( RuntimeException )
+{
+ sal_Int32 nIndex = GetIndex_Impl( Name );
+ if( USHRT_MAX != nIndex )
+ return _aProps.getConstArray()[ nIndex ];
+ return Property();
+}
+
+sal_Bool PropertySetInfoImpl::hasPropertyByName(const ::rtl::OUString& Name) throw( RuntimeException )
+{
+ sal_Int32 nIndex = GetIndex_Impl( Name );
+ return USHRT_MAX != nIndex;
+}
+
+
+//============================================================================
+
+SbPropertySetInfo::SbPropertySetInfo()
+{
+}
+
+//----------------------------------------------------------------------------
+
+SbPropertySetInfo::SbPropertySetInfo( const SbPropertyValueArr_Impl &rPropVals )
+{
+ aImpl._aProps.realloc( rPropVals.Count() );
+ for ( sal_uInt16 n = 0; n < rPropVals.Count(); ++n )
+ {
+ Property &rProp = aImpl._aProps.getArray()[n];
+ const PropertyValue &rPropVal = *rPropVals.GetObject(n);
+ rProp.Name = rPropVal.Name;
+ rProp.Handle = rPropVal.Handle;
+ rProp.Type = getCppuVoidType();
+ rProp.Attributes = 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+
+SbPropertySetInfo::~SbPropertySetInfo()
+{
+}
+
+//-------------------------------------------------------------------------
+
+Sequence< Property > SbPropertySetInfo::getProperties(void) throw( RuntimeException )
+{
+ return aImpl.getProperties();
+}
+
+Property SbPropertySetInfo::getPropertyByName(const ::rtl::OUString& Name)
+ throw( RuntimeException )
+{
+ return aImpl.getPropertyByName( Name );
+}
+
+sal_Bool SbPropertySetInfo::hasPropertyByName(const ::rtl::OUString& Name)
+ throw( RuntimeException )
+{
+ return aImpl.hasPropertyByName( Name );
+}
+
+
+//----------------------------------------------------------------------------
+
+SbPropertyContainer::SbPropertyContainer()
+{
+}
+
+//----------------------------------------------------------------------------
+
+SbPropertyContainer::~SbPropertyContainer()
+{
+}
+
+//----------------------------------------------------------------------------
+void SbPropertyContainer::addProperty(const ::rtl::OUString& Name,
+ sal_Int16 Attributes,
+ const Any& DefaultValue)
+ throw( PropertyExistException, IllegalTypeException,
+ IllegalArgumentException, RuntimeException )
+{
+ (void)Name;
+ (void)Attributes;
+ (void)DefaultValue;
+}
+
+//----------------------------------------------------------------------------
+void SbPropertyContainer::removeProperty(const ::rtl::OUString& Name)
+ throw( UnknownPropertyException, RuntimeException )
+{
+ (void)Name;
+}
+
+//----------------------------------------------------------------------------
+// XPropertySetInfo
+Sequence< Property > SbPropertyContainer::getProperties(void) throw ()
+{
+ return aImpl.getProperties();
+}
+
+Property SbPropertyContainer::getPropertyByName(const ::rtl::OUString& Name)
+ throw( RuntimeException )
+{
+ return aImpl.getPropertyByName( Name );
+}
+
+sal_Bool SbPropertyContainer::hasPropertyByName(const ::rtl::OUString& Name)
+ throw( RuntimeException )
+{
+ return aImpl.hasPropertyByName( Name );
+}
+
+//----------------------------------------------------------------------------
+
+Sequence< PropertyValue > SbPropertyContainer::getPropertyValues(void)
+{
+ return Sequence<PropertyValue>();
+}
+
+//----------------------------------------------------------------------------
+
+void SbPropertyContainer::setPropertyValues(const Sequence< PropertyValue >& PropertyValues_)
+{
+ (void)PropertyValues_;
+}
+
+//----------------------------------------------------------------------------
+
+void RTL_Impl_CreatePropertySet( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // We need at least one parameter
+ // TODO: In this case < 2 is not correct ;-)
+ if ( rPar.Count() < 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Get class names of struct
+ String aServiceName( RTL_CONSTASCII_USTRINGPARAM("stardiv.uno.beans.PropertySet") );
+
+#if 0
+ // Service suchen und instanzieren
+ Reference< XMultiServiceFactory > xServiceManager = getProcessServiceFactory();
+ Reference< XInterface > xInterface;
+ if( xProv.is() )
+ xInterface = xProv->newInstance();
+#else
+ Reference< XInterface > xInterface = (OWeakObject*) new SbPropertyValues();
+#endif
+
+ SbxVariableRef refVar = rPar.Get(0);
+ if( xInterface.is() )
+ {
+ // Set PropertyValues
+ Any aArgAsAny = sbxToUnoValue( rPar.Get(1),
+ getCppuType( (Sequence<PropertyValue>*)0 ) );
+ Sequence<PropertyValue> *pArg =
+ (Sequence<PropertyValue>*) aArgAsAny.getValue();
+ Reference< XPropertyAccess > xPropAcc = Reference< XPropertyAccess >::query( xInterface );
+ xPropAcc->setPropertyValues( *pArg );
+
+ // Build a SbUnoObject and return it
+ Any aAny;
+ aAny <<= xInterface;
+ SbUnoObjectRef xUnoObj = new SbUnoObject( aServiceName, aAny );
+ if( xUnoObj->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID )
+ {
+ // Return object
+ refVar->PutObject( (SbUnoObject*)xUnoObj );
+ return;
+ }
+ }
+
+ // Object could not be created
+ refVar->PutObject( NULL );
+}
+
diff --git a/basic/source/classes/sb.cxx b/basic/source/classes/sb.cxx
new file mode 100644
index 000000000000..e2f53dd8ed8e
--- /dev/null
+++ b/basic/source/classes/sb.cxx
@@ -0,0 +1,2135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_basic.hxx"
+
+#include <stdio.h>
+
+#include "sb.hxx"
+#include <tools/rcid.h>
+#include <tools/config.hxx>
+#include <tools/stream.hxx>
+#ifndef __RSC //autogen
+#include <tools/errinf.hxx>
+#endif
+#include <basic/sbx.hxx>
+#include <tools/list.hxx>
+#include <tools/shl.hxx>
+#include <tools/rc.hxx>
+#include <vcl/svapp.hxx>
+#include "sbunoobj.hxx"
+#include "sbjsmeth.hxx"
+#include "sbjsmod.hxx"
+#include "sbintern.hxx"
+#include "disas.hxx"
+#include "runtime.hxx"
+#include <basic/sbuno.hxx>
+#include <basic/sbobjmod.hxx>
+#include "stdobj.hxx"
+#include "filefmt.hxx"
+#include "sb.hrc"
+#include <basrid.hxx>
+#include <vos/mutex.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include "errobject.hxx"
+#include <hash_map>
+
+#include <com/sun/star/script/ModuleType.hpp>
+#include <com/sun/star/script/ModuleInfo.hpp>
+using namespace ::com::sun::star::script;
+
+// #pragma SW_SEGMENT_CLASS( SBASIC, SBASIC_CODE )
+
+SV_IMPL_VARARR(SbTextPortions,SbTextPortion)
+
+TYPEINIT1(StarBASIC,SbxObject)
+
+#define RTLNAME "@SBRTL"
+// i#i68894#
+using namespace ::com::sun::star;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::UNO_QUERY;
+using com::sun::star::lang::XMultiServiceFactory;
+
+const static String aThisComponent( RTL_CONSTASCII_USTRINGPARAM("ThisComponent") );
+const static String aVBAHook( RTL_CONSTASCII_USTRINGPARAM( "VBAGlobals" ) );
+
+SbxObject* StarBASIC::getVBAGlobals( )
+{
+ if ( !pVBAGlobals )
+ {
+ Any aThisDoc;
+ if ( GetUNOConstant("ThisComponent", aThisDoc) )
+ {
+ Reference< XMultiServiceFactory > xDocFac( aThisDoc, UNO_QUERY );
+ if ( xDocFac.is() )
+ {
+ try
+ {
+ xDocFac->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals" ) ) );
+ }
+ catch( Exception& )
+ {
+ // Ignore
+ }
+ }
+ }
+ pVBAGlobals = (SbUnoObject*)Find( aVBAHook , SbxCLASS_DONTCARE );
+ }
+ return pVBAGlobals;
+}
+
+// i#i68894#
+SbxVariable* StarBASIC::VBAFind( const String& rName, SbxClassType t )
+{
+ if( rName == aThisComponent )
+ return NULL;
+ // rename to init globals
+ if ( getVBAGlobals( ) )
+ return pVBAGlobals->Find( rName, t );
+ return NULL;
+
+}
+// Create array for conversion SFX <-> VB error code
+struct SFX_VB_ErrorItem
+{
+ sal_uInt16 nErrorVB;
+ SbError nErrorSFX;
+};
+
+const SFX_VB_ErrorItem __FAR_DATA SFX_VB_ErrorTab[] =
+{
+ { 1, SbERR_BASIC_EXCEPTION }, // #87844 Map exception to error code 1
+ { 2, SbERR_SYNTAX },
+ { 3, SbERR_NO_GOSUB },
+ { 4, SbERR_REDO_FROM_START },
+ { 5, SbERR_BAD_ARGUMENT },
+ { 6, SbERR_MATH_OVERFLOW },
+ { 7, SbERR_NO_MEMORY },
+ { 8, SbERR_ALREADY_DIM },
+ { 9, SbERR_OUT_OF_RANGE },
+ { 10, SbERR_DUPLICATE_DEF },
+ { 11, SbERR_ZERODIV },
+ { 12, SbERR_VAR_UNDEFINED },
+ { 13, SbERR_CONVERSION },
+ { 14, SbERR_BAD_PARAMETER },
+ { 18, SbERR_USER_ABORT },
+ { 20, SbERR_BAD_RESUME },
+ { 28, SbERR_STACK_OVERFLOW },
+ { 35, SbERR_PROC_UNDEFINED },
+ { 48, SbERR_BAD_DLL_LOAD },
+ { 49, SbERR_BAD_DLL_CALL },
+ { 51, SbERR_INTERNAL_ERROR },
+ { 52, SbERR_BAD_CHANNEL },
+ { 53, SbERR_FILE_NOT_FOUND },
+ { 54, SbERR_BAD_FILE_MODE },
+ { 55, SbERR_FILE_ALREADY_OPEN },
+ { 57, SbERR_IO_ERROR },
+ { 58, SbERR_FILE_EXISTS },
+ { 59, SbERR_BAD_RECORD_LENGTH },
+ { 61, SbERR_DISK_FULL },
+ { 62, SbERR_READ_PAST_EOF },
+ { 63, SbERR_BAD_RECORD_NUMBER },
+ { 67, SbERR_TOO_MANY_FILES },
+ { 68, SbERR_NO_DEVICE },
+ { 70, SbERR_ACCESS_DENIED },
+ { 71, SbERR_NOT_READY },
+ { 73, SbERR_NOT_IMPLEMENTED },
+ { 74, SbERR_DIFFERENT_DRIVE },
+ { 75, SbERR_ACCESS_ERROR },
+ { 76, SbERR_PATH_NOT_FOUND },
+ { 91, SbERR_NO_OBJECT },
+ { 93, SbERR_BAD_PATTERN },
+ { 94, SBERR_IS_NULL },
+ { 250, SbERR_DDE_ERROR },
+ { 280, SbERR_DDE_WAITINGACK },
+ { 281, SbERR_DDE_OUTOFCHANNELS },
+ { 282, SbERR_DDE_NO_RESPONSE },
+ { 283, SbERR_DDE_MULT_RESPONSES },
+ { 284, SbERR_DDE_CHANNEL_LOCKED },
+ { 285, SbERR_DDE_NOTPROCESSED },
+ { 286, SbERR_DDE_TIMEOUT },
+ { 287, SbERR_DDE_USER_INTERRUPT },
+ { 288, SbERR_DDE_BUSY },
+ { 289, SbERR_DDE_NO_DATA },
+ { 290, SbERR_DDE_WRONG_DATA_FORMAT },
+ { 291, SbERR_DDE_PARTNER_QUIT },
+ { 292, SbERR_DDE_CONV_CLOSED },
+ { 293, SbERR_DDE_NO_CHANNEL },
+ { 294, SbERR_DDE_INVALID_LINK },
+ { 295, SbERR_DDE_QUEUE_OVERFLOW },
+ { 296, SbERR_DDE_LINK_ALREADY_EST },
+ { 297, SbERR_DDE_LINK_INV_TOPIC },
+ { 298, SbERR_DDE_DLL_NOT_FOUND },
+ { 323, SbERR_CANNOT_LOAD },
+ { 341, SbERR_BAD_INDEX },
+ { 366, SbERR_NO_ACTIVE_OBJECT },
+ { 380, SbERR_BAD_PROP_VALUE },
+ { 382, SbERR_PROP_READONLY },
+ { 394, SbERR_PROP_WRITEONLY },
+ { 420, SbERR_INVALID_OBJECT },
+ { 423, SbERR_NO_METHOD },
+ { 424, SbERR_NEEDS_OBJECT },
+ { 425, SbERR_INVALID_USAGE_OBJECT },
+ { 430, SbERR_NO_OLE },
+ { 438, SbERR_BAD_METHOD },
+ { 440, SbERR_OLE_ERROR },
+ { 445, SbERR_BAD_ACTION },
+ { 446, SbERR_NO_NAMED_ARGS },
+ { 447, SbERR_BAD_LOCALE },
+ { 448, SbERR_NAMED_NOT_FOUND },
+ { 449, SbERR_NOT_OPTIONAL },
+ { 450, SbERR_WRONG_ARGS },
+ { 451, SbERR_NOT_A_COLL },
+ { 452, SbERR_BAD_ORDINAL },
+ { 453, SbERR_DLLPROC_NOT_FOUND },
+ { 460, SbERR_BAD_CLIPBD_FORMAT },
+ { 951, SbERR_UNEXPECTED },
+ { 952, SbERR_EXPECTED },
+ { 953, SbERR_SYMBOL_EXPECTED },
+ { 954, SbERR_VAR_EXPECTED },
+ { 955, SbERR_LABEL_EXPECTED },
+ { 956, SbERR_LVALUE_EXPECTED },
+ { 957, SbERR_VAR_DEFINED },
+ { 958, SbERR_PROC_DEFINED },
+ { 959, SbERR_LABEL_DEFINED },
+ { 960, SbERR_UNDEF_VAR },
+ { 961, SbERR_UNDEF_ARRAY },
+ { 962, SbERR_UNDEF_PROC },
+ { 963, SbERR_UNDEF_LABEL },
+ { 964, SbERR_UNDEF_TYPE },
+ { 965, SbERR_BAD_EXIT },
+ { 966, SbERR_BAD_BLOCK },
+ { 967, SbERR_BAD_BRACKETS },
+ { 968, SbERR_BAD_DECLARATION },
+ { 969, SbERR_BAD_PARAMETERS },
+ { 970, SbERR_BAD_CHAR_IN_NUMBER },
+ { 971, SbERR_MUST_HAVE_DIMS },
+ { 972, SbERR_NO_IF },
+ { 973, SbERR_NOT_IN_SUBR },
+ { 974, SbERR_NOT_IN_MAIN },
+ { 975, SbERR_WRONG_DIMS },
+ { 976, SbERR_BAD_OPTION },
+ { 977, SbERR_CONSTANT_REDECLARED },
+ { 978, SbERR_PROG_TOO_LARGE },
+ { 979, SbERR_NO_STRINGS_ARRAYS },
+ { 1000, SbERR_PROPERTY_NOT_FOUND },
+ { 1001, SbERR_METHOD_NOT_FOUND },
+ { 1002, SbERR_ARG_MISSING },
+ { 1003, SbERR_BAD_NUMBER_OF_ARGS },
+ { 1004, SbERR_METHOD_FAILED },
+ { 1005, SbERR_SETPROP_FAILED },
+ { 1006, SbERR_GETPROP_FAILED },
+ { 1007, SbERR_BASIC_COMPAT },
+ { 0xFFFF, 0xFFFFFFFFL } // End mark
+};
+
+// The StarBASIC factory is a hack. When a SbModule is created, its pointer
+// is saved and given to the following SbProperties/SbMethods. This restores
+// the Modul-relationshop. But it works only when a modul is loaded.
+// Can cause troubles with separately loaded properties!
+
+SbxBase* SbiFactory::Create( sal_uInt16 nSbxId, sal_uInt32 nCreator )
+{
+ if( nCreator == SBXCR_SBX )
+ {
+ String aEmpty;
+ switch( nSbxId )
+ {
+ case SBXID_BASIC:
+ return new StarBASIC( NULL );
+ case SBXID_BASICMOD:
+ return new SbModule( aEmpty );
+ case SBXID_BASICPROP:
+ return new SbProperty( aEmpty, SbxVARIANT, NULL );
+ case SBXID_BASICMETHOD:
+ return new SbMethod( aEmpty, SbxVARIANT, NULL );
+ case SBXID_JSCRIPTMOD:
+ return new SbJScriptModule( aEmpty );
+ case SBXID_JSCRIPTMETH:
+ return new SbJScriptMethod( aEmpty, SbxVARIANT, NULL );
+ }
+ }
+ return NULL;
+}
+
+SbxObject* SbiFactory::CreateObject( const String& rClass )
+{
+ if( rClass.EqualsIgnoreCaseAscii( "StarBASIC" ) )
+ return new StarBASIC( NULL );
+ else
+ if( rClass.EqualsIgnoreCaseAscii( "StarBASICModule" ) )
+ {
+ String aEmpty;
+ return new SbModule( aEmpty );
+ }
+ else
+ if( rClass.EqualsIgnoreCaseAscii( "Collection" ) )
+ {
+ String aCollectionName( RTL_CONSTASCII_USTRINGPARAM("Collection") );
+ return new BasicCollection( aCollectionName );
+ }
+ else
+ return NULL;
+}
+
+
+// Factory class to create OLE objects
+class SbOLEFactory : public SbxFactory
+{
+public:
+ virtual SbxBase* Create( sal_uInt16 nSbxId, sal_uInt32 = SBXCR_SBX );
+ virtual SbxObject* CreateObject( const String& );
+};
+
+SbxBase* SbOLEFactory::Create( sal_uInt16, sal_uInt32 )
+{
+ // Not supported
+ return NULL;
+}
+
+SbUnoObject* createOLEObject_Impl( const String& aType ); // sbunoobj.cxx
+
+SbxObject* SbOLEFactory::CreateObject( const String& rClassName )
+{
+ SbxObject* pRet = createOLEObject_Impl( rClassName );
+ return pRet;
+}
+
+
+//========================================================================
+// SbFormFactory, show user forms by: dim as new <user form name>
+
+class SbFormFactory : public SbxFactory
+{
+public:
+ virtual SbxBase* Create( sal_uInt16 nSbxId, sal_uInt32 = SBXCR_SBX );
+ virtual SbxObject* CreateObject( const String& );
+};
+
+SbxBase* SbFormFactory::Create( sal_uInt16, sal_uInt32 )
+{
+ // Not supported
+ return NULL;
+}
+
+SbxObject* SbFormFactory::CreateObject( const String& rClassName )
+{
+ if( SbModule* pMod = pMOD )
+ {
+ if( SbxVariable* pVar = pMod->Find( rClassName, SbxCLASS_OBJECT ) )
+ {
+ if( SbUserFormModule* pFormModule = PTR_CAST( SbUserFormModule, pVar->GetObject() ) )
+ {
+ bool bInitState = pFormModule->getInitState();
+ if( bInitState )
+ {
+ // Not the first instantiate, reset
+ bool bTriggerTerminateEvent = false;
+ pFormModule->ResetApiObj( bTriggerTerminateEvent );
+ pFormModule->setInitState( false );
+ }
+ else
+ {
+ pFormModule->Load();
+ }
+ return pFormModule->CreateInstance();
+ }
+ }
+ }
+ return 0;
+}
+
+
+//========================================================================
+// SbTypeFactory
+
+SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj )
+{
+ SbxObject* pRet = new SbxObject( rTypeObj );
+ pRet->PutObject( pRet );
+
+ // Copy the properties, not only the reference to them
+ SbxArray* pProps = pRet->GetProperties();
+ sal_uInt32 nCount = pProps->Count32();
+ for( sal_uInt32 i = 0 ; i < nCount ; i++ )
+ {
+ SbxVariable* pVar = pProps->Get32( i );
+ SbxProperty* pProp = PTR_CAST( SbxProperty, pVar );
+ if( pProp )
+ {
+ SbxProperty* pNewProp = new SbxProperty( *pProp );
+ SbxDataType eVarType = pVar->GetType();
+ if( eVarType & SbxARRAY )
+ {
+ SbxBase* pParObj = pVar->GetObject();
+ SbxDimArray* pSource = PTR_CAST(SbxDimArray,pParObj);
+ SbxDimArray* pDest = new SbxDimArray( pVar->GetType() );
+ sal_Int32 lb = 0;
+ sal_Int32 ub = 0;
+
+ pDest->setHasFixedSize( pSource->hasFixedSize() );
+ if ( pSource->GetDims() && pSource->hasFixedSize() )
+ {
+ for ( sal_Int32 j = 1 ; j <= pSource->GetDims(); ++j )
+ {
+ pSource->GetDim32( (sal_Int32)j, lb, ub );
+ pDest->AddDim32( lb, ub );
+ }
+ }
+ else
+ pDest->unoAddDim( 0, -1 ); // variant array
+
+ sal_uInt16 nSavFlags = pVar->GetFlags();
+ pNewProp->ResetFlag( SBX_FIXED );
+ // need to reset the FIXED flag
+ // when calling PutObject ( because the type will not match Object )
+ pNewProp->PutObject( pDest );
+ pNewProp->SetFlags( nSavFlags );
+ }
+ if( eVarType == SbxOBJECT )
+ {
+ SbxBase* pObjBase = pVar->GetObject();
+ SbxObject* pSrcObj = PTR_CAST(SbxObject,pObjBase);
+ SbxObject* pDestObj = NULL;
+ if( pSrcObj != NULL )
+ pDestObj = cloneTypeObjectImpl( *pSrcObj );
+ pNewProp->PutObject( pDestObj );
+ }
+ pProps->PutDirect( pNewProp, i );
+ }
+ }
+ return pRet;
+}
+
+// Factory class to create user defined objects (type command)
+class SbTypeFactory : public SbxFactory
+{
+public:
+ virtual SbxBase* Create( sal_uInt16 nSbxId, sal_uInt32 = SBXCR_SBX );
+ virtual SbxObject* CreateObject( const String& );
+};
+
+SbxBase* SbTypeFactory::Create( sal_uInt16, sal_uInt32 )
+{
+ // Not supported
+ return NULL;
+}
+
+SbxObject* SbTypeFactory::CreateObject( const String& rClassName )
+{
+ SbxObject* pRet = NULL;
+ SbModule* pMod = pMOD;
+ if( pMod )
+ {
+ const SbxObject* pObj = pMod->FindType( rClassName );
+ if( pObj )
+ pRet = cloneTypeObjectImpl( *pObj );
+ }
+ return pRet;
+}
+
+SbxObject* createUserTypeImpl( const String& rClassName )
+{
+ SbxObject* pRetObj = pTYPEFAC->CreateObject( rClassName );
+ return pRetObj;
+}
+
+TYPEINIT1(SbClassModuleObject,SbModule)
+
+SbClassModuleObject::SbClassModuleObject( SbModule* pClassModule )
+ : SbModule( pClassModule->GetName() )
+ , mpClassModule( pClassModule )
+ , mbInitializeEventDone( false )
+{
+ aOUSource = pClassModule->aOUSource;
+ aComment = pClassModule->aComment;
+ pImage = pClassModule->pImage;
+ pBreaks = pClassModule->pBreaks;
+
+ SetClassName( pClassModule->GetName() );
+
+ // Allow search only internally
+ ResetFlag( SBX_GBLSEARCH );
+
+ // Copy the methods from original class module
+ SbxArray* pClassMethods = pClassModule->GetMethods();
+ sal_uInt32 nMethodCount = pClassMethods->Count32();
+ sal_uInt32 i;
+ for( i = 0 ; i < nMethodCount ; i++ )
+ {
+ SbxVariable* pVar = pClassMethods->Get32( i );
+
+ // Exclude SbIfaceMapperMethod to copy them in a second step
+ SbIfaceMapperMethod* pIfaceMethod = PTR_CAST( SbIfaceMapperMethod, pVar );
+ if( !pIfaceMethod )
+ {
+ SbMethod* pMethod = PTR_CAST(SbMethod, pVar );
+ if( pMethod )
+ {
+ sal_uInt16 nFlags_ = pMethod->GetFlags();
+ pMethod->SetFlag( SBX_NO_BROADCAST );
+ SbMethod* pNewMethod = new SbMethod( *pMethod );
+ pNewMethod->ResetFlag( SBX_NO_BROADCAST );
+ pMethod->SetFlags( nFlags_ );
+ pNewMethod->pMod = this;
+ pNewMethod->SetParent( this );
+ pMethods->PutDirect( pNewMethod, i );
+ StartListening( pNewMethod->GetBroadcaster(), sal_True );
+ }
+ }
+ }
+
+ // Copy SbIfaceMapperMethod in a second step to ensure that
+ // the corresponding base methods have already been copied
+ for( i = 0 ; i < nMethodCount ; i++ )
+ {
+ SbxVariable* pVar = pClassMethods->Get32( i );
+
+ SbIfaceMapperMethod* pIfaceMethod = PTR_CAST( SbIfaceMapperMethod, pVar );
+ if( pIfaceMethod )
+ {
+ SbMethod* pImplMethod = pIfaceMethod->getImplMethod();
+ if( !pImplMethod )
+ {
+ DBG_ERROR( "No ImplMethod" );
+ continue;
+ }
+
+ // Search for own copy of ImplMethod
+ String aImplMethodName = pImplMethod->GetName();
+ SbxVariable* p = pMethods->Find( aImplMethodName, SbxCLASS_METHOD );
+ SbMethod* pImplMethodCopy = p ? PTR_CAST(SbMethod,p) : NULL;
+ if( !pImplMethodCopy )
+ {
+ DBG_ERROR( "Found no ImplMethod copy" );
+ continue;
+ }
+ SbIfaceMapperMethod* pNewIfaceMethod =
+ new SbIfaceMapperMethod( pIfaceMethod->GetName(), pImplMethodCopy );
+ pMethods->PutDirect( pNewIfaceMethod, i );
+ }
+ }
+
+ // Copy the properties from original class module
+ SbxArray* pClassProps = pClassModule->GetProperties();
+ sal_uInt32 nPropertyCount = pClassProps->Count32();
+ for( i = 0 ; i < nPropertyCount ; i++ )
+ {
+ SbxVariable* pVar = pClassProps->Get32( i );
+ SbProcedureProperty* pProcedureProp = PTR_CAST( SbProcedureProperty, pVar );
+ if( pProcedureProp )
+ {
+ sal_uInt16 nFlags_ = pProcedureProp->GetFlags();
+ pProcedureProp->SetFlag( SBX_NO_BROADCAST );
+ SbProcedureProperty* pNewProp = new SbProcedureProperty
+ ( pProcedureProp->GetName(), pProcedureProp->GetType() );
+ // ( pProcedureProp->GetName(), pProcedureProp->GetType(), this );
+ pNewProp->SetFlags( nFlags_ ); // Copy flags
+ pNewProp->ResetFlag( SBX_NO_BROADCAST ); // except the Broadcast if it was set
+ pProcedureProp->SetFlags( nFlags_ );
+ pProps->PutDirect( pNewProp, i );
+ StartListening( pNewProp->GetBroadcaster(), sal_True );
+ }
+ else
+ {
+ SbxProperty* pProp = PTR_CAST( SbxProperty, pVar );
+ if( pProp )
+ {
+ sal_uInt16 nFlags_ = pProp->GetFlags();
+ pProp->SetFlag( SBX_NO_BROADCAST );
+ SbxProperty* pNewProp = new SbxProperty( *pProp );
+
+ // Special handling for modules instances and collections, they need
+ // to be instantiated, otherwise all refer to the same base object
+ SbxDataType eVarType = pProp->GetType();
+ if( eVarType == SbxOBJECT )
+ {
+ SbxBase* pObjBase = pProp->GetObject();
+ SbxObject* pObj = PTR_CAST(SbxObject,pObjBase);
+ if( pObj != NULL )
+ {
+ String aObjClass = pObj->GetClassName();
+
+ SbClassModuleObject* pClassModuleObj = PTR_CAST(SbClassModuleObject,pObjBase);
+ if( pClassModuleObj != NULL )
+ {
+ SbModule* pLclClassModule = pClassModuleObj->getClassModule();
+ SbClassModuleObject* pNewObj = new SbClassModuleObject( pLclClassModule );
+ pNewObj->SetName( pProp->GetName() );
+ pNewObj->SetParent( pLclClassModule->pParent );
+ pNewProp->PutObject( pNewObj );
+ }
+ else if( aObjClass.EqualsIgnoreCaseAscii( "Collection" ) )
+ {
+ String aCollectionName( RTL_CONSTASCII_USTRINGPARAM("Collection") );
+ BasicCollection* pNewCollection = new BasicCollection( aCollectionName );
+ pNewCollection->SetName( pProp->GetName() );
+ pNewCollection->SetParent( pClassModule->pParent );
+ pNewProp->PutObject( pNewCollection );
+ }
+ }
+ }
+
+ pNewProp->ResetFlag( SBX_NO_BROADCAST );
+ pNewProp->SetParent( this );
+ pProps->PutDirect( pNewProp, i );
+ pProp->SetFlags( nFlags_ );
+ }
+ }
+ }
+ SetModuleType( ModuleType::CLASS );
+ mbVBACompat = pClassModule->mbVBACompat;
+}
+
+SbClassModuleObject::~SbClassModuleObject()
+{
+ if( StarBASIC::IsRunning() )
+ triggerTerminateEvent();
+
+ // Must be deleted by base class dtor because this data
+ // is not owned by the SbClassModuleObject object
+ pImage = NULL;
+ pBreaks = NULL;
+}
+
+void SbClassModuleObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType )
+{
+ handleProcedureProperties( rBC, rHint );
+}
+
+SbxVariable* SbClassModuleObject::Find( const XubString& rName, SbxClassType t )
+{
+ SbxVariable* pRes = SbxObject::Find( rName, t );
+ if( pRes )
+ {
+ triggerInitializeEvent();
+
+ SbIfaceMapperMethod* pIfaceMapperMethod = PTR_CAST(SbIfaceMapperMethod,pRes);
+ if( pIfaceMapperMethod )
+ {
+ pRes = pIfaceMapperMethod->getImplMethod();
+ pRes->SetFlag( SBX_EXTFOUND );
+ }
+ }
+ return pRes;
+}
+
+void SbClassModuleObject::triggerInitializeEvent( void )
+{
+ static String aInitMethodName( RTL_CONSTASCII_USTRINGPARAM("Class_Initialize") );
+
+ if( mbInitializeEventDone )
+ return;
+
+ mbInitializeEventDone = true;
+
+ // Search method
+ SbxVariable* pMeth = SbxObject::Find( aInitMethodName, SbxCLASS_METHOD );
+ if( pMeth )
+ {
+ SbxValues aVals;
+ pMeth->Get( aVals );
+ }
+}
+
+void SbClassModuleObject::triggerTerminateEvent( void )
+{
+ static String aTermMethodName( RTL_CONSTASCII_USTRINGPARAM("Class_Terminate") );
+
+ if( !mbInitializeEventDone || GetSbData()->bRunInit )
+ return;
+
+ // Search method
+ SbxVariable* pMeth = SbxObject::Find( aTermMethodName, SbxCLASS_METHOD );
+ if( pMeth )
+ {
+ SbxValues aVals;
+ pMeth->Get( aVals );
+ }
+}
+
+
+SbClassData::SbClassData( void )
+{
+ mxIfaces = new SbxArray();
+}
+
+void SbClassData::clear( void )
+{
+ mxIfaces->Clear();
+ maRequiredTypes.clear();
+}
+
+SbClassFactory::SbClassFactory( void )
+{
+ String aDummyName;
+ xClassModules = new SbxObject( aDummyName );
+}
+
+SbClassFactory::~SbClassFactory()
+{}
+
+void SbClassFactory::AddClassModule( SbModule* pClassModule )
+{
+ SbxObject* pParent = pClassModule->GetParent();
+ xClassModules->Insert( pClassModule );
+ pClassModule->SetParent( pParent );
+}
+
+void SbClassFactory::RemoveClassModule( SbModule* pClassModule )
+{
+ xClassModules->Remove( pClassModule );
+}
+
+SbxBase* SbClassFactory::Create( sal_uInt16, sal_uInt32 )
+{
+ // Not supported
+ return NULL;
+}
+
+SbxObject* SbClassFactory::CreateObject( const String& rClassName )
+{
+ SbxVariable* pVar = xClassModules->Find( rClassName, SbxCLASS_DONTCARE );
+ SbxObject* pRet = NULL;
+ if( pVar )
+ {
+ SbModule* pMod = (SbModule*)pVar;
+ pRet = new SbClassModuleObject( pMod );
+ }
+ return pRet;
+}
+
+SbModule* SbClassFactory::FindClass( const String& rClassName )
+{
+ SbxVariable* pVar = xClassModules->Find( rClassName, SbxCLASS_DONTCARE );
+ SbModule* pMod = pVar ? (SbModule*)pVar : NULL;
+ return pMod;
+}
+
+typedef std::vector< StarBASIC* > DocBasicVector;
+static DocBasicVector GaDocBasics;
+
+StarBASIC::StarBASIC( StarBASIC* p, sal_Bool bIsDocBasic )
+ : SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("StarBASIC") ) ), bDocBasic( bIsDocBasic )
+{
+ SetParent( p );
+ pLibInfo = NULL;
+ bNoRtl = bBreak = sal_False;
+ bVBAEnabled = sal_False;
+ pModules = new SbxArray;
+
+ if( !GetSbData()->nInst++ )
+ {
+ pSBFAC = new SbiFactory;
+ AddFactory( pSBFAC );
+ pTYPEFAC = new SbTypeFactory;
+ AddFactory( pTYPEFAC );
+ pCLASSFAC = new SbClassFactory;
+ AddFactory( pCLASSFAC );
+ pOLEFAC = new SbOLEFactory;
+ AddFactory( pOLEFAC );
+ pFORMFAC = new SbFormFactory;
+ AddFactory( pFORMFAC );
+ pUNOFAC = new SbUnoFactory;
+ AddFactory( pUNOFAC );
+ }
+ pRtl = new SbiStdObject( String( RTL_CONSTASCII_USTRINGPARAM(RTLNAME) ), this );
+ // Search via StarBasic is always global
+ SetFlag( SBX_GBLSEARCH );
+ pVBAGlobals = NULL;
+ bQuit = sal_False;
+
+ if( bDocBasic )
+ GaDocBasics.push_back( this );
+}
+
+// #51727 Override SetModified so that the modified state
+// is not given to the parent
+void StarBASIC::SetModified( sal_Bool b )
+{
+ SbxBase::SetModified( b );
+}
+
+StarBASIC::~StarBASIC()
+{
+ if( !--GetSbData()->nInst )
+ {
+ RemoveFactory( pSBFAC );
+ delete pSBFAC; pSBFAC = NULL;
+ RemoveFactory( pUNOFAC );
+ delete pUNOFAC; pUNOFAC = NULL;
+ RemoveFactory( pTYPEFAC );
+ delete pTYPEFAC; pTYPEFAC = NULL;
+ RemoveFactory( pCLASSFAC );
+ delete pCLASSFAC; pCLASSFAC = NULL;
+ RemoveFactory( pOLEFAC );
+ delete pOLEFAC; pOLEFAC = NULL;
+ RemoveFactory( pFORMFAC );
+ delete pFORMFAC; pFORMFAC = NULL;
+
+#ifdef DBG_UTIL
+ // There is no need to clean SbiData at program end,
+ // but we dislike MLK's at Purify
+ // TODO: Where else???
+ SbiGlobals** pp = (SbiGlobals**) ::GetAppData( SHL_SBC );
+ SbiGlobals* p = *pp;
+ if( p )
+ {
+ delete p;
+ *pp = 0;
+ }
+#endif
+ }
+ else if( bDocBasic )
+ {
+ SbxError eOld = SbxBase::GetError();
+
+ DocBasicVector::iterator it;
+ for( it = GaDocBasics.begin() ; it != GaDocBasics.end() ; ++it )
+ {
+ if( *it == this )
+ {
+ GaDocBasics.erase( it );
+ break;
+ }
+ }
+ for( it = GaDocBasics.begin() ; it != GaDocBasics.end() ; ++it )
+ {
+ StarBASIC* pBasic = *it;
+ pBasic->implClearDependingVarsOnDelete( this );
+ }
+
+ SbxBase::ResetError();
+ if( eOld != SbxERR_OK )
+ SbxBase::SetError( eOld );
+ }
+
+ // #100326 Set Parent NULL in registered listeners
+ if( xUnoListeners.Is() )
+ {
+ sal_uInt16 uCount = xUnoListeners->Count();
+ for( sal_uInt16 i = 0 ; i < uCount ; i++ )
+ {
+ SbxVariable* pListenerObj = xUnoListeners->Get( i );
+ pListenerObj->SetParent( NULL );
+ }
+ xUnoListeners = NULL;
+ }
+
+ clearUnoMethodsForBasic( this );
+ disposeComVariablesForBasic( this );
+}
+
+// Override new() operator, so that everyone can create a new instance
+void* StarBASIC::operator new( size_t n )
+{
+ if( n < sizeof( StarBASIC ) )
+ {
+// DBG_ASSERT( sal_False, "Warnung: inkompatibler BASIC-Stand!" );
+ n = sizeof( StarBASIC );
+ }
+ return ::operator new( n );
+}
+
+void StarBASIC::operator delete( void* p )
+{
+ ::operator delete( p );
+}
+
+void StarBASIC::implClearDependingVarsOnDelete( StarBASIC* pDeletedBasic )
+{
+ if( this != pDeletedBasic )
+ {
+ for( sal_uInt16 i = 0; i < pModules->Count(); i++ )
+ {
+ SbModule* p = (SbModule*)pModules->Get( i );
+ p->ClearVarsDependingOnDeletedBasic( pDeletedBasic );
+ }
+ }
+
+ for( sal_uInt16 nObj = 0; nObj < pObjs->Count(); nObj++ )
+ {
+ SbxVariable* pVar = pObjs->Get( nObj );
+ StarBASIC* pBasic = PTR_CAST(StarBASIC,pVar);
+ if( pBasic && pBasic != pDeletedBasic )
+ pBasic->implClearDependingVarsOnDelete( pDeletedBasic );
+ }
+}
+
+
+/**************************************************************************
+*
+* Creation/Managment of modules
+*
+**************************************************************************/
+
+SbModule* StarBASIC::MakeModule( const String& rName, const String& rSrc )
+{
+ return MakeModule32( rName, rSrc );
+}
+
+SbModule* StarBASIC::MakeModule32( const String& rName, const ::rtl::OUString& rSrc )
+{
+ ModuleInfo mInfo;
+ mInfo.ModuleType = ModuleType::NORMAL;
+ return MakeModule32( rName, mInfo, rSrc );
+}
+SbModule* StarBASIC::MakeModule32( const String& rName, const ModuleInfo& mInfo, const rtl::OUString& rSrc )
+{
+
+ OSL_TRACE("create module %s type mInfo %d", rtl::OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr(), mInfo.ModuleType );
+ SbModule* p = NULL;
+ switch ( mInfo.ModuleType )
+ {
+ case ModuleType::DOCUMENT:
+ // In theory we should be able to create Object modules
+ // in ordinary basic ( in vba mode thought these are create
+ // by the application/basic and not by the user )
+ p = new SbObjModule( rName, mInfo, isVBAEnabled() );
+ break;
+ case ModuleType::CLASS:
+ p = new SbModule( rName, isVBAEnabled() );
+ p->SetModuleType( ModuleType::CLASS );
+ break;
+ case ModuleType::FORM:
+ p = new SbUserFormModule( rName, mInfo, isVBAEnabled() );
+ break;
+ default:
+ p = new SbModule( rName, isVBAEnabled() );
+
+ }
+ p->SetSource32( rSrc );
+ p->SetParent( this );
+ pModules->Insert( p, pModules->Count() );
+ SetModified( sal_True );
+ return p;
+}
+
+void StarBASIC::Insert( SbxVariable* pVar )
+{
+ if( pVar->IsA( TYPE(SbModule) ) )
+ {
+ pModules->Insert( pVar, pModules->Count() );
+ pVar->SetParent( this );
+ StartListening( pVar->GetBroadcaster(), sal_True );
+ }
+ else
+ {
+ sal_Bool bWasModified = IsModified();
+ SbxObject::Insert( pVar );
+ if( !bWasModified && pVar->IsSet( SBX_DONTSTORE ) )
+ SetModified( sal_False );
+ }
+}
+
+void StarBASIC::Remove( SbxVariable* pVar )
+{
+ if( pVar->IsA( TYPE(SbModule) ) )
+ {
+ // #87540 Can be last reference!
+ SbxVariableRef xVar = pVar;
+ pModules->Remove( pVar );
+ pVar->SetParent( 0 );
+ EndListening( pVar->GetBroadcaster() );
+ }
+ else
+ SbxObject::Remove( pVar );
+}
+
+sal_Bool StarBASIC::Compile( SbModule* pMod )
+{
+ return pMod ? pMod->Compile() : sal_False;
+}
+
+sal_Bool StarBASIC::Disassemble( SbModule* pMod, String& rText )
+{
+ rText.Erase();
+ if( pMod )
+ pMod->Disassemble( rText );
+ return sal_Bool( rText.Len() != 0 );
+}
+
+void StarBASIC::Clear()
+{
+ while( pModules->Count() )
+ pModules->Remove( pModules->Count() - 1 );
+}
+
+SbModule* StarBASIC::FindModule( const String& rName )
+{
+ for( sal_uInt16 i = 0; i < pModules->Count(); i++ )
+ {
+ SbModule* p = (SbModule*) pModules->Get( i );
+ if( p->GetName().EqualsIgnoreCaseAscii( rName ) )
+ return p;
+ }
+ return NULL;
+}
+
+
+struct ClassModuleRunInitItem
+{
+ SbModule* m_pModule;
+ bool m_bProcessing;
+ bool m_bRunInitDone;
+ //ModuleVector m_vModulesDependingOnThisModule;
+
+ ClassModuleRunInitItem( void )
+ : m_pModule( NULL )
+ , m_bProcessing( false )
+ , m_bRunInitDone( false )
+ {}
+ ClassModuleRunInitItem( SbModule* pModule )
+ : m_pModule( pModule )
+ , m_bProcessing( false )
+ , m_bRunInitDone( false )
+ {}
+};
+
+// Derive from has_map type instead of typedef
+// to allow forward declaration in sbmod.hxx
+class ModuleInitDependencyMap : public
+ std::hash_map< ::rtl::OUString, ClassModuleRunInitItem,
+ ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > >
+{};
+
+void SbModule::implProcessModuleRunInit( ModuleInitDependencyMap& rMap, ClassModuleRunInitItem& rItem )
+{
+ rItem.m_bProcessing = true;
+
+ //bool bAnyDependencies = true;
+ SbModule* pModule = rItem.m_pModule;
+ if( pModule->pClassData != NULL )
+ {
+ StringVector& rReqTypes = pModule->pClassData->maRequiredTypes;
+ if( rReqTypes.size() > 0 )
+ {
+ for( StringVector::iterator it = rReqTypes.begin() ; it != rReqTypes.end() ; ++it )
+ {
+ String& rStr = *it;
+
+ // Is required type a class module?
+ ModuleInitDependencyMap::iterator itFind = rMap.find( rStr );
+ if( itFind != rMap.end() )
+ {
+ ClassModuleRunInitItem& rParentItem = itFind->second;
+ if( rParentItem.m_bProcessing )
+ {
+ // TODO: raise error?
+ DBG_ERROR( "Cyclic module dependency detected" );
+ continue;
+ }
+
+ if( !rParentItem.m_bRunInitDone )
+ implProcessModuleRunInit( rMap, rParentItem );
+ }
+ }
+ }
+ }
+
+ pModule->RunInit();
+ rItem.m_bRunInitDone = true;
+ rItem.m_bProcessing = false;
+}
+
+// Run Init-Code of all modules (including inserted libraries)
+void StarBASIC::InitAllModules( StarBASIC* pBasicNotToInit )
+{
+ ::vos::OGuard guard( Application::GetSolarMutex() );
+
+ // Init own modules
+ for ( sal_uInt16 nMod = 0; nMod < pModules->Count(); nMod++ )
+ {
+ SbModule* pModule = (SbModule*)pModules->Get( nMod );
+ if( !pModule->IsCompiled() )
+ pModule->Compile();
+ }
+ // compile modules first then RunInit ( otherwise there is
+ // can be order dependency, e.g. classmodule A has a member
+ // of of type classmodule B and classmodule B hasn't been compiled yet )
+
+ // Consider required types to init in right order. Class modules
+ // that are required by other modules have to be initialized first.
+ ModuleInitDependencyMap aMIDMap;
+ for ( sal_uInt16 nMod = 0; nMod < pModules->Count(); nMod++ )
+ {
+ SbModule* pModule = (SbModule*)pModules->Get( nMod );
+ String aModuleName = pModule->GetName();
+ if( pModule->isProxyModule() )
+ aMIDMap[aModuleName] = ClassModuleRunInitItem( pModule );
+ }
+
+ ModuleInitDependencyMap::iterator it;
+ for( it = aMIDMap.begin() ; it != aMIDMap.end(); ++it )
+ {
+ ClassModuleRunInitItem& rItem = it->second;
+ SbModule::implProcessModuleRunInit( aMIDMap, rItem );
+ }
+
+ // Call RunInit on standard modules
+ for ( sal_uInt16 nMod = 0; nMod < pModules->Count(); nMod++ )
+ {
+ SbModule* pModule = (SbModule*)pModules->Get( nMod );
+ if( !pModule->isProxyModule() )
+ pModule->RunInit();
+ }
+
+ // Check all objects if they are BASIC,
+ // if yes initialize
+ for ( sal_uInt16 nObj = 0; nObj < pObjs->Count(); nObj++ )
+ {
+ SbxVariable* pVar = pObjs->Get( nObj );
+ StarBASIC* pBasic = PTR_CAST(StarBASIC,pVar);
+ if( pBasic && pBasic != pBasicNotToInit )
+ pBasic->InitAllModules();
+ }
+}
+
+// #88329 Put modules back to not initialised state to
+// force reinitialisation at next start
+void StarBASIC::DeInitAllModules( void )
+{
+ // Deinit own modules
+ for ( sal_uInt16 nMod = 0; nMod < pModules->Count(); nMod++ )
+ {
+ SbModule* pModule = (SbModule*)pModules->Get( nMod );
+ if( pModule->pImage && !pModule->isProxyModule() && !pModule->ISA(SbObjModule) )
+ pModule->pImage->bInit = false;
+ }
+
+ for ( sal_uInt16 nObj = 0; nObj < pObjs->Count(); nObj++ )
+ {
+ SbxVariable* pVar = pObjs->Get( nObj );
+ StarBASIC* pBasic = PTR_CAST(StarBASIC,pVar);
+ if( pBasic )
+ pBasic->DeInitAllModules();
+ }
+}
+
+// #43011 For TestTool, to delete global vars
+void StarBASIC::ClearGlobalVars( void )
+{
+ SbxArrayRef xProps( GetProperties() );
+ sal_uInt16 nPropCount = xProps->Count();
+ for ( sal_uInt16 nProp = 0 ; nProp < nPropCount ; ++nProp )
+ {
+ SbxBase* pVar = xProps->Get( nProp );
+ pVar->Clear();
+ }
+ SetModified( sal_True );
+}
+
+// This implementation at first searches within the runtime library,
+// then it looks for an element within one module. This moudle can be
+// a public var or an entrypoint. If it is not found and we look for a
+// method and a module with the given name is found the search continues
+// for entrypoint "Main".
+// If this fails again a conventional search over objects is performend.
+SbxVariable* StarBASIC::Find( const String& rName, SbxClassType t )
+{
+ static String aMainStr( RTL_CONSTASCII_USTRINGPARAM("Main") );
+
+ SbxVariable* pRes = NULL;
+ SbModule* pNamed = NULL;
+ // "Extended" search in Runtime Lib
+ // but only if SbiRuntime has not set the flag
+ if( !bNoRtl )
+ {
+ if( t == SbxCLASS_DONTCARE || t == SbxCLASS_OBJECT )
+ {
+ if( rName.EqualsIgnoreCaseAscii( RTLNAME ) )
+ pRes = pRtl;
+ }
+ if( !pRes )
+ pRes = ((SbiStdObject*) (SbxObject*) pRtl)->Find( rName, t );
+ if( pRes )
+ pRes->SetFlag( SBX_EXTFOUND );
+ }
+ // Search module
+ if( !pRes )
+ for( sal_uInt16 i = 0; i < pModules->Count(); i++ )
+ {
+ SbModule* p = (SbModule*) pModules->Get( i );
+ if( p->IsVisible() )
+ {
+ // Remember modul fpr Main() call
+ // or is the name equal?!?
+ if( p->GetName().EqualsIgnoreCaseAscii( rName ) )
+ {
+ if( t == SbxCLASS_OBJECT || t == SbxCLASS_DONTCARE )
+ {
+ pRes = p; break;
+ }
+ pNamed = p;
+ }
+ // Only variables qualified by the Module Name e.g. Sheet1.foo
+ // should work for Documant && Class type Modules
+ sal_Int32 nType = p->GetModuleType();
+ if ( nType == ModuleType::DOCUMENT || nType == ModuleType::FORM )
+ continue;
+
+ // otherwise check if the element is available
+ // unset GBLSEARCH-Flag (due to Rekursion)
+ sal_uInt16 nGblFlag = p->GetFlags() & SBX_GBLSEARCH;
+ p->ResetFlag( SBX_GBLSEARCH );
+ pRes = p->Find( rName, t );
+ p->SetFlag( nGblFlag );
+ if( pRes )
+ break;
+ }
+ }
+ if( !pRes && pNamed && ( t == SbxCLASS_METHOD || t == SbxCLASS_DONTCARE ) &&
+ !pNamed->GetName().EqualsIgnoreCaseAscii( aMainStr ) )
+ pRes = pNamed->Find( aMainStr, SbxCLASS_METHOD );
+ if( !pRes )
+ pRes = SbxObject::Find( rName, t );
+ return pRes;
+}
+
+sal_Bool StarBASIC::Call( const String& rName, SbxArray* pParam )
+{
+ sal_Bool bRes = SbxObject::Call( rName, pParam );
+ if( !bRes )
+ {
+ SbxError eErr = SbxBase::GetError();
+ SbxBase::ResetError();
+ if( eErr != SbxERR_OK )
+ RTError( (SbError)eErr, 0, 0, 0 );
+ }
+ return bRes;
+}
+
+// Find method via name (e.g. query via BASIC IDE)
+SbxBase* StarBASIC::FindSBXInCurrentScope( const String& rName )
+{
+ if( !pINST )
+ return NULL;
+ if( !pINST->pRun )
+ return NULL;
+ return pINST->pRun->FindElementExtern( rName );
+}
+
+// Preserve old interface
+SbxVariable* StarBASIC::FindVarInCurrentScopy
+( const String& rName, sal_uInt16& rStatus )
+{
+ rStatus = 1; // Presumption: nothing found
+ SbxVariable* pVar = NULL;
+ SbxBase* pSbx = FindSBXInCurrentScope( rName );
+ if( pSbx )
+ {
+ if( !pSbx->ISA(SbxMethod) && !pSbx->ISA(SbxObject) )
+ pVar = PTR_CAST(SbxVariable,pSbx);
+ }
+ if( pVar )
+ rStatus = 0; // We found something
+ return pVar;
+}
+
+void StarBASIC::QuitAndExitApplication()
+{
+ Stop();
+ bQuit = sal_True;
+}
+
+void StarBASIC::Stop()
+{
+ SbiInstance* p = pINST;
+ while( p )
+ {
+ p->Stop();
+ p = p->pNext;
+ }
+}
+
+sal_Bool StarBASIC::IsRunning()
+{
+ return sal_Bool( pINST != NULL );
+}
+
+/**************************************************************************
+*
+* Object factories and others
+*
+**************************************************************************/
+
+// Activation of an object. There is no need to access active objects
+// with name via BASIC. If NULL is given, everything is activated.
+void StarBASIC::ActivateObject( const String* pName, sal_Bool bActivate )
+{
+ if( pName )
+ {
+ SbxObject* p = (SbxObject*) SbxObject::Find( *pName, SbxCLASS_OBJECT );
+ if( p )
+ {
+ if( bActivate )
+ p->SetFlag( SBX_EXTSEARCH );
+ else
+ p->ResetFlag( SBX_EXTSEARCH );
+ }
+ }
+ else
+ {
+ for( sal_uInt16 i = 0; i < GetObjects()->Count(); i++ )
+ {
+ SbxObject* p = (SbxObject*) GetObjects()->Get( i );
+ if( bActivate )
+ p->SetFlag( SBX_EXTSEARCH );
+ else
+ p->ResetFlag( SBX_EXTSEARCH );
+ }
+ }
+}
+
+/**************************************************************************
+*
+* Debugging and error handling
+*
+**************************************************************************/
+
+SbMethod* StarBASIC::GetActiveMethod( sal_uInt16 nLevel )
+{
+ if( pINST )
+ return pINST->GetCaller( nLevel );
+ else
+ return NULL;
+}
+
+SbModule* StarBASIC::GetActiveModule()
+{
+ if( pINST && !IsCompilerError() )
+ return pINST->GetActiveModule();
+ else
+ return pCMOD;
+}
+
+sal_uInt16 StarBASIC::BreakPoint( sal_uInt16 l, sal_uInt16 c1, sal_uInt16 c2 )
+{
+ SetErrorData( 0, l, c1, c2 );
+ bBreak = sal_True;
+ if( GetSbData()->aBreakHdl.IsSet() )
+ return (sal_uInt16) GetSbData()->aBreakHdl.Call( this );
+ else
+ return BreakHdl();
+}
+
+sal_uInt16 StarBASIC::StepPoint( sal_uInt16 l, sal_uInt16 c1, sal_uInt16 c2 )
+{
+ SetErrorData( 0, l, c1, c2 );
+ bBreak = sal_False;
+ if( GetSbData()->aBreakHdl.IsSet() )
+ return (sal_uInt16) GetSbData()->aBreakHdl.Call( this );
+ else
+ return BreakHdl();
+}
+
+sal_uInt16 __EXPORT StarBASIC::BreakHdl()
+{
+ return (sal_uInt16) ( aBreakHdl.IsSet()
+ ? aBreakHdl.Call( this ) : SbDEBUG_CONTINUE );
+}
+
+// Calls for error handler and break handler
+sal_uInt16 StarBASIC::GetLine() { return GetSbData()->nLine; }
+sal_uInt16 StarBASIC::GetCol1() { return GetSbData()->nCol1; }
+sal_uInt16 StarBASIC::GetCol2() { return GetSbData()->nCol2; }
+
+// Specific to error handler
+SbError StarBASIC::GetErrorCode() { return GetSbData()->nCode; }
+const String& StarBASIC::GetErrorText() { return GetSbData()->aErrMsg; }
+sal_Bool StarBASIC::IsCompilerError() { return GetSbData()->bCompiler; }
+void StarBASIC::SetGlobalLanguageMode( SbLanguageMode eLanguageMode )
+{
+ GetSbData()->eLanguageMode = eLanguageMode;
+}
+SbLanguageMode StarBASIC::GetGlobalLanguageMode()
+{
+ return GetSbData()->eLanguageMode;
+}
+// Local settings
+SbLanguageMode StarBASIC::GetLanguageMode()
+{
+ // Use global settings?
+ if( eLanguageMode == SB_LANG_GLOBAL )
+ return GetSbData()->eLanguageMode;
+ else
+ return eLanguageMode;
+}
+
+// AB: 29.3.96
+// Das Mapping zwischen alten und neuen Fehlercodes erfolgt, indem die Tabelle
+// SFX_VB_ErrorTab[] durchsucht wird. Dies ist zwar nicht besonders performant,
+// verbraucht aber viel weniger Speicher als entsprechende switch-Bloecke.
+// Die Umrechnung von Fehlercodes muss nicht schnell sein, daher auch keine
+// binaere Suche bei VB-Error -> SFX-Error.
+
+// Neue Fehler-Codes auf alte, Sbx-Kompatible zurueckmappen
+sal_uInt16 StarBASIC::GetVBErrorCode( SbError nError )
+{
+ sal_uInt16 nRet = 0;
+
+ if( SbiRuntime::isVBAEnabled() )
+ {
+ switch( nError )
+ {
+ case SbERR_BASIC_ARRAY_FIX:
+ return 10;
+ case SbERR_BASIC_STRING_OVERFLOW:
+ return 14;
+ case SbERR_BASIC_EXPR_TOO_COMPLEX:
+ return 16;
+ case SbERR_BASIC_OPER_NOT_PERFORM:
+ return 17;
+ case SbERR_BASIC_TOO_MANY_DLL:
+ return 47;
+ case SbERR_BASIC_LOOP_NOT_INIT:
+ return 92;
+ default:
+ nRet = 0;
+ }
+ }
+
+ // Suchschleife
+ const SFX_VB_ErrorItem* pErrItem;
+ sal_uInt16 nIndex = 0;
+ do
+ {
+ pErrItem = SFX_VB_ErrorTab + nIndex;
+ if( pErrItem->nErrorSFX == nError )
+ {
+ nRet = pErrItem->nErrorVB;
+ break;
+ }
+ nIndex++;
+ }
+ while( pErrItem->nErrorVB != 0xFFFF ); // bis End-Marke
+ return nRet;
+}
+
+SbError StarBASIC::GetSfxFromVBError( sal_uInt16 nError )
+{
+ SbError nRet = 0L;
+
+ if( SbiRuntime::isVBAEnabled() )
+ {
+ switch( nError )
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 12:
+ case 73:
+ return 0L;
+ case 10:
+ return SbERR_BASIC_ARRAY_FIX;
+ case 14:
+ return SbERR_BASIC_STRING_OVERFLOW;
+ case 16:
+ return SbERR_BASIC_EXPR_TOO_COMPLEX;
+ case 17:
+ return SbERR_BASIC_OPER_NOT_PERFORM;
+ case 47:
+ return SbERR_BASIC_TOO_MANY_DLL;
+ case 92:
+ return SbERR_BASIC_LOOP_NOT_INIT;
+ default:
+ nRet = 0L;
+ }
+ }
+ const SFX_VB_ErrorItem* pErrItem;
+ sal_uInt16 nIndex = 0;
+ do
+ {
+ pErrItem = SFX_VB_ErrorTab + nIndex;
+ if( pErrItem->nErrorVB == nError )
+ {
+ nRet = pErrItem->nErrorSFX;
+ break;
+ }
+ else if( pErrItem->nErrorVB > nError )
+ break; // kann nicht mehr gefunden werden
+
+ nIndex++;
+ }
+ while( pErrItem->nErrorVB != 0xFFFF ); // bis End-Marke
+ return nRet;
+}
+
+// Error- / Break-Daten setzen
+void StarBASIC::SetErrorData
+( SbError nCode, sal_uInt16 nLine, sal_uInt16 nCol1, sal_uInt16 nCol2 )
+{
+ SbiGlobals& aGlobals = *GetSbData();
+ aGlobals.nCode = nCode;
+ aGlobals.nLine = nLine;
+ aGlobals.nCol1 = nCol1;
+ aGlobals.nCol2 = nCol2;
+}
+
+//----------------------------------------------------------------
+// Hilfsklasse zum Zugriff auf String SubResourcen einer Resource.
+// Quelle: sfx2\source\doc\docfile.cxx (TLX)
+struct BasicStringList_Impl : private Resource
+{
+ ResId aResId;
+
+ BasicStringList_Impl( ResId& rErrIdP, sal_uInt16 nId)
+ : Resource( rErrIdP ),aResId(nId, *rErrIdP.GetResMgr() ){}
+ ~BasicStringList_Impl() { FreeResource(); }
+
+ String GetString(){ return String( aResId ); }
+ sal_Bool IsErrorTextAvailable( void )
+ { return IsAvailableRes(aResId.SetRT(RSC_STRING)); }
+};
+//----------------------------------------------------------------
+
+// #60175 Flag, das bei Basic-Fehlern das Anziehen der SFX-Resourcen verhindert
+static sal_Bool bStaticSuppressSfxResource = sal_False;
+
+void StarBASIC::StaticSuppressSfxResource( sal_Bool bSuppress )
+{
+ bStaticSuppressSfxResource = bSuppress;
+}
+
+// Hack for #83750, use bStaticSuppressSfxResource as setup flag
+sal_Bool runsInSetup( void )
+{
+ return bStaticSuppressSfxResource;
+}
+
+
+void StarBASIC::MakeErrorText( SbError nId, const String& aMsg )
+{
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+
+ if( bStaticSuppressSfxResource )
+ {
+ GetSbData()->aErrMsg = String( RTL_CONSTASCII_USTRINGPARAM("No resource: Error message not available") );
+ return;
+ }
+
+ sal_uInt16 nOldID = GetVBErrorCode( nId );
+
+ // Hilfsklasse instanzieren
+ BasResId aId( RID_BASIC_START );
+ BasicStringList_Impl aMyStringList( aId, sal_uInt16(nId & ERRCODE_RES_MASK) );
+
+ if( aMyStringList.IsErrorTextAvailable() )
+ {
+ // Merge Message mit Zusatztext
+ String aMsg1 = aMyStringList.GetString();
+ // Argument-Platzhalter durch %s ersetzen
+ String aSrgStr( RTL_CONSTASCII_USTRINGPARAM("$(ARG1)") );
+ sal_uInt16 nResult = aMsg1.Search( aSrgStr );
+
+ if( nResult != STRING_NOTFOUND )
+ {
+ aMsg1.Erase( nResult, aSrgStr.Len() );
+ aMsg1.Insert( aMsg, nResult );
+ }
+ GetSbData()->aErrMsg = aMsg1;
+ }
+ else if( nOldID != 0 )
+ {
+ String aStdMsg( RTL_CONSTASCII_USTRINGPARAM("Fehler ") );
+ aStdMsg += String::CreateFromInt32( nOldID);
+ aStdMsg += String( RTL_CONSTASCII_USTRINGPARAM(": Kein Fehlertext verfuegbar!") );
+ GetSbData()->aErrMsg = aStdMsg;
+ }
+ else
+ GetSbData()->aErrMsg = String::EmptyString();
+
+}
+
+sal_Bool StarBASIC::CError
+ ( SbError code, const String& rMsg, sal_uInt16 l, sal_uInt16 c1, sal_uInt16 c2 )
+{
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+
+ // Compiler-Fehler waehrend der Laufzeit -> Programm anhalten
+ if( IsRunning() )
+ {
+ // #109018 Check if running Basic is affected
+ StarBASIC* pStartedBasic = pINST->GetBasic();
+ if( pStartedBasic != this )
+ return sal_False;
+
+ Stop();
+ }
+
+ // Flag setzen, damit GlobalRunInit den Fehler mitbekommt
+ GetSbData()->bGlobalInitErr = sal_True;
+
+ // Fehlertext basteln
+ MakeErrorText( code, rMsg );
+
+ // Umsetzung des Codes fuer String-Transport in SFX-Error
+ if( rMsg.Len() )
+ code = (sal_uIntPtr)*new StringErrorInfo( code, String(rMsg) );
+
+ SetErrorData( code, l, c1, c2 );
+ GetSbData()->bCompiler = sal_True;
+ sal_Bool bRet;
+ if( GetSbData()->aErrHdl.IsSet() )
+ bRet = (sal_Bool) GetSbData()->aErrHdl.Call( this );
+ else
+ bRet = ErrorHdl();
+ GetSbData()->bCompiler = sal_False; // nur sal_True fuer Error-Handler
+ return bRet;
+}
+
+sal_Bool StarBASIC::RTError
+ ( SbError code, sal_uInt16 l, sal_uInt16 c1, sal_uInt16 c2 )
+{
+ return RTError( code, String(), l, c1, c2 );
+}
+
+sal_Bool StarBASIC::RTError( SbError code, const String& rMsg, sal_uInt16 l, sal_uInt16 c1, sal_uInt16 c2 )
+{
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+
+ SbError c = code;
+ if( (c & ERRCODE_CLASS_MASK) == ERRCODE_CLASS_COMPILER )
+ c = 0;
+ MakeErrorText( c, rMsg );
+
+ // Umsetzung des Codes fuer String-Transport in SFX-Error
+ if( rMsg.Len() )
+ {
+ // very confusing, even though MakeErrorText sets up the error text
+ // seems that this is not used ( if rMsg already has content )
+ // In the case of VBA MakeErrorText also formats the error to be alittle more
+ // like vba ( adds an error number etc )
+ if ( SbiRuntime::isVBAEnabled() && ( code == SbERR_BASIC_COMPAT ) )
+ {
+ String aTmp = '\'';
+ aTmp += String::CreateFromInt32( SbxErrObject::getUnoErrObject()->getNumber() );
+ aTmp += String( RTL_CONSTASCII_USTRINGPARAM("\'\n") );
+ aTmp += GetSbData()->aErrMsg.Len() ? GetSbData()->aErrMsg : rMsg;
+ code = (sal_uIntPtr)*new StringErrorInfo( code, aTmp );
+ }
+ else
+ code = (sal_uIntPtr)*new StringErrorInfo( code, String(rMsg) );
+ }
+
+ SetErrorData( code, l, c1, c2 );
+ if( GetSbData()->aErrHdl.IsSet() )
+ return (sal_Bool) GetSbData()->aErrHdl.Call( this );
+ else
+ return ErrorHdl();
+}
+
+void StarBASIC::Error( SbError n )
+{
+ Error( n, String() );
+}
+
+void StarBASIC::Error( SbError n, const String& rMsg )
+{
+ if( pINST )
+ pINST->Error( n, rMsg );
+}
+
+void StarBASIC::FatalError( SbError n )
+{
+ if( pINST )
+ pINST->FatalError( n );
+}
+
+void StarBASIC::FatalError( SbError _errCode, const String& _details )
+{
+ if( pINST )
+ pINST->FatalError( _errCode, _details );
+}
+
+SbError StarBASIC::GetErrBasic()
+{
+ if( pINST )
+ return pINST->GetErr();
+ else
+ return 0;
+}
+
+// #66536 Zusatz-Message fuer RTL-Funktion Error zugreifbar machen
+String StarBASIC::GetErrorMsg()
+{
+ if( pINST )
+ return pINST->GetErrorMsg();
+ else
+ return String();
+}
+
+sal_uInt16 StarBASIC::GetErl()
+{
+ if( pINST )
+ return pINST->GetErl();
+ else
+ return 0;
+}
+
+sal_Bool __EXPORT StarBASIC::ErrorHdl()
+{
+ return (sal_Bool) ( aErrorHdl.IsSet()
+ ? aErrorHdl.Call( this ) : sal_False );
+}
+
+Link StarBASIC::GetGlobalErrorHdl()
+{
+ return GetSbData()->aErrHdl;
+}
+
+void StarBASIC::SetGlobalErrorHdl( const Link& rLink )
+{
+ GetSbData()->aErrHdl = rLink;
+}
+
+
+Link StarBASIC::GetGlobalBreakHdl()
+{
+ return GetSbData()->aBreakHdl;
+}
+
+void StarBASIC::SetGlobalBreakHdl( const Link& rLink )
+{
+ GetSbData()->aBreakHdl = rLink;
+}
+
+SbxArrayRef StarBASIC::getUnoListeners( void )
+{
+ if( !xUnoListeners.Is() )
+ xUnoListeners = new SbxArray();
+ return xUnoListeners;
+}
+
+
+/**************************************************************************
+*
+* Laden und Speichern
+*
+**************************************************************************/
+
+sal_Bool StarBASIC::LoadData( SvStream& r, sal_uInt16 nVer )
+{
+ if( !SbxObject::LoadData( r, nVer ) )
+ return sal_False;
+
+ // #95459 Delete dialogs, otherwise endless recursion
+ // in SbxVarable::GetType() if dialogs are accessed
+ sal_uInt16 nObjCount = pObjs->Count();
+ SbxVariable** ppDeleteTab = new SbxVariable*[ nObjCount ];
+ sal_uInt16 nObj;
+
+ for( nObj = 0 ; nObj < nObjCount ; nObj++ )
+ {
+ SbxVariable* pVar = pObjs->Get( nObj );
+ StarBASIC* pBasic = PTR_CAST( StarBASIC, pVar );
+ ppDeleteTab[nObj] = pBasic ? NULL : pVar;
+ }
+ for( nObj = 0 ; nObj < nObjCount ; nObj++ )
+ {
+ SbxVariable* pVar = ppDeleteTab[nObj];
+ if( pVar )
+ pObjs->Remove( pVar );
+ }
+ delete[] ppDeleteTab;
+
+ sal_uInt16 nMod;
+ pModules->Clear();
+ r >> nMod;
+ for( sal_uInt16 i = 0; i < nMod; i++ )
+ {
+ SbModule* pMod = (SbModule*) SbxBase::Load( r );
+ if( !pMod )
+ return sal_False;
+ else if( pMod->ISA(SbJScriptModule) )
+ {
+ // Ref zuweisen, damit pMod deleted wird
+ SbModuleRef xRef = pMod;
+ }
+ else
+ {
+ pMod->SetParent( this );
+ pModules->Put( pMod, i );
+ }
+ }
+ // HACK fuer SFX-Mist!
+ SbxVariable* p = Find( String( RTL_CONSTASCII_USTRINGPARAM("FALSE") ), SbxCLASS_PROPERTY );
+ if( p )
+ Remove( p );
+ p = Find( String( RTL_CONSTASCII_USTRINGPARAM("TRUE") ), SbxCLASS_PROPERTY );
+ if( p )
+ Remove( p );
+ // Ende des Hacks!
+ // Suche ueber StarBASIC ist immer global
+ DBG_ASSERT( IsSet( SBX_GBLSEARCH ), "Basic ohne GBLSEARCH geladen" );
+ SetFlag( SBX_GBLSEARCH );
+ return sal_True;
+}
+
+sal_Bool StarBASIC::StoreData( SvStream& r ) const
+{
+ if( !SbxObject::StoreData( r ) )
+ return sal_False;
+ r << (sal_uInt16) pModules->Count();
+ for( sal_uInt16 i = 0; i < pModules->Count(); i++ )
+ {
+ SbModule* p = (SbModule*) pModules->Get( i );
+ if( !p->Store( r ) )
+ return sal_False;
+ }
+ return sal_True;
+}
+
+sal_Bool StarBASIC::LoadOldModules( SvStream& )
+{
+ return sal_False;
+}
+
+bool StarBASIC::GetUNOConstant( const sal_Char* _pAsciiName, ::com::sun::star::uno::Any& aOut )
+{
+ bool bRes = false;
+ ::rtl::OUString sVarName( ::rtl::OUString::createFromAscii( _pAsciiName ) );
+ SbUnoObject* pGlobs = dynamic_cast<SbUnoObject*>( Find( sVarName, SbxCLASS_DONTCARE ) );
+ if ( pGlobs )
+ {
+ aOut = pGlobs->getUnoAny();
+ bRes = true;
+ }
+ return bRes;
+}
+
+Reference< frame::XModel > StarBASIC::GetModelFromBasic( SbxObject* pBasic )
+{
+ OSL_PRECOND( pBasic != NULL, "getModelFromBasic: illegal call!" );
+ if ( !pBasic )
+ return NULL;
+
+ // look for the ThisComponent variable, first in the parent (which
+ // might be the document's Basic), then in the parent's parent (which might be
+ // the application Basic)
+ const ::rtl::OUString sThisComponent( RTL_CONSTASCII_USTRINGPARAM( "ThisComponent" ) );
+ SbxVariable* pThisComponent = NULL;
+
+ SbxObject* pLookup = pBasic->GetParent();
+ while ( pLookup && !pThisComponent )
+ {
+ pThisComponent = pLookup->Find( sThisComponent, SbxCLASS_OBJECT );
+ pLookup = pLookup->GetParent();
+ }
+ if ( !pThisComponent )
+ {
+ OSL_TRACE("Failed to get ThisComponent");
+ // the application Basic, at the latest, should have this variable
+ return NULL;
+ }
+
+ Any aThisComponentAny( sbxToUnoValue( pThisComponent ) );
+ Reference< frame::XModel > xModel( aThisComponentAny, UNO_QUERY );
+ if ( !xModel.is() )
+ {
+ // it's no XModel. Okay, ThisComponent nowadays is allowed to be a controller.
+ Reference< frame::XController > xController( aThisComponentAny, UNO_QUERY );
+ if ( xController.is() )
+ xModel = xController->getModel();
+ }
+
+ if ( !xModel.is() )
+ return NULL;
+
+#if OSL_DEBUG_LEVEL > 0
+ OSL_TRACE("Have model ThisComponent points to url %s",
+ ::rtl::OUStringToOString( xModel->getURL(),
+ RTL_TEXTENCODING_ASCII_US ).pData->buffer );
+#endif
+
+ return xModel;
+}
+
+
+//========================================================================
+// #118116 Implementation Collection object
+
+TYPEINIT1(BasicCollection,SbxObject)
+
+static const char pCountStr[] = "Count";
+static const char pAddStr[] = "Add";
+static const char pItemStr[] = "Item";
+static const char pRemoveStr[] = "Remove";
+static sal_uInt16 nCountHash = 0, nAddHash, nItemHash, nRemoveHash;
+
+SbxInfoRef BasicCollection::xAddInfo = NULL;
+SbxInfoRef BasicCollection::xItemInfo = NULL;
+
+BasicCollection::BasicCollection( const XubString& rClass )
+ : SbxObject( rClass )
+{
+ if( !nCountHash )
+ {
+ nCountHash = MakeHashCode( String::CreateFromAscii( pCountStr ) );
+ nAddHash = MakeHashCode( String::CreateFromAscii( pAddStr ) );
+ nItemHash = MakeHashCode( String::CreateFromAscii( pItemStr ) );
+ nRemoveHash = MakeHashCode( String::CreateFromAscii( pRemoveStr ) );
+ }
+ Initialize();
+
+}
+
+BasicCollection::~BasicCollection()
+{}
+
+void BasicCollection::Clear()
+{
+ SbxObject::Clear();
+ Initialize();
+}
+
+void BasicCollection::Initialize()
+{
+ xItemArray = new SbxArray();
+ SetType( SbxOBJECT );
+ SetFlag( SBX_FIXED );
+ ResetFlag( SBX_WRITE );
+ SbxVariable* p;
+ p = Make( String::CreateFromAscii( pCountStr ), SbxCLASS_PROPERTY, SbxINTEGER );
+ p->ResetFlag( SBX_WRITE );
+ p->SetFlag( SBX_DONTSTORE );
+ p = Make( String::CreateFromAscii( pAddStr ), SbxCLASS_METHOD, SbxEMPTY );
+ p->SetFlag( SBX_DONTSTORE );
+ p = Make( String::CreateFromAscii( pItemStr ), SbxCLASS_METHOD, SbxVARIANT );
+ p->SetFlag( SBX_DONTSTORE );
+ p = Make( String::CreateFromAscii( pRemoveStr ), SbxCLASS_METHOD, SbxEMPTY );
+ p->SetFlag( SBX_DONTSTORE );
+ if ( !xAddInfo.Is() )
+ {
+ xAddInfo = new SbxInfo;
+ xAddInfo->AddParam( String( RTL_CONSTASCII_USTRINGPARAM("Item") ), SbxVARIANT, SBX_READ );
+ xAddInfo->AddParam( String( RTL_CONSTASCII_USTRINGPARAM("Key") ), SbxVARIANT, SBX_READ | SBX_OPTIONAL );
+ xAddInfo->AddParam( String( RTL_CONSTASCII_USTRINGPARAM("Before") ), SbxVARIANT, SBX_READ | SBX_OPTIONAL );
+ xAddInfo->AddParam( String( RTL_CONSTASCII_USTRINGPARAM("After") ), SbxVARIANT, SBX_READ | SBX_OPTIONAL );
+ }
+ if ( !xItemInfo.Is() )
+ {
+ xItemInfo = new SbxInfo;
+ xItemInfo->AddParam( String( RTL_CONSTASCII_USTRINGPARAM("Index") ), SbxVARIANT, SBX_READ | SBX_OPTIONAL);
+ }
+}
+
+SbxVariable* BasicCollection::Find( const XubString& rName, SbxClassType t )
+{
+ SbxVariable* pFind = SbxObject::Find( rName, t );
+ return pFind;
+}
+
+void BasicCollection::SFX_NOTIFY( SfxBroadcaster& rCst, const TypeId& rId1,
+ const SfxHint& rHint, const TypeId& rId2 )
+{
+ const SbxHint* p = PTR_CAST(SbxHint,&rHint);
+ if( p )
+ {
+ sal_uIntPtr nId = p->GetId();
+ sal_Bool bRead = sal_Bool( nId == SBX_HINT_DATAWANTED );
+ sal_Bool bWrite = sal_Bool( nId == SBX_HINT_DATACHANGED );
+ sal_Bool bRequestInfo = sal_Bool( nId == SBX_HINT_INFOWANTED );
+ SbxVariable* pVar = p->GetVar();
+ SbxArray* pArg = pVar->GetParameters();
+ XubString aVarName( pVar->GetName() );
+ if( bRead || bWrite )
+ {
+ if( pVar->GetHashCode() == nCountHash
+ && aVarName.EqualsIgnoreCaseAscii( pCountStr ) )
+ pVar->PutLong( xItemArray->Count32() );
+ else if( pVar->GetHashCode() == nAddHash
+ && aVarName.EqualsIgnoreCaseAscii( pAddStr ) )
+ CollAdd( pArg );
+ else if( pVar->GetHashCode() == nItemHash
+ && aVarName.EqualsIgnoreCaseAscii( pItemStr ) )
+ CollItem( pArg );
+ else if( pVar->GetHashCode() == nRemoveHash
+ && aVarName.EqualsIgnoreCaseAscii( pRemoveStr ) )
+ CollRemove( pArg );
+ else
+ SbxObject::SFX_NOTIFY( rCst, rId1, rHint, rId2 );
+ return;
+ }
+ else if ( bRequestInfo )
+ {
+ if( pVar->GetHashCode() == nAddHash
+ && aVarName.EqualsIgnoreCaseAscii( pAddStr ) )
+ pVar->SetInfo( xAddInfo );
+ else if( pVar->GetHashCode() == nItemHash
+ && aVarName.EqualsIgnoreCaseAscii( pItemStr ) )
+ pVar->SetInfo( xItemInfo );
+ }
+ }
+ SbxObject::SFX_NOTIFY( rCst, rId1, rHint, rId2 );
+}
+
+sal_Int32 BasicCollection::implGetIndex( SbxVariable* pIndexVar )
+{
+ sal_Int32 nIndex = -1;
+ if( pIndexVar->GetType() == SbxSTRING )
+ nIndex = implGetIndexForName( pIndexVar->GetString() );
+ else
+ nIndex = pIndexVar->GetLong() - 1;
+ return nIndex;
+}
+
+sal_Int32 BasicCollection::implGetIndexForName( const String& rName )
+{
+ sal_Int32 nIndex = -1;
+ sal_Int32 nCount = xItemArray->Count32();
+ sal_Int32 nNameHash = MakeHashCode( rName );
+ for( sal_Int32 i = 0 ; i < nCount ; i++ )
+ {
+ SbxVariable* pVar = xItemArray->Get32( i );
+ if( pVar->GetHashCode() == nNameHash &&
+ pVar->GetName().EqualsIgnoreCaseAscii( rName ) )
+ {
+ nIndex = i;
+ break;
+ }
+ }
+ return nIndex;
+}
+
+void BasicCollection::CollAdd( SbxArray* pPar_ )
+{
+ sal_uInt16 nCount = pPar_->Count();
+ if( nCount < 2 || nCount > 5 )
+ {
+ SetError( SbxERR_WRONG_ARGS );
+ return;
+ }
+
+ SbxVariable* pItem = pPar_->Get(1);
+ if( pItem )
+ {
+ int nNextIndex;
+ if( nCount < 4 )
+ {
+ nNextIndex = xItemArray->Count();
+ }
+ else
+ {
+ SbxVariable* pBefore = pPar_->Get(3);
+ if( nCount == 5 )
+ {
+ if( !( pBefore->IsErr() || ( pBefore->GetType() == SbxEMPTY ) ) )
+ {
+ SetError( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ SbxVariable* pAfter = pPar_->Get(4);
+ sal_Int32 nAfterIndex = implGetIndex( pAfter );
+ if( nAfterIndex == -1 )
+ {
+ SetError( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ nNextIndex = nAfterIndex + 1;
+ }
+ else // if( nCount == 4 )
+ {
+ sal_Int32 nBeforeIndex = implGetIndex( pBefore );
+ if( nBeforeIndex == -1 )
+ {
+ SetError( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ nNextIndex = nBeforeIndex;
+ }
+ }
+
+ SbxVariableRef pNewItem = new SbxVariable( *pItem );
+ if( nCount >= 3 )
+ {
+ SbxVariable* pKey = pPar_->Get(2);
+ if( !( pKey->IsErr() || ( pKey->GetType() == SbxEMPTY ) ) )
+ {
+ if( pKey->GetType() != SbxSTRING )
+ {
+ SetError( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ String aKey = pKey->GetString();
+ if( implGetIndexForName( aKey ) != -1 )
+ {
+ SetError( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ pNewItem->SetName( aKey );
+ }
+ }
+ pNewItem->SetFlag( SBX_READWRITE );
+ xItemArray->Insert32( pNewItem, nNextIndex );
+ }
+ else
+ {
+ SetError( SbERR_BAD_ARGUMENT );
+ return;
+ }
+}
+
+void BasicCollection::CollItem( SbxArray* pPar_ )
+{
+ if( pPar_->Count() != 2 )
+ {
+ SetError( SbxERR_WRONG_ARGS );
+ return;
+ }
+ SbxVariable* pRes = NULL;
+ SbxVariable* p = pPar_->Get( 1 );
+ sal_Int32 nIndex = implGetIndex( p );
+ if( nIndex >= 0 && nIndex < (sal_Int32)xItemArray->Count32() )
+ pRes = xItemArray->Get32( nIndex );
+ if( !pRes )
+ SetError( SbERR_BAD_ARGUMENT );
+ else
+ *(pPar_->Get(0)) = *pRes;
+}
+
+void BasicCollection::CollRemove( SbxArray* pPar_ )
+{
+ if( pPar_ == NULL || pPar_->Count() != 2 )
+ {
+ SetError( SbxERR_WRONG_ARGS );
+ return;
+ }
+
+ SbxVariable* p = pPar_->Get( 1 );
+ sal_Int32 nIndex = implGetIndex( p );
+ if( nIndex >= 0 && nIndex < (sal_Int32)xItemArray->Count32() )
+ xItemArray->Remove32( nIndex );
+ else
+ SetError( SbERR_BAD_ARGUMENT );
+}
+
diff --git a/basic/source/classes/sb.src b/basic/source/classes/sb.src
new file mode 100644
index 000000000000..73cc1c3a0b2c
--- /dev/null
+++ b/basic/source/classes/sb.src
@@ -0,0 +1,681 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+#define __RSC
+#ifndef _ERRCODE_HXX //autogen
+#include <tools/errcode.hxx>
+#endif
+#include "sb.hrc"
+#include <basic/sberrors.hxx>
+
+Resource RID_BASIC_START
+{
+ String SbERR_SYNTAX & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Syntax error." ;
+ };
+ String SbERR_NO_GOSUB & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Return without Gosub." ;
+ };
+ String SbERR_REDO_FROM_START & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Incorrect entry; please retry." ;
+ };
+ String SbERR_BAD_ARGUMENT & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Ung³ltiger Prozeduraufruf : Ungltiger Prozeduraufruf */
+ Text [ en-US ] = "Invalid procedure call." ;
+ };
+ String SbERR_MATH_OVERFLOW & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? šberlauf : Überlauf */
+ Text [ en-US ] = "Overflow." ;
+ };
+ String SbERR_NO_MEMORY & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Nicht gen³gend Speicher : Nicht gengend Speicher */
+ Text [ en-US ] = "Not enough memory." ;
+ };
+ String SbERR_ALREADY_DIM & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Array already dimensioned." ;
+ };
+ String SbERR_OUT_OF_RANGE & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Index au˜erhalb des definierten Bereichs : Index auÿerhalb des definierten Bereichs */
+ Text [ en-US ] = "Index out of defined range." ;
+ };
+ String SbERR_DUPLICATE_DEF & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Duplicate definition." ;
+ };
+ String SbERR_ZERODIV & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Division by zero." ;
+ };
+ String SbERR_VAR_UNDEFINED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Variable not defined." ;
+ };
+ String SbERR_CONVERSION & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Datentypen unvertrõglich : Datentypen unvertr§glich */
+ Text [ en-US ] = "Data type mismatch." ;
+ };
+ String SbERR_BAD_PARAMETER & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Ung³ltiger Parameter : Ungltiger Parameter */
+ Text [ en-US ] = "Invalid parameter." ;
+ };
+ String SbERR_USER_ABORT & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Process interrupted by user." ;
+ };
+ String SbERR_BAD_RESUME & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Resume without error." ;
+ };
+ String SbERR_STACK_OVERFLOW & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Nicht gen³gend Stapelspeicher : Nicht gengend Stapelspeicher */
+ Text [ en-US ] = "Not enough stack memory." ;
+ };
+ String SbERR_PROC_UNDEFINED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Sub-procedure or function procedure not defined." ;
+ };
+ String SbERR_BAD_DLL_LOAD & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Error loading DLL file." ;
+ };
+ String SbERR_BAD_DLL_CALL & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Wrong DLL call convention." ;
+ };
+ String SbERR_INTERNAL_ERROR & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Internal error $(ARG1)." ;
+ };
+ String SbERR_BAD_CHANNEL & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Invalid file name or file number." ;
+ };
+ String SbERR_FILE_NOT_FOUND & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "File not found." ;
+ };
+ String SbERR_BAD_FILE_MODE & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Incorrect file mode." ;
+ };
+ String SbERR_FILE_ALREADY_OPEN & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Datei bereits ge÷ffnet : Datei bereits ge”ffnet */
+ Text [ en-US ] = "File already open." ;
+ };
+ String SbERR_IO_ERROR & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Gerõte-E/A-Fehler : Ger§te-E/A-Fehler */
+ Text [ en-US ] = "Device I/O error." ;
+ };
+ String SbERR_FILE_EXISTS & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "File already exists." ;
+ };
+ String SbERR_BAD_RECORD_LENGTH & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Falsche Datensatzlõnge : Falsche Datensatzl§nge */
+ Text [ en-US ] = "Incorrect record length." ;
+ };
+ String SbERR_DISK_FULL & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Disk or hard drive full." ;
+ };
+ String SbERR_READ_PAST_EOF & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Lesen ³ber das Ende der Datei hinaus : Lesen ber das Ende der Datei hinaus */
+ Text [ en-US ] = "Reading exceeds EOF." ;
+ };
+ String SbERR_BAD_RECORD_NUMBER & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Incorrect record number." ;
+ };
+ String SbERR_TOO_MANY_FILES & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Too many files." ;
+ };
+ String SbERR_NO_DEVICE & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Gerõt nicht verf³gbar : Ger§t nicht verfgbar */
+ Text [ en-US ] = "Device not available." ;
+ };
+ String SbERR_ACCESS_DENIED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Access denied." ;
+ };
+ String SbERR_NOT_READY & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Disk not ready." ;
+ };
+ String SbERR_NOT_IMPLEMENTED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Not implemented." ;
+ };
+ String SbERR_DIFFERENT_DRIVE & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Umbenennen auf verschiedenen Laufwerken nicht m÷glich : Umbenennen auf verschiedenen Laufwerken nicht m”glich */
+ Text [ en-US ] = "Renaming on different drives impossible." ;
+ };
+ String SbERR_ACCESS_ERROR & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Path/File access error." ;
+ };
+ String SbERR_PATH_NOT_FOUND & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Path not found." ;
+ };
+ String SbERR_NO_OBJECT & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Object variable not set." ;
+ };
+ String SbERR_BAD_PATTERN & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Zeichenfolgenmuster unzulõssig : Zeichenfolgenmuster unzul§ssig */
+ Text [ en-US ] = "Invalid string pattern." ;
+ };
+ String SBERR_IS_NULL & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Verwendung von Null unzulõssig : Verwendung von Null unzul§ssig */
+ Text [ en-US ] = "Use of zero not permitted." ;
+ };
+ String SbERR_DDE_ERROR & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "DDE Error." ;
+ };
+ String SbERR_DDE_WAITINGACK & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Awaiting response to DDE connection." ;
+ };
+ String SbERR_DDE_OUTOFCHANNELS & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Keine freien DDE-Kanõle : Keine freien DDE-Kan§le */
+ Text [ en-US ] = "No DDE channels available." ;
+ };
+ String SbERR_DDE_NO_RESPONSE & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "No application responded to DDE connect initiation." ;
+ };
+ String SbERR_DDE_MULT_RESPONSES & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Too many applications responded to DDE connect initiation." ;
+ };
+ String SbERR_DDE_CHANNEL_LOCKED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "DDE channel locked." ;
+ };
+ String SbERR_DDE_NOTPROCESSED & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Fremdapplikation kann DDE-Operation nicht ausf³hren : Fremdapplikation kann DDE-Operation nicht ausfhren */
+ Text [ en-US ] = "External application cannot execute DDE operation." ;
+ };
+ String SbERR_DDE_TIMEOUT & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Zeit³berschreitung wõhrend des Wartens auf DDE-Antwort : Zeitberschreitung w§hrend des Wartens auf DDE-Antwort */
+ Text [ en-US ] = "Timeout while waiting for DDE response." ;
+ };
+ String SbERR_DDE_USER_INTERRUPT & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Benutzer dr³ckte ESCAPE wõhrend der DDE-Operation : Benutzer drckte ESCAPE w§hrend der DDE-Operation */
+ Text [ en-US ] = "User pressed ESCAPE during DDE operation." ;
+ };
+ String SbERR_DDE_BUSY & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "External application busy." ;
+ };
+ String SbERR_DDE_NO_DATA & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "DDE operation without data." ;
+ };
+ String SbERR_DDE_WRONG_DATA_FORMAT & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Data are in wrong format." ;
+ };
+ String SbERR_DDE_PARTNER_QUIT & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "External application has been terminated." ;
+ };
+ String SbERR_DDE_CONV_CLOSED & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? DDE-Verbindung ist unterbrochen oder geõndert worden : DDE-Verbindung ist unterbrochen oder ge§ndert worden */
+ Text [ en-US ] = "DDE connection interrupted or modified." ;
+ };
+ String SbERR_DDE_NO_CHANNEL & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "DDE method invoked with no channel open." ;
+ };
+ String SbERR_DDE_INVALID_LINK & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Ung³ltiges DDE-Linkformat : Ungltiges DDE-Linkformat */
+ Text [ en-US ] = "Invalid DDE link format." ;
+ };
+ String SbERR_DDE_QUEUE_OVERFLOW & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "DDE message has been lost." ;
+ };
+ String SbERR_DDE_LINK_ALREADY_EST & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Paste Link bereits durchgef³hrt : Paste Link bereits durchgefhrt */
+ Text [ en-US ] = "Paste link already performed." ;
+ };
+ String SbERR_DDE_LINK_INV_TOPIC & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? LinkMode kann wegen ung³ltigen Link-Topics nicht gesetzt werden : LinkMode kann wegen ungltigen Link-Topics nicht gesetzt werden */
+ Text [ en-US ] = "Link mode cannot be set due to invalid link topic." ;
+ };
+ String SbERR_DDE_DLL_NOT_FOUND & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? F³r DDE wird DDEML.DLL ben÷tigt : Fr DDE wird DDEML.DLL ben”tigt */
+ Text [ en-US ] = "DDE requires the DDEML.DLL file." ;
+ };
+ String SbERR_CANNOT_LOAD & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Das Modul kann nicht geladen werden, ung³ltiges Format : Das Modul kann nicht geladen werden, ungltiges Format */
+ Text [ en-US ] = "Module cannot be loaded; invalid format." ;
+ };
+ String SbERR_BAD_INDEX & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Ung³ltiger Objektindex : Ungltiger Objektindex */
+ Text [ en-US ] = "Invalid object index." ;
+ };
+ String SbERR_NO_ACTIVE_OBJECT & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Objekt ist nicht verf³gbar : Objekt ist nicht verfgbar */
+ Text [ en-US ] = "Object is not available." ;
+ };
+ String SbERR_BAD_PROP_VALUE & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Falscher Wert f³r Eigenschaft : Falscher Wert fr Eigenschaft */
+ Text [ en-US ] = "Incorrect property value." ;
+ };
+ String SbERR_PROP_READONLY & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Eigenschaft ist schreibgesch³tzt : Eigenschaft ist schreibgeschtzt */
+ Text [ en-US ] = "This property is read-only." ;
+ };
+ String SbERR_PROP_WRITEONLY & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Eigenschaft ist lesegesch³tzt : Eigenschaft ist lesegeschtzt */
+ Text [ en-US ] = "This property is write only." ;
+ };
+ String SbERR_INVALID_OBJECT & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Ung³ltige Objektreferenz : Ungltige Objektreferenz */
+ Text [ en-US ] = "Invalid object reference." ;
+ };
+ String SbERR_NO_METHOD & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Property or method not found: $(ARG1)." ;
+ };
+ String SbERR_NEEDS_OBJECT & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Object required." ;
+ };
+ String SbERR_INVALID_USAGE_OBJECT & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Invalid use of an object." ;
+ };
+ String SbERR_NO_OLE & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? OLE-Automatisierung wird von diesem Objekt nicht unterst³tzt : OLE-Automatisierung wird von diesem Objekt nicht untersttzt */
+ Text [ en-US ] = "OLE Automation is not supported by this object." ;
+ };
+ String SbERR_BAD_METHOD & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Objekt unterst³tzt diese Eigenschaft oder Methode nicht : Objekt untersttzt diese Eigenschaft oder Methode nicht */
+ Text [ en-US ] = "This property or method is not supported by the object." ;
+ };
+ String SbERR_OLE_ERROR & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "OLE Automation Error." ;
+ };
+ String SbERR_BAD_ACTION & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Diese Aktion wird vom angegebenen Objekt nicht unterst³tzt : Diese Aktion wird vom angegebenen Objekt nicht untersttzt */
+ Text [ en-US ] = "This action is not supported by given object." ;
+ };
+ String SbERR_NO_NAMED_ARGS & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Benannte Argumente werden vom angegebenen Objekt nicht unterst³tzt : Benannte Argumente werden vom angegebenen Objekt nicht untersttzt */
+ Text [ en-US ] = "Named arguments are not supported by given object." ;
+ };
+ String SbERR_BAD_LOCALE & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Das aktuelle Gebietsschema wird vom angegebenen Objekt nicht unterst³tzt : Das aktuelle Gebietsschema wird vom angegebenen Objekt nicht untersttzt */
+ Text [ en-US ] = "The current locale setting is not supported by the given object." ;
+ };
+ String SbERR_NAMED_NOT_FOUND & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Named argument not found." ;
+ };
+ String SbERR_NOT_OPTIONAL & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Argument is not optional." ;
+ };
+ String SbERR_WRONG_ARGS & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Invalid number of arguments." ;
+ };
+ String SbERR_NOT_A_COLL & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Object is not a list." ;
+ };
+ String SbERR_BAD_ORDINAL & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Ordnungszahl ung³ltig : Ordnungszahl ungltig */
+ Text [ en-US ] = "Invalid ordinal number." ;
+ };
+ String SbERR_DLLPROC_NOT_FOUND & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Specified DLL function not found." ;
+ };
+ String SbERR_BAD_CLIPBD_FORMAT & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Ung³ltiges Clipboard-Format : Ungltiges Clipboard-Format */
+ Text [ en-US ] = "Invalid clipboard format." ;
+ };
+ String SbERR_PROPERTY_NOT_FOUND & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Object does not have this property." ;
+ };
+ String SbERR_METHOD_NOT_FOUND & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Object does not have this method." ;
+ };
+ String SbERR_ARG_MISSING & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Required argument lacking." ;
+ };
+ String SbERR_BAD_NUMBER_OF_ARGS & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Ung³ltige Anzahl von Argumenten : Ungltige Anzahl von Argumenten */
+ Text [ en-US ] = "Invalid number of arguments." ;
+ };
+ String SbERR_METHOD_FAILED & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Fehler in Ausf³hrung einer Methode : Fehler in Ausfhrung einer Methode */
+ Text [ en-US ] = "Error executing a method." ;
+ };
+ String SbERR_SETPROP_FAILED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Unable to set property." ;
+ };
+ String SbERR_GETPROP_FAILED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Unable to determine property." ;
+ };
+ // Compiler errors. These are not runtime errors.
+ String SbERR_UNEXPECTED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Unexpected symbol: $(ARG1)." ;
+ };
+ String SbERR_EXPECTED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Expected: $(ARG1)." ;
+ };
+ String SbERR_SYMBOL_EXPECTED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Symbol expected." ;
+ };
+ String SbERR_VAR_EXPECTED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Variable expected." ;
+ };
+ String SbERR_LABEL_EXPECTED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Label expected." ;
+ };
+ String SbERR_LVALUE_EXPECTED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Value cannot be applied." ;
+ };
+ String SbERR_VAR_DEFINED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Variable $(ARG1) already defined." ;
+ };
+ String SbERR_PROC_DEFINED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Sub procedure or function procedure $(ARG1) already defined." ;
+ };
+ String SbERR_LABEL_DEFINED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Label $(ARG1) already defined." ;
+ };
+ String SbERR_UNDEF_VAR & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Variable $(ARG1) not found." ;
+ };
+ String SbERR_UNDEF_ARRAY & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Array or procedure $(ARG1) not found." ;
+ };
+ String SbERR_UNDEF_PROC & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Procedure $(ARG1) not found." ;
+ };
+ String SbERR_UNDEF_LABEL & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Label $(ARG1) undefined." ;
+ };
+ String SbERR_UNDEF_TYPE & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Unknown data type $(ARG1)." ;
+ };
+ String SbERR_BAD_EXIT & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Exit $(ARG1) expected." ;
+ };
+ String SbERR_BAD_BLOCK & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Statement block still open: $(ARG1) missing." ;
+ };
+ String SbERR_BAD_BRACKETS & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Parentheses do not match." ;
+ };
+ String SbERR_BAD_DECLARATION & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Symbol $(ARG1) already defined differently." ;
+ };
+ String SbERR_BAD_PARAMETERS & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Parameters do not correspond to procedure." ;
+ };
+ String SbERR_BAD_CHAR_IN_NUMBER & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Ung³ltiges Zeichen in Zahl : Ungltiges Zeichen in Zahl */
+ Text [ en-US ] = "Invalid character in number." ;
+ };
+ String SbERR_MUST_HAVE_DIMS & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Array mu˜ dimensioniert werden : Array muÿ dimensioniert werden */
+ Text [ en-US ] = "Array must be dimensioned." ;
+ };
+ String SbERR_NO_IF & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Else/Endif without If." ;
+ };
+ String SbERR_NOT_IN_SUBR & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? $(ARG1) innerhalb einer Prozedur unzulõssig : $(ARG1) innerhalb einer Prozedur unzul§ssig */
+ Text [ en-US ] = "$(ARG1) not allowed within a procedure." ;
+ };
+ String SbERR_NOT_IN_MAIN & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? $(ARG1) au˜erhalb einer Prozedur unzulõssig : $(ARG1) auÿerhalb einer Prozedur unzul§ssig */
+ Text [ en-US ] = "$(ARG1) not allowed outside a procedure." ;
+ };
+ String SbERR_WRONG_DIMS & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Dimension specifications do not match." ;
+ };
+ String SbERR_BAD_OPTION & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Unknown option: $(ARG1)." ;
+ };
+ String SbERR_CONSTANT_REDECLARED & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Constant $(ARG1) redefined." ;
+ };
+ String SbERR_PROG_TOO_LARGE & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Programm ist zu gro˜ : Programm ist zu groÿ */
+ Text [ en-US ] = "Program too large." ;
+ };
+ String SbERR_NO_STRINGS_ARRAYS & ERRCODE_RES_MASK
+ {
+ /* ### ACHTUNG: Neuer Text in Resource? Strings oder Arrays unzulõssig : Strings oder Arrays unzul§ssig */
+ Text [ en-US ] = "Strings or arrays not permitted." ;
+ };
+ String ERRCODE_BASIC_EXCEPTION & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "An exception occurred $(ARG1)." ;
+ };
+ String ERRCODE_BASIC_ARRAY_FIX & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "This array is fixed or temporarily locked." ;
+ };
+ String ERRCODE_BASIC_STRING_OVERFLOW & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Out of string space." ;
+ };
+ String ERRCODE_BASIC_EXPR_TOO_COMPLEX & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Expression Too Complex." ;
+ };
+ String ERRCODE_BASIC_OPER_NOT_PERFORM & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Can't perform requested operation." ;
+ };
+ String ERRCODE_BASIC_TOO_MANY_DLL & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Too many DLL application clients." ;
+ };
+ String ERRCODE_BASIC_LOOP_NOT_INIT & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "For loop not initialized." ;
+ };
+ String ERRCODE_BASIC_COMPAT & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "$(ARG1)" ;
+ };
+};
+ // Hinweis: IDS_SBERR_TERMINATED = IDS_SBERR_START+2000.
+String IDS_SBERR_TERMINATED
+{
+ Text [ en-US ] = "The macro running has been interrupted" ;
+};
+String IDS_SBERR_STOREREF
+{
+ Text [ en-US ] = "Reference will not be saved: ";
+};
+String ERRCODE_BASMGR_LIBLOAD & ERRCODE_RES_MASK
+{
+ /* ### ACHTUNG: Neuer Text in Resource? Fehler beim Laden der Bibliothek '$(ARG1)' : Fehler beim Laden der Bibliothek ''$(ARG1)'' */
+ /* ### ACHTUNG: Neuer Text in Resource? Fehler beim Laden der Bibliothek '$(ARG1)' : Fehler beim Laden der Bibliothek ''$(ARG1) */
+ /* ### ACHTUNG: Neuer Text in Resource? Fehler beim Laden der Bibliothek '$(ARG1)' : Fehler beim Laden der Bibliothek ''$(ARG1) */
+ /* ### ACHTUNG: Neuer Text in Resource? Fehler beim Laden der Bibliothek '$(ARG1)' : Fehler beim Laden der Bibliothek ''$(ARG1)'' */
+ Text [ en-US ] = "Error loading library '$(ARG1)'." ;
+};
+String ERRCODE_BASMGR_LIBSAVE & ERRCODE_RES_MASK
+{
+ /* ### ACHTUNG: Neuer Text in Resource? Fehler beim Speichern der Bibliothek: '$(ARG1)' : Fehler beim Speichern der Bibliothek: ''$(ARG1)'' */
+ /* ### ACHTUNG: Neuer Text in Resource? Fehler beim Speichern der Bibliothek: '$(ARG1)' : Fehler beim Speichern der Bibliothek: ''$(ARG1) */
+ /* ### ACHTUNG: Neuer Text in Resource? Fehler beim Speichern der Bibliothek: '$(ARG1)' : Fehler beim Speichern der Bibliothek: ''$(ARG1) */
+ /* ### ACHTUNG: Neuer Text in Resource? Fehler beim Speichern der Bibliothek: '$(ARG1)' : Fehler beim Speichern der Bibliothek: ''$(ARG1)'' */
+ Text [ en-US ] = "Error saving library: '$(ARG1)'." ;
+};
+String ERRCODE_BASMGR_MGROPEN & ERRCODE_RES_MASK
+{
+ /* ### ACHTUNG: Neuer Text in Resource? Das BASIC aus der Datei '$(ARG1)' konnte nicht initialisiert werden : Das BASIC aus der Datei ''$(ARG1)'' konnte nicht initialisiert werden */
+ /* ### ACHTUNG: Neuer Text in Resource? Das BASIC aus der Datei '$(ARG1)' konnte nicht initialisiert werden : Das BASIC aus der Datei ''$(ARG1)'' konnte nicht initialisiert werden */
+ /* ### ACHTUNG: Neuer Text in Resource? Das BASIC aus der Datei '$(ARG1)' konnte nicht initialisiert werden : Das BASIC aus der Datei ''$(ARG1)'' konnte nicht initialisiert werden */
+ /* ### ACHTUNG: Neuer Text in Resource? Das BASIC aus der Datei '$(ARG1)' konnte nicht initialisiert werden : Das BASIC aus der Datei ''$(ARG1)'' konnte nicht initialisiert werden */
+ Text [ en-US ] = "The BASIC from the file '$(ARG1)' could not be initialized." ;
+};
+String ERRCODE_BASMGR_MGRSAVE & ERRCODE_RES_MASK
+{
+ Text [ en-US ] = "Error saving BASIC: '$(ARG1)'." ;
+};
+String ERRCODE_BASMGR_REMOVELIB & ERRCODE_RES_MASK
+{
+ Text [ en-US ] = "Error removing library." ;
+};
+String ERRCODE_BASMGR_UNLOADLIB & ERRCODE_RES_MASK
+{
+ Text [ en-US ] = "The library could not be removed from memory." ;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/basic/source/classes/sbintern.cxx b/basic/source/classes/sbintern.cxx
new file mode 100644
index 000000000000..2b1f32e474d5
--- /dev/null
+++ b/basic/source/classes/sbintern.cxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_basic.hxx"
+#include <tools/shl.hxx>
+
+#include "sbintern.hxx"
+#include "sbunoobj.hxx"
+#include "token.hxx" // Tokenizer
+#include "symtbl.hxx" // Symbolverwaltung
+#include "parser.hxx" // Parser
+#include "codegen.hxx" // Code-Generator
+#include <basic/basmgr.hxx>
+
+SV_IMPL_PTRARR(SbErrorStack, SbErrorStackEntry*)
+
+SbiGlobals* GetSbData()
+{
+ SbiGlobals** pp = (SbiGlobals**) ::GetAppData( SHL_SBC );
+ SbiGlobals* p = *pp;
+ if( !p )
+ p = *pp = new SbiGlobals;
+ return p;
+}
+
+SbiGlobals::SbiGlobals()
+{
+ pInst = NULL;
+ pMod = NULL;
+ pSbFac= NULL;
+ pUnoFac = NULL;
+ pTypeFac = NULL;
+ pOLEFac = NULL;
+ pCompMod = NULL; // JSM
+ nInst = 0;
+ nCode = 0;
+ nLine = 0;
+ nCol1 = nCol2 = 0;
+ bCompiler = sal_False;
+ bGlobalInitErr = sal_False;
+ bRunInit = sal_False;
+ eLanguageMode = SB_LANG_BASIC;
+ pErrStack = NULL;
+ pTransliterationWrapper = NULL;
+ bBlockCompilerError = sal_False;
+ pAppBasMgr = NULL;
+ pMSOMacroRuntimLib = NULL;
+}
+
+SbiGlobals::~SbiGlobals()
+{
+ delete pErrStack;
+ delete pSbFac;
+ delete pUnoFac;
+ delete pTransliterationWrapper;
+}
+
diff --git a/basic/source/classes/sbunoobj.cxx b/basic/source/classes/sbunoobj.cxx
new file mode 100755
index 000000000000..13ae406cb305
--- /dev/null
+++ b/basic/source/classes/sbunoobj.cxx
@@ -0,0 +1,4855 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_basic.hxx"
+//#include <stl_queue.h>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#ifndef _TOOLERR_HXX //autogen
+#include <tools/errcode.hxx>
+#endif
+#include <svl/hint.hxx>
+
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <comphelper/extract.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+
+#include <com/sun/star/script/ArrayWrapper.hpp>
+#include <com/sun/star/script/NativeObjectWrapper.hpp>
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/uno/DeploymentException.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyConcept.hpp>
+#include <com/sun/star/beans/MethodConcept.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/script/BasicErrorException.hpp>
+#include <com/sun/star/script/XAllListener.hpp>
+#include <com/sun/star/script/XInvocationAdapterFactory.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/script/XDefaultProperty.hpp>
+#include <com/sun/star/script/XDirectInvocation.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/reflection/XIdlArray.hpp>
+#include <com/sun/star/reflection/XIdlReflection.hpp>
+#include <com/sun/star/reflection/XIdlClassProvider.hpp>
+#include <com/sun/star/reflection/XServiceConstructorDescription.hpp>
+#include <com/sun/star/bridge/oleautomation/NamedArgument.hpp>
+#include <com/sun/star/bridge/oleautomation/Date.hpp>
+#include <com/sun/star/bridge/oleautomation/Decimal.hpp>
+#include <com/sun/star/bridge/oleautomation/Currency.hpp>
+#include <com/sun/star/bridge/oleautomation/XAutomationObject.hpp>
+
+
+using com::sun::star::uno::Reference;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::reflection;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::script;
+using namespace com::sun::star::container;
+using namespace com::sun::star::bridge;
+using namespace cppu;
+
+
+#include<basic/sbstar.hxx>
+#include<basic/sbuno.hxx>
+#include<basic/sberrors.hxx>
+#include<sbunoobj.hxx>
+#include"sbjsmod.hxx"
+#include<basic/basmgr.hxx>
+#include<sbintern.hxx>
+#include<runtime.hxx>
+
+#include<math.h>
+#include <hash_map>
+#include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
+#include <com/sun/star/reflection/XConstantsTypeDescription.hpp>
+
+TYPEINIT1(SbUnoMethod,SbxMethod)
+TYPEINIT1(SbUnoProperty,SbxProperty)
+TYPEINIT1(SbUnoObject,SbxObject)
+TYPEINIT1(SbUnoClass,SbxObject)
+TYPEINIT1(SbUnoService,SbxObject)
+TYPEINIT1(SbUnoServiceCtor,SbxMethod)
+TYPEINIT1(SbUnoSingleton,SbxObject)
+
+typedef WeakImplHelper1< XAllListener > BasicAllListenerHelper;
+
+// Flag, um immer ueber Invocation zu gehen
+//#define INVOCATION_ONLY
+
+
+// Identifier fuer die dbg_-Properies als Strings anlegen
+static char const ID_DBG_SUPPORTEDINTERFACES[] = "Dbg_SupportedInterfaces";
+static char const ID_DBG_PROPERTIES[] = "Dbg_Properties";
+static char const ID_DBG_METHODS[] = "Dbg_Methods";
+
+static ::rtl::OUString aSeqLevelStr( RTL_CONSTASCII_USTRINGPARAM("[]") );
+static ::rtl::OUString defaultNameSpace( RTL_CONSTASCII_USTRINGPARAM("ooo.vba") );
+
+// Gets the default property for an uno object. Note: There is some
+// redirection built in. The property name specifies the name
+// of the default property.
+
+bool SbUnoObject::getDefaultPropName( SbUnoObject* pUnoObj, String& sDfltProp )
+{
+ bool result = false;
+ Reference< XDefaultProperty> xDefaultProp( pUnoObj->maTmpUnoObj, UNO_QUERY );
+ if ( xDefaultProp.is() )
+ {
+ sDfltProp = xDefaultProp->getDefaultPropertyName();
+ if ( sDfltProp.Len() )
+ result = true;
+ }
+ return result;
+}
+
+SbxVariable* getDefaultProp( SbxVariable* pRef )
+{
+ SbxVariable* pDefaultProp = NULL;
+ if ( pRef->GetType() == SbxOBJECT )
+ {
+ SbxObject* pObj = PTR_CAST(SbxObject,(SbxVariable*) pRef);
+ if ( !pObj )
+ {
+ SbxBase* pObjVarObj = pRef->GetObject();
+ pObj = PTR_CAST(SbxObject,pObjVarObj);
+ }
+ if ( pObj && pObj->ISA(SbUnoObject) )
+ {
+ SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,(SbxObject*)pObj);
+ pDefaultProp = pUnoObj->GetDfltProperty();
+ }
+ }
+ return pDefaultProp;
+}
+
+Reference< XComponentContext > getComponentContext_Impl( void )
+{
+ static Reference< XComponentContext > xContext;
+
+ // Haben wir schon CoreReflection, sonst besorgen
+ if( !xContext.is() )
+ {
+ Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+ Reference< XPropertySet > xProps( xFactory, UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ if (xProps.is())
+ {
+ xProps->getPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext;
+ OSL_ASSERT( xContext.is() );
+ }
+ }
+ return xContext;
+}
+
+// CoreReflection statisch speichern
+Reference< XIdlReflection > getCoreReflection_Impl( void )
+{
+ static Reference< XIdlReflection > xCoreReflection;
+
+ // Haben wir schon CoreReflection, sonst besorgen
+ if( !xCoreReflection.is() )
+ {
+ Reference< XComponentContext > xContext = getComponentContext_Impl();
+ if( xContext.is() )
+ {
+ xContext->getValueByName(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection") ) )
+ >>= xCoreReflection;
+ OSL_ENSURE( xCoreReflection.is(), "### CoreReflection singleton not accessable!?" );
+ }
+ if( !xCoreReflection.is() )
+ {
+ throw DeploymentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection singleton not accessable") ),
+ Reference< XInterface >() );
+ }
+ }
+ return xCoreReflection;
+}
+
+// CoreReflection statisch speichern
+Reference< XHierarchicalNameAccess > getCoreReflection_HierarchicalNameAccess_Impl( void )
+{
+ static Reference< XHierarchicalNameAccess > xCoreReflection_HierarchicalNameAccess;
+
+ if( !xCoreReflection_HierarchicalNameAccess.is() )
+ {
+ Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
+ if( xCoreReflection.is() )
+ {
+ xCoreReflection_HierarchicalNameAccess =
+ Reference< XHierarchicalNameAccess >( xCoreReflection, UNO_QUERY );
+ }
+ }
+ return xCoreReflection_HierarchicalNameAccess;
+}
+
+// Hold TypeProvider statically
+Reference< XHierarchicalNameAccess > getTypeProvider_Impl( void )
+{
+ static Reference< XHierarchicalNameAccess > xAccess;
+
+ // Haben wir schon CoreReflection, sonst besorgen
+ if( !xAccess.is() )
+ {
+ Reference< XComponentContext > xContext = getComponentContext_Impl();
+ if( xContext.is() )
+ {
+ xContext->getValueByName(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theTypeDescriptionManager") ) )
+ >>= xAccess;
+ OSL_ENSURE( xAccess.is(), "### TypeDescriptionManager singleton not accessable!?" );
+ }
+ if( !xAccess.is() )
+ {
+ throw DeploymentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM
+ ("/singletons/com.sun.star.reflection.theTypeDescriptionManager singleton not accessable") ),
+ Reference< XInterface >() );
+ }
+ }
+ return xAccess;
+}
+
+// Hold TypeConverter statically
+Reference< XTypeConverter > getTypeConverter_Impl( void )
+{
+ static Reference< XTypeConverter > xTypeConverter;
+
+ // Haben wir schon CoreReflection, sonst besorgen
+ if( !xTypeConverter.is() )
+ {
+ Reference< XComponentContext > xContext = getComponentContext_Impl();
+ if( xContext.is() )
+ {
+ Reference<XMultiComponentFactory> xSMgr = xContext->getServiceManager();
+ xTypeConverter = Reference<XTypeConverter>(
+ xSMgr->createInstanceWithContext(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter")),
+ xContext ), UNO_QUERY );
+ }
+ if( !xTypeConverter.is() )
+ {
+ throw DeploymentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM
+ ("com.sun.star.script.Converter service not accessable") ),
+ Reference< XInterface >() );
+ }
+ }
+ return xTypeConverter;
+}
+
+
+// #111851 factory function to create an OLE object
+SbUnoObject* createOLEObject_Impl( const String& aType )
+{
+ static Reference< XMultiServiceFactory > xOLEFactory;
+ static bool bNeedsInit = true;
+
+ if( bNeedsInit )
+ {
+ bNeedsInit = false;
+
+ Reference< XComponentContext > xContext = getComponentContext_Impl();
+ if( xContext.is() )
+ {
+ Reference<XMultiComponentFactory> xSMgr = xContext->getServiceManager();
+ xOLEFactory = Reference<XMultiServiceFactory>(
+ xSMgr->createInstanceWithContext(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.OleObjectFactory")),
+ xContext ), UNO_QUERY );
+ }
+ }
+
+ SbUnoObject* pUnoObj = NULL;
+ if( xOLEFactory.is() )
+ {
+ // some type names available in VBA can not be directly used in COM
+ ::rtl::OUString aOLEType = aType;
+ if ( aOLEType.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SAXXMLReader30" ) ) ) )
+ aOLEType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Msxml2.SAXXMLReader.3.0" ) );
+
+ Reference< XInterface > xOLEObject = xOLEFactory->createInstance( aOLEType );
+ if( xOLEObject.is() )
+ {
+ Any aAny;
+ aAny <<= xOLEObject;
+ pUnoObj = new SbUnoObject( aType, aAny );
+ }
+ }
+ return pUnoObj;
+}
+
+
+namespace
+{
+ void lcl_indent( ::rtl::OUStringBuffer& _inout_rBuffer, sal_Int32 _nLevel )
+ {
+ while ( _nLevel-- > 0 )
+ _inout_rBuffer.appendAscii( " " );
+ }
+}
+
+void implAppendExceptionMsg( ::rtl::OUStringBuffer& _inout_rBuffer, const Exception& _e, const ::rtl::OUString& _rExceptionType, sal_Int32 _nLevel )
+{
+ _inout_rBuffer.appendAscii( "\n" );
+ lcl_indent( _inout_rBuffer, _nLevel );
+ _inout_rBuffer.appendAscii( "Type: " );
+
+ if ( _rExceptionType.getLength() == 0 )
+ _inout_rBuffer.appendAscii( "Unknown" );
+ else
+ _inout_rBuffer.append( _rExceptionType );
+
+ _inout_rBuffer.appendAscii( "\n" );
+ lcl_indent( _inout_rBuffer, _nLevel );
+ _inout_rBuffer.appendAscii( "Message: " );
+ _inout_rBuffer.append( _e.Message );
+
+}
+
+// Fehlermeldungs-Message bei Exception zusammenbauen
+::rtl::OUString implGetExceptionMsg( const Exception& e, const ::rtl::OUString& aExceptionType_ )
+{
+ ::rtl::OUStringBuffer aMessageBuf;
+ implAppendExceptionMsg( aMessageBuf, e, aExceptionType_, 0 );
+ return aMessageBuf.makeStringAndClear();
+}
+
+String implGetExceptionMsg( const Any& _rCaughtException )
+{
+ OSL_PRECOND( _rCaughtException.getValueTypeClass() == TypeClass_EXCEPTION, "implGetExceptionMsg: illegal argument!" );
+ if ( _rCaughtException.getValueTypeClass() != TypeClass_EXCEPTION )
+ return String();
+
+ return implGetExceptionMsg( *static_cast< const Exception* >( _rCaughtException.getValue() ), _rCaughtException.getValueTypeName() );
+}
+
+Any convertAny( const Any& rVal, const Type& aDestType )
+{
+ Any aConvertedVal;
+ Reference< XTypeConverter > xConverter = getTypeConverter_Impl();
+ try
+ {
+ aConvertedVal = xConverter->convertTo( rVal, aDestType );
+ }
+ catch( const IllegalArgumentException& )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( ::cppu::getCaughtException() ) );
+ return aConvertedVal;
+ }
+ catch( CannotConvertException& e2 )
+ {
+ String aCannotConvertExceptionName
+ ( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.IllegalArgumentException" ) );
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( e2, aCannotConvertExceptionName ) );
+ return aConvertedVal;
+ }
+ return aConvertedVal;
+}
+
+
+// #105565 Special Object to wrap a strongly typed Uno Any
+TYPEINIT1(SbUnoAnyObject,SbxObject)
+
+
+// TODO: Spaeter auslagern
+Reference<XIdlClass> TypeToIdlClass( const Type& rType )
+{
+ // void als Default-Klasse eintragen
+ Reference<XIdlClass> xRetClass;
+ typelib_TypeDescription * pTD = 0;
+ rType.getDescription( &pTD );
+
+ if( pTD )
+ {
+ ::rtl::OUString sOWName( pTD->pTypeName );
+ Reference< XIdlReflection > xRefl = getCoreReflection_Impl();
+ xRetClass = xRefl->forName( sOWName );
+ }
+ return xRetClass;
+}
+
+// Exception type unknown
+template< class EXCEPTION >
+String implGetExceptionMsg( const EXCEPTION& e )
+{
+ return implGetExceptionMsg( e, ::getCppuType( &e ).getTypeName() );
+}
+
+// Error-Message fuer WrappedTargetExceptions
+String implGetWrappedMsg( const WrappedTargetException& e )
+{
+ String aMsg;
+ Any aWrappedAny = e.TargetException;
+ Type aExceptionType = aWrappedAny.getValueType();
+
+ // Really an Exception?
+ if( aExceptionType.getTypeClass() == TypeClass_EXCEPTION )
+ {
+ Exception& e_ = *( (Exception*)aWrappedAny.getValue() );
+ aMsg = implGetExceptionMsg( e_, String( aExceptionType.getTypeName() ) );
+ }
+ // Otherwise use WrappedTargetException itself
+ else
+ {
+ aMsg = implGetExceptionMsg( e );
+ }
+
+ return aMsg;
+}
+
+void implHandleBasicErrorException( BasicErrorException& e )
+{
+ SbError nError = StarBASIC::GetSfxFromVBError( (sal_uInt16)e.ErrorCode );
+ StarBASIC::Error( nError, e.ErrorMessageArgument );
+}
+
+void implHandleWrappedTargetException( const Any& _rWrappedTargetException )
+{
+ Any aExamine( _rWrappedTargetException );
+
+ // completely strip the first InvocationTargetException, its error message isn't of any
+ // interest to the user, it just says something like "invoking the UNO method went wrong.".
+ InvocationTargetException aInvocationError;
+ if ( aExamine >>= aInvocationError )
+ aExamine = aInvocationError.TargetException;
+
+ BasicErrorException aBasicError;
+
+ SbError nError( ERRCODE_BASIC_EXCEPTION );
+ ::rtl::OUStringBuffer aMessageBuf;
+
+ // strip any other WrappedTargetException instances, but this time preserve the error messages.
+ WrappedTargetException aWrapped;
+ sal_Int32 nLevel = 0;
+ while ( aExamine >>= aWrapped )
+ {
+ // special handling for BasicErrorException errors
+ if ( aWrapped.TargetException >>= aBasicError )
+ {
+ nError = StarBASIC::GetSfxFromVBError( (sal_uInt16)aBasicError.ErrorCode );
+ aMessageBuf.append( aBasicError.ErrorMessageArgument );
+ aExamine.clear();
+ break;
+ }
+
+ // append this round's message
+ implAppendExceptionMsg( aMessageBuf, aWrapped, aExamine.getValueTypeName(), nLevel );
+ if ( aWrapped.TargetException.getValueTypeClass() == TypeClass_EXCEPTION )
+ // there is a next chain element
+ aMessageBuf.appendAscii( "\nTargetException:" );
+
+ // next round
+ aExamine = aWrapped.TargetException;
+ ++nLevel;
+ }
+
+ if ( aExamine.getValueTypeClass() == TypeClass_EXCEPTION )
+ {
+ // the last element in the chain is still an exception, but no WrappedTargetException
+ implAppendExceptionMsg( aMessageBuf, *static_cast< const Exception* >( aExamine.getValue() ), aExamine.getValueTypeName(), nLevel );
+ }
+
+ StarBASIC::Error( nError, aMessageBuf.makeStringAndClear() );
+}
+
+static void implHandleAnyException( const Any& _rCaughtException )
+{
+ BasicErrorException aBasicError;
+ WrappedTargetException aWrappedError;
+
+ if ( _rCaughtException >>= aBasicError )
+ {
+ implHandleBasicErrorException( aBasicError );
+ }
+ else if ( _rCaughtException >>= aWrappedError )
+ {
+ implHandleWrappedTargetException( _rCaughtException );
+ }
+ else
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( _rCaughtException ) );
+ }
+}
+
+
+// NativeObjectWrapper handling
+struct ObjectItem
+{
+ SbxObjectRef m_xNativeObj;
+
+ ObjectItem( void )
+ {}
+ ObjectItem( SbxObject* pNativeObj )
+ : m_xNativeObj( pNativeObj )
+ {}
+};
+static std::vector< ObjectItem > GaNativeObjectWrapperVector;
+
+void clearNativeObjectWrapperVector( void )
+{
+ GaNativeObjectWrapperVector.clear();
+}
+
+sal_uInt32 lcl_registerNativeObjectWrapper( SbxObject* pNativeObj )
+{
+ sal_uInt32 nIndex = GaNativeObjectWrapperVector.size();
+ GaNativeObjectWrapperVector.push_back( ObjectItem( pNativeObj ) );
+ return nIndex;
+}
+
+SbxObject* lcl_getNativeObject( sal_uInt32 nIndex )
+{
+ SbxObjectRef xRetObj;
+ if( nIndex < GaNativeObjectWrapperVector.size() )
+ {
+ ObjectItem& rItem = GaNativeObjectWrapperVector[ nIndex ];
+ xRetObj = rItem.m_xNativeObj;
+ }
+ return xRetObj;
+}
+
+
+// Von Uno nach Sbx wandeln
+SbxDataType unoToSbxType( TypeClass eType )
+{
+ SbxDataType eRetType = SbxVOID;
+
+ switch( eType )
+ {
+ case TypeClass_INTERFACE:
+ case TypeClass_TYPE:
+ case TypeClass_STRUCT:
+ case TypeClass_EXCEPTION: eRetType = SbxOBJECT; break;
+
+ /* folgende Typen lassen wir erstmal weg
+ case TypeClass_SERVICE: break;
+ case TypeClass_CLASS: break;
+ case TypeClass_TYPEDEF: break;
+ case TypeClass_UNION: break;
+ case TypeClass_ARRAY: break;
+ */
+ case TypeClass_ENUM: eRetType = SbxLONG; break;
+ case TypeClass_SEQUENCE:
+ eRetType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
+ break;
+
+ /*
+ case TypeClass_VOID: break;
+ case TypeClass_UNKNOWN: break;
+ */
+
+ case TypeClass_ANY: eRetType = SbxVARIANT; break;
+ case TypeClass_BOOLEAN: eRetType = SbxBOOL; break;
+ case TypeClass_CHAR: eRetType = SbxCHAR; break;
+ case TypeClass_STRING: eRetType = SbxSTRING; break;
+ case TypeClass_FLOAT: eRetType = SbxSINGLE; break;
+ case TypeClass_DOUBLE: eRetType = SbxDOUBLE; break;
+ //case TypeClass_OCTET: break;
+ case TypeClass_BYTE: eRetType = SbxINTEGER; break;
+ //case TypeClass_INT: eRetType = SbxINT; break;
+ case TypeClass_SHORT: eRetType = SbxINTEGER; break;
+ case TypeClass_LONG: eRetType = SbxLONG; break;
+ case TypeClass_HYPER: eRetType = SbxSALINT64; break;
+ //case TypeClass_UNSIGNED_OCTET: break;
+ case TypeClass_UNSIGNED_SHORT: eRetType = SbxUSHORT; break;
+ case TypeClass_UNSIGNED_LONG: eRetType = SbxULONG; break;
+ case TypeClass_UNSIGNED_HYPER: eRetType = SbxSALUINT64;break;
+ //case TypeClass_UNSIGNED_INT: eRetType = SbxUINT; break;
+ //case TypeClass_UNSIGNED_BYTE: eRetType = SbxUSHORT; break;
+ default: break;
+ }
+ return eRetType;
+}
+
+SbxDataType unoToSbxType( const Reference< XIdlClass >& xIdlClass )
+{
+ SbxDataType eRetType = SbxVOID;
+ if( xIdlClass.is() )
+ {
+ TypeClass eType = xIdlClass->getTypeClass();
+ eRetType = unoToSbxType( eType );
+ }
+ return eRetType;
+}
+
+static void implSequenceToMultiDimArray( SbxDimArray*& pArray, Sequence< sal_Int32 >& indices, Sequence< sal_Int32 >& sizes, const Any& aValue, sal_Int32& dimension, sal_Bool bIsZeroIndex, Type* pType = NULL )
+{
+ Type aType = aValue.getValueType();
+ TypeClass eTypeClass = aType.getTypeClass();
+
+ sal_Int32 indicesIndex = indices.getLength() -1;
+ sal_Int32 dimCopy = dimension;
+
+ if ( eTypeClass == TypeClass_SEQUENCE )
+ {
+ Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aType );
+ Reference< XIdlArray > xIdlArray = xIdlTargetClass->getArray();
+ typelib_TypeDescription * pTD = 0;
+ aType.getDescription( &pTD );
+ Type aElementType( ((typelib_IndirectTypeDescription *)pTD)->pType );
+ ::typelib_typedescription_release( pTD );
+
+ sal_Int32 nLen = xIdlArray->getLen( aValue );
+ for ( sal_Int32 index = 0; index < nLen; ++index )
+ {
+ Any aElementAny = xIdlArray->get( aValue, (sal_uInt32)index );
+ // This detects the dimension were currently processing
+ if ( dimCopy == dimension )
+ {
+ ++dimCopy;
+ if ( sizes.getLength() < dimCopy )
+ {
+ sizes.realloc( sizes.getLength() + 1 );
+ sizes[ sizes.getLength() - 1 ] = nLen;
+ indices.realloc( indices.getLength() + 1 );
+ indicesIndex = indices.getLength() - 1;
+ }
+ }
+
+ if ( bIsZeroIndex )
+ indices[ dimCopy - 1 ] = index;
+ else
+ indices[ dimCopy - 1] = index + 1;
+
+ implSequenceToMultiDimArray( pArray, indices, sizes, aElementAny, dimCopy, bIsZeroIndex, &aElementType );
+ }
+
+ }
+ else
+ {
+ if ( indices.getLength() < 1 )
+ {
+ // Should never ever get here ( indices.getLength()
+ // should equal number of dimensions in the array )
+ // And that should at least be 1 !
+ // #QUESTION is there a better error?
+ StarBASIC::Error( SbERR_INVALID_OBJECT );
+ return;
+ }
+
+ SbxDataType eSbxElementType = unoToSbxType( pType ? pType->getTypeClass() : aValue.getValueTypeClass() );
+ if ( !pArray )
+ {
+ pArray = new SbxDimArray( eSbxElementType );
+ sal_Int32 nIndexLen = indices.getLength();
+
+ // Dimension the array
+ for ( sal_Int32 index = 0; index < nIndexLen; ++index )
+ {
+ if ( bIsZeroIndex )
+ pArray->unoAddDim32( 0, sizes[ index ] - 1);
+ else
+ pArray->unoAddDim32( 1, sizes[ index ] );
+
+ }
+ }
+
+ if ( pArray )
+ {
+ SbxVariableRef xVar = new SbxVariable( eSbxElementType );
+ unoToSbxValue( (SbxVariable*)xVar, aValue );
+
+ sal_Int32* pIndices = indices.getArray();
+ pArray->Put32( (SbxVariable*)xVar, pIndices );
+
+ }
+ }
+}
+
+void unoToSbxValue( SbxVariable* pVar, const Any& aValue )
+{
+ Type aType = aValue.getValueType();
+ TypeClass eTypeClass = aType.getTypeClass();
+ switch( eTypeClass )
+ {
+ case TypeClass_TYPE:
+ {
+ // Map Type to IdlClass
+ Type aType_;
+ aValue >>= aType_;
+ Reference<XIdlClass> xClass = TypeToIdlClass( aType_ );
+ Any aClassAny;
+ aClassAny <<= xClass;
+
+ // SbUnoObject instanzieren
+ String aName;
+ SbUnoObject* pSbUnoObject = new SbUnoObject( aName, aClassAny );
+ SbxObjectRef xWrapper = (SbxObject*)pSbUnoObject;
+
+ // #51475 Wenn das Objekt ungueltig ist null liefern
+ if( pSbUnoObject->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID )
+ {
+ pVar->PutObject( NULL );
+ }
+ else
+ {
+ pVar->PutObject( xWrapper );
+ }
+ }
+ break;
+ // Interfaces und Structs muessen in ein SbUnoObject gewrappt werden
+ case TypeClass_INTERFACE:
+ case TypeClass_STRUCT:
+ case TypeClass_EXCEPTION:
+ {
+ if( eTypeClass == TypeClass_STRUCT )
+ {
+ ArrayWrapper aWrap;
+ NativeObjectWrapper aNativeObjectWrapper;
+ if ( (aValue >>= aWrap) )
+ {
+ SbxDimArray* pArray = NULL;
+ Sequence< sal_Int32 > indices;
+ Sequence< sal_Int32 > sizes;
+ sal_Int32 dimension = 0;
+ implSequenceToMultiDimArray( pArray, indices, sizes, aWrap.Array, dimension, aWrap.IsZeroIndex );
+ if ( pArray )
+ {
+ SbxDimArrayRef xArray = pArray;
+ sal_uInt16 nFlags = pVar->GetFlags();
+ pVar->ResetFlag( SBX_FIXED );
+ pVar->PutObject( (SbxDimArray*)xArray );
+ pVar->SetFlags( nFlags );
+ }
+ else
+ pVar->PutEmpty();
+ break;
+ }
+ else if ( (aValue >>= aNativeObjectWrapper) )
+ {
+ sal_uInt32 nIndex = 0;
+ if( (aNativeObjectWrapper.ObjectId >>= nIndex) )
+ {
+ SbxObject* pObj = lcl_getNativeObject( nIndex );
+ pVar->PutObject( pObj );
+ }
+ else
+ pVar->PutEmpty();
+ break;
+ }
+ else
+ {
+ SbiInstance* pInst = pINST;
+ if( pInst && pInst->IsCompatibility() )
+ {
+ oleautomation::Date aDate;
+ if( (aValue >>= aDate) )
+ {
+ pVar->PutDate( aDate.Value );
+ break;
+ }
+ else
+ {
+ oleautomation::Decimal aDecimal;
+ if( (aValue >>= aDecimal) )
+ {
+ pVar->PutDecimal( aDecimal );
+ break;
+ }
+ else
+ {
+ oleautomation::Currency aCurrency;
+ if( (aValue >>= aCurrency) )
+ {
+ sal_Int64 nValue64 = aCurrency.Value;
+ SbxINT64 aInt64;
+ aInt64.nHigh =
+ sal::static_int_cast< sal_Int32 >(
+ nValue64 >> 32);
+ aInt64.nLow = (sal_uInt32)( nValue64 & 0xffffffff );
+ pVar->PutCurrency( aInt64 );
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ // SbUnoObject instanzieren
+ String aName;
+ SbUnoObject* pSbUnoObject = new SbUnoObject( aName, aValue );
+ //If this is called externally e.g. from the scripting
+ //framework then there is no 'active' runtime the default property will not be set up
+ //only a vba object will have XDefaultProp set anyway so... this
+ //test seems a bit of overkill
+ //if ( SbiRuntime::isVBAEnabled() )
+ {
+ String sDfltPropName;
+
+ if ( SbUnoObject::getDefaultPropName( pSbUnoObject, sDfltPropName ) )
+ pSbUnoObject->SetDfltProperty( sDfltPropName );
+ }
+ SbxObjectRef xWrapper = (SbxObject*)pSbUnoObject;
+
+ // #51475 Wenn das Objekt ungueltig ist null liefern
+ if( pSbUnoObject->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID )
+ {
+ pVar->PutObject( NULL );
+ }
+ else
+ {
+ pVar->PutObject( xWrapper );
+ }
+ }
+ break;
+
+ /* folgende Typen lassen wir erstmal weg
+ case TypeClass_SERVICE: break;
+ case TypeClass_CLASS: break;
+ case TypeClass_TYPEDEF: break;
+ case TypeClass_UNION: break;
+ case TypeClass_ENUM: break;
+ case TypeClass_ARRAY: break;
+ */
+
+ case TypeClass_ENUM:
+ {
+ sal_Int32 nEnum = 0;
+ enum2int( nEnum, aValue );
+ pVar->PutLong( nEnum );
+ }
+ break;
+
+ case TypeClass_SEQUENCE:
+ {
+ Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aType );
+ Reference< XIdlArray > xIdlArray = xIdlTargetClass->getArray();
+ sal_Int32 i, nLen = xIdlArray->getLen( aValue );
+
+ typelib_TypeDescription * pTD = 0;
+ aType.getDescription( &pTD );
+ OSL_ASSERT( pTD && pTD->eTypeClass == typelib_TypeClass_SEQUENCE );
+ Type aElementType( ((typelib_IndirectTypeDescription *)pTD)->pType );
+ ::typelib_typedescription_release( pTD );
+
+ // In Basic Array anlegen
+ SbxDimArrayRef xArray;
+ SbxDataType eSbxElementType = unoToSbxType( aElementType.getTypeClass() );
+ xArray = new SbxDimArray( eSbxElementType );
+ if( nLen > 0 )
+ {
+ xArray->unoAddDim32( 0, nLen - 1 );
+
+ // Elemente als Variablen eintragen
+ for( i = 0 ; i < nLen ; i++ )
+ {
+ // Elemente wandeln
+ Any aElementAny = xIdlArray->get( aValue, (sal_uInt32)i );
+ SbxVariableRef xVar = new SbxVariable( eSbxElementType );
+ unoToSbxValue( (SbxVariable*)xVar, aElementAny );
+
+ // Ins Array braten
+ xArray->Put32( (SbxVariable*)xVar, &i );
+ }
+ }
+ else
+ {
+ xArray->unoAddDim( 0, -1 );
+ }
+
+ // Array zurueckliefern
+ sal_uInt16 nFlags = pVar->GetFlags();
+ pVar->ResetFlag( SBX_FIXED );
+ pVar->PutObject( (SbxDimArray*)xArray );
+ pVar->SetFlags( nFlags );
+
+ // #54548, Die Parameter duerfen hier nicht weggehauen werden
+ //pVar->SetParameters( NULL );
+ }
+ break;
+
+ /*
+ case TypeClass_VOID: break;
+ case TypeClass_UNKNOWN: break;
+
+ case TypeClass_ANY:
+ {
+ // Any rausholen und konvertieren
+ //Any* pAny = (Any*)aValue.get();
+ //if( pAny )
+ //unoToSbxValue( pVar, *pAny );
+ }
+ break;
+ */
+
+ case TypeClass_BOOLEAN: pVar->PutBool( *(sal_Bool*)aValue.getValue() ); break;
+ case TypeClass_CHAR:
+ {
+ pVar->PutChar( *(sal_Unicode*)aValue.getValue() );
+ break;
+ }
+ case TypeClass_STRING: { ::rtl::OUString val; aValue >>= val; pVar->PutString( String( val ) ); } break;
+ case TypeClass_FLOAT: { float val = 0; aValue >>= val; pVar->PutSingle( val ); } break;
+ case TypeClass_DOUBLE: { double val = 0; aValue >>= val; pVar->PutDouble( val ); } break;
+ //case TypeClass_OCTET: break;
+ case TypeClass_BYTE: { sal_Int8 val = 0; aValue >>= val; pVar->PutInteger( val ); } break;
+ //case TypeClass_INT: break;
+ case TypeClass_SHORT: { sal_Int16 val = 0; aValue >>= val; pVar->PutInteger( val ); } break;
+ case TypeClass_LONG: { sal_Int32 val = 0; aValue >>= val; pVar->PutLong( val ); } break;
+ case TypeClass_HYPER: { sal_Int64 val = 0; aValue >>= val; pVar->PutInt64( val ); } break;
+ //case TypeClass_UNSIGNED_OCTET:break;
+ case TypeClass_UNSIGNED_SHORT: { sal_uInt16 val = 0; aValue >>= val; pVar->PutUShort( val ); } break;
+ case TypeClass_UNSIGNED_LONG: { sal_uInt32 val = 0; aValue >>= val; pVar->PutULong( val ); } break;
+ case TypeClass_UNSIGNED_HYPER: { sal_uInt64 val = 0; aValue >>= val; pVar->PutUInt64( val ); } break;
+ //case TypeClass_UNSIGNED_INT: break;
+ //case TypeClass_UNSIGNED_BYTE: break;
+ default: pVar->PutEmpty(); break;
+ }
+}
+
+// Reflection fuer Sbx-Typen liefern
+Type getUnoTypeForSbxBaseType( SbxDataType eType )
+{
+ Type aRetType = getCppuVoidType();
+ switch( eType )
+ {
+ //case SbxEMPTY: eRet = TypeClass_VOID; break;
+ case SbxNULL: aRetType = ::getCppuType( (const Reference< XInterface > *)0 ); break;
+ case SbxINTEGER: aRetType = ::getCppuType( (sal_Int16*)0 ); break;
+ case SbxLONG: aRetType = ::getCppuType( (sal_Int32*)0 ); break;
+ case SbxSINGLE: aRetType = ::getCppuType( (float*)0 ); break;
+ case SbxDOUBLE: aRetType = ::getCppuType( (double*)0 ); break;
+ case SbxCURRENCY: aRetType = ::getCppuType( (oleautomation::Currency*)0 ); break;
+ case SbxDECIMAL: aRetType = ::getCppuType( (oleautomation::Decimal*)0 ); break;
+ case SbxDATE: {
+ SbiInstance* pInst = pINST;
+ if( pInst && pInst->IsCompatibility() )
+ aRetType = ::getCppuType( (double*)0 );
+ else
+ aRetType = ::getCppuType( (oleautomation::Date*)0 );
+ }
+ break;
+ // case SbxDATE: aRetType = ::getCppuType( (double*)0 ); break;
+ case SbxSTRING: aRetType = ::getCppuType( (::rtl::OUString*)0 ); break;
+ //case SbxOBJECT: break;
+ //case SbxERROR: break;
+ case SbxBOOL: aRetType = ::getCppuType( (sal_Bool*)0 ); break;
+ case SbxVARIANT: aRetType = ::getCppuType( (Any*)0 ); break;
+ //case SbxDATAOBJECT: break;
+ case SbxCHAR: aRetType = ::getCppuType( (sal_Unicode*)0 ); break;
+ case SbxBYTE: aRetType = ::getCppuType( (sal_Int8*)0 ); break;
+ case SbxUSHORT: aRetType = ::getCppuType( (sal_uInt16*)0 ); break;
+ case SbxULONG: aRetType = ::getCppuType( (sal_uInt32*)0 ); break;
+ //case SbxLONG64: break;
+ //case SbxULONG64: break;
+ // Maschinenabhaengige zur Sicherheit auf Hyper abbilden
+ case SbxINT: aRetType = ::getCppuType( (sal_Int32*)0 ); break;
+ case SbxUINT: aRetType = ::getCppuType( (sal_uInt32*)0 ); break;
+ //case SbxVOID: break;
+ //case SbxHRESULT: break;
+ //case SbxPOINTER: break;
+ //case SbxDIMARRAY: break;
+ //case SbxCARRAY: break;
+ //case SbxUSERDEF: break;
+ //case SbxLPSTR: break;
+ //case SbxLPWSTR: break;
+ //case SbxCoreSTRING: break;
+ default: break;
+ }
+ return aRetType;
+}
+
+// Konvertierung von Sbx nach Uno ohne bekannte Zielklasse fuer TypeClass_ANY
+Type getUnoTypeForSbxValue( SbxValue* pVal )
+{
+ Type aRetType = getCppuVoidType();
+ if( !pVal )
+ return aRetType;
+
+ // SbxType nach Uno wandeln
+ SbxDataType eBaseType = pVal->SbxValue::GetType();
+ if( eBaseType == SbxOBJECT )
+ {
+ SbxBaseRef xObj = (SbxBase*)pVal->GetObject();
+ if( !xObj )
+ {
+ // #109936 No error any more
+ // StarBASIC::Error( SbERR_INVALID_OBJECT );
+ aRetType = getCppuType( static_cast<Reference<XInterface> *>(0) );
+ return aRetType;
+ }
+
+ if( xObj->ISA(SbxDimArray) )
+ {
+ SbxBase* pObj = (SbxBase*)xObj;
+ SbxDimArray* pArray = (SbxDimArray*)pObj;
+
+ short nDims = pArray->GetDims();
+ Type aElementType = getUnoTypeForSbxBaseType( (SbxDataType)(pArray->GetType() & 0xfff) );
+ TypeClass eElementTypeClass = aElementType.getTypeClass();
+
+ // Normal case: One dimensional array
+ sal_Int32 nLower, nUpper;
+ if( nDims == 1 && pArray->GetDim32( 1, nLower, nUpper ) )
+ {
+ if( eElementTypeClass == TypeClass_VOID || eElementTypeClass == TypeClass_ANY )
+ {
+ // Wenn alle Elemente des Arrays vom gleichen Typ sind, wird
+ // der genommen, sonst wird das ganze als Any-Sequence betrachtet
+ sal_Bool bNeedsInit = sal_True;
+
+ sal_Int32 nSize = nUpper - nLower + 1;
+ sal_Int32 nIdx = nLower;
+ for( sal_Int32 i = 0 ; i < nSize ; i++,nIdx++ )
+ {
+ SbxVariableRef xVar = pArray->Get32( &nIdx );
+ Type aType = getUnoTypeForSbxValue( (SbxVariable*)xVar );
+ if( bNeedsInit )
+ {
+ if( aType.getTypeClass() == TypeClass_VOID )
+ {
+ // #88522
+ // if only first element is void: different types -> []any
+ // if all elements are void: []void is not allowed -> []any
+ aElementType = getCppuType( (Any*)0 );
+ break;
+ }
+ aElementType = aType;
+ bNeedsInit = sal_False;
+ }
+ else if( aElementType != aType )
+ {
+ // Verschiedene Typen -> AnySequence
+ aElementType = getCppuType( (Any*)0 );
+ break;
+ }
+ }
+ }
+
+ ::rtl::OUString aSeqTypeName( aSeqLevelStr );
+ aSeqTypeName += aElementType.getTypeName();
+ aRetType = Type( TypeClass_SEQUENCE, aSeqTypeName );
+ }
+ // #i33795 Map also multi dimensional arrays to corresponding sequences
+ else if( nDims > 1 )
+ {
+ if( eElementTypeClass == TypeClass_VOID || eElementTypeClass == TypeClass_ANY )
+ {
+ // For this check the array's dim structure does not matter
+ sal_uInt32 nFlatArraySize = pArray->Count32();
+
+ sal_Bool bNeedsInit = sal_True;
+ for( sal_uInt32 i = 0 ; i < nFlatArraySize ; i++ )
+ {
+ SbxVariableRef xVar = pArray->SbxArray::Get32( i );
+ Type aType = getUnoTypeForSbxValue( (SbxVariable*)xVar );
+ if( bNeedsInit )
+ {
+ if( aType.getTypeClass() == TypeClass_VOID )
+ {
+ // if only first element is void: different types -> []any
+ // if all elements are void: []void is not allowed -> []any
+ aElementType = getCppuType( (Any*)0 );
+ break;
+ }
+ aElementType = aType;
+ bNeedsInit = sal_False;
+ }
+ else if( aElementType != aType )
+ {
+ // Verschiedene Typen -> AnySequence
+ aElementType = getCppuType( (Any*)0 );
+ break;
+ }
+ }
+ }
+
+ ::rtl::OUString aSeqTypeName;
+ for( short iDim = 0 ; iDim < nDims ; iDim++ )
+ aSeqTypeName += aSeqLevelStr;
+ aSeqTypeName += aElementType.getTypeName();
+ aRetType = Type( TypeClass_SEQUENCE, aSeqTypeName );
+ }
+ }
+ // Kein Array, sondern...
+ else if( xObj->ISA(SbUnoObject) )
+ {
+ aRetType = ((SbUnoObject*)(SbxBase*)xObj)->getUnoAny().getValueType();
+ }
+ // SbUnoAnyObject?
+ else if( xObj->ISA(SbUnoAnyObject) )
+ {
+ aRetType = ((SbUnoAnyObject*)(SbxBase*)xObj)->getValue().getValueType();
+ }
+ // Sonst ist es ein Nicht-Uno-Basic-Objekt -> default==void liefern
+ }
+ // Kein Objekt, Basistyp konvertieren
+ else
+ {
+ aRetType = getUnoTypeForSbxBaseType( eBaseType );
+ }
+ return aRetType;
+}
+
+// Deklaration Konvertierung von Sbx nach Uno mit bekannter Zielklasse
+Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty = NULL );
+
+// Konvertierung von Sbx nach Uno ohne bekannte Zielklasse fuer TypeClass_ANY
+Any sbxToUnoValueImpl( SbxVariable* pVar, bool bBlockConversionToSmallestType = false )
+{
+ SbxDataType eBaseType = pVar->SbxValue::GetType();
+ if( eBaseType == SbxOBJECT )
+ {
+ SbxBaseRef xObj = (SbxBase*)pVar->GetObject();
+ if( xObj.Is() )
+ {
+ if( xObj->ISA(SbUnoAnyObject) )
+ return ((SbUnoAnyObject*)(SbxBase*)xObj)->getValue();
+ if( xObj->ISA(SbClassModuleObject) )
+ {
+ Any aRetAny;
+ SbClassModuleObject* pClassModuleObj = (SbClassModuleObject*)(SbxBase*)xObj;
+ SbModule* pClassModule = pClassModuleObj->getClassModule();
+ if( pClassModule->createCOMWrapperForIface( aRetAny, pClassModuleObj ) )
+ return aRetAny;
+ }
+ if( !xObj->ISA(SbUnoObject) )
+ {
+ // Create NativeObjectWrapper to identify object in case of callbacks
+ SbxObject* pObj = PTR_CAST(SbxObject,pVar->GetObject());
+ if( pObj != NULL )
+ {
+ NativeObjectWrapper aNativeObjectWrapper;
+ sal_uInt32 nIndex = lcl_registerNativeObjectWrapper( pObj );
+ aNativeObjectWrapper.ObjectId <<= nIndex;
+ Any aRetAny;
+ aRetAny <<= aNativeObjectWrapper;
+ return aRetAny;
+ }
+ }
+ }
+ }
+
+ Type aType = getUnoTypeForSbxValue( pVar );
+ TypeClass eType = aType.getTypeClass();
+
+ if( !bBlockConversionToSmallestType )
+ {
+ // #79615 Choose "smallest" represention for int values
+ // because up cast is allowed, downcast not
+ switch( eType )
+ {
+ case TypeClass_FLOAT:
+ case TypeClass_DOUBLE:
+ {
+ double d = pVar->GetDouble();
+ if( d == floor( d ) )
+ {
+ if( d >= -128 && d <= 127 )
+ aType = ::getCppuType( (sal_Int8*)0 );
+ else if( d >= SbxMININT && d <= SbxMAXINT )
+ aType = ::getCppuType( (sal_Int16*)0 );
+ else if( d >= -SbxMAXLNG && d <= SbxMAXLNG )
+ aType = ::getCppuType( (sal_Int32*)0 );
+ }
+ break;
+ }
+ case TypeClass_SHORT:
+ {
+ sal_Int16 n = pVar->GetInteger();
+ if( n >= -128 && n <= 127 )
+ aType = ::getCppuType( (sal_Int8*)0 );
+ break;
+ }
+ case TypeClass_LONG:
+ {
+ sal_Int32 n = pVar->GetLong();
+ if( n >= -128 && n <= 127 )
+ aType = ::getCppuType( (sal_Int8*)0 );
+ else if( n >= SbxMININT && n <= SbxMAXINT )
+ aType = ::getCppuType( (sal_Int16*)0 );
+ break;
+ }
+ case TypeClass_UNSIGNED_SHORT:
+ {
+ sal_uInt16 n = pVar->GetUShort();
+ if( n <= 255 )
+ aType = ::getCppuType( (sal_uInt8*)0 );
+ break;
+ }
+ case TypeClass_UNSIGNED_LONG:
+ {
+ sal_uInt32 n = pVar->GetLong();
+ if( n <= 255 )
+ aType = ::getCppuType( (sal_uInt8*)0 );
+ else if( n <= SbxMAXUINT )
+ aType = ::getCppuType( (sal_uInt16*)0 );
+ break;
+ }
+ default: break;
+ }
+ }
+
+ return sbxToUnoValue( pVar, aType );
+}
+
+
+
+// Helper function for StepREDIMP
+static Any implRekMultiDimArrayToSequence( SbxDimArray* pArray,
+ const Type& aElemType, short nMaxDimIndex, short nActualDim,
+ sal_Int32* pActualIndices, sal_Int32* pLowerBounds, sal_Int32* pUpperBounds )
+{
+ sal_Int32 nSeqLevel = nMaxDimIndex - nActualDim + 1;
+ ::rtl::OUString aSeqTypeName;
+ sal_Int32 i;
+ for( i = 0 ; i < nSeqLevel ; i++ )
+ aSeqTypeName += aSeqLevelStr;
+
+ aSeqTypeName += aElemType.getTypeName();
+ Type aSeqType( TypeClass_SEQUENCE, aSeqTypeName );
+
+ // Create Sequence instance
+ Any aRetVal;
+ Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aSeqType );
+ xIdlTargetClass->createObject( aRetVal );
+
+ // Alloc sequence according to array bounds
+ sal_Int32 nUpper = pUpperBounds[nActualDim];
+ sal_Int32 nLower = pLowerBounds[nActualDim];
+ sal_Int32 nSeqSize = nUpper - nLower + 1;
+ Reference< XIdlArray > xArray = xIdlTargetClass->getArray();
+ xArray->realloc( aRetVal, nSeqSize );
+
+ sal_Int32& ri = pActualIndices[nActualDim];
+
+ for( ri = nLower,i = 0 ; ri <= nUpper ; ri++,i++ )
+ {
+ Any aElementVal;
+
+ if( nActualDim < nMaxDimIndex )
+ {
+ aElementVal = implRekMultiDimArrayToSequence( pArray, aElemType,
+ nMaxDimIndex, nActualDim + 1, pActualIndices, pLowerBounds, pUpperBounds );
+ }
+ else
+ {
+ SbxVariable* pSource = pArray->Get32( pActualIndices );
+ aElementVal = sbxToUnoValue( pSource, aElemType );
+ }
+
+ try
+ {
+ // In die Sequence uebernehmen
+ xArray->set( aRetVal, i, aElementVal );
+ }
+ catch( const IllegalArgumentException& )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( ::cppu::getCaughtException() ) );
+ }
+ catch (IndexOutOfBoundsException&)
+ {
+ StarBASIC::Error( SbERR_OUT_OF_RANGE );
+ }
+ }
+ return aRetVal;
+}
+
+// Map old interface
+Any sbxToUnoValue( SbxVariable* pVar )
+{
+ return sbxToUnoValueImpl( pVar );
+}
+
+
+// Funktion, um einen globalen Bezeichner im
+// UnoScope zu suchen und fuer Sbx zu wrappen
+static bool implGetTypeByName( const String& rName, Type& rRetType )
+{
+ bool bSuccess = false;
+
+ Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
+ if( xTypeAccess->hasByHierarchicalName( rName ) )
+ {
+ Any aRet = xTypeAccess->getByHierarchicalName( rName );
+ Reference< XTypeDescription > xTypeDesc;
+ aRet >>= xTypeDesc;
+
+ if( xTypeDesc.is() )
+ {
+ rRetType = Type( xTypeDesc->getTypeClass(), xTypeDesc->getName() );
+ bSuccess = true;
+ }
+ }
+ return bSuccess;
+}
+
+
+// Konvertierung von Sbx nach Uno mit bekannter Zielklasse
+Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty )
+{
+ Any aRetVal;
+
+ // #94560 No conversion of empty/void for MAYBE_VOID properties
+ if( pUnoProperty && pUnoProperty->Attributes & PropertyAttribute::MAYBEVOID )
+ {
+ if( pVar->IsEmpty() )
+ return aRetVal;
+ }
+
+ SbxDataType eBaseType = pVar->SbxValue::GetType();
+ if( eBaseType == SbxOBJECT )
+ {
+ SbxBaseRef xObj = (SbxBase*)pVar->GetObject();
+ if( xObj.Is() && xObj->ISA(SbUnoAnyObject) )
+ {
+ return ((SbUnoAnyObject*)(SbxBase*)xObj)->getValue();
+ }
+ }
+
+ TypeClass eType = rType.getTypeClass();
+ switch( eType )
+ {
+ case TypeClass_INTERFACE:
+ case TypeClass_STRUCT:
+ case TypeClass_EXCEPTION:
+ {
+ Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( rType );
+
+ // Null-Referenz?
+ if( pVar->IsNull() && eType == TypeClass_INTERFACE )
+ {
+ Reference< XInterface > xRef;
+ ::rtl::OUString aClassName = xIdlTargetClass->getName();
+ Type aClassType( xIdlTargetClass->getTypeClass(), aClassName.getStr() );
+ aRetVal.setValue( &xRef, aClassType );
+ }
+ else
+ {
+ // #112368 Special conversion for Decimal, Currency and Date
+ if( eType == TypeClass_STRUCT )
+ {
+ SbiInstance* pInst = pINST;
+ if( pInst && pInst->IsCompatibility() )
+ {
+ if( rType == ::getCppuType( (oleautomation::Decimal*)0 ) )
+ {
+ oleautomation::Decimal aDecimal;
+ pVar->fillAutomationDecimal( aDecimal );
+ aRetVal <<= aDecimal;
+ break;
+ }
+ else if( rType == ::getCppuType( (oleautomation::Currency*)0 ) )
+ {
+ SbxINT64 aInt64 = pVar->GetCurrency();
+ oleautomation::Currency aCurrency;
+ sal_Int64& rnValue64 = aCurrency.Value;
+ rnValue64 = aInt64.nHigh;
+ rnValue64 <<= 32;
+ rnValue64 |= aInt64.nLow;
+ aRetVal <<= aCurrency;
+ break;
+ }
+ else if( rType == ::getCppuType( (oleautomation::Date*)0 ) )
+ {
+ oleautomation::Date aDate;
+ aDate.Value = pVar->GetDate();
+ aRetVal <<= aDate;
+ break;
+ }
+ }
+ }
+
+ SbxBaseRef pObj = (SbxBase*)pVar->GetObject();
+ if( pObj && pObj->ISA(SbUnoObject) )
+ {
+ aRetVal = ((SbUnoObject*)(SbxBase*)pObj)->getUnoAny();
+ }
+ else
+ {
+ // #109936 NULL object -> NULL XInterface
+ Reference<XInterface> xInt;
+ aRetVal <<= xInt;
+ }
+ }
+ }
+ break;
+
+ case TypeClass_TYPE:
+ {
+ if( eBaseType == SbxOBJECT )
+ {
+ // XIdlClass?
+ Reference< XIdlClass > xIdlClass;
+
+ SbxBaseRef pObj = (SbxBase*)pVar->GetObject();
+ if( pObj && pObj->ISA(SbUnoObject) )
+ {
+ Any aUnoAny = ((SbUnoObject*)(SbxBase*)pObj)->getUnoAny();
+ aUnoAny >>= xIdlClass;
+ }
+
+ if( xIdlClass.is() )
+ {
+ ::rtl::OUString aClassName = xIdlClass->getName();
+ Type aType( xIdlClass->getTypeClass(), aClassName.getStr() );
+ aRetVal <<= aType;
+ }
+ }
+ else if( eBaseType == SbxSTRING )
+ {
+ // String representing type?
+ String aTypeName = pVar->GetString();
+ Type aType;
+ bool bSuccess = implGetTypeByName( aTypeName, aType );
+ if( bSuccess )
+ aRetVal <<= aType;
+ }
+ }
+ break;
+
+ /* folgende Typen lassen wir erstmal weg
+ case TypeClass_SERVICE: break;
+ case TypeClass_CLASS: break;
+ case TypeClass_TYPEDEF: break;
+ case TypeClass_UNION: break;
+ case TypeClass_ENUM: break;
+ case TypeClass_ARRAY: break;
+ */
+
+ // Array -> Sequence
+ case TypeClass_ENUM:
+ {
+ aRetVal = int2enum( pVar->GetLong(), rType );
+ }
+ break;
+
+ case TypeClass_SEQUENCE:
+ {
+ SbxBaseRef xObj = (SbxBase*)pVar->GetObject();
+ if( xObj && xObj->ISA(SbxDimArray) )
+ {
+ SbxBase* pObj = (SbxBase*)xObj;
+ SbxDimArray* pArray = (SbxDimArray*)pObj;
+
+ short nDims = pArray->GetDims();
+
+ // Normal case: One dimensional array
+ sal_Int32 nLower, nUpper;
+ if( nDims == 1 && pArray->GetDim32( 1, nLower, nUpper ) )
+ {
+ sal_Int32 nSeqSize = nUpper - nLower + 1;
+
+ // Instanz der geforderten Sequence erzeugen
+ Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( rType );
+ xIdlTargetClass->createObject( aRetVal );
+ Reference< XIdlArray > xArray = xIdlTargetClass->getArray();
+ xArray->realloc( aRetVal, nSeqSize );
+
+ // Element-Type
+ ::rtl::OUString aClassName = xIdlTargetClass->getName();
+ typelib_TypeDescription * pSeqTD = 0;
+ typelib_typedescription_getByName( &pSeqTD, aClassName.pData );
+ OSL_ASSERT( pSeqTD );
+ Type aElemType( ((typelib_IndirectTypeDescription *)pSeqTD)->pType );
+ // Reference< XIdlClass > xElementClass = TypeToIdlClass( aElemType );
+
+ // Alle Array-Member umwandeln und eintragen
+ sal_Int32 nIdx = nLower;
+ for( sal_Int32 i = 0 ; i < nSeqSize ; i++,nIdx++ )
+ {
+ SbxVariableRef xVar = pArray->Get32( &nIdx );
+
+ // Wert von Sbx nach Uno wandeln
+ Any aAnyValue = sbxToUnoValue( (SbxVariable*)xVar, aElemType );
+
+ try
+ {
+ // In die Sequence uebernehmen
+ xArray->set( aRetVal, i, aAnyValue );
+ }
+ catch( const IllegalArgumentException& )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( ::cppu::getCaughtException() ) );
+ }
+ catch (IndexOutOfBoundsException&)
+ {
+ StarBASIC::Error( SbERR_OUT_OF_RANGE );
+ }
+ }
+ }
+ // #i33795 Map also multi dimensional arrays to corresponding sequences
+ else if( nDims > 1 )
+ {
+ // Element-Type
+ typelib_TypeDescription * pSeqTD = 0;
+ Type aCurType( rType );
+ sal_Int32 nSeqLevel = 0;
+ Type aElemType;
+ do
+ {
+ ::rtl::OUString aTypeName = aCurType.getTypeName();
+ typelib_typedescription_getByName( &pSeqTD, aTypeName.pData );
+ OSL_ASSERT( pSeqTD );
+ if( pSeqTD->eTypeClass == typelib_TypeClass_SEQUENCE )
+ {
+ aCurType = Type( ((typelib_IndirectTypeDescription *)pSeqTD)->pType );
+ nSeqLevel++;
+ }
+ else
+ {
+ aElemType = aCurType;
+ break;
+ }
+ }
+ while( true );
+
+ if( nSeqLevel == nDims )
+ {
+ sal_Int32* pLowerBounds = new sal_Int32[nDims];
+ sal_Int32* pUpperBounds = new sal_Int32[nDims];
+ sal_Int32* pActualIndices = new sal_Int32[nDims];
+ for( short i = 1 ; i <= nDims ; i++ )
+ {
+ sal_Int32 lBound, uBound;
+ pArray->GetDim32( i, lBound, uBound );
+
+ short j = i - 1;
+ pActualIndices[j] = pLowerBounds[j] = lBound;
+ pUpperBounds[j] = uBound;
+ }
+
+ aRetVal = implRekMultiDimArrayToSequence( pArray, aElemType,
+ nDims - 1, 0, pActualIndices, pLowerBounds, pUpperBounds );
+
+ delete[] pUpperBounds;
+ delete[] pLowerBounds;
+ delete[] pActualIndices;
+ }
+ }
+ }
+ }
+ break;
+
+ /*
+ case TypeClass_VOID: break;
+ case TypeClass_UNKNOWN: break;
+ */
+
+ // Bei Any die Klassen-unabhaengige Konvertierungs-Routine nutzen
+ case TypeClass_ANY:
+ {
+ aRetVal = sbxToUnoValueImpl( pVar );
+ }
+ break;
+
+ case TypeClass_BOOLEAN:
+ {
+ sal_Bool b = pVar->GetBool();
+ aRetVal.setValue( &b, getBooleanCppuType() );
+ break;
+ }
+ case TypeClass_CHAR:
+ {
+ sal_Unicode c = pVar->GetChar();
+ aRetVal.setValue( &c , getCharCppuType() );
+ break;
+ }
+ case TypeClass_STRING: aRetVal <<= pVar->GetOUString(); break;
+ case TypeClass_FLOAT: aRetVal <<= pVar->GetSingle(); break;
+ case TypeClass_DOUBLE: aRetVal <<= pVar->GetDouble(); break;
+ //case TypeClass_OCTET: break;
+
+ case TypeClass_BYTE:
+ {
+ sal_Int16 nVal = pVar->GetInteger();
+ sal_Bool bOverflow = sal_False;
+ if( nVal < -128 )
+ {
+ bOverflow = sal_True;
+ nVal = -128;
+ }
+ else if( nVal > 127 )
+ {
+ bOverflow = sal_True;
+ nVal = 127;
+ }
+ if( bOverflow )
+ StarBASIC::Error( ERRCODE_BASIC_MATH_OVERFLOW );
+
+ sal_Int8 nByteVal = (sal_Int8)nVal;
+ aRetVal <<= nByteVal;
+ break;
+ }
+ //case TypeClass_INT: break;
+ case TypeClass_SHORT: aRetVal <<= (sal_Int16)( pVar->GetInteger() ); break;
+ case TypeClass_LONG: aRetVal <<= (sal_Int32)( pVar->GetLong() ); break;
+ case TypeClass_HYPER: aRetVal <<= (sal_Int64)( pVar->GetInt64() ); break;
+ //case TypeClass_UNSIGNED_OCTET:break;
+ case TypeClass_UNSIGNED_SHORT: aRetVal <<= (sal_uInt16)( pVar->GetUShort() ); break;
+ case TypeClass_UNSIGNED_LONG: aRetVal <<= (sal_uInt32)( pVar->GetULong() ); break;
+ case TypeClass_UNSIGNED_HYPER: aRetVal <<= (sal_uInt64)( pVar->GetUInt64() ); break;
+ //case TypeClass_UNSIGNED_INT: break;
+ //case TypeClass_UNSIGNED_BYTE: break;
+ default: break;
+ }
+
+ return aRetVal;
+}
+
+// Dbg-Hilfsmethode zum Auslesen der in einem Object implementierten Interfaces
+String Impl_GetInterfaceInfo( const Reference< XInterface >& x, const Reference< XIdlClass >& xClass, sal_uInt16 nRekLevel )
+{
+ Type aIfaceType = ::getCppuType( (const Reference< XInterface > *)0 );
+ static Reference< XIdlClass > xIfaceClass = TypeToIdlClass( aIfaceType );
+
+ String aRetStr;
+ for( sal_uInt16 i = 0 ; i < nRekLevel ; i++ )
+ aRetStr.AppendAscii( " " );
+ aRetStr += String( xClass->getName() );
+ ::rtl::OUString aClassName = xClass->getName();
+ Type aClassType( xClass->getTypeClass(), aClassName.getStr() );
+
+ // Pruefen, ob das Interface wirklich unterstuetzt wird
+ if( !x->queryInterface( aClassType ).hasValue() )
+ {
+ aRetStr.AppendAscii( " (ERROR: Not really supported!)\n" );
+ }
+ // Gibt es Super-Interfaces
+ else
+ {
+ aRetStr.AppendAscii( "\n" );
+
+ // Super-Interfaces holen
+ Sequence< Reference< XIdlClass > > aSuperClassSeq = xClass->getSuperclasses();
+ const Reference< XIdlClass >* pClasses = aSuperClassSeq.getConstArray();
+ sal_uInt32 nSuperIfaceCount = aSuperClassSeq.getLength();
+ for( sal_uInt32 j = 0 ; j < nSuperIfaceCount ; j++ )
+ {
+ const Reference< XIdlClass >& rxIfaceClass = pClasses[j];
+ if( !rxIfaceClass->equals( xIfaceClass ) )
+ aRetStr += Impl_GetInterfaceInfo( x, rxIfaceClass, nRekLevel + 1 );
+ }
+ }
+ return aRetStr;
+}
+
+String getDbgObjectNameImpl( SbUnoObject* pUnoObj )
+{
+ String aName;
+ if( pUnoObj )
+ {
+ aName = pUnoObj->GetClassName();
+ if( !aName.Len() )
+ {
+ Any aToInspectObj = pUnoObj->getUnoAny();
+ TypeClass eType = aToInspectObj.getValueType().getTypeClass();
+ Reference< XInterface > xObj;
+ if( eType == TypeClass_INTERFACE )
+ xObj = *(Reference< XInterface >*)aToInspectObj.getValue();
+ if( xObj.is() )
+ {
+ Reference< XServiceInfo > xServiceInfo( xObj, UNO_QUERY );
+ if( xServiceInfo.is() )
+ aName = xServiceInfo->getImplementationName();
+ }
+ }
+ }
+ return aName;
+}
+
+String getDbgObjectName( SbUnoObject* pUnoObj )
+{
+ String aName = getDbgObjectNameImpl( pUnoObj );
+ if( !aName.Len() )
+ aName.AppendAscii( "Unknown" );
+
+ String aRet;
+ if( aName.Len() > 20 )
+ aRet.AppendAscii( "\n" );
+ aRet.AppendAscii( "\"" );
+ aRet += aName;
+ aRet.AppendAscii( "\":" );
+ return aRet;
+}
+
+String getBasicObjectTypeName( SbxObject* pObj )
+{
+ String aName;
+ if( pObj )
+ {
+ SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pObj);
+ if( pUnoObj )
+ aName = getDbgObjectNameImpl( pUnoObj );
+ }
+ return aName;
+}
+
+bool checkUnoObjectType( SbUnoObject* pUnoObj,
+ const String& aClass )
+{
+ Any aToInspectObj = pUnoObj->getUnoAny();
+ TypeClass eType = aToInspectObj.getValueType().getTypeClass();
+ if( eType != TypeClass_INTERFACE )
+ return false;
+ const Reference< XInterface > x = *(Reference< XInterface >*)aToInspectObj.getValue();
+
+ // Return true for XInvocation based objects as interface type names don't count then
+ Reference< XInvocation > xInvocation( x, UNO_QUERY );
+ if( xInvocation.is() )
+ return true;
+
+ bool result = false;
+ Reference< XTypeProvider > xTypeProvider( x, UNO_QUERY );
+ if( xTypeProvider.is() )
+ {
+ Sequence< Type > aTypeSeq = xTypeProvider->getTypes();
+ const Type* pTypeArray = aTypeSeq.getConstArray();
+ sal_uInt32 nIfaceCount = aTypeSeq.getLength();
+ for( sal_uInt32 j = 0 ; j < nIfaceCount ; j++ )
+ {
+ const Type& rType = pTypeArray[j];
+
+ Reference<XIdlClass> xClass = TypeToIdlClass( rType );
+ if( !xClass.is() )
+ {
+ DBG_ERROR("failed to get XIdlClass for type");
+ break;
+ }
+ ::rtl::OUString sClassName = xClass->getName();
+ if ( sClassName.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.oleautomation.XAutomationObject" ) ) ) )
+ {
+ // there is a hack in the extensions/source/ole/oleobj.cxx to return the typename of the automation object, lets check if it
+ // matches
+ Reference< XInvocation > xInv( aToInspectObj, UNO_QUERY );
+ if ( xInv.is() )
+ {
+ rtl::OUString sTypeName;
+ xInv->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("$GetTypeName") ) ) >>= sTypeName;
+ if ( sTypeName.getLength() == 0 || sTypeName.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("IDispatch") ) ) )
+ // can't check type, leave it pass
+ result = true;
+ else
+ result = sTypeName.equals( aClass );
+ }
+ break; // finished checking automation object
+ }
+ OSL_TRACE("Checking if object implements %s",
+ OUStringToOString( defaultNameSpace + aClass,
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+ // although interfaces in the ooo.vba.vba namespace
+ // obey the idl rules and have a leading X, in basic we
+ // want to be able to do something like
+ // 'dim wrkbooks as WorkBooks'
+ // so test assumes the 'X' has been dropped
+ sal_Int32 indexLastDot = sClassName.lastIndexOf('.');
+ if ( indexLastDot > -1 && sClassName.copy( indexLastDot + 1).equalsIgnoreAsciiCase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("X") ) + aClass ) )
+ {
+ result = true;
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+// Dbg-Hilfsmethode zum Auslesen der in einem Object implementierten Interfaces
+String Impl_GetSupportedInterfaces( SbUnoObject* pUnoObj )
+{
+ Any aToInspectObj = pUnoObj->getUnoAny();
+
+ // #54898: Nur TypeClass Interface zulasssen
+ TypeClass eType = aToInspectObj.getValueType().getTypeClass();
+ String aRet;
+ if( eType != TypeClass_INTERFACE )
+ {
+ aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM(ID_DBG_SUPPORTEDINTERFACES) );
+ aRet.AppendAscii( " not available.\n(TypeClass is not TypeClass_INTERFACE)\n" );
+ }
+ else
+ {
+ // Interface aus dem Any besorgen
+ const Reference< XInterface > x = *(Reference< XInterface >*)aToInspectObj.getValue();
+
+ // XIdlClassProvider-Interface ansprechen
+ Reference< XIdlClassProvider > xClassProvider( x, UNO_QUERY );
+ Reference< XTypeProvider > xTypeProvider( x, UNO_QUERY );
+
+ aRet.AssignAscii( "Supported interfaces by object " );
+ String aObjName = getDbgObjectName( pUnoObj );
+ aRet += aObjName;
+ aRet.AppendAscii( "\n" );
+ if( xTypeProvider.is() )
+ {
+ // Interfaces der Implementation holen
+ Sequence< Type > aTypeSeq = xTypeProvider->getTypes();
+ const Type* pTypeArray = aTypeSeq.getConstArray();
+ sal_uInt32 nIfaceCount = aTypeSeq.getLength();
+ for( sal_uInt32 j = 0 ; j < nIfaceCount ; j++ )
+ {
+ const Type& rType = pTypeArray[j];
+
+ Reference<XIdlClass> xClass = TypeToIdlClass( rType );
+ if( xClass.is() )
+ {
+ aRet += Impl_GetInterfaceInfo( x, xClass, 1 );
+ }
+ else
+ {
+ typelib_TypeDescription * pTD = 0;
+ rType.getDescription( &pTD );
+ String TypeName( ::rtl::OUString( pTD->pTypeName ) );
+
+ aRet.AppendAscii( "*** ERROR: No IdlClass for type \"" );
+ aRet += TypeName;
+ aRet.AppendAscii( "\"\n*** Please check type library\n" );
+ }
+ }
+ }
+ else if( xClassProvider.is() )
+ {
+
+ DBG_ERROR( "XClassProvider not supported in UNO3" );
+ }
+ }
+ return aRet;
+}
+
+
+
+// Dbg-Hilfsmethode SbxDataType -> String
+String Dbg_SbxDataType2String( SbxDataType eType )
+{
+ String aRet( RTL_CONSTASCII_USTRINGPARAM("Unknown Sbx-Type!") );
+ switch( +eType )
+ {
+ case SbxEMPTY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxEMPTY") ); break;
+ case SbxNULL: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxNULL") ); break;
+ case SbxINTEGER: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxINTEGER") ); break;
+ case SbxLONG: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLONG") ); break;
+ case SbxSINGLE: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxSINGLE") ); break;
+ case SbxDOUBLE: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDOUBLE") ); break;
+ case SbxCURRENCY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCURRENCY") ); break;
+ case SbxDECIMAL: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDECIMAL") ); break;
+ case SbxDATE: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDATE") ); break;
+ case SbxSTRING: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxSTRING") ); break;
+ case SbxOBJECT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxOBJECT") ); break;
+ case SbxERROR: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxERROR") ); break;
+ case SbxBOOL: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxBOOL") ); break;
+ case SbxVARIANT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxVARIANT") ); break;
+ case SbxDATAOBJECT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDATAOBJECT") ); break;
+ case SbxCHAR: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCHAR") ); break;
+ case SbxBYTE: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxBYTE") ); break;
+ case SbxUSHORT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUSHORT") ); break;
+ case SbxULONG: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxULONG") ); break;
+ case SbxLONG64: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLONG64") ); break;
+ case SbxULONG64: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxULONG64") ); break;
+ case SbxSALINT64: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxINT64") ); break;
+ case SbxSALUINT64: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUINT64") ); break;
+ case SbxINT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxINT") ); break;
+ case SbxUINT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUINT") ); break;
+ case SbxVOID: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxVOID") ); break;
+ case SbxHRESULT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxHRESULT") ); break;
+ case SbxPOINTER: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxPOINTER") ); break;
+ case SbxDIMARRAY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDIMARRAY") ); break;
+ case SbxCARRAY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCARRAY") ); break;
+ case SbxUSERDEF: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUSERDEF") ); break;
+ case SbxLPSTR: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLPSTR") ); break;
+ case SbxLPWSTR: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLPWSTR") ); break;
+ case SbxCoreSTRING: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCoreSTRING" ) ); break;
+ case SbxOBJECT | SbxARRAY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxARRAY") ); break;
+ default: break;
+ }
+ return aRet;
+}
+
+// Dbg-Hilfsmethode zum Anzeigen der Properties eines SbUnoObjects
+String Impl_DumpProperties( SbUnoObject* pUnoObj )
+{
+ String aRet( RTL_CONSTASCII_USTRINGPARAM("Properties of object ") );
+ String aObjName = getDbgObjectName( pUnoObj );
+ aRet += aObjName;
+
+ // Uno-Infos auswerten, um Arrays zu erkennen
+ Reference< XIntrospectionAccess > xAccess = pUnoObj->getIntrospectionAccess();
+ if( !xAccess.is() )
+ {
+ Reference< XInvocation > xInvok = pUnoObj->getInvocation();
+ if( xInvok.is() )
+ xAccess = xInvok->getIntrospection();
+ }
+ if( !xAccess.is() )
+ {
+ aRet.AppendAscii( "\nUnknown, no introspection available\n" );
+ return aRet;
+ }
+
+ Sequence<Property> props = xAccess->getProperties( PropertyConcept::ALL - PropertyConcept::DANGEROUS );
+ sal_uInt32 nUnoPropCount = props.getLength();
+ const Property* pUnoProps = props.getConstArray();
+
+ SbxArray* pProps = pUnoObj->GetProperties();
+ sal_uInt16 nPropCount = pProps->Count();
+ sal_uInt16 nPropsPerLine = 1 + nPropCount / 30;
+ for( sal_uInt16 i = 0; i < nPropCount; i++ )
+ {
+ SbxVariable* pVar = pProps->Get( i );
+ if( pVar )
+ {
+ String aPropStr;
+ if( (i % nPropsPerLine) == 0 )
+ aPropStr.AppendAscii( "\n" );
+
+ // Typ und Namen ausgeben
+ // Ist es in Uno eine Sequence?
+ SbxDataType eType = pVar->GetFullType();
+
+ sal_Bool bMaybeVoid = sal_False;
+ if( i < nUnoPropCount )
+ {
+ const Property& rProp = pUnoProps[ i ];
+
+ // #63133: Bei MAYBEVOID Typ aus Uno neu konvertieren,
+ // damit nicht immer nur SbxEMPTY ausgegben wird.
+ if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
+ {
+ eType = unoToSbxType( rProp.Type.getTypeClass() );
+ bMaybeVoid = sal_True;
+ }
+ if( eType == SbxOBJECT )
+ {
+ Type aType = rProp.Type;
+ if( aType.getTypeClass() == TypeClass_SEQUENCE )
+ eType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
+ }
+ }
+ aPropStr += Dbg_SbxDataType2String( eType );
+ if( bMaybeVoid )
+ aPropStr.AppendAscii( "/void" );
+ aPropStr.AppendAscii( " " );
+ aPropStr += pVar->GetName();
+
+ if( i == nPropCount - 1 )
+ aPropStr.AppendAscii( "\n" );
+ else
+ aPropStr.AppendAscii( "; " );
+
+ aRet += aPropStr;
+ }
+ }
+ return aRet;
+}
+
+// Dbg-Hilfsmethode zum Anzeigen der Methoden eines SbUnoObjects
+String Impl_DumpMethods( SbUnoObject* pUnoObj )
+{
+ String aRet( RTL_CONSTASCII_USTRINGPARAM("Methods of object ") );
+ String aObjName = getDbgObjectName( pUnoObj );
+ aRet += aObjName;
+
+ // XIntrospectionAccess, um die Typen der Parameter auch ausgeben zu koennen
+ Reference< XIntrospectionAccess > xAccess = pUnoObj->getIntrospectionAccess();
+ if( !xAccess.is() )
+ {
+ Reference< XInvocation > xInvok = pUnoObj->getInvocation();
+ if( xInvok.is() )
+ xAccess = xInvok->getIntrospection();
+ }
+ if( !xAccess.is() )
+ {
+ aRet.AppendAscii( "\nUnknown, no introspection available\n" );
+ return aRet;
+ }
+ Sequence< Reference< XIdlMethod > > methods = xAccess->getMethods
+ ( MethodConcept::ALL - MethodConcept::DANGEROUS );
+ const Reference< XIdlMethod >* pUnoMethods = methods.getConstArray();
+
+ SbxArray* pMethods = pUnoObj->GetMethods();
+ sal_uInt16 nMethodCount = pMethods->Count();
+ if( !nMethodCount )
+ {
+ aRet.AppendAscii( "\nNo methods found\n" );
+ return aRet;
+ }
+ sal_uInt16 nPropsPerLine = 1 + nMethodCount / 30;
+ for( sal_uInt16 i = 0; i < nMethodCount; i++ )
+ {
+ SbxVariable* pVar = pMethods->Get( i );
+ if( pVar )
+ {
+ String aPropStr;
+ if( (i % nPropsPerLine) == 0 )
+ aPropStr.AppendAscii( "\n" );
+
+ // Methode ansprechen
+ const Reference< XIdlMethod >& rxMethod = pUnoMethods[i];
+
+ // Ist es in Uno eine Sequence?
+ SbxDataType eType = pVar->GetFullType();
+ if( eType == SbxOBJECT )
+ {
+ Reference< XIdlClass > xClass = rxMethod->getReturnType();
+ if( xClass.is() && xClass->getTypeClass() == TypeClass_SEQUENCE )
+ eType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
+ }
+ // Name und Typ ausgeben
+ aPropStr += Dbg_SbxDataType2String( eType );
+ aPropStr.AppendAscii( " " );
+ aPropStr += pVar->GetName();
+ aPropStr.AppendAscii( " ( " );
+
+ // get-Methode darf keinen Parameter haben
+ Sequence< Reference< XIdlClass > > aParamsSeq = rxMethod->getParameterTypes();
+ sal_uInt32 nParamCount = aParamsSeq.getLength();
+ const Reference< XIdlClass >* pParams = aParamsSeq.getConstArray();
+
+ if( nParamCount > 0 )
+ {
+ for( sal_uInt16 j = 0; j < nParamCount; j++ )
+ {
+ String aTypeStr = Dbg_SbxDataType2String( unoToSbxType( pParams[ j ] ) );
+ aPropStr += aTypeStr;
+
+ if( j < nParamCount - 1 )
+ aPropStr.AppendAscii( ", " );
+ }
+ }
+ else
+ aPropStr.AppendAscii( "void" );
+
+ aPropStr.AppendAscii( " ) " );
+
+ if( i == nMethodCount - 1 )
+ aPropStr.AppendAscii( "\n" );
+ else
+ aPropStr.AppendAscii( "; " );
+
+ aRet += aPropStr;
+ }
+ }
+ return aRet;
+}
+
+TYPEINIT1(AutomationNamedArgsSbxArray,SbxArray)
+
+// Implementation SbUnoObject
+void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType )
+{
+ if( bNeedIntrospection )
+ doIntrospection();
+
+ const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
+ if( pHint )
+ {
+ SbxVariable* pVar = pHint->GetVar();
+ SbxArray* pParams = pVar->GetParameters();
+ SbUnoProperty* pProp = PTR_CAST(SbUnoProperty,pVar);
+ SbUnoMethod* pMeth = PTR_CAST(SbUnoMethod,pVar);
+ if( pProp )
+ {
+ bool bInvocation = pProp->isInvocationBased();
+ if( pHint->GetId() == SBX_HINT_DATAWANTED )
+ {
+ // Test-Properties
+ sal_Int32 nId = pProp->nId;
+ if( nId < 0 )
+ {
+ // Id == -1: Implementierte Interfaces gemaess ClassProvider anzeigen
+ if( nId == -1 ) // Property ID_DBG_SUPPORTEDINTERFACES"
+ {
+ String aRetStr = Impl_GetSupportedInterfaces( this );
+ pVar->PutString( aRetStr );
+ }
+ // Id == -2: Properties ausgeben
+ else if( nId == -2 ) // Property ID_DBG_PROPERTIES
+ {
+ // Jetzt muessen alle Properties angelegt werden
+ implCreateAll();
+ String aRetStr = Impl_DumpProperties( this );
+ pVar->PutString( aRetStr );
+ }
+ // Id == -3: Methoden ausgeben
+ else if( nId == -3 ) // Property ID_DBG_METHODS
+ {
+ // Jetzt muessen alle Properties angelegt werden
+ implCreateAll();
+ String aRetStr = Impl_DumpMethods( this );
+ pVar->PutString( aRetStr );
+ }
+ return;
+ }
+
+ if( !bInvocation && mxUnoAccess.is() )
+ {
+ try
+ {
+ // Wert holen
+ Reference< XPropertySet > xPropSet( mxUnoAccess->queryAdapter( ::getCppuType( (const Reference< XPropertySet > *)0 ) ), UNO_QUERY );
+ Any aRetAny = xPropSet->getPropertyValue( pProp->GetName() );
+ // Die Nutzung von getPropertyValue (statt ueber den Index zu gehen) ist
+ // nicht optimal, aber die Umstellung auf XInvocation steht ja ohnehin an
+ // Ansonsten kann auch FastPropertySet genutzt werden
+
+ // Wert von Uno nach Sbx uebernehmen
+ unoToSbxValue( pVar, aRetAny );
+ }
+ catch( const Exception& )
+ {
+ implHandleAnyException( ::cppu::getCaughtException() );
+ }
+ }
+ else if( bInvocation && mxInvocation.is() )
+ {
+ try
+ {
+ // Wert holen
+ Any aRetAny = mxInvocation->getValue( pProp->GetName() );
+
+ // Wert von Uno nach Sbx uebernehmen
+ unoToSbxValue( pVar, aRetAny );
+ }
+ catch( const Exception& )
+ {
+ implHandleAnyException( ::cppu::getCaughtException() );
+ }
+ }
+ }
+ else if( pHint->GetId() == SBX_HINT_DATACHANGED )
+ {
+ if( !bInvocation && mxUnoAccess.is() )
+ {
+ if( pProp->aUnoProp.Attributes & PropertyAttribute::READONLY )
+ {
+ StarBASIC::Error( SbERR_PROP_READONLY );
+ return;
+ }
+
+ // Wert von Uno nach Sbx uebernehmen
+ Any aAnyValue = sbxToUnoValue( pVar, pProp->aUnoProp.Type, &pProp->aUnoProp );
+ try
+ {
+ // Wert setzen
+ Reference< XPropertySet > xPropSet( mxUnoAccess->queryAdapter( ::getCppuType( (const Reference< XPropertySet > *)0 ) ), UNO_QUERY );
+ xPropSet->setPropertyValue( pProp->GetName(), aAnyValue );
+ // Die Nutzung von getPropertyValue (statt ueber den Index zu gehen) ist
+ // nicht optimal, aber die Umstellung auf XInvocation steht ja ohnehin an
+ // Ansonsten kann auch FastPropertySet genutzt werden
+ }
+ catch( const Exception& )
+ {
+ implHandleAnyException( ::cppu::getCaughtException() );
+ }
+ }
+ else if( bInvocation && mxInvocation.is() )
+ {
+ // Wert von Uno nach Sbx uebernehmen
+ Any aAnyValue = sbxToUnoValueImpl( pVar );
+ try
+ {
+ // Wert setzen
+ mxInvocation->setValue( pProp->GetName(), aAnyValue );
+ }
+ catch( const Exception& )
+ {
+ implHandleAnyException( ::cppu::getCaughtException() );
+ }
+ }
+ }
+ }
+ else if( pMeth )
+ {
+ bool bInvocation = pMeth->isInvocationBased();
+ if( pHint->GetId() == SBX_HINT_DATAWANTED )
+ {
+ // Anzahl Parameter -1 wegen Param0 == this
+ sal_uInt32 nParamCount = pParams ? ((sal_uInt32)pParams->Count() - 1) : 0;
+ Sequence<Any> args;
+ sal_Bool bOutParams = sal_False;
+ sal_uInt32 i;
+
+ if( !bInvocation && mxUnoAccess.is() )
+ {
+ // Infos holen
+ const Sequence<ParamInfo>& rInfoSeq = pMeth->getParamInfos();
+ const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
+ sal_uInt32 nUnoParamCount = rInfoSeq.getLength();
+ sal_uInt32 nAllocParamCount = nParamCount;
+
+ // Ueberschuessige Parameter ignorieren, Alternative: Error schmeissen
+ if( nParamCount > nUnoParamCount )
+ {
+ nParamCount = nUnoParamCount;
+ nAllocParamCount = nParamCount;
+ }
+ else if( nParamCount < nUnoParamCount )
+ {
+ SbiInstance* pInst = pINST;
+ if( pInst && pInst->IsCompatibility() )
+ {
+ // Check types
+ bool bError = false;
+ for( i = nParamCount ; i < nUnoParamCount ; i++ )
+ {
+ const ParamInfo& rInfo = pParamInfos[i];
+ const Reference< XIdlClass >& rxClass = rInfo.aType;
+ if( rxClass->getTypeClass() != TypeClass_ANY )
+ {
+ bError = true;
+ StarBASIC::Error( SbERR_NOT_OPTIONAL );
+ }
+ }
+ if( !bError )
+ nAllocParamCount = nUnoParamCount;
+ }
+ }
+
+ if( nAllocParamCount > 0 )
+ {
+ args.realloc( nAllocParamCount );
+ Any* pAnyArgs = args.getArray();
+ for( i = 0 ; i < nParamCount ; i++ )
+ {
+ const ParamInfo& rInfo = pParamInfos[i];
+ const Reference< XIdlClass >& rxClass = rInfo.aType;
+ //const XIdlClassRef& rxClass = pUnoParams[i];
+
+ com::sun::star::uno::Type aType( rxClass->getTypeClass(), rxClass->getName() );
+
+ // ACHTUNG: Bei den Sbx-Parametern den Offset nicht vergessen!
+ pAnyArgs[i] = sbxToUnoValue( pParams->Get( (sal_uInt16)(i+1) ), aType );
+
+ // Wenn es nicht schon feststeht pruefen, ob Out-Parameter vorliegen
+ if( !bOutParams )
+ {
+ ParamMode aParamMode = rInfo.aMode;
+ if( aParamMode != ParamMode_IN )
+ bOutParams = sal_True;
+ }
+ }
+ }
+ }
+ else if( bInvocation && pParams && mxInvocation.is() )
+ {
+ bool bOLEAutomation = true;
+ // TODO: bOLEAutomation = xOLEAutomation.is()
+
+ AutomationNamedArgsSbxArray* pArgNamesArray = NULL;
+ if( bOLEAutomation )
+ pArgNamesArray = PTR_CAST(AutomationNamedArgsSbxArray,pParams);
+
+ args.realloc( nParamCount );
+ Any* pAnyArgs = args.getArray();
+ bool bBlockConversionToSmallestType = pINST->IsCompatibility();
+ if( pArgNamesArray )
+ {
+ Sequence< ::rtl::OUString >& rNameSeq = pArgNamesArray->getNames();
+ ::rtl::OUString* pNames = rNameSeq.getArray();
+
+ Any aValAny;
+ for( i = 0 ; i < nParamCount ; i++ )
+ {
+ sal_uInt16 iSbx = (sal_uInt16)(i+1);
+
+ // ACHTUNG: Bei den Sbx-Parametern den Offset nicht vergessen!
+ aValAny = sbxToUnoValueImpl( pParams->Get( iSbx ),
+ bBlockConversionToSmallestType );
+
+ ::rtl::OUString aParamName = pNames[iSbx];
+ if( aParamName.getLength() )
+ {
+ oleautomation::NamedArgument aNamedArgument;
+ aNamedArgument.Name = aParamName;
+ aNamedArgument.Value = aValAny;
+ pAnyArgs[i] <<= aNamedArgument;
+ }
+ else
+ {
+ pAnyArgs[i] = aValAny;
+ }
+ }
+ }
+ else
+ {
+ for( i = 0 ; i < nParamCount ; i++ )
+ {
+ // ACHTUNG: Bei den Sbx-Parametern den Offset nicht vergessen!
+ pAnyArgs[i] = sbxToUnoValueImpl( pParams->Get( (sal_uInt16)(i+1) ),
+ bBlockConversionToSmallestType );
+ }
+ }
+ }
+
+ // Methode callen
+ GetSbData()->bBlockCompilerError = sal_True; // #106433 Block compiler errors for API calls
+ try
+ {
+ if( !bInvocation && mxUnoAccess.is() )
+ {
+ Any aRetAny = pMeth->m_xUnoMethod->invoke( getUnoAny(), args );
+
+ // Wert von Uno nach Sbx uebernehmen
+ unoToSbxValue( pVar, aRetAny );
+
+ // Muessen wir Out-Parameter zurueckkopieren?
+ if( bOutParams )
+ {
+ const Any* pAnyArgs = args.getConstArray();
+
+ // Infos holen
+ const Sequence<ParamInfo>& rInfoSeq = pMeth->getParamInfos();
+ const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
+
+ sal_uInt32 j;
+ for( j = 0 ; j < nParamCount ; j++ )
+ {
+ const ParamInfo& rInfo = pParamInfos[j];
+ ParamMode aParamMode = rInfo.aMode;
+ if( aParamMode != ParamMode_IN )
+ unoToSbxValue( (SbxVariable*)pParams->Get( (sal_uInt16)(j+1) ), pAnyArgs[ j ] );
+ }
+ }
+ }
+ else if( bInvocation && mxInvocation.is() )
+ {
+ Reference< XDirectInvocation > xDirectInvoke;
+ if ( pMeth->needsDirectInvocation() )
+ xDirectInvoke.set( mxInvocation, UNO_QUERY );
+
+ Any aRetAny;
+ if ( xDirectInvoke.is() )
+ aRetAny = xDirectInvoke->directInvoke( pMeth->GetName(), args );
+ else
+ {
+ Sequence< sal_Int16 > OutParamIndex;
+ Sequence< Any > OutParam;
+ aRetAny = mxInvocation->invoke( pMeth->GetName(), args, OutParamIndex, OutParam );
+
+ const sal_Int16* pIndices = OutParamIndex.getConstArray();
+ sal_uInt32 nLen = OutParamIndex.getLength();
+ if( nLen )
+ {
+ const Any* pNewValues = OutParam.getConstArray();
+ for( sal_uInt32 j = 0 ; j < nLen ; j++ )
+ {
+ sal_Int16 iTarget = pIndices[ j ];
+ if( iTarget >= (sal_Int16)nParamCount )
+ break;
+ unoToSbxValue( (SbxVariable*)pParams->Get( (sal_uInt16)(j+1) ), pNewValues[ j ] );
+ }
+ }
+ }
+
+ // Wert von Uno nach Sbx uebernehmen
+ unoToSbxValue( pVar, aRetAny );
+ }
+
+ // #55460, Parameter hier weghauen, da das in unoToSbxValue()
+ // bei Arrays wegen #54548 nicht mehr gemacht wird
+ if( pParams )
+ pVar->SetParameters( NULL );
+ }
+ catch( const Exception& )
+ {
+ implHandleAnyException( ::cppu::getCaughtException() );
+ }
+ GetSbData()->bBlockCompilerError = sal_False; // #106433 Unblock compiler errors
+ }
+ }
+ else
+ SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+ }
+}
+
+
+#ifdef INVOCATION_ONLY
+// Aus USR
+Reference< XInvocation > createDynamicInvocationFor( const Any& aAny );
+#endif
+
+SbUnoObject::SbUnoObject( const String& aName_, const Any& aUnoObj_ )
+ : SbxObject( aName_ )
+ , bNeedIntrospection( sal_True )
+ , bNativeCOMObject( sal_False )
+{
+ static Reference< XIntrospection > xIntrospection;
+
+ // Default-Properties von Sbx wieder rauspruegeln
+ Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_DONTCARE );
+ Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Parent") ), SbxCLASS_DONTCARE );
+
+ // Typ des Objekts pruefen
+ TypeClass eType = aUnoObj_.getValueType().getTypeClass();
+ Reference< XInterface > x;
+ if( eType == TypeClass_INTERFACE )
+ {
+ // Interface aus dem Any besorgen
+ x = *(Reference< XInterface >*)aUnoObj_.getValue();
+ if( !x.is() )
+ return;
+ }
+
+ Reference< XTypeProvider > xTypeProvider;
+#ifdef INVOCATION_ONLY
+ // Invocation besorgen
+ mxInvocation = createDynamicInvocationFor( aUnoObj_ );
+#else
+ // Hat das Object selbst eine Invocation?
+ mxInvocation = Reference< XInvocation >( x, UNO_QUERY );
+
+ xTypeProvider = Reference< XTypeProvider >( x, UNO_QUERY );
+#endif
+
+ if( mxInvocation.is() )
+ {
+ // #94670: This is WRONG because then the MaterialHolder doesn't refer
+ // to the object implementing XInvocation but to the object passed to
+ // the invocation service!!!
+ // mxMaterialHolder = Reference< XMaterialHolder >::query( mxInvocation );
+
+ // ExactName holen
+ mxExactNameInvocation = Reference< XExactName >::query( mxInvocation );
+
+ // Rest bezieht sich nur auf Introspection
+ if( !xTypeProvider.is() )
+ {
+ bNeedIntrospection = sal_False;
+ return;
+ }
+
+ // Ignore introspection based members for COM objects to avoid
+ // hiding of equally named COM symbols, e.g. XInvocation::getValue
+ Reference< oleautomation::XAutomationObject > xAutomationObject( aUnoObj_, UNO_QUERY );
+ if( xAutomationObject.is() )
+ bNativeCOMObject = sal_True;
+ }
+
+ maTmpUnoObj = aUnoObj_;
+
+
+ //*** Namen bestimmen ***
+ sal_Bool bFatalError = sal_True;
+
+ // Ist es ein Interface oder eine struct?
+ sal_Bool bSetClassName = sal_False;
+ String aClassName_;
+ if( eType == TypeClass_STRUCT || eType == TypeClass_EXCEPTION )
+ {
+ // Struct ist Ok
+ bFatalError = sal_False;
+
+ // #67173 Echten Klassen-Namen eintragen
+ if( aName_.Len() == 0 )
+ {
+ aClassName_ = String( aUnoObj_.getValueType().getTypeName() );
+ bSetClassName = sal_True;
+ }
+ }
+ else if( eType == TypeClass_INTERFACE )
+ {
+ // #70197 Interface geht immer durch Typ im Any
+ bFatalError = sal_False;
+
+ // Nach XIdlClassProvider-Interface fragen
+ Reference< XIdlClassProvider > xClassProvider( x, UNO_QUERY );
+ if( xClassProvider.is() )
+ {
+ // #67173 Echten Klassen-Namen eintragen
+ if( aName_.Len() == 0 )
+ {
+ Sequence< Reference< XIdlClass > > szClasses = xClassProvider->getIdlClasses();
+ sal_uInt32 nLen = szClasses.getLength();
+ if( nLen )
+ {
+ const Reference< XIdlClass > xImplClass = szClasses.getConstArray()[ 0 ];
+ if( xImplClass.is() )
+ {
+ aClassName_ = String( xImplClass->getName() );
+ bSetClassName = sal_True;
+ }
+ }
+ }
+ }
+ }
+ if( bSetClassName )
+ SetClassName( aClassName_ );
+
+ // Weder Interface noch Struct -> FatalError
+ if( bFatalError )
+ {
+ StarBASIC::FatalError( ERRCODE_BASIC_EXCEPTION );
+ return;
+ }
+
+ // #67781 Introspection erst on demand durchfuehren
+}
+
+SbUnoObject::~SbUnoObject()
+{
+}
+
+
+// #76470 Introspection on Demand durchfuehren
+void SbUnoObject::doIntrospection( void )
+{
+ static Reference< XIntrospection > xIntrospection;
+
+ if( !bNeedIntrospection )
+ return;
+ bNeedIntrospection = sal_False;
+
+ if( !xIntrospection.is() )
+ {
+ // Introspection-Service holen
+ Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
+ if ( xFactory.is() )
+ {
+ Reference< XInterface > xI = xFactory->createInstance( rtl::OUString::createFromAscii("com.sun.star.beans.Introspection") );
+ if (xI.is())
+ xIntrospection = Reference< XIntrospection >::query( xI );
+ //xI->queryInterface( ::getCppuType( (const Reference< XIntrospection > *)0 ), xIntrospection );
+ }
+ }
+ if( !xIntrospection.is() )
+ {
+ StarBASIC::FatalError( ERRCODE_BASIC_EXCEPTION );
+ return;
+ }
+
+ // Introspection durchfuehren
+ try
+ {
+ mxUnoAccess = xIntrospection->inspect( maTmpUnoObj );
+ }
+ catch( RuntimeException& e )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
+ }
+
+ if( !mxUnoAccess.is() )
+ {
+ // #51475 Ungueltiges Objekt kennzeichnen (kein mxMaterialHolder)
+ return;
+ }
+
+ // MaterialHolder vom Access holen
+ mxMaterialHolder = Reference< XMaterialHolder >::query( mxUnoAccess );
+
+ // ExactName vom Access holen
+ mxExactName = Reference< XExactName >::query( mxUnoAccess );
+}
+
+
+
+
+// #67781 Start einer Liste aller SbUnoMethod-Instanzen
+static SbUnoMethod* pFirst = NULL;
+
+void clearUnoMethodsForBasic( StarBASIC* pBasic )
+{
+ SbUnoMethod* pMeth = pFirst;
+ while( pMeth )
+ {
+ SbxObject* pObject = dynamic_cast< SbxObject* >( pMeth->GetParent() );
+ if ( pObject )
+ {
+ StarBASIC* pModBasic = dynamic_cast< StarBASIC* >( pObject->GetParent() );
+ if ( pModBasic == pBasic )
+ {
+ // for now the solution is to remove the method from the list and to clear it,
+ // but in case the element should be correctly transfered to another StarBASIC,
+ // we should either set module parent to NULL without clearing it, or even
+ // set the new StarBASIC as the parent of the module
+ // pObject->SetParent( NULL );
+
+ if( pMeth == pFirst )
+ pFirst = pMeth->pNext;
+ else if( pMeth->pPrev )
+ pMeth->pPrev->pNext = pMeth->pNext;
+ if( pMeth->pNext )
+ pMeth->pNext->pPrev = pMeth->pPrev;
+
+ pMeth->pPrev = NULL;
+ pMeth->pNext = NULL;
+
+ pMeth->SbxValue::Clear();
+ pObject->SbxValue::Clear();
+
+ // start from the beginning after object clearing, the cycle will end since the method is removed each time
+ pMeth = pFirst;
+ }
+ else
+ pMeth = pMeth->pNext;
+ }
+ else
+ pMeth = pMeth->pNext;
+ }
+}
+
+void clearUnoMethods( void )
+{
+ SbUnoMethod* pMeth = pFirst;
+ while( pMeth )
+ {
+ pMeth->SbxValue::Clear();
+ pMeth = pMeth->pNext;
+ }
+}
+
+
+SbUnoMethod::SbUnoMethod
+(
+ const String& aName_,
+ SbxDataType eSbxType,
+ Reference< XIdlMethod > xUnoMethod_,
+ bool bInvocation,
+ bool bDirect
+)
+ : SbxMethod( aName_, eSbxType )
+ , mbInvocation( bInvocation )
+ , mbDirectInvocation( bDirect )
+{
+ m_xUnoMethod = xUnoMethod_;
+ pParamInfoSeq = NULL;
+
+ // #67781 Methode in Liste eintragen
+ pNext = pFirst;
+ pPrev = NULL;
+ pFirst = this;
+ if( pNext )
+ pNext->pPrev = this;
+}
+
+SbUnoMethod::~SbUnoMethod()
+{
+ delete pParamInfoSeq;
+
+ if( this == pFirst )
+ pFirst = pNext;
+ else if( pPrev )
+ pPrev->pNext = pNext;
+ if( pNext )
+ pNext->pPrev = pPrev;
+}
+
+SbxInfo* SbUnoMethod::GetInfo()
+{
+ if( !pInfo && m_xUnoMethod.is() )
+ {
+ SbiInstance* pInst = pINST;
+ if( pInst && pInst->IsCompatibility() )
+ {
+ pInfo = new SbxInfo();
+
+ const Sequence<ParamInfo>& rInfoSeq = getParamInfos();
+ const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
+ sal_uInt32 nParamCount = rInfoSeq.getLength();
+
+ for( sal_uInt32 i = 0 ; i < nParamCount ; i++ )
+ {
+ const ParamInfo& rInfo = pParamInfos[i];
+ ::rtl::OUString aParamName = rInfo.aName;
+
+ // const Reference< XIdlClass >& rxClass = rInfo.aType;
+ SbxDataType t = SbxVARIANT;
+ sal_uInt16 nFlags_ = SBX_READ;
+ pInfo->AddParam( aParamName, t, nFlags_ );
+ }
+ }
+ }
+ return pInfo;
+}
+
+const Sequence<ParamInfo>& SbUnoMethod::getParamInfos( void )
+{
+ if( !pParamInfoSeq && m_xUnoMethod.is() )
+ {
+ Sequence<ParamInfo> aTmp = m_xUnoMethod->getParameterInfos() ;
+ pParamInfoSeq = new Sequence<ParamInfo>( aTmp );
+ }
+ return *pParamInfoSeq;
+}
+
+SbUnoProperty::SbUnoProperty
+(
+ const String& aName_,
+ SbxDataType eSbxType,
+ const Property& aUnoProp_,
+ sal_Int32 nId_,
+ bool bInvocation
+)
+ : SbxProperty( aName_, eSbxType )
+ , aUnoProp( aUnoProp_ )
+ , nId( nId_ )
+ , mbInvocation( bInvocation )
+{
+ // #54548, bei bedarf Dummy-Array einsetzen, damit SbiRuntime::CheckArray() geht
+ static SbxArrayRef xDummyArray = new SbxArray( SbxVARIANT );
+ if( eSbxType & SbxARRAY )
+ PutObject( xDummyArray );
+}
+
+SbUnoProperty::~SbUnoProperty()
+{}
+
+
+SbxVariable* SbUnoObject::Find( const String& rName, SbxClassType t )
+{
+ static Reference< XIdlMethod > xDummyMethod;
+ static Property aDummyProp;
+
+ SbxVariable* pRes = SbxObject::Find( rName, t );
+
+ if( bNeedIntrospection )
+ doIntrospection();
+
+ // Neu 4.3.1999: Properties on Demand anlegen, daher jetzt perIntrospectionAccess
+ // suchen, ob doch eine Property oder Methode des geforderten Namens existiert
+ if( !pRes )
+ {
+ ::rtl::OUString aUName( rName );
+ if( mxUnoAccess.is() && !bNativeCOMObject )
+ {
+ if( mxExactName.is() )
+ {
+ ::rtl::OUString aUExactName = mxExactName->getExactName( aUName );
+ if( aUExactName.getLength() )
+ aUName = aUExactName;
+ }
+ if( mxUnoAccess->hasProperty( aUName, PropertyConcept::ALL - PropertyConcept::DANGEROUS ) )
+ {
+ const Property& rProp = mxUnoAccess->
+ getProperty( aUName, PropertyConcept::ALL - PropertyConcept::DANGEROUS );
+
+ // #58455 Wenn die Property void sein kann, muss als Typ Variant gesetzt werden
+ SbxDataType eSbxType;
+ if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
+ eSbxType = SbxVARIANT;
+ else
+ eSbxType = unoToSbxType( rProp.Type.getTypeClass() );
+
+ // Property anlegen und reinbraten
+ SbxVariableRef xVarRef = new SbUnoProperty( rProp.Name, eSbxType, rProp, 0, false );
+ QuickInsert( (SbxVariable*)xVarRef );
+ pRes = xVarRef;
+ }
+ else if( mxUnoAccess->hasMethod( aUName,
+ MethodConcept::ALL - MethodConcept::DANGEROUS ) )
+ {
+ // Methode ansprechen
+ const Reference< XIdlMethod >& rxMethod = mxUnoAccess->
+ getMethod( aUName, MethodConcept::ALL - MethodConcept::DANGEROUS );
+
+ // SbUnoMethode anlegen und reinbraten
+ SbxVariableRef xMethRef = new SbUnoMethod( rxMethod->getName(),
+ unoToSbxType( rxMethod->getReturnType() ), rxMethod, false );
+ QuickInsert( (SbxVariable*)xMethRef );
+ pRes = xMethRef;
+ }
+
+ // Wenn immer noch nichts gefunden wurde, muss geprueft werden, ob NameAccess vorliegt
+ if( !pRes )
+ {
+ try
+ {
+ Reference< XNameAccess > xNameAccess( mxUnoAccess->queryAdapter( ::getCppuType( (const Reference< XPropertySet > *)0 ) ), UNO_QUERY );
+ ::rtl::OUString aUName2( rName );
+
+ if( xNameAccess.is() && xNameAccess->hasByName( aUName2 ) )
+ {
+ Any aAny = xNameAccess->getByName( aUName2 );
+
+ // ACHTUNG: Die hier erzeugte Variable darf wegen bei XNameAccess
+ // nicht als feste Property in das Object aufgenommen werden und
+ // wird daher nirgendwo gehalten.
+ // Wenn das Probleme gibt, muss das kuenstlich gemacht werden oder
+ // es muss eine Klasse SbUnoNameAccessProperty geschaffen werden,
+ // bei der die Existenz staendig neu ueberprueft und die ggf. weg-
+ // geworfen wird, wenn der Name nicht mehr gefunden wird.
+ pRes = new SbxVariable( SbxVARIANT );
+ unoToSbxValue( pRes, aAny );
+ }
+ }
+ catch( NoSuchElementException& e )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
+ }
+ catch( const Exception& )
+ {
+ // Anlegen, damit der Exception-Fehler nicht ueberschrieben wird
+ if( !pRes )
+ pRes = new SbxVariable( SbxVARIANT );
+
+ implHandleAnyException( ::cppu::getCaughtException() );
+ }
+ }
+ }
+ if( !pRes && mxInvocation.is() )
+ {
+ if( mxExactNameInvocation.is() )
+ {
+ ::rtl::OUString aUExactName = mxExactNameInvocation->getExactName( aUName );
+ if( aUExactName.getLength() )
+ aUName = aUExactName;
+ }
+
+ try
+ {
+ if( mxInvocation->hasProperty( aUName ) )
+ {
+ // Property anlegen und reinbraten
+ SbxVariableRef xVarRef = new SbUnoProperty( aUName, SbxVARIANT, aDummyProp, 0, true );
+ QuickInsert( (SbxVariable*)xVarRef );
+ pRes = xVarRef;
+ }
+ else if( mxInvocation->hasMethod( aUName ) )
+ {
+ // SbUnoMethode anlegen und reinbraten
+ SbxVariableRef xMethRef = new SbUnoMethod( aUName, SbxVARIANT, xDummyMethod, true );
+ QuickInsert( (SbxVariable*)xMethRef );
+ pRes = xMethRef;
+ }
+ else
+ {
+ Reference< XDirectInvocation > xDirectInvoke( mxInvocation, UNO_QUERY );
+ if ( xDirectInvoke.is() && xDirectInvoke->hasMember( aUName ) )
+ {
+ SbxVariableRef xMethRef = new SbUnoMethod( aUName, SbxVARIANT, xDummyMethod, true, true );
+ QuickInsert( (SbxVariable*)xMethRef );
+ pRes = xMethRef;
+ }
+
+ }
+ }
+ catch( RuntimeException& e )
+ {
+ // Anlegen, damit der Exception-Fehler nicht ueberschrieben wird
+ if( !pRes )
+ pRes = new SbxVariable( SbxVARIANT );
+
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
+ }
+ }
+ }
+
+ // Ganz am Schluss noch pruefen, ob die Dbg_-Properties gemeint sind
+
+ if( !pRes )
+ {
+ if( rName.EqualsIgnoreCaseAscii( ID_DBG_SUPPORTEDINTERFACES ) ||
+ rName.EqualsIgnoreCaseAscii( ID_DBG_PROPERTIES ) ||
+ rName.EqualsIgnoreCaseAscii( ID_DBG_METHODS ) )
+ {
+ // Anlegen
+ implCreateDbgProperties();
+
+ // Jetzt muessen sie regulaer gefunden werden
+ pRes = SbxObject::Find( rName, SbxCLASS_DONTCARE );
+ }
+ }
+ return pRes;
+}
+
+
+// Hilfs-Methode zum Anlegen der dbg_-Properties
+void SbUnoObject::implCreateDbgProperties( void )
+{
+ Property aProp;
+
+ // Id == -1: Implementierte Interfaces gemaess ClassProvider anzeigen
+ SbxVariableRef xVarRef = new SbUnoProperty( String(RTL_CONSTASCII_USTRINGPARAM(ID_DBG_SUPPORTEDINTERFACES)), SbxSTRING, aProp, -1, false );
+ QuickInsert( (SbxVariable*)xVarRef );
+
+ // Id == -2: Properties ausgeben
+ xVarRef = new SbUnoProperty( String(RTL_CONSTASCII_USTRINGPARAM(ID_DBG_PROPERTIES)), SbxSTRING, aProp, -2, false );
+ QuickInsert( (SbxVariable*)xVarRef );
+
+ // Id == -3: Methoden ausgeben
+ xVarRef = new SbUnoProperty( String(RTL_CONSTASCII_USTRINGPARAM(ID_DBG_METHODS)), SbxSTRING, aProp, -3, false );
+ QuickInsert( (SbxVariable*)xVarRef );
+}
+
+void SbUnoObject::implCreateAll( void )
+{
+ // Bestehende Methoden und Properties alle wieder wegwerfen
+ pMethods = new SbxArray;
+ pProps = new SbxArray;
+
+ if( bNeedIntrospection ) doIntrospection();
+
+ // Instrospection besorgen
+ Reference< XIntrospectionAccess > xAccess = mxUnoAccess;
+ if( !xAccess.is() || bNativeCOMObject )
+ {
+ if( mxInvocation.is() )
+ xAccess = mxInvocation->getIntrospection();
+ else if( bNativeCOMObject )
+ return;
+ }
+ if( !xAccess.is() )
+ return;
+
+ // Properties anlegen
+ Sequence<Property> props = xAccess->getProperties( PropertyConcept::ALL - PropertyConcept::DANGEROUS );
+ sal_uInt32 nPropCount = props.getLength();
+ const Property* pProps_ = props.getConstArray();
+
+ sal_uInt32 i;
+ for( i = 0 ; i < nPropCount ; i++ )
+ {
+ const Property& rProp = pProps_[ i ];
+
+ // #58455 Wenn die Property void sein kann, muss als Typ Variant gesetzt werden
+ SbxDataType eSbxType;
+ if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
+ eSbxType = SbxVARIANT;
+ else
+ eSbxType = unoToSbxType( rProp.Type.getTypeClass() );
+
+ // Property anlegen und reinbraten
+ SbxVariableRef xVarRef = new SbUnoProperty( rProp.Name, eSbxType, rProp, i, false );
+ QuickInsert( (SbxVariable*)xVarRef );
+ }
+
+ // Dbg_-Properties anlegen
+ implCreateDbgProperties();
+
+ // Methoden anlegen
+ Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods
+ ( MethodConcept::ALL - MethodConcept::DANGEROUS );
+ sal_uInt32 nMethCount = aMethodSeq.getLength();
+ const Reference< XIdlMethod >* pMethods_ = aMethodSeq.getConstArray();
+ for( i = 0 ; i < nMethCount ; i++ )
+ {
+ // Methode ansprechen
+ const Reference< XIdlMethod >& rxMethod = pMethods_[i];
+
+ // SbUnoMethode anlegen und reinbraten
+ SbxVariableRef xMethRef = new SbUnoMethod
+ ( rxMethod->getName(), unoToSbxType( rxMethod->getReturnType() ), rxMethod, false );
+ QuickInsert( (SbxVariable*)xMethRef );
+ }
+}
+
+
+// Wert rausgeben
+Any SbUnoObject::getUnoAny( void )
+{
+ Any aRetAny;
+ if( bNeedIntrospection ) doIntrospection();
+ if( mxMaterialHolder.is() )
+ aRetAny = mxMaterialHolder->getMaterial();
+ else if( mxInvocation.is() )
+ aRetAny <<= mxInvocation;
+ return aRetAny;
+}
+
+// Hilfsmethode zum Anlegen einer Uno-Struct per CoreReflection
+SbUnoObject* Impl_CreateUnoStruct( const String& aClassName )
+{
+ // CoreReflection holen
+ Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
+ if( !xCoreReflection.is() )
+ return NULL;
+
+ // Klasse suchen
+ Reference< XIdlClass > xClass;
+ Reference< XHierarchicalNameAccess > xHarryName =
+ getCoreReflection_HierarchicalNameAccess_Impl();
+ if( xHarryName.is() && xHarryName->hasByHierarchicalName( aClassName ) )
+ xClass = xCoreReflection->forName( aClassName );
+ if( !xClass.is() )
+ return NULL;
+
+ // Ist es ueberhaupt ein struct?
+ TypeClass eType = xClass->getTypeClass();
+ if ( ( eType != TypeClass_STRUCT ) && ( eType != TypeClass_EXCEPTION ) )
+ return NULL;
+
+ // Instanz erzeugen
+ Any aNewAny;
+ xClass->createObject( aNewAny );
+
+ // SbUnoObject daraus basteln
+ SbUnoObject* pUnoObj = new SbUnoObject( aClassName, aNewAny );
+ return pUnoObj;
+}
+
+
+// Factory-Klasse fuer das Anlegen von Uno-Structs per DIM AS NEW
+SbxBase* SbUnoFactory::Create( sal_uInt16, sal_uInt32 )
+{
+ // Ueber SbxId laeuft in Uno nix
+ return NULL;
+}
+
+SbxObject* SbUnoFactory::CreateObject( const String& rClassName )
+{
+ return Impl_CreateUnoStruct( rClassName );
+}
+
+
+// Provisorische Schnittstelle fuer UNO-Anbindung
+// Liefert ein SbxObject, das ein Uno-Interface wrappt
+SbxObjectRef GetSbUnoObject( const String& aName, const Any& aUnoObj_ )
+{
+ return new SbUnoObject( aName, aUnoObj_ );
+}
+
+// Force creation of all properties for debugging
+void createAllObjectProperties( SbxObject* pObj )
+{
+ if( !pObj )
+ return;
+
+ SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pObj);
+ if( pUnoObj )
+ pUnoObj->createAllProperties();
+ else
+ pObj->GetAll( SbxCLASS_DONTCARE );
+}
+
+
+void RTL_Impl_CreateUnoStruct( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // Wir brauchen mindestens 1 Parameter
+ if ( rPar.Count() < 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Klassen-Name der struct holen
+ String aClassName = rPar.Get(1)->GetString();
+
+ // Versuchen, gleichnamige Struct zu erzeugen
+ SbUnoObjectRef xUnoObj = Impl_CreateUnoStruct( aClassName );
+ if( !xUnoObj )
+ return;
+
+ // Objekt zurueckliefern
+ SbxVariableRef refVar = rPar.Get(0);
+ refVar->PutObject( (SbUnoObject*)xUnoObj );
+}
+
+void RTL_Impl_CreateUnoService( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // Wir brauchen mindestens 1 Parameter
+ if ( rPar.Count() < 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Klassen-Name der struct holen
+ String aServiceName = rPar.Get(1)->GetString();
+
+ // Service suchen und instanzieren
+ Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
+ Reference< XInterface > xInterface;
+ if ( xFactory.is() )
+ {
+ try
+ {
+ xInterface = xFactory->createInstance( aServiceName );
+ }
+ catch( const Exception& )
+ {
+ implHandleAnyException( ::cppu::getCaughtException() );
+ }
+ }
+
+ SbxVariableRef refVar = rPar.Get(0);
+ if( xInterface.is() )
+ {
+ Any aAny;
+ aAny <<= xInterface;
+
+ // SbUnoObject daraus basteln und zurueckliefern
+ SbUnoObjectRef xUnoObj = new SbUnoObject( aServiceName, aAny );
+ if( xUnoObj->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID )
+ {
+ // Objekt zurueckliefern
+ refVar->PutObject( (SbUnoObject*)xUnoObj );
+ }
+ else
+ {
+ refVar->PutObject( NULL );
+ }
+ }
+ else
+ {
+ refVar->PutObject( NULL );
+ }
+}
+
+void RTL_Impl_CreateUnoServiceWithArguments( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // Wir brauchen mindestens 2 Parameter
+ if ( rPar.Count() < 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Klassen-Name der struct holen
+ String aServiceName = rPar.Get(1)->GetString();
+ Any aArgAsAny = sbxToUnoValue( rPar.Get(2),
+ getCppuType( (Sequence<Any>*)0 ) );
+ Sequence< Any > aArgs;
+ aArgAsAny >>= aArgs;
+
+ // Service suchen und instanzieren
+ Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
+ Reference< XInterface > xInterface;
+ if ( xFactory.is() )
+ {
+ try
+ {
+ xInterface = xFactory->createInstanceWithArguments( aServiceName, aArgs );
+ }
+ catch( const Exception& )
+ {
+ implHandleAnyException( ::cppu::getCaughtException() );
+ }
+ }
+
+ SbxVariableRef refVar = rPar.Get(0);
+ if( xInterface.is() )
+ {
+ Any aAny;
+ aAny <<= xInterface;
+
+ // SbUnoObject daraus basteln und zurueckliefern
+ SbUnoObjectRef xUnoObj = new SbUnoObject( aServiceName, aAny );
+ if( xUnoObj->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID )
+ {
+ // Objekt zurueckliefern
+ refVar->PutObject( (SbUnoObject*)xUnoObj );
+ }
+ else
+ {
+ refVar->PutObject( NULL );
+ }
+ }
+ else
+ {
+ refVar->PutObject( NULL );
+ }
+}
+
+void RTL_Impl_GetProcessServiceManager( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ SbxVariableRef refVar = rPar.Get(0);
+
+ // Globalen Service-Manager holen
+ Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
+ if( xFactory.is() )
+ {
+ Any aAny;
+ aAny <<= xFactory;
+
+ // SbUnoObject daraus basteln und zurueckliefern
+ SbUnoObjectRef xUnoObj = new SbUnoObject( String( RTL_CONSTASCII_USTRINGPARAM("ProcessServiceManager") ), aAny );
+ refVar->PutObject( (SbUnoObject*)xUnoObj );
+ }
+ else
+ {
+ refVar->PutObject( NULL );
+ }
+}
+
+void RTL_Impl_HasInterfaces( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // Wir brauchen mindestens 2 Parameter
+ sal_uInt16 nParCount = rPar.Count();
+ if( nParCount < 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Variable fuer Rueckgabewert
+ SbxVariableRef refVar = rPar.Get(0);
+ refVar->PutBool( sal_False );
+
+ // Uno-Objekt holen
+ SbxBaseRef pObj = (SbxBase*)rPar.Get( 1 )->GetObject();
+ if( !(pObj && pObj->ISA(SbUnoObject)) )
+ return;
+ Any aAny = ((SbUnoObject*)(SbxBase*)pObj)->getUnoAny();
+ TypeClass eType = aAny.getValueType().getTypeClass();
+ if( eType != TypeClass_INTERFACE )
+ return;
+
+ // Interface aus dem Any besorgen
+ Reference< XInterface > x = *(Reference< XInterface >*)aAny.getValue();
+
+ // CoreReflection holen
+ Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
+ if( !xCoreReflection.is() )
+ return;
+
+ for( sal_uInt16 i = 2 ; i < nParCount ; i++ )
+ {
+ // Interface-Name der struct holen
+ String aIfaceName = rPar.Get( i )->GetString();
+
+ // Klasse suchen
+ Reference< XIdlClass > xClass = xCoreReflection->forName( aIfaceName );
+ if( !xClass.is() )
+ return;
+
+ // Pruefen, ob das Interface unterstuetzt wird
+ ::rtl::OUString aClassName = xClass->getName();
+ Type aClassType( xClass->getTypeClass(), aClassName.getStr() );
+ if( !x->queryInterface( aClassType ).hasValue() )
+ return;
+ }
+
+ // Alles hat geklappt, dann sal_True liefern
+ refVar->PutBool( sal_True );
+}
+
+void RTL_Impl_IsUnoStruct( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // Wir brauchen mindestens 1 Parameter
+ if ( rPar.Count() < 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Variable fuer Rueckgabewert
+ SbxVariableRef refVar = rPar.Get(0);
+ refVar->PutBool( sal_False );
+
+ // Uno-Objekt holen
+ SbxVariableRef xParam = rPar.Get( 1 );
+ if( !xParam->IsObject() )
+ return;
+ SbxBaseRef pObj = (SbxBase*)rPar.Get( 1 )->GetObject();
+ if( !(pObj && pObj->ISA(SbUnoObject)) )
+ return;
+ Any aAny = ((SbUnoObject*)(SbxBase*)pObj)->getUnoAny();
+ TypeClass eType = aAny.getValueType().getTypeClass();
+ if( eType == TypeClass_STRUCT )
+ refVar->PutBool( sal_True );
+}
+
+
+void RTL_Impl_EqualUnoObjects( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Variable fuer Rueckgabewert
+ SbxVariableRef refVar = rPar.Get(0);
+ refVar->PutBool( sal_False );
+
+ // Uno-Objekte holen
+ SbxVariableRef xParam1 = rPar.Get( 1 );
+ if( !xParam1->IsObject() )
+ return;
+ SbxBaseRef pObj1 = (SbxBase*)xParam1->GetObject();
+ if( !(pObj1 && pObj1->ISA(SbUnoObject)) )
+ return;
+ Any aAny1 = ((SbUnoObject*)(SbxBase*)pObj1)->getUnoAny();
+ TypeClass eType1 = aAny1.getValueType().getTypeClass();
+ if( eType1 != TypeClass_INTERFACE )
+ return;
+ Reference< XInterface > x1;
+ aAny1 >>= x1;
+ //XInterfaceRef x1 = *(XInterfaceRef*)aAny1.get();
+
+ SbxVariableRef xParam2 = rPar.Get( 2 );
+ if( !xParam2->IsObject() )
+ return;
+ SbxBaseRef pObj2 = (SbxBase*)xParam2->GetObject();
+ if( !(pObj2 && pObj2->ISA(SbUnoObject)) )
+ return;
+ Any aAny2 = ((SbUnoObject*)(SbxBase*)pObj2)->getUnoAny();
+ TypeClass eType2 = aAny2.getValueType().getTypeClass();
+ if( eType2 != TypeClass_INTERFACE )
+ return;
+ Reference< XInterface > x2;
+ aAny2 >>= x2;
+ //XInterfaceRef x2 = *(XInterfaceRef*)aAny2.get();
+
+ if( x1 == x2 )
+ refVar->PutBool( sal_True );
+}
+
+typedef std::hash_map< ::rtl::OUString, std::vector< ::rtl::OUString >, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > ModuleHash;
+
+
+// helper wrapper function to interact with TypeProvider and
+// XTypeDescriptionEnumerationAccess.
+// if it fails for whatever reason
+// returned Reference<> be null e.g. .is() will be false
+
+Reference< XTypeDescriptionEnumeration >
+getTypeDescriptorEnumeration( const ::rtl::OUString& sSearchRoot,
+ const Sequence< TypeClass >& types, TypeDescriptionSearchDepth depth )
+{
+ Reference< XTypeDescriptionEnumeration > xEnum;
+ Reference< XTypeDescriptionEnumerationAccess> xTypeEnumAccess( getTypeProvider_Impl(), UNO_QUERY );
+ if ( xTypeEnumAccess.is() )
+ {
+ try
+ {
+ xEnum = xTypeEnumAccess->createTypeDescriptionEnumeration(
+ sSearchRoot, types, depth );
+ }
+ catch( NoSuchTypeNameException& /*nstne*/ ) {}
+ catch( InvalidTypeNameException& /*nstne*/ ) {}
+ }
+ return xEnum;
+}
+
+typedef std::hash_map< ::rtl::OUString, Any, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > VBAConstantsHash;
+
+SbxVariable* getVBAConstant( const String& rName )
+{
+ SbxVariable* pConst = NULL;
+ static VBAConstantsHash aConstCache;
+ static bool isInited = false;
+ if ( !isInited )
+ {
+ Sequence< TypeClass > types(1);
+ types[ 0 ] = TypeClass_CONSTANTS;
+ Reference< XTypeDescriptionEnumeration > xEnum = getTypeDescriptorEnumeration( defaultNameSpace, types, TypeDescriptionSearchDepth_INFINITE );
+
+ if ( !xEnum.is() )
+ return NULL;
+
+ while ( xEnum->hasMoreElements() )
+ {
+ Reference< XConstantsTypeDescription > xConstants( xEnum->nextElement(), UNO_QUERY );
+ if ( xConstants.is() )
+ {
+ Sequence< Reference< XConstantTypeDescription > > aConsts = xConstants->getConstants();
+ Reference< XConstantTypeDescription >* pSrc = aConsts.getArray();
+ sal_Int32 nLen = aConsts.getLength();
+ for ( sal_Int32 index =0; index<nLen; ++pSrc, ++index )
+ {
+ Reference< XConstantTypeDescription >& rXConst =
+ *pSrc;
+ ::rtl::OUString sFullName = rXConst->getName();
+ sal_Int32 indexLastDot = sFullName.lastIndexOf('.');
+ ::rtl::OUString sLeafName;
+ if ( indexLastDot > -1 )
+ sLeafName = sFullName.copy( indexLastDot + 1);
+ aConstCache[ sLeafName.toAsciiLowerCase() ] = rXConst->getConstantValue();
+ }
+ }
+ }
+ isInited = true;
+ }
+ ::rtl::OUString sKey( rName );
+ VBAConstantsHash::const_iterator it = aConstCache.find( sKey.toAsciiLowerCase() );
+ if ( it != aConstCache.end() )
+ {
+ pConst = new SbxVariable( SbxVARIANT );
+ pConst->SetName( rName );
+ unoToSbxValue( pConst, it->second );
+ }
+ return pConst;
+}
+
+// Funktion, um einen globalen Bezeichner im
+// UnoScope zu suchen und fuer Sbx zu wrappen
+SbUnoClass* findUnoClass( const String& rName )
+{
+ // #105550 Check if module exists
+ SbUnoClass* pUnoClass = NULL;
+
+ Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
+ if( xTypeAccess->hasByHierarchicalName( rName ) )
+ {
+ Any aRet = xTypeAccess->getByHierarchicalName( rName );
+ Reference< XTypeDescription > xTypeDesc;
+ aRet >>= xTypeDesc;
+
+ if( xTypeDesc.is() )
+ {
+ TypeClass eTypeClass = xTypeDesc->getTypeClass();
+ if( eTypeClass == TypeClass_MODULE || eTypeClass == TypeClass_CONSTANTS )
+ pUnoClass = new SbUnoClass( rName );
+ }
+ }
+ return pUnoClass;
+}
+
+SbxVariable* SbUnoClass::Find( const XubString& rName, SbxClassType t )
+{
+ (void)t;
+
+ SbxVariable* pRes = SbxObject::Find( rName, SbxCLASS_VARIABLE );
+
+ // Wenn nichts gefunden wird, ist das Sub-Modul noch nicht bekannt
+ if( !pRes )
+ {
+ // Wenn es schon eine Klasse ist, nach einen Feld fragen
+ if( m_xClass.is() )
+ {
+ // Ist es ein Field
+ ::rtl::OUString aUStr( rName );
+ Reference< XIdlField > xField = m_xClass->getField( aUStr );
+ Reference< XIdlClass > xClass;
+ if( xField.is() )
+ {
+ try
+ {
+ Any aAny;
+ aAny = xField->get( aAny );
+
+ // Nach Sbx wandeln
+ pRes = new SbxVariable( SbxVARIANT );
+ pRes->SetName( rName );
+ unoToSbxValue( pRes, aAny );
+ }
+ catch( const Exception& )
+ {
+ implHandleAnyException( ::cppu::getCaughtException() );
+ }
+ }
+ }
+ else
+ {
+ // Vollqualifizierten Namen erweitern
+ String aNewName = GetName();
+ aNewName.AppendAscii( "." );
+ aNewName += rName;
+
+ // CoreReflection holen
+ Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
+ if( xCoreReflection.is() )
+ {
+ // Ist es eine Konstante?
+ Reference< XHierarchicalNameAccess > xHarryName( xCoreReflection, UNO_QUERY );
+ if( xHarryName.is() )
+ {
+ try
+ {
+ Any aValue = xHarryName->getByHierarchicalName( aNewName );
+ TypeClass eType = aValue.getValueType().getTypeClass();
+
+ // Interface gefunden? Dann ist es eine Klasse
+ if( eType == TypeClass_INTERFACE )
+ {
+ Reference< XInterface > xIface = *(Reference< XInterface >*)aValue.getValue();
+ Reference< XIdlClass > xClass( xIface, UNO_QUERY );
+ if( xClass.is() )
+ {
+ pRes = new SbxVariable( SbxVARIANT );
+ SbxObjectRef xWrapper = (SbxObject*)new SbUnoClass( aNewName, xClass );
+ pRes->PutObject( xWrapper );
+ }
+ }
+ else
+ {
+ pRes = new SbxVariable( SbxVARIANT );
+ unoToSbxValue( pRes, aValue );
+ }
+ }
+ catch( NoSuchElementException& e1 )
+ {
+ String aMsg = implGetExceptionMsg( e1 );
+ }
+ }
+
+ // Sonst wieder als Klasse annehmen
+ if( !pRes )
+ {
+ SbUnoClass* pNewClass = findUnoClass( aNewName );
+ if( pNewClass )
+ {
+ pRes = new SbxVariable( SbxVARIANT );
+ SbxObjectRef xWrapper = (SbxObject*)pNewClass;
+ pRes->PutObject( xWrapper );
+ }
+ }
+
+ // An UNO service?
+ if( !pRes )
+ {
+ SbUnoService* pUnoService = findUnoService( aNewName );
+ if( pUnoService )
+ {
+ pRes = new SbxVariable( SbxVARIANT );
+ SbxObjectRef xWrapper = (SbxObject*)pUnoService;
+ pRes->PutObject( xWrapper );
+ }
+ }
+
+ // An UNO singleton?
+ if( !pRes )
+ {
+ SbUnoSingleton* pUnoSingleton = findUnoSingleton( aNewName );
+ if( pUnoSingleton )
+ {
+ pRes = new SbxVariable( SbxVARIANT );
+ SbxObjectRef xWrapper = (SbxObject*)pUnoSingleton;
+ pRes->PutObject( xWrapper );
+ }
+ }
+ }
+ }
+
+ if( pRes )
+ {
+ pRes->SetName( rName );
+
+ // Variable einfuegen, damit sie spaeter im Find gefunden wird
+ QuickInsert( pRes );
+
+ // Uns selbst gleich wieder als Listener rausnehmen,
+ // die Werte sind alle konstant
+ if( pRes->IsBroadcaster() )
+ EndListening( pRes->GetBroadcaster(), sal_True );
+ }
+ }
+ return pRes;
+}
+
+
+SbUnoService* findUnoService( const String& rName )
+{
+ SbUnoService* pSbUnoService = NULL;
+
+ Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
+ if( xTypeAccess->hasByHierarchicalName( rName ) )
+ {
+ Any aRet = xTypeAccess->getByHierarchicalName( rName );
+ Reference< XTypeDescription > xTypeDesc;
+ aRet >>= xTypeDesc;
+
+ if( xTypeDesc.is() )
+ {
+ TypeClass eTypeClass = xTypeDesc->getTypeClass();
+ if( eTypeClass == TypeClass_SERVICE )
+ {
+ Reference< XServiceTypeDescription2 > xServiceTypeDesc( xTypeDesc, UNO_QUERY );
+ if( xServiceTypeDesc.is() )
+ pSbUnoService = new SbUnoService( rName, xServiceTypeDesc );
+ }
+ }
+ }
+ return pSbUnoService;
+}
+
+SbxVariable* SbUnoService::Find( const String& rName, SbxClassType )
+{
+ SbxVariable* pRes = SbxObject::Find( rName, SbxCLASS_METHOD );
+
+ if( !pRes )
+ {
+ // Wenn es schon eine Klasse ist, nach einen Feld fragen
+ if( m_bNeedsInit && m_xServiceTypeDesc.is() )
+ {
+ m_bNeedsInit = false;
+
+ Sequence< Reference< XServiceConstructorDescription > > aSCDSeq = m_xServiceTypeDesc->getConstructors();
+ const Reference< XServiceConstructorDescription >* pCtorSeq = aSCDSeq.getConstArray();
+ int nCtorCount = aSCDSeq.getLength();
+ for( int i = 0 ; i < nCtorCount ; ++i )
+ {
+ Reference< XServiceConstructorDescription > xCtor = pCtorSeq[i];
+
+ String aName( xCtor->getName() );
+ if( !aName.Len() )
+ {
+ if( xCtor->isDefaultConstructor() )
+ aName = String::CreateFromAscii( "create" );
+ }
+
+ if( aName.Len() )
+ {
+ // Create and insert SbUnoServiceCtor
+ SbxVariableRef xSbCtorRef = new SbUnoServiceCtor( aName, xCtor );
+ QuickInsert( (SbxVariable*)xSbCtorRef );
+ }
+ }
+
+ pRes = SbxObject::Find( rName, SbxCLASS_METHOD );
+ }
+ }
+
+ return pRes;
+}
+
+void SbUnoService::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType )
+{
+ const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
+ if( pHint )
+ {
+ SbxVariable* pVar = pHint->GetVar();
+ SbxArray* pParams = pVar->GetParameters();
+ SbUnoServiceCtor* pUnoCtor = PTR_CAST(SbUnoServiceCtor,pVar);
+ if( pUnoCtor && pHint->GetId() == SBX_HINT_DATAWANTED )
+ {
+ // Parameter count -1 because of Param0 == this
+ sal_uInt32 nParamCount = pParams ? ((sal_uInt32)pParams->Count() - 1) : 0;
+ Sequence<Any> args;
+ sal_Bool bOutParams = sal_False;
+
+ Reference< XServiceConstructorDescription > xCtor = pUnoCtor->getServiceCtorDesc();
+ Sequence< Reference< XParameter > > aParameterSeq = xCtor->getParameters();
+ const Reference< XParameter >* pParameterSeq = aParameterSeq.getConstArray();
+ sal_uInt32 nUnoParamCount = aParameterSeq.getLength();
+
+ // Default: Ignore not needed parameters
+ bool bParameterError = false;
+
+ // Is the last parameter a rest parameter?
+ bool bRestParameterMode = false;
+ if( nUnoParamCount > 0 )
+ {
+ Reference< XParameter > xLastParam = pParameterSeq[ nUnoParamCount - 1 ];
+ if( xLastParam.is() )
+ {
+ if( xLastParam->isRestParameter() )
+ bRestParameterMode = true;
+ }
+ }
+
+ // Too many parameters with context as first parameter?
+ sal_uInt16 nSbxParameterOffset = 1;
+ sal_uInt16 nParameterOffsetByContext = 0;
+ Reference < XComponentContext > xFirstParamContext;
+ if( nParamCount > nUnoParamCount )
+ {
+ // Check if first parameter is a context and use it
+ // then in createInstanceWithArgumentsAndContext
+ Any aArg0 = sbxToUnoValue( pParams->Get( nSbxParameterOffset ) );
+ if( (aArg0 >>= xFirstParamContext) && xFirstParamContext.is() )
+ nParameterOffsetByContext = 1;
+ }
+
+ sal_uInt32 nEffectiveParamCount = nParamCount - nParameterOffsetByContext;
+ sal_uInt32 nAllocParamCount = nEffectiveParamCount;
+ if( nEffectiveParamCount > nUnoParamCount )
+ {
+ if( !bRestParameterMode )
+ {
+ nEffectiveParamCount = nUnoParamCount;
+ nAllocParamCount = nUnoParamCount;
+ }
+ }
+ // Not enough parameters?
+ else if( nUnoParamCount > nEffectiveParamCount )
+ {
+ // RestParameterMode only helps if one (the last) parameter is missing
+ int nDiff = nUnoParamCount - nEffectiveParamCount;
+ if( !bRestParameterMode || nDiff > 1 )
+ {
+ bParameterError = true;
+ StarBASIC::Error( SbERR_NOT_OPTIONAL );
+ }
+ }
+
+ if( !bParameterError )
+ {
+ if( nAllocParamCount > 0 )
+ {
+ args.realloc( nAllocParamCount );
+ Any* pAnyArgs = args.getArray();
+ for( sal_uInt32 i = 0 ; i < nEffectiveParamCount ; i++ )
+ {
+ sal_uInt16 iSbx = (sal_uInt16)(i + nSbxParameterOffset + nParameterOffsetByContext);
+
+ // bRestParameterMode allows nEffectiveParamCount > nUnoParamCount
+ Reference< XParameter > xParam;
+ if( i < nUnoParamCount )
+ {
+ xParam = pParameterSeq[i];
+ if( !xParam.is() )
+ continue;
+
+ Reference< XTypeDescription > xParamTypeDesc = xParam->getType();
+ if( !xParamTypeDesc.is() )
+ continue;
+ com::sun::star::uno::Type aType( xParamTypeDesc->getTypeClass(), xParamTypeDesc->getName() );
+
+ // sbx paramter needs offset 1
+ pAnyArgs[i] = sbxToUnoValue( pParams->Get( iSbx ), aType );
+
+ // Check for out parameter if not already done
+ if( !bOutParams )
+ {
+ if( xParam->isOut() )
+ bOutParams = sal_True;
+ }
+ }
+ else
+ {
+ pAnyArgs[i] = sbxToUnoValue( pParams->Get( iSbx ) );
+ }
+ }
+ }
+
+ // "Call" ctor using createInstanceWithArgumentsAndContext
+ Reference < XComponentContext > xContext;
+ if( xFirstParamContext.is() )
+ {
+ xContext = xFirstParamContext;
+ }
+ else
+ {
+ Reference < XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW );
+ xContext.set( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" )) ), UNO_QUERY_THROW );
+ }
+ Reference< XMultiComponentFactory > xServiceMgr( xContext->getServiceManager() );
+
+ Any aRetAny;
+ if( xServiceMgr.is() )
+ {
+ String aServiceName = GetName();
+ Reference < XInterface > xRet;
+ try
+ {
+ xRet = xServiceMgr->createInstanceWithArgumentsAndContext( aServiceName, args, xContext );
+ }
+ catch( const Exception& )
+ {
+ implHandleAnyException( ::cppu::getCaughtException() );
+ }
+ aRetAny <<= xRet;
+ }
+ unoToSbxValue( pVar, aRetAny );
+
+ // Copy back out parameters?
+ if( bOutParams )
+ {
+ const Any* pAnyArgs = args.getConstArray();
+
+ for( sal_uInt32 j = 0 ; j < nUnoParamCount ; j++ )
+ {
+ Reference< XParameter > xParam = pParameterSeq[j];
+ if( !xParam.is() )
+ continue;
+
+ if( xParam->isOut() )
+ unoToSbxValue( (SbxVariable*)pParams->Get( (sal_uInt16)(j+1) ), pAnyArgs[ j ] );
+ }
+ }
+ }
+ }
+ else
+ SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+ }
+}
+
+
+
+static SbUnoServiceCtor* pFirstCtor = NULL;
+
+void clearUnoServiceCtors( void )
+{
+ SbUnoServiceCtor* pCtor = pFirstCtor;
+ while( pCtor )
+ {
+ pCtor->SbxValue::Clear();
+ pCtor = pCtor->pNext;
+ }
+}
+
+SbUnoServiceCtor::SbUnoServiceCtor( const String& aName_, Reference< XServiceConstructorDescription > xServiceCtorDesc )
+ : SbxMethod( aName_, SbxOBJECT )
+ , m_xServiceCtorDesc( xServiceCtorDesc )
+{
+}
+
+SbUnoServiceCtor::~SbUnoServiceCtor()
+{
+}
+
+SbxInfo* SbUnoServiceCtor::GetInfo()
+{
+ SbxInfo* pRet = NULL;
+
+ return pRet;
+}
+
+
+SbUnoSingleton* findUnoSingleton( const String& rName )
+{
+ SbUnoSingleton* pSbUnoSingleton = NULL;
+
+ Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
+ if( xTypeAccess->hasByHierarchicalName( rName ) )
+ {
+ Any aRet = xTypeAccess->getByHierarchicalName( rName );
+ Reference< XTypeDescription > xTypeDesc;
+ aRet >>= xTypeDesc;
+
+ if( xTypeDesc.is() )
+ {
+ TypeClass eTypeClass = xTypeDesc->getTypeClass();
+ if( eTypeClass == TypeClass_SINGLETON )
+ {
+ Reference< XSingletonTypeDescription > xSingletonTypeDesc( xTypeDesc, UNO_QUERY );
+ if( xSingletonTypeDesc.is() )
+ pSbUnoSingleton = new SbUnoSingleton( rName, xSingletonTypeDesc );
+ }
+ }
+ }
+ return pSbUnoSingleton;
+}
+
+SbUnoSingleton::SbUnoSingleton( const String& aName_,
+ const Reference< XSingletonTypeDescription >& xSingletonTypeDesc )
+ : SbxObject( aName_ )
+ , m_xSingletonTypeDesc( xSingletonTypeDesc )
+{
+ SbxVariableRef xGetMethodRef =
+ new SbxMethod( String( RTL_CONSTASCII_USTRINGPARAM( "get" ) ), SbxOBJECT );
+ QuickInsert( (SbxVariable*)xGetMethodRef );
+}
+
+void SbUnoSingleton::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType )
+{
+ const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
+ if( pHint )
+ {
+ SbxVariable* pVar = pHint->GetVar();
+ SbxArray* pParams = pVar->GetParameters();
+ sal_uInt32 nParamCount = pParams ? ((sal_uInt32)pParams->Count() - 1) : 0;
+ sal_uInt32 nAllowedParamCount = 1;
+
+ Reference < XComponentContext > xContextToUse;
+ if( nParamCount > 0 )
+ {
+ // Check if first parameter is a context and use it then
+ Reference < XComponentContext > xFirstParamContext;
+ Any aArg1 = sbxToUnoValue( pParams->Get( 1 ) );
+ if( (aArg1 >>= xFirstParamContext) && xFirstParamContext.is() )
+ xContextToUse = xFirstParamContext;
+ }
+
+ if( !xContextToUse.is() )
+ {
+ Reference < XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW );
+ xContextToUse.set( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" )) ), UNO_QUERY_THROW );
+ --nAllowedParamCount;
+ }
+
+ if( nParamCount > nAllowedParamCount )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ Any aRetAny;
+ if( xContextToUse.is() )
+ {
+ String aSingletonName( RTL_CONSTASCII_USTRINGPARAM("/singletons/") );
+ aSingletonName += GetName();
+ Reference < XInterface > xRet;
+ xContextToUse->getValueByName( aSingletonName ) >>= xRet;
+ aRetAny <<= xRet;
+ }
+ unoToSbxValue( pVar, aRetAny );
+ }
+ else
+ SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+}
+
+
+//========================================================================
+//========================================================================
+//========================================================================
+
+// Implementation eines EventAttacher-bezogenen AllListeners, der
+// nur einzelne Events an einen allgemeinen AllListener weiterleitet
+class BasicAllListener_Impl : public BasicAllListenerHelper
+{
+ virtual void firing_impl(const AllEventObject& Event, Any* pRet);
+
+public:
+ SbxObjectRef xSbxObj;
+ ::rtl::OUString aPrefixName;
+
+ BasicAllListener_Impl( const ::rtl::OUString& aPrefixName );
+ ~BasicAllListener_Impl();
+
+ // Methoden von XInterface
+ //virtual sal_Bool queryInterface( Uik aUik, Reference< XInterface > & rOut );
+
+ // Methoden von XAllListener
+ virtual void SAL_CALL firing(const AllEventObject& Event) throw ( RuntimeException );
+ virtual Any SAL_CALL approveFiring(const AllEventObject& Event) throw ( RuntimeException );
+
+ // Methoden von XEventListener
+ virtual void SAL_CALL disposing(const EventObject& Source) throw ( RuntimeException );
+};
+
+
+//========================================================================
+BasicAllListener_Impl::BasicAllListener_Impl
+(
+ const ::rtl::OUString & aPrefixName_
+)
+ : aPrefixName( aPrefixName_ )
+{
+}
+
+//========================================================================
+BasicAllListener_Impl::~BasicAllListener_Impl()
+{
+}
+
+//========================================================================
+
+void BasicAllListener_Impl::firing_impl( const AllEventObject& Event, Any* pRet )
+{
+ vos::OGuard guard( Application::GetSolarMutex() );
+
+ if( xSbxObj.Is() )
+ {
+ ::rtl::OUString aMethodName = aPrefixName;
+ aMethodName = aMethodName + Event.MethodName;
+
+ SbxVariable * pP = xSbxObj;
+ while( pP->GetParent() )
+ {
+ pP = pP->GetParent();
+ StarBASIC * pLib = PTR_CAST(StarBASIC,pP);
+ if( pLib )
+ {
+ // In Basic Array anlegen
+ SbxArrayRef xSbxArray = new SbxArray( SbxVARIANT );
+ const Any * pArgs = Event.Arguments.getConstArray();
+ sal_Int32 nCount = Event.Arguments.getLength();
+ for( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ // Elemente wandeln
+ SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
+ unoToSbxValue( (SbxVariable*)xVar, pArgs[i] );
+ xSbxArray->Put( xVar, sal::static_int_cast< sal_uInt16 >(i+1) );
+ }
+
+ pLib->Call( aMethodName, xSbxArray );
+
+ // Return-Wert aus dem Param-Array holen, wenn verlangt
+ if( pRet )
+ {
+ SbxVariable* pVar = xSbxArray->Get( 0 );
+ if( pVar )
+ {
+ // #95792 Avoid a second call
+ sal_uInt16 nFlags = pVar->GetFlags();
+ pVar->SetFlag( SBX_NO_BROADCAST );
+ *pRet = sbxToUnoValueImpl( pVar );
+ pVar->SetFlags( nFlags );
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
+
+// Methoden von XAllListener
+void BasicAllListener_Impl::firing( const AllEventObject& Event ) throw ( RuntimeException )
+{
+ firing_impl( Event, NULL );
+}
+
+Any BasicAllListener_Impl::approveFiring( const AllEventObject& Event ) throw ( RuntimeException )
+{
+ Any aRetAny;
+ firing_impl( Event, &aRetAny );
+ return aRetAny;
+}
+
+//========================================================================
+// Methoden von XEventListener
+void BasicAllListener_Impl ::disposing(const EventObject& ) throw ( RuntimeException )
+{
+ vos::OGuard guard( Application::GetSolarMutex() );
+
+ xSbxObj.Clear();
+}
+
+
+
+//*************************************************************************
+// class InvocationToAllListenerMapper
+// helper class to map XInvocation to XAllListener (also in project eventattacher!)
+//*************************************************************************
+class InvocationToAllListenerMapper : public WeakImplHelper1< XInvocation >
+{
+public:
+ InvocationToAllListenerMapper( const Reference< XIdlClass >& ListenerType,
+ const Reference< XAllListener >& AllListener, const Any& Helper );
+
+ // XInvocation
+ virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection(void) throw( RuntimeException );
+ virtual Any SAL_CALL invoke(const ::rtl::OUString& FunctionName, const Sequence< Any >& Params, Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam)
+ throw( IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException );
+ virtual void SAL_CALL setValue(const ::rtl::OUString& PropertyName, const Any& Value)
+ throw( UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException );
+ virtual Any SAL_CALL getValue(const ::rtl::OUString& PropertyName) throw( UnknownPropertyException, RuntimeException );
+ virtual sal_Bool SAL_CALL hasMethod(const ::rtl::OUString& Name) throw( RuntimeException );
+ virtual sal_Bool SAL_CALL hasProperty(const ::rtl::OUString& Name) throw( RuntimeException );
+
+private:
+ Reference< XIdlReflection > m_xCoreReflection;
+ Reference< XAllListener > m_xAllListener;
+ Reference< XIdlClass > m_xListenerType;
+ Any m_Helper;
+};
+
+
+// Function to replace AllListenerAdapterService::createAllListerAdapter
+Reference< XInterface > createAllListenerAdapter
+(
+ const Reference< XInvocationAdapterFactory >& xInvocationAdapterFactory,
+ const Reference< XIdlClass >& xListenerType,
+ const Reference< XAllListener >& xListener,
+ const Any& Helper
+)
+{
+ Reference< XInterface > xAdapter;
+ if( xInvocationAdapterFactory.is() && xListenerType.is() && xListener.is() )
+ {
+ Reference< XInvocation > xInvocationToAllListenerMapper =
+ (XInvocation*)new InvocationToAllListenerMapper( xListenerType, xListener, Helper );
+ Type aListenerType( xListenerType->getTypeClass(), xListenerType->getName() );
+ xAdapter = xInvocationAdapterFactory->createAdapter( xInvocationToAllListenerMapper, aListenerType );
+ }
+ return xAdapter;
+}
+
+
+//--------------------------------------------------------------------------------------------------
+// InvocationToAllListenerMapper
+InvocationToAllListenerMapper::InvocationToAllListenerMapper
+ ( const Reference< XIdlClass >& ListenerType, const Reference< XAllListener >& AllListener, const Any& Helper )
+ : m_xAllListener( AllListener )
+ , m_xListenerType( ListenerType )
+ , m_Helper( Helper )
+{
+}
+
+//*************************************************************************
+Reference< XIntrospectionAccess > SAL_CALL InvocationToAllListenerMapper::getIntrospection(void)
+ throw( RuntimeException )
+{
+ return Reference< XIntrospectionAccess >();
+}
+
+//*************************************************************************
+Any SAL_CALL InvocationToAllListenerMapper::invoke(const ::rtl::OUString& FunctionName, const Sequence< Any >& Params,
+ Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam)
+ throw( IllegalArgumentException, CannotConvertException,
+ InvocationTargetException, RuntimeException )
+{
+ (void)OutParamIndex;
+ (void)OutParam ;
+
+ Any aRet;
+
+ // Check if to firing or approveFiring has to be called
+ Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( FunctionName );
+ sal_Bool bApproveFiring = sal_False;
+ if( !xMethod.is() )
+ return aRet;
+ Reference< XIdlClass > xReturnType = xMethod->getReturnType();
+ Sequence< Reference< XIdlClass > > aExceptionSeq = xMethod->getExceptionTypes();
+ if( ( xReturnType.is() && xReturnType->getTypeClass() != TypeClass_VOID ) ||
+ aExceptionSeq.getLength() > 0 )
+ {
+ bApproveFiring = sal_True;
+ }
+ else
+ {
+ Sequence< ParamInfo > aParamSeq = xMethod->getParameterInfos();
+ sal_uInt32 nParamCount = aParamSeq.getLength();
+ if( nParamCount > 1 )
+ {
+ const ParamInfo* pInfos = aParamSeq.getConstArray();
+ for( sal_uInt32 i = 0 ; i < nParamCount ; i++ )
+ {
+ if( pInfos[ i ].aMode != ParamMode_IN )
+ {
+ bApproveFiring = sal_True;
+ break;
+ }
+ }
+ }
+ }
+
+ AllEventObject aAllEvent;
+ aAllEvent.Source = (OWeakObject*) this;
+ aAllEvent.Helper = m_Helper;
+ aAllEvent.ListenerType = Type(m_xListenerType->getTypeClass(), m_xListenerType->getName() );
+ aAllEvent.MethodName = FunctionName;
+ aAllEvent.Arguments = Params;
+ if( bApproveFiring )
+ aRet = m_xAllListener->approveFiring( aAllEvent );
+ else
+ m_xAllListener->firing( aAllEvent );
+ return aRet;
+}
+
+//*************************************************************************
+void SAL_CALL InvocationToAllListenerMapper::setValue(const ::rtl::OUString& PropertyName, const Any& Value)
+ throw( UnknownPropertyException, CannotConvertException,
+ InvocationTargetException, RuntimeException )
+{
+ (void)PropertyName;
+ (void)Value;
+}
+
+//*************************************************************************
+Any SAL_CALL InvocationToAllListenerMapper::getValue(const ::rtl::OUString& PropertyName)
+ throw( UnknownPropertyException, RuntimeException )
+{
+ (void)PropertyName;
+
+ return Any();
+}
+
+//*************************************************************************
+sal_Bool SAL_CALL InvocationToAllListenerMapper::hasMethod(const ::rtl::OUString& Name)
+ throw( RuntimeException )
+{
+ Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( Name );
+ return xMethod.is();
+}
+
+//*************************************************************************
+sal_Bool SAL_CALL InvocationToAllListenerMapper::hasProperty(const ::rtl::OUString& Name)
+ throw( RuntimeException )
+{
+ Reference< XIdlField > xField = m_xListenerType->getField( Name );
+ return xField.is();
+}
+
+//========================================================================
+// Uno-Service erzeugen
+// 1. Parameter == Prefix-Name der Makros
+// 2. Parameter == voll qualifizierter Name des Listeners
+void SbRtl_CreateUnoListener( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
+//RTLFUNC(CreateUnoListener)
+{
+ (void)bWrite;
+
+ // Wir brauchen 2 Parameter
+ if ( rPar.Count() != 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Klassen-Name der struct holen
+ String aPrefixName = rPar.Get(1)->GetString();
+ String aListenerClassName = rPar.Get(2)->GetString();
+
+ // CoreReflection holen
+ Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
+ if( !xCoreReflection.is() )
+ return;
+
+ // AllListenerAdapterService holen
+ Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
+ if( !xFactory.is() )
+ return;
+
+ // Klasse suchen
+ Reference< XIdlClass > xClass = xCoreReflection->forName( aListenerClassName );
+ if( !xClass.is() )
+ return;
+
+ // AB, 30.11.1999 InvocationAdapterFactory holen
+ Reference< XInvocationAdapterFactory > xInvocationAdapterFactory = Reference< XInvocationAdapterFactory >(
+ xFactory->createInstance( rtl::OUString::createFromAscii("com.sun.star.script.InvocationAdapterFactory") ), UNO_QUERY );
+
+ BasicAllListener_Impl * p;
+ Reference< XAllListener > xAllLst = p = new BasicAllListener_Impl( aPrefixName );
+ Any aTmp;
+ Reference< XInterface > xLst = createAllListenerAdapter( xInvocationAdapterFactory, xClass, xAllLst, aTmp );
+ if( !xLst.is() )
+ return;
+
+ ::rtl::OUString aClassName = xClass->getName();
+ Type aClassType( xClass->getTypeClass(), aClassName.getStr() );
+ aTmp = xLst->queryInterface( aClassType );
+ if( !aTmp.hasValue() )
+ return;
+
+ SbUnoObject* pUnoObj = new SbUnoObject( aListenerClassName, aTmp );
+ p->xSbxObj = pUnoObj;
+ p->xSbxObj->SetParent( pBasic );
+
+ // #100326 Register listener object to set Parent NULL in Dtor
+ SbxArrayRef xBasicUnoListeners = pBasic->getUnoListeners();
+ xBasicUnoListeners->Insert( pUnoObj, xBasicUnoListeners->Count() );
+
+ // Objekt zurueckliefern
+ SbxVariableRef refVar = rPar.Get(0);
+ refVar->PutObject( p->xSbxObj );
+}
+
+//========================================================================
+// Represents the DefaultContext property of the ProcessServiceManager
+// in the Basic runtime system.
+void RTL_Impl_GetDefaultContext( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ SbxVariableRef refVar = rPar.Get(0);
+
+ Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+ Reference< XPropertySet> xPSMPropertySet( xFactory, UNO_QUERY );
+ if( xPSMPropertySet.is() )
+ {
+ Any aContextAny = xPSMPropertySet->getPropertyValue(
+ String( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) );
+
+ SbUnoObjectRef xUnoObj = new SbUnoObject
+ ( String( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ),
+ aContextAny );
+ refVar->PutObject( (SbUnoObject*)xUnoObj );
+ }
+ else
+ {
+ refVar->PutObject( NULL );
+ }
+}
+
+//========================================================================
+// Creates a Basic wrapper object for a strongly typed Uno value
+// 1. parameter: Uno type as full qualified type name, e.g. "byte[]"
+void RTL_Impl_CreateUnoValue( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ static String aTypeTypeString( RTL_CONSTASCII_USTRINGPARAM("type") );
+
+ // 2 parameters needed
+ if ( rPar.Count() != 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Klassen-Name der struct holen
+ String aTypeName = rPar.Get(1)->GetString();
+ SbxVariable* pVal = rPar.Get(2);
+
+ if( aTypeName == aTypeTypeString )
+ {
+ SbxDataType eBaseType = pVal->SbxValue::GetType();
+ String aValTypeName;
+ if( eBaseType == SbxSTRING )
+ {
+ aValTypeName = pVal->GetString();
+ }
+ else if( eBaseType == SbxOBJECT )
+ {
+ // XIdlClass?
+ Reference< XIdlClass > xIdlClass;
+
+ SbxBaseRef pObj = (SbxBase*)pVal->GetObject();
+ if( pObj && pObj->ISA(SbUnoObject) )
+ {
+ Any aUnoAny = ((SbUnoObject*)(SbxBase*)pObj)->getUnoAny();
+ aUnoAny >>= xIdlClass;
+ }
+
+ if( xIdlClass.is() )
+ aValTypeName = xIdlClass->getName();
+ }
+ Type aType;
+ bool bSuccess = implGetTypeByName( aValTypeName, aType );
+ if( bSuccess )
+ {
+ Any aTypeAny( aType );
+ SbxVariableRef refVar = rPar.Get(0);
+ SbxObjectRef xUnoAnyObject = new SbUnoAnyObject( aTypeAny );
+ refVar->PutObject( xUnoAnyObject );
+ }
+ return;
+ }
+
+ // Check the type
+ Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
+ Any aRet;
+ try
+ {
+ aRet = xTypeAccess->getByHierarchicalName( aTypeName );
+ }
+ catch( NoSuchElementException& e1 )
+ {
+ String aNoSuchElementExceptionName
+ ( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.NoSuchElementException" ) );
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( e1, aNoSuchElementExceptionName ) );
+ return;
+ }
+ Reference< XTypeDescription > xTypeDesc;
+ aRet >>= xTypeDesc;
+ TypeClass eTypeClass = xTypeDesc->getTypeClass();
+ Type aDestType( eTypeClass, aTypeName );
+
+
+ // Preconvert value
+ Any aVal = sbxToUnoValueImpl( pVal );
+ Any aConvertedVal = convertAny( aVal, aDestType );
+
+ /*
+ // Convert
+ Reference< XTypeConverter > xConverter = getTypeConverter_Impl();
+ try
+ {
+ aConvertedVal = xConverter->convertTo( aVal, aDestType );
+ }
+ catch( IllegalArgumentException& e1 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( ::cppu::getCaughtException() ) );
+ return;
+ }
+ catch( CannotConvertException& e2 )
+ {
+ String aCannotConvertExceptionName
+ ( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.IllegalArgumentException" ) );
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( e2, aCannotConvertExceptionName ) );
+ return;
+ }
+ */
+
+ SbxVariableRef refVar = rPar.Get(0);
+ SbxObjectRef xUnoAnyObject = new SbUnoAnyObject( aConvertedVal );
+ refVar->PutObject( xUnoAnyObject );
+}
+
+//==========================================================================
+
+namespace {
+class OMutexBasis
+{
+protected:
+ // this mutex is necessary for OInterfaceContainerHelper
+ ::osl::Mutex m_aMutex;
+};
+} // namespace
+
+typedef WeakImplHelper2< XInvocation, XComponent > ModuleInvocationProxyHelper;
+
+class ModuleInvocationProxy : public OMutexBasis,
+ public ModuleInvocationProxyHelper
+{
+ ::rtl::OUString m_aPrefix;
+ SbxObjectRef m_xScopeObj;
+ bool m_bProxyIsClassModuleObject;
+
+ ::cppu::OInterfaceContainerHelper m_aListeners;
+
+public:
+ ModuleInvocationProxy( const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj );
+ ~ModuleInvocationProxy()
+ {}
+
+ // XInvocation
+ virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection() throw();
+ virtual void SAL_CALL setValue( const ::rtl::OUString& rProperty, const Any& rValue )
+ throw( UnknownPropertyException );
+ virtual Any SAL_CALL getValue( const ::rtl::OUString& rProperty )
+ throw( UnknownPropertyException );
+ virtual sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& rName ) throw();
+ virtual sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& rProp ) throw();
+
+ virtual Any SAL_CALL invoke( const ::rtl::OUString& rFunction,
+ const Sequence< Any >& rParams,
+ Sequence< sal_Int16 >& rOutParamIndex,
+ Sequence< Any >& rOutParam )
+ throw( CannotConvertException, InvocationTargetException );
+
+ // XComponent
+ virtual void SAL_CALL dispose() throw(RuntimeException);
+ virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException);
+ virtual void SAL_CALL removeEventListener( const Reference< XEventListener >& aListener ) throw (RuntimeException);
+};
+
+ModuleInvocationProxy::ModuleInvocationProxy( const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj )
+ : m_aPrefix( aPrefix + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_") ) )
+ , m_xScopeObj( xScopeObj )
+ , m_aListeners( m_aMutex )
+{
+ m_bProxyIsClassModuleObject = xScopeObj.Is() ? xScopeObj->ISA(SbClassModuleObject) : false;
+}
+
+Reference< XIntrospectionAccess > SAL_CALL ModuleInvocationProxy::getIntrospection() throw()
+{
+ return Reference< XIntrospectionAccess >();
+}
+
+void SAL_CALL ModuleInvocationProxy::setValue( const ::rtl::OUString& rProperty, const Any& rValue ) throw( UnknownPropertyException )
+{
+ if( !m_bProxyIsClassModuleObject )
+ throw UnknownPropertyException();
+
+ vos::OGuard guard( Application::GetSolarMutex() );
+
+ ::rtl::OUString aPropertyFunctionName( RTL_CONSTASCII_USTRINGPARAM( "Property Set ") );
+ aPropertyFunctionName += m_aPrefix;
+ aPropertyFunctionName += rProperty;
+
+ SbxVariable* p = m_xScopeObj->Find( aPropertyFunctionName, SbxCLASS_METHOD );
+ SbMethod* pMeth = p != NULL ? PTR_CAST(SbMethod,p) : NULL;
+ if( pMeth == NULL )
+ {
+ // TODO: Check vba behavior concernig missing function
+ //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
+ throw UnknownPropertyException();
+ }
+
+ // Setup parameter
+ SbxArrayRef xArray = new SbxArray;
+ SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
+ unoToSbxValue( (SbxVariable*)xVar, rValue );
+ xArray->Put( xVar, 1 );
+
+ // Call property method
+ SbxVariableRef xValue = new SbxVariable;
+ pMeth->SetParameters( xArray );
+ pMeth->Call( xValue );
+ //aRet = sbxToUnoValue( xValue );
+ pMeth->SetParameters( NULL );
+
+ // TODO: OutParameter?
+
+ // throw InvocationTargetException();
+
+ //return aRet;
+
+}
+
+Any SAL_CALL ModuleInvocationProxy::getValue( const ::rtl::OUString& rProperty ) throw( UnknownPropertyException )
+{
+ if( !m_bProxyIsClassModuleObject )
+ throw UnknownPropertyException();
+
+ vos::OGuard guard( Application::GetSolarMutex() );
+
+ ::rtl::OUString aPropertyFunctionName( RTL_CONSTASCII_USTRINGPARAM( "Property Get ") );
+ aPropertyFunctionName += m_aPrefix;
+ aPropertyFunctionName += rProperty;
+
+ SbxVariable* p = m_xScopeObj->Find( aPropertyFunctionName, SbxCLASS_METHOD );
+ SbMethod* pMeth = p != NULL ? PTR_CAST(SbMethod,p) : NULL;
+ if( pMeth == NULL )
+ {
+ // TODO: Check vba behavior concernig missing function
+ //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
+ throw UnknownPropertyException();
+ }
+
+ // Call method
+ SbxVariableRef xValue = new SbxVariable;
+ pMeth->Call( xValue );
+ Any aRet = sbxToUnoValue( xValue );
+ return aRet;
+}
+
+sal_Bool SAL_CALL ModuleInvocationProxy::hasMethod( const ::rtl::OUString& ) throw()
+{
+ return sal_False;
+}
+
+sal_Bool SAL_CALL ModuleInvocationProxy::hasProperty( const ::rtl::OUString& ) throw()
+{
+ return sal_False;
+}
+
+Any SAL_CALL ModuleInvocationProxy::invoke( const ::rtl::OUString& rFunction,
+ const Sequence< Any >& rParams,
+ Sequence< sal_Int16 >&,
+ Sequence< Any >& )
+ throw( CannotConvertException, InvocationTargetException )
+{
+ vos::OGuard guard( Application::GetSolarMutex() );
+
+ Any aRet;
+ SbxObjectRef xScopeObj = m_xScopeObj;
+ if( !xScopeObj.Is() )
+ return aRet;
+
+ ::rtl::OUString aFunctionName = m_aPrefix;
+ aFunctionName += rFunction;
+
+ sal_Bool bSetRescheduleBack = sal_False;
+ sal_Bool bOldReschedule = sal_True;
+ SbiInstance* pInst = pINST;
+ if( pInst && pInst->IsCompatibility() )
+ {
+ bOldReschedule = pInst->IsReschedule();
+ if ( bOldReschedule )
+ {
+ pInst->EnableReschedule( sal_False );
+ bSetRescheduleBack = sal_True;
+ }
+ }
+
+ SbxVariable* p = xScopeObj->Find( aFunctionName, SbxCLASS_METHOD );
+ SbMethod* pMeth = p != NULL ? PTR_CAST(SbMethod,p) : NULL;
+ if( pMeth == NULL )
+ {
+ // TODO: Check vba behavior concernig missing function
+ //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
+ return aRet;
+ }
+
+ // Setup parameters
+ SbxArrayRef xArray;
+ sal_Int32 nParamCount = rParams.getLength();
+ if( nParamCount )
+ {
+ xArray = new SbxArray;
+ const Any *pArgs = rParams.getConstArray();
+ for( sal_Int32 i = 0 ; i < nParamCount ; i++ )
+ {
+ SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
+ unoToSbxValue( (SbxVariable*)xVar, pArgs[i] );
+ xArray->Put( xVar, sal::static_int_cast< sal_uInt16 >(i+1) );
+ }
+ }
+
+ // Call method
+ SbxVariableRef xValue = new SbxVariable;
+ if( xArray.Is() )
+ pMeth->SetParameters( xArray );
+ pMeth->Call( xValue );
+ aRet = sbxToUnoValue( xValue );
+ pMeth->SetParameters( NULL );
+
+ if( bSetRescheduleBack )
+ pInst->EnableReschedule( bOldReschedule );
+
+ // TODO: OutParameter?
+
+ return aRet;
+}
+
+void SAL_CALL ModuleInvocationProxy::dispose()
+ throw(RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ EventObject aEvent( (XComponent*)this );
+ m_aListeners.disposeAndClear( aEvent );
+
+ m_xScopeObj = NULL;
+}
+
+void SAL_CALL ModuleInvocationProxy::addEventListener( const Reference< XEventListener >& xListener )
+ throw (RuntimeException)
+{
+ m_aListeners.addInterface( xListener );
+}
+
+void SAL_CALL ModuleInvocationProxy::removeEventListener( const Reference< XEventListener >& xListener )
+ throw (RuntimeException)
+{
+ m_aListeners.removeInterface( xListener );
+}
+
+
+Reference< XInterface > createComListener( const Any& aControlAny, const ::rtl::OUString& aVBAType,
+ const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj )
+{
+ Reference< XInterface > xRet;
+
+ Reference< XComponentContext > xContext = getComponentContext_Impl();
+ Reference< XMultiComponentFactory > xServiceMgr( xContext->getServiceManager() );
+
+ Reference< XInvocation > xProxy = new ModuleInvocationProxy( aPrefix, xScopeObj );
+
+ Sequence<Any> args( 3 );
+ args[0] <<= aControlAny;
+ args[1] <<= aVBAType;
+ args[2] <<= xProxy;
+
+ try
+ {
+ xRet = xServiceMgr->createInstanceWithArgumentsAndContext(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.custom.UnoComListener")),
+ args, xContext );
+ }
+ catch( const Exception& )
+ {
+ implHandleAnyException( ::cppu::getCaughtException() );
+ }
+
+ return xRet;
+}
+
+typedef std::vector< WeakReference< XComponent > > ComponentRefVector;
+
+struct StarBasicDisposeItem
+{
+ StarBASIC* m_pBasic;
+ SbxArrayRef m_pRegisteredVariables;
+ ComponentRefVector m_vComImplementsObjects;
+
+ StarBasicDisposeItem( StarBASIC* pBasic )
+ : m_pBasic( pBasic )
+ {
+ m_pRegisteredVariables = new SbxArray();
+ }
+};
+
+typedef std::vector< StarBasicDisposeItem* > DisposeItemVector;
+
+static DisposeItemVector GaDisposeItemVector;
+
+DisposeItemVector::iterator lcl_findItemForBasic( StarBASIC* pBasic )
+{
+ DisposeItemVector::iterator it;
+ for( it = GaDisposeItemVector.begin() ; it != GaDisposeItemVector.end() ; ++it )
+ {
+ StarBasicDisposeItem* pItem = *it;
+ if( pItem->m_pBasic == pBasic )
+ return it;
+ }
+ return GaDisposeItemVector.end();
+}
+
+StarBasicDisposeItem* lcl_getOrCreateItemForBasic( StarBASIC* pBasic )
+{
+ DisposeItemVector::iterator it = lcl_findItemForBasic( pBasic );
+ StarBasicDisposeItem* pItem = (it != GaDisposeItemVector.end()) ? *it : NULL;
+ if( pItem == NULL )
+ {
+ pItem = new StarBasicDisposeItem( pBasic );
+ GaDisposeItemVector.push_back( pItem );
+ }
+ return pItem;
+}
+
+void registerComponentToBeDisposedForBasic
+ ( Reference< XComponent > xComponent, StarBASIC* pBasic )
+{
+ StarBasicDisposeItem* pItem = lcl_getOrCreateItemForBasic( pBasic );
+ pItem->m_vComImplementsObjects.push_back( xComponent );
+}
+
+void registerComListenerVariableForBasic( SbxVariable* pVar, StarBASIC* pBasic )
+{
+ StarBasicDisposeItem* pItem = lcl_getOrCreateItemForBasic( pBasic );
+ SbxArray* pArray = pItem->m_pRegisteredVariables;
+ pArray->Put( pVar, pArray->Count() );
+}
+
+void disposeComVariablesForBasic( StarBASIC* pBasic )
+{
+ DisposeItemVector::iterator it = lcl_findItemForBasic( pBasic );
+ if( it != GaDisposeItemVector.end() )
+ {
+ StarBasicDisposeItem* pItem = *it;
+
+ SbxArray* pArray = pItem->m_pRegisteredVariables;
+ sal_uInt16 nCount = pArray->Count();
+ for( sal_uInt16 i = 0 ; i < nCount ; ++i )
+ {
+ SbxVariable* pVar = pArray->Get( i );
+ pVar->ClearComListener();
+ }
+
+ ComponentRefVector& rv = pItem->m_vComImplementsObjects;
+ ComponentRefVector::iterator itCRV;
+ for( itCRV = rv.begin() ; itCRV != rv.end() ; ++itCRV )
+ {
+ try
+ {
+ Reference< XComponent > xComponent( (*itCRV).get(), UNO_QUERY_THROW );
+ xComponent->dispose();
+ }
+ catch( Exception& )
+ {}
+ }
+
+ delete pItem;
+ GaDisposeItemVector.erase( it );
+ }
+}
+
+
+// Handle module implements mechanism for OLE types
+bool SbModule::createCOMWrapperForIface( Any& o_rRetAny, SbClassModuleObject* pProxyClassModuleObject )
+{
+ // For now: Take first interface that allows to instantiate COM wrapper
+ // TODO: Check if support for multiple interfaces is needed
+
+ Reference< XComponentContext > xContext = getComponentContext_Impl();
+ Reference< XMultiComponentFactory > xServiceMgr( xContext->getServiceManager() );
+ Reference< XSingleServiceFactory > xComImplementsFactory
+ (
+ xServiceMgr->createInstanceWithContext(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.custom.ComImplementsFactory")), xContext ),
+ UNO_QUERY
+ );
+ if( !xComImplementsFactory.is() )
+ return false;
+
+ bool bSuccess = false;
+
+ SbxArray* pModIfaces = pClassData->mxIfaces;
+ sal_uInt16 nCount = pModIfaces->Count();
+ for( sal_uInt16 i = 0 ; i < nCount ; ++i )
+ {
+ SbxVariable* pVar = pModIfaces->Get( i );
+ ::rtl::OUString aIfaceName = pVar->GetName();
+
+ if( aIfaceName.getLength() != 0 )
+ {
+ ::rtl::OUString aPureIfaceName = aIfaceName;
+ sal_Int32 indexLastDot = aIfaceName.lastIndexOf('.');
+ if ( indexLastDot > -1 )
+ aPureIfaceName = aIfaceName.copy( indexLastDot + 1 );
+
+ Reference< XInvocation > xProxy = new ModuleInvocationProxy( aPureIfaceName, pProxyClassModuleObject );
+
+ Sequence<Any> args( 2 );
+ args[0] <<= aIfaceName;
+ args[1] <<= xProxy;
+
+ Reference< XInterface > xRet;
+ bSuccess = false;
+ try
+ {
+ xRet = xComImplementsFactory->createInstanceWithArguments( args );
+ bSuccess = true;
+ }
+ catch( const Exception& )
+ {
+ implHandleAnyException( ::cppu::getCaughtException() );
+ }
+
+ if( bSuccess )
+ {
+ Reference< XComponent > xComponent( xProxy, UNO_QUERY );
+ if( xComponent.is() )
+ {
+ StarBASIC* pParentBasic = NULL;
+ SbxObject* pCurObject = this;
+ do
+ {
+ SbxObject* pObjParent = pCurObject->GetParent();
+ pParentBasic = PTR_CAST( StarBASIC, pObjParent );
+ pCurObject = pObjParent;
+ }
+ while( pParentBasic == NULL && pCurObject != NULL );
+
+ OSL_ASSERT( pParentBasic != NULL );
+ registerComponentToBeDisposedForBasic( xComponent, pParentBasic );
+ }
+
+ o_rRetAny <<= xRet;
+ break;
+ }
+ }
+ }
+
+ return bSuccess;
+}
+
+
+// Due to an incorrect behavior IE returns an object instead of a string
+// in some scenarios. Calling toString at the object may correct this.
+// Helper function used in sbxvalue.cxx
+bool handleToStringForCOMObjects( SbxObject* pObj, SbxValue* pVal )
+{
+ bool bSuccess = false;
+
+ SbUnoObject* pUnoObj = NULL;
+ if( pObj != NULL && (pUnoObj = PTR_CAST(SbUnoObject,(SbxObject*)pObj)) != NULL )
+ {
+ // Only for native COM objects
+ if( pUnoObj->isNativeCOMObject() )
+ {
+ SbxVariableRef pMeth = pObj->Find( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "toString" ) ), SbxCLASS_METHOD );
+ if ( pMeth.Is() )
+ {
+ SbxValues aRes;
+ pMeth->Get( aRes );
+ pVal->Put( aRes );
+ bSuccess = true;
+ }
+ }
+ }
+ return bSuccess;
+}
+
diff --git a/basic/source/classes/sbxmod.cxx b/basic/source/classes/sbxmod.cxx
new file mode 100755
index 000000000000..a268568a410d
--- /dev/null
+++ b/basic/source/classes/sbxmod.cxx
@@ -0,0 +1,2626 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_basic.hxx"
+
+#include <list>
+
+#include <vos/macros.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/stream.hxx>
+#include <svl/brdcst.hxx>
+#include <tools/shl.hxx>
+#include <basic/sbx.hxx>
+#include "sb.hxx"
+#include <sbjsmeth.hxx>
+#include "sbjsmod.hxx"
+#include "sbintern.hxx"
+#include "image.hxx"
+#include "opcodes.hxx"
+#include "runtime.hxx"
+#include "token.hxx"
+#include "sbunoobj.hxx"
+#include "sbtrace.hxx"
+
+
+//#include <basic/hilight.hxx>
+#include <svtools/syntaxhighlight.hxx>
+
+#include <basic/basrdll.hxx>
+#include <vos/mutex.hxx>
+#include <basic/sbobjmod.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/script/ModuleType.hpp>
+#include <com/sun/star/script/vba/XVBACompatibility.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+using namespace com::sun::star;
+
+// for the bsearch
+#ifdef WNT
+#define CDECL _cdecl
+#endif
+#if defined(UNX) || defined(OS2)
+#define CDECL
+#endif
+#ifdef UNX
+#include <sys/resource.h>
+#endif
+
+#include <stdio.h>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <comphelper/processfactory.hxx>
+#include <vcl/svapp.hxx>
+#include <map>
+#include <com/sun/star/reflection/XProxyFactory.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <basic/sbobjmod.hxx>
+#include <com/sun/star/uno/XAggregation.hpp>
+#include <map>
+#include <com/sun/star/script/XInvocation.hpp>
+
+ using namespace ::com::sun::star;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::reflection;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::script;
+
+
+#include <com/sun/star/script/XLibraryContainer.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/awt/XDialogProvider.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <comphelper/anytostring.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+typedef ::cppu::WeakImplHelper1< XInvocation > DocObjectWrapper_BASE;
+typedef ::std::map< sal_Int16, Any, ::std::less< sal_Int16 > > OutParamMap;
+::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar );
+void unoToSbxValue( SbxVariable* pVar, const ::com::sun::star::uno::Any& aValue );
+
+class DocObjectWrapper : public DocObjectWrapper_BASE
+{
+ Reference< XAggregation > m_xAggProxy;
+ Reference< XInvocation > m_xAggInv;
+ Reference< XTypeProvider > m_xAggregateTypeProv;
+ Sequence< Type > m_Types;
+ SbModule* m_pMod;
+ SbMethodRef getMethod( const rtl::OUString& aName ) throw (RuntimeException);
+ SbPropertyRef getProperty( const rtl::OUString& aName ) throw (RuntimeException);
+ String mName; // for debugging
+
+public:
+ DocObjectWrapper( SbModule* pMod );
+ virtual ~DocObjectWrapper();
+
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (RuntimeException)
+ {
+ if( !m_xAggregateTypeProv.is() )
+ throw RuntimeException();
+ return m_xAggregateTypeProv->getImplementationId();
+ }
+
+ virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection( ) throw (RuntimeException);
+
+ virtual Any SAL_CALL invoke( const ::rtl::OUString& aFunctionName, const Sequence< Any >& aParams, Sequence< ::sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) throw (IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException);
+ virtual void SAL_CALL setValue( const ::rtl::OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException);
+ virtual Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName ) throw (UnknownPropertyException, RuntimeException);
+ virtual ::sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName ) throw (RuntimeException);
+ virtual ::sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName ) throw (RuntimeException);
+ virtual Any SAL_CALL queryInterface( const Type& aType ) throw ( RuntimeException );
+
+ virtual Sequence< Type > SAL_CALL getTypes() throw ( RuntimeException );
+};
+
+DocObjectWrapper::DocObjectWrapper( SbModule* pVar ) : m_pMod( pVar ), mName( pVar->GetName() )
+{
+ SbObjModule* pMod = PTR_CAST(SbObjModule,pVar);
+ if ( pMod )
+ {
+ if ( pMod->GetModuleType() == ModuleType::DOCUMENT )
+ {
+ Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+ // Use proxy factory service to create aggregatable proxy.
+ SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pMod->GetObject() );
+ Reference< XInterface > xIf;
+ if ( pUnoObj )
+ {
+ Any aObj = pUnoObj->getUnoAny();
+ aObj >>= xIf;
+ if ( xIf.is() )
+ {
+ m_xAggregateTypeProv.set( xIf, UNO_QUERY );
+ m_xAggInv.set( xIf, UNO_QUERY );
+ }
+ }
+ if ( xIf.is() )
+ {
+ try
+ {
+ Reference< XMultiComponentFactory > xMFac( xFactory, UNO_QUERY_THROW );
+ Reference< XPropertySet> xPSMPropertySet( xMFac, UNO_QUERY_THROW );
+ Reference< XComponentContext > xCtx;
+ xPSMPropertySet->getPropertyValue(
+ String( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xCtx;
+ Reference< XProxyFactory > xProxyFac( xMFac->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.ProxyFactory" ) ), xCtx ), UNO_QUERY_THROW );
+ m_xAggProxy = xProxyFac->createProxy( xIf );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "DocObjectWrapper::DocObjectWrapper: Caught exception!" );
+ }
+ }
+
+ if ( m_xAggProxy.is() )
+ {
+ osl_incrementInterlockedCount( &m_refCount );
+
+ /* i35609 - Fix crash on Solaris. The setDelegator call needs
+ to be in its own block to ensure that all temporary Reference
+ instances that are acquired during the call are released
+ before m_refCount is decremented again */
+ {
+ m_xAggProxy->setDelegator( static_cast< cppu::OWeakObject * >( this ) );
+ }
+
+ osl_decrementInterlockedCount( &m_refCount );
+ }
+ }
+ }
+}
+
+void SAL_CALL
+DocObjectWrapper::acquire() throw ()
+{
+ osl_incrementInterlockedCount( &m_refCount );
+ OSL_TRACE("DocObjectWrapper::acquire(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount );
+}
+void SAL_CALL
+DocObjectWrapper::release() throw ()
+{
+ if ( osl_decrementInterlockedCount( &m_refCount ) == 0 )
+ {
+ OSL_TRACE("DocObjectWrapper::release(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount );
+ delete this;
+ }
+ else
+ OSL_TRACE("DocObjectWrapper::release(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount );
+}
+
+DocObjectWrapper::~DocObjectWrapper()
+{
+}
+
+Sequence< Type > SAL_CALL DocObjectWrapper::getTypes()
+ throw ( RuntimeException )
+{
+ if ( m_Types.getLength() == 0 )
+ {
+ Sequence< Type > sTypes;
+ if ( m_xAggregateTypeProv.is() )
+ sTypes = m_xAggregateTypeProv->getTypes();
+ m_Types.realloc( sTypes.getLength() + 1 );
+ Type* pPtr = m_Types.getArray();
+ for ( int i=0; i<m_Types.getLength(); ++i, ++pPtr )
+ {
+ if ( i == 0 )
+ *pPtr = XInvocation::static_type( NULL );
+ else
+ *pPtr = sTypes[ i - 1 ];
+ }
+ }
+ return m_Types;
+}
+
+Reference< XIntrospectionAccess > SAL_CALL
+DocObjectWrapper::getIntrospection( ) throw (RuntimeException)
+{
+ return NULL;
+}
+
+Any SAL_CALL
+DocObjectWrapper::invoke( const ::rtl::OUString& aFunctionName, const Sequence< Any >& aParams, Sequence< ::sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) throw (IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException)
+{
+ if ( m_xAggInv.is() && m_xAggInv->hasMethod( aFunctionName ) )
+ return m_xAggInv->invoke( aFunctionName, aParams, aOutParamIndex, aOutParam );
+ SbMethodRef pMethod = getMethod( aFunctionName );
+ if ( !pMethod )
+ throw RuntimeException();
+ // check number of parameters
+ sal_Int32 nParamsCount = aParams.getLength();
+ SbxInfo* pInfo = pMethod->GetInfo();
+ if ( pInfo )
+ {
+ sal_Int32 nSbxOptional = 0;
+ sal_uInt16 n = 1;
+ for ( const SbxParamInfo* pParamInfo = pInfo->GetParam( n ); pParamInfo; pParamInfo = pInfo->GetParam( ++n ) )
+ {
+ if ( ( pParamInfo->nFlags & SBX_OPTIONAL ) != 0 )
+ ++nSbxOptional;
+ else
+ nSbxOptional = 0;
+ }
+ sal_Int32 nSbxCount = n - 1;
+ if ( nParamsCount < nSbxCount - nSbxOptional )
+ {
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "wrong number of parameters!" ) ), Reference< XInterface >() );
+ }
+ }
+ // set parameters
+ SbxArrayRef xSbxParams;
+ if ( nParamsCount > 0 )
+ {
+ xSbxParams = new SbxArray;
+ const Any* pParams = aParams.getConstArray();
+ for ( sal_Int32 i = 0; i < nParamsCount; ++i )
+ {
+ SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT );
+ unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), pParams[i] );
+ xSbxParams->Put( xSbxVar, static_cast< sal_uInt16 >( i ) + 1 );
+
+ // Enable passing by ref
+ if ( xSbxVar->GetType() != SbxVARIANT )
+ xSbxVar->SetFlag( SBX_FIXED );
+ }
+ }
+ if ( xSbxParams.Is() )
+ pMethod->SetParameters( xSbxParams );
+
+ // call method
+ SbxVariableRef xReturn = new SbxVariable;
+ ErrCode nErr = SbxERR_OK;
+
+ nErr = pMethod->Call( xReturn );
+ Any aReturn;
+ // get output parameters
+ if ( xSbxParams.Is() )
+ {
+ SbxInfo* pInfo_ = pMethod->GetInfo();
+ if ( pInfo_ )
+ {
+ OutParamMap aOutParamMap;
+ for ( sal_uInt16 n = 1, nCount = xSbxParams->Count(); n < nCount; ++n )
+ {
+ const SbxParamInfo* pParamInfo = pInfo_->GetParam( n );
+ if ( pParamInfo && ( pParamInfo->eType & SbxBYREF ) != 0 )
+ {
+ SbxVariable* pVar = xSbxParams->Get( n );
+ if ( pVar )
+ {
+ SbxVariableRef xVar = pVar;
+ aOutParamMap.insert( OutParamMap::value_type( n - 1, sbxToUnoValue( xVar ) ) );
+ }
+ }
+ }
+ sal_Int32 nOutParamCount = aOutParamMap.size();
+ aOutParamIndex.realloc( nOutParamCount );
+ aOutParam.realloc( nOutParamCount );
+ sal_Int16* pOutParamIndex = aOutParamIndex.getArray();
+ Any* pOutParam = aOutParam.getArray();
+ for ( OutParamMap::iterator aIt = aOutParamMap.begin(); aIt != aOutParamMap.end(); ++aIt, ++pOutParamIndex, ++pOutParam )
+ {
+ *pOutParamIndex = aIt->first;
+ *pOutParam = aIt->second;
+ }
+ }
+ }
+
+ // get return value
+ aReturn = sbxToUnoValue( xReturn );
+
+ pMethod->SetParameters( NULL );
+
+ return aReturn;
+}
+
+void SAL_CALL
+DocObjectWrapper::setValue( const ::rtl::OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException)
+{
+ if ( m_xAggInv.is() && m_xAggInv->hasProperty( aPropertyName ) )
+ return m_xAggInv->setValue( aPropertyName, aValue );
+
+ SbPropertyRef pProperty = getProperty( aPropertyName );
+ if ( !pProperty.Is() )
+ throw UnknownPropertyException();
+ unoToSbxValue( (SbxVariable*) pProperty, aValue );
+}
+
+Any SAL_CALL
+DocObjectWrapper::getValue( const ::rtl::OUString& aPropertyName ) throw (UnknownPropertyException, RuntimeException)
+{
+ if ( m_xAggInv.is() && m_xAggInv->hasProperty( aPropertyName ) )
+ return m_xAggInv->getValue( aPropertyName );
+
+ SbPropertyRef pProperty = getProperty( aPropertyName );
+ if ( !pProperty.Is() )
+ throw UnknownPropertyException();
+
+ SbxVariable* pProp = ( SbxVariable* ) pProperty;
+ if ( pProp->GetType() == SbxEMPTY )
+ pProperty->Broadcast( SBX_HINT_DATAWANTED );
+
+ Any aRet = sbxToUnoValue( pProp );
+ return aRet;
+}
+
+::sal_Bool SAL_CALL
+DocObjectWrapper::hasMethod( const ::rtl::OUString& aName ) throw (RuntimeException)
+{
+ if ( m_xAggInv.is() && m_xAggInv->hasMethod( aName ) )
+ return sal_True;
+ return getMethod( aName ).Is();
+}
+
+::sal_Bool SAL_CALL
+DocObjectWrapper::hasProperty( const ::rtl::OUString& aName ) throw (RuntimeException)
+{
+ sal_Bool bRes = sal_False;
+ if ( m_xAggInv.is() && m_xAggInv->hasProperty( aName ) )
+ bRes = sal_True;
+ else bRes = getProperty( aName ).Is();
+ return bRes;
+}
+
+Any SAL_CALL DocObjectWrapper::queryInterface( const Type& aType )
+ throw ( RuntimeException )
+{
+ Any aRet = DocObjectWrapper_BASE::queryInterface( aType );
+ if ( aRet.hasValue() )
+ return aRet;
+ else if ( m_xAggProxy.is() )
+ aRet = m_xAggProxy->queryAggregation( aType );
+ return aRet;
+}
+
+SbMethodRef DocObjectWrapper::getMethod( const rtl::OUString& aName ) throw (RuntimeException)
+{
+ SbMethodRef pMethod = NULL;
+ if ( m_pMod )
+ {
+ sal_uInt16 nSaveFlgs = m_pMod->GetFlags();
+ // Limit search to this module
+ m_pMod->ResetFlag( SBX_GBLSEARCH );
+ pMethod = (SbMethod*) m_pMod->SbModule::Find( aName, SbxCLASS_METHOD );
+ m_pMod->SetFlags( nSaveFlgs );
+ }
+
+ return pMethod;
+}
+
+SbPropertyRef DocObjectWrapper::getProperty( const rtl::OUString& aName ) throw (RuntimeException)
+{
+ SbPropertyRef pProperty = NULL;
+ if ( m_pMod )
+ {
+ sal_uInt16 nSaveFlgs = m_pMod->GetFlags();
+ // Limit search to this module.
+ m_pMod->ResetFlag( SBX_GBLSEARCH );
+ pProperty = (SbProperty*)m_pMod->SbModule::Find( aName, SbxCLASS_PROPERTY );
+ m_pMod->SetFlag( nSaveFlgs );
+ }
+
+ return pProperty;
+}
+
+TYPEINIT1(SbModule,SbxObject)
+TYPEINIT1(SbMethod,SbxMethod)
+TYPEINIT1(SbProperty,SbxProperty)
+TYPEINIT1(SbProcedureProperty,SbxProperty)
+TYPEINIT1(SbJScriptModule,SbModule)
+TYPEINIT1(SbJScriptMethod,SbMethod)
+TYPEINIT1(SbObjModule,SbModule)
+TYPEINIT1(SbUserFormModule,SbObjModule)
+
+typedef std::vector<HighlightPortion> HighlightPortions;
+
+bool getDefaultVBAMode( StarBASIC* pb )
+{
+ bool bResult = false;
+ if ( pb && pb->IsDocBasic() )
+ {
+ uno::Any aDoc;
+ if ( pb->GetUNOConstant( "ThisComponent", aDoc ) )
+ {
+ uno::Reference< beans::XPropertySet > xProp( aDoc, uno::UNO_QUERY );
+ if ( xProp.is() )
+ {
+ uno::Reference< script::vba::XVBACompatibility > xVBAMode( xProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BasicLibraries") ) ), uno::UNO_QUERY );
+ if ( xVBAMode.is() )
+ bResult = xVBAMode->getVBACompatibilityMode() == sal_True;
+ }
+ }
+ }
+ return bResult;
+}
+
+class AsyncQuitHandler
+{
+ AsyncQuitHandler() {}
+ AsyncQuitHandler( const AsyncQuitHandler&);
+public:
+ static AsyncQuitHandler& instance()
+ {
+ static AsyncQuitHandler dInst;
+ return dInst;
+ }
+
+ void QuitApplication()
+ {
+ uno::Reference< lang::XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+ if ( xFactory.is() )
+ {
+ uno::Reference< frame::XDesktop > xDeskTop( xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop") ) ), uno::UNO_QUERY );
+ if ( xDeskTop.is() )
+ xDeskTop->terminate();
+ }
+ }
+ DECL_LINK( OnAsyncQuit, void* );
+};
+
+IMPL_LINK( AsyncQuitHandler, OnAsyncQuit, void*, /*pNull*/ )
+{
+ QuitApplication();
+ return 0L;
+}
+
+bool VBAUnlockControllers( StarBASIC* pBasic )
+{
+ bool bRes = false;
+ if ( pBasic && pBasic->IsDocBasic() )
+ {
+ SbUnoObject* pGlobs = dynamic_cast< SbUnoObject* >( pBasic->Find( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ThisComponent" ) ), SbxCLASS_DONTCARE ) );
+ if ( pGlobs ) try
+ {
+ uno::Reference< frame::XModel > xModel( pGlobs->getUnoAny(), uno::UNO_QUERY_THROW );
+ if ( xModel->hasControllersLocked() )
+ xModel->unlockControllers();
+ bRes = true;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ return bRes;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+// Ein BASIC-Modul hat EXTSEARCH gesetzt, damit die im Modul enthaltenen
+// Elemente von anderen Modulen aus gefunden werden koennen.
+
+SbModule::SbModule( const String& rName, sal_Bool bVBACompat )
+ : SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("StarBASICModule") ) ),
+ pImage( NULL ), pBreaks( NULL ), pClassData( NULL ), mbVBACompat( bVBACompat ), pDocObject( NULL ), bIsProxyModule( false )
+{
+ SetName( rName );
+ SetFlag( SBX_EXTSEARCH | SBX_GBLSEARCH );
+ SetModuleType( script::ModuleType::NORMAL );
+
+ // #i92642: Set name property to intitial name
+ SbxVariable* pNameProp = pProps->Find( String( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_PROPERTY );
+ if( pNameProp != NULL )
+ pNameProp->PutString( GetName() );
+}
+
+SbModule::~SbModule()
+{
+ OSL_TRACE("Module named %s is destructing", rtl::OUStringToOString( GetName(), RTL_TEXTENCODING_UTF8 ).getStr() );
+ if( pImage )
+ delete pImage;
+ if( pBreaks )
+ delete pBreaks;
+ if( pClassData )
+ delete pClassData;
+ mxWrapper = NULL;
+}
+
+uno::Reference< script::XInvocation >
+SbModule::GetUnoModule()
+{
+ if ( !mxWrapper.is() )
+ mxWrapper = new DocObjectWrapper( this );
+
+ OSL_TRACE("Module named %s returning wrapper mxWrapper (0x%x)", rtl::OUStringToOString( GetName(), RTL_TEXTENCODING_UTF8 ).getStr(), mxWrapper.get() );
+ return mxWrapper;
+}
+
+sal_Bool SbModule::IsCompiled() const
+{
+ return sal_Bool( pImage != 0 );
+}
+
+const SbxObject* SbModule::FindType( String aTypeName ) const
+{
+ return pImage ? pImage->FindType( aTypeName ) : NULL;
+}
+
+
+// Aus dem Codegenerator: Loeschen des Images und Invalidieren der Entries
+
+void SbModule::StartDefinitions()
+{
+ delete pImage; pImage = NULL;
+ if( pClassData )
+ pClassData->clear();
+
+ // Methoden und Properties bleiben erhalten, sind jedoch ungueltig
+ // schliesslich sind ja u.U. die Infos belegt
+ sal_uInt16 i;
+ for( i = 0; i < pMethods->Count(); i++ )
+ {
+ SbMethod* p = PTR_CAST(SbMethod,pMethods->Get( i ) );
+ if( p )
+ p->bInvalid = sal_True;
+ }
+ for( i = 0; i < pProps->Count(); )
+ {
+ SbProperty* p = PTR_CAST(SbProperty,pProps->Get( i ) );
+ if( p )
+ pProps->Remove( i );
+ else
+ i++;
+ }
+}
+
+// Methode anfordern/anlegen
+
+SbMethod* SbModule::GetMethod( const String& rName, SbxDataType t )
+{
+ SbxVariable* p = pMethods->Find( rName, SbxCLASS_METHOD );
+ SbMethod* pMeth = p ? PTR_CAST(SbMethod,p) : NULL;
+ if( p && !pMeth )
+ pMethods->Remove( p );
+ if( !pMeth )
+ {
+ pMeth = new SbMethod( rName, t, this );
+ pMeth->SetParent( this );
+ pMeth->SetFlags( SBX_READ );
+ pMethods->Put( pMeth, pMethods->Count() );
+ StartListening( pMeth->GetBroadcaster(), sal_True );
+ }
+ // Per Default ist die Methode GUELTIG, da sie auch vom Compiler
+ // (Codegenerator) erzeugt werden kann
+ pMeth->bInvalid = sal_False;
+ pMeth->ResetFlag( SBX_FIXED );
+ pMeth->SetFlag( SBX_WRITE );
+ pMeth->SetType( t );
+ pMeth->ResetFlag( SBX_WRITE );
+ if( t != SbxVARIANT )
+ pMeth->SetFlag( SBX_FIXED );
+ return pMeth;
+}
+
+// Property anfordern/anlegen
+
+SbProperty* SbModule::GetProperty( const String& rName, SbxDataType t )
+{
+ SbxVariable* p = pProps->Find( rName, SbxCLASS_PROPERTY );
+ SbProperty* pProp = p ? PTR_CAST(SbProperty,p) : NULL;
+ if( p && !pProp )
+ pProps->Remove( p );
+ if( !pProp )
+ {
+ pProp = new SbProperty( rName, t, this );
+ pProp->SetFlag( SBX_READWRITE );
+ pProp->SetParent( this );
+ pProps->Put( pProp, pProps->Count() );
+ StartListening( pProp->GetBroadcaster(), sal_True );
+ }
+ return pProp;
+}
+
+SbProcedureProperty* SbModule::GetProcedureProperty
+ ( const String& rName, SbxDataType t )
+{
+ SbxVariable* p = pProps->Find( rName, SbxCLASS_PROPERTY );
+ SbProcedureProperty* pProp = p ? PTR_CAST(SbProcedureProperty,p) : NULL;
+ if( p && !pProp )
+ pProps->Remove( p );
+ if( !pProp )
+ {
+ pProp = new SbProcedureProperty( rName, t );
+ pProp->SetFlag( SBX_READWRITE );
+ pProp->SetParent( this );
+ pProps->Put( pProp, pProps->Count() );
+ StartListening( pProp->GetBroadcaster(), sal_True );
+ }
+ return pProp;
+}
+
+SbIfaceMapperMethod* SbModule::GetIfaceMapperMethod
+ ( const String& rName, SbMethod* pImplMeth )
+{
+ SbxVariable* p = pMethods->Find( rName, SbxCLASS_METHOD );
+ SbIfaceMapperMethod* pMapperMethod = p ? PTR_CAST(SbIfaceMapperMethod,p) : NULL;
+ if( p && !pMapperMethod )
+ pMethods->Remove( p );
+ if( !pMapperMethod )
+ {
+ pMapperMethod = new SbIfaceMapperMethod( rName, pImplMeth );
+ pMapperMethod->SetParent( this );
+ pMapperMethod->SetFlags( SBX_READ );
+ pMethods->Put( pMapperMethod, pMethods->Count() );
+ }
+ pMapperMethod->bInvalid = sal_False;
+ return pMapperMethod;
+}
+
+SbIfaceMapperMethod::~SbIfaceMapperMethod()
+{
+}
+
+TYPEINIT1(SbIfaceMapperMethod,SbMethod)
+
+
+// Aus dem Codegenerator: Ungueltige Eintraege entfernen
+
+void SbModule::EndDefinitions( sal_Bool bNewState )
+{
+ for( sal_uInt16 i = 0; i < pMethods->Count(); )
+ {
+ SbMethod* p = PTR_CAST(SbMethod,pMethods->Get( i ) );
+ if( p )
+ {
+ if( p->bInvalid )
+ pMethods->Remove( p );
+ else
+ {
+ p->bInvalid = bNewState;
+ i++;
+ }
+ }
+ else
+ i++;
+ }
+ SetModified( sal_True );
+}
+
+void SbModule::Clear()
+{
+ delete pImage; pImage = NULL;
+ if( pClassData )
+ pClassData->clear();
+ SbxObject::Clear();
+}
+
+
+SbxVariable* SbModule::Find( const XubString& rName, SbxClassType t )
+{
+ // make sure a search in an uninstatiated class module will fail
+ SbxVariable* pRes = SbxObject::Find( rName, t );
+ if ( bIsProxyModule && !GetSbData()->bRunInit )
+ return NULL;
+ if( !pRes && pImage )
+ {
+ SbiInstance* pInst = pINST;
+ if( pInst && pInst->IsCompatibility() )
+ {
+ // Put enum types as objects into module,
+ // allows MyEnum.First notation
+ SbxArrayRef xArray = pImage->GetEnums();
+ if( xArray.Is() )
+ {
+ SbxVariable* pEnumVar = xArray->Find( rName, SbxCLASS_DONTCARE );
+ SbxObject* pEnumObject = PTR_CAST( SbxObject, pEnumVar );
+ if( pEnumObject )
+ {
+ bool bPrivate = pEnumObject->IsSet( SBX_PRIVATE );
+ String aEnumName = pEnumObject->GetName();
+
+ pRes = new SbxVariable( SbxOBJECT );
+ pRes->SetName( aEnumName );
+ pRes->SetParent( this );
+ pRes->SetFlag( SBX_READ );
+ if( bPrivate )
+ pRes->SetFlag( SBX_PRIVATE );
+ pRes->PutObject( pEnumObject );
+ }
+ }
+ }
+ }
+ return pRes;
+}
+
+const ::rtl::OUString& SbModule::GetSource32() const
+{
+ return aOUSource;
+}
+
+const String& SbModule::GetSource() const
+{
+ static String aRetStr;
+ aRetStr = aOUSource;
+ return aRetStr;
+}
+
+// Parent und BASIC sind eins!
+
+void SbModule::SetParent( SbxObject* p )
+{
+ // #118083: Assertion is not valid any more
+ // DBG_ASSERT( !p || p->IsA( TYPE(StarBASIC) ), "SbModules nur in BASIC eintragen" );
+ pParent = p;
+}
+
+void SbModule::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType )
+{
+ const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
+ if( pHint )
+ {
+ SbxVariable* pVar = pHint->GetVar();
+ SbProperty* pProp = PTR_CAST(SbProperty,pVar);
+ SbMethod* pMeth = PTR_CAST(SbMethod,pVar);
+ if( pProp )
+ {
+ if( pProp->GetModule() != this )
+ SetError( SbxERR_BAD_ACTION );
+ }
+ else if( pMeth )
+ {
+ if( pHint->GetId() == SBX_HINT_DATAWANTED )
+ {
+ if( pMeth->bInvalid && !Compile() )
+ // Auto-Compile hat nicht geklappt!
+ StarBASIC::Error( SbERR_BAD_PROP_VALUE );
+ else
+ {
+ // Aufruf eines Unterprogramms
+ SbModule* pOld = pMOD;
+ pMOD = this;
+ Run( (SbMethod*) pVar );
+ pMOD = pOld;
+ }
+ }
+ }
+ else
+ {
+ // #i92642: Special handling for name property to avoid
+ // side effects when using name as variable implicitely
+ bool bForwardToSbxObject = true;
+
+ sal_uIntPtr nId = pHint->GetId();
+ if( (nId == SBX_HINT_DATAWANTED || nId == SBX_HINT_DATACHANGED) &&
+ pVar->GetName().EqualsIgnoreCaseAscii( "name" ) )
+ bForwardToSbxObject = false;
+
+ if( bForwardToSbxObject )
+ SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+ }
+ }
+}
+
+// Das Setzen der Source macht das Image ungueltig
+// und scant die Methoden-Definitionen neu ein
+
+void SbModule::SetSource( const String& r )
+{
+ SetSource32( r );
+}
+
+void SbModule::SetSource32( const ::rtl::OUString& r )
+{
+ // Default basic mode to library container mode, but.. allow Option VBASupport 0/1 override
+ SetVBACompat( getDefaultVBAMode( static_cast< StarBASIC*>( GetParent() ) ) );
+ aOUSource = r;
+ StartDefinitions();
+ SbiTokenizer aTok( r );
+ while( !aTok.IsEof() )
+ {
+ SbiToken eEndTok = NIL;
+
+ // Suchen nach SUB oder FUNCTION
+ SbiToken eLastTok = NIL;
+ while( !aTok.IsEof() )
+ {
+ // #32385: Nicht bei declare
+ SbiToken eCurTok = aTok.Next();
+ if( eLastTok != DECLARE )
+ {
+ if( eCurTok == SUB )
+ {
+ eEndTok = ENDSUB; break;
+ }
+ if( eCurTok == FUNCTION )
+ {
+ eEndTok = ENDFUNC; break;
+ }
+ if( eCurTok == PROPERTY )
+ {
+ eEndTok = ENDPROPERTY; break;
+ }
+ if( eCurTok == OPTION )
+ {
+ eCurTok = aTok.Next();
+ if( eCurTok == COMPATIBLE )
+ aTok.SetCompatible( true );
+ else if ( ( eCurTok == VBASUPPORT ) && ( aTok.Next() == NUMBER ) )
+ {
+ sal_Bool bIsVBA = ( aTok.GetDbl()== 1 );
+ SetVBACompat( bIsVBA );
+ aTok.SetCompatible( bIsVBA );
+ }
+ }
+ }
+ eLastTok = eCurTok;
+ }
+ // Definition der Methode
+ SbMethod* pMeth = NULL;
+ if( eEndTok != NIL )
+ {
+ sal_uInt16 nLine1 = aTok.GetLine();
+ if( aTok.Next() == SYMBOL )
+ {
+ String aName_( aTok.GetSym() );
+ SbxDataType t = aTok.GetType();
+ if( t == SbxVARIANT && eEndTok == ENDSUB )
+ t = SbxVOID;
+ pMeth = GetMethod( aName_, t );
+ pMeth->nLine1 = pMeth->nLine2 = nLine1;
+ // Die Methode ist erst mal GUELTIG
+ pMeth->bInvalid = sal_False;
+ }
+ else
+ eEndTok = NIL;
+ }
+ // Skip bis END SUB/END FUNCTION
+ if( eEndTok != NIL )
+ {
+ while( !aTok.IsEof() )
+ {
+ if( aTok.Next() == eEndTok )
+ {
+ pMeth->nLine2 = aTok.GetLine();
+ break;
+ }
+ }
+ if( aTok.IsEof() )
+ pMeth->nLine2 = aTok.GetLine();
+ }
+ }
+ EndDefinitions( sal_True );
+}
+
+void SbModule::SetComment( const String& r )
+{
+ aComment = r;
+ SetModified( sal_True );
+}
+
+SbMethod* SbModule::GetFunctionForLine( sal_uInt16 nLine )
+{
+ for( sal_uInt16 i = 0; i < pMethods->Count(); i++ )
+ {
+ SbMethod* p = (SbMethod*) pMethods->Get( i );
+ if( p->GetSbxId() == SBXID_BASICMETHOD )
+ {
+ if( nLine >= p->nLine1 && nLine <= p->nLine2 )
+ return p;
+ }
+ }
+ return NULL;
+}
+
+// Ausstrahlen eines Hints an alle Basics
+
+static void _SendHint( SbxObject* pObj, sal_uIntPtr nId, SbMethod* p )
+{
+ // Selbst ein BASIC?
+ if( pObj->IsA( TYPE(StarBASIC) ) && pObj->IsBroadcaster() )
+ pObj->GetBroadcaster().Broadcast( SbxHint( nId, p ) );
+ // Dann die Unterobjekte fragen
+ SbxArray* pObjs = pObj->GetObjects();
+ for( sal_uInt16 i = 0; i < pObjs->Count(); i++ )
+ {
+ SbxVariable* pVar = pObjs->Get( i );
+ if( pVar->IsA( TYPE(SbxObject) ) )
+ _SendHint( PTR_CAST(SbxObject,pVar), nId, p );
+ }
+}
+
+static void SendHint( SbxObject* pObj, sal_uIntPtr nId, SbMethod* p )
+{
+ while( pObj->GetParent() )
+ pObj = pObj->GetParent();
+ _SendHint( pObj, nId, p );
+}
+
+// #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
+// beim Programm-Ende freigeben, damit nichts gehalten wird.
+void ClearUnoObjectsInRTL_Impl_Rek( StarBASIC* pBasic )
+{
+ // return-Wert von CreateUnoService loeschen
+ static String aName( RTL_CONSTASCII_USTRINGPARAM("CreateUnoService") );
+ SbxVariable* pVar = pBasic->GetRtl()->Find( aName, SbxCLASS_METHOD );
+ if( pVar )
+ pVar->SbxValue::Clear();
+
+ // return-Wert von CreateUnoDialog loeschen
+ static String aName2( RTL_CONSTASCII_USTRINGPARAM("CreateUnoDialog") );
+ pVar = pBasic->GetRtl()->Find( aName2, SbxCLASS_METHOD );
+ if( pVar )
+ pVar->SbxValue::Clear();
+
+ // return-Wert von CDec loeschen
+ static String aName3( RTL_CONSTASCII_USTRINGPARAM("CDec") );
+ pVar = pBasic->GetRtl()->Find( aName3, SbxCLASS_METHOD );
+ if( pVar )
+ pVar->SbxValue::Clear();
+
+ // return-Wert von CreateObject loeschen
+ static String aName4( RTL_CONSTASCII_USTRINGPARAM("CreateObject") );
+ pVar = pBasic->GetRtl()->Find( aName4, SbxCLASS_METHOD );
+ if( pVar )
+ pVar->SbxValue::Clear();
+
+ // Ueber alle Sub-Basics gehen
+ SbxArray* pObjs = pBasic->GetObjects();
+ sal_uInt16 nCount = pObjs->Count();
+ for( sal_uInt16 i = 0 ; i < nCount ; i++ )
+ {
+ SbxVariable* pObjVar = pObjs->Get( i );
+ StarBASIC* pSubBasic = PTR_CAST( StarBASIC, pObjVar );
+ if( pSubBasic )
+ ClearUnoObjectsInRTL_Impl_Rek( pSubBasic );
+ }
+}
+
+void ClearUnoObjectsInRTL_Impl( StarBASIC* pBasic )
+{
+ // #67781 Rueckgabewerte der Uno-Methoden loeschen
+ clearUnoMethods();
+ clearUnoServiceCtors();
+
+ ClearUnoObjectsInRTL_Impl_Rek( pBasic );
+
+ // Oberstes Basic suchen
+ SbxObject* p = pBasic;
+ while( p->GetParent() )
+ p = p->GetParent();
+ if( ((StarBASIC*)p) != pBasic )
+ ClearUnoObjectsInRTL_Impl_Rek( (StarBASIC*)p );
+}
+sal_Bool SbModule::IsVBACompat() const
+{
+ return mbVBACompat;
+}
+
+void SbModule::SetVBACompat( sal_Bool bCompat )
+{
+ mbVBACompat = bCompat;
+}
+// Ausfuehren eines BASIC-Unterprogramms
+sal_uInt16 SbModule::Run( SbMethod* pMeth )
+{
+ static sal_uInt16 nMaxCallLevel = 0;
+ static String aMSOMacroRuntimeLibName = String::CreateFromAscii( "Launcher" );
+ static String aMSOMacroRuntimeAppSymbol = String::CreateFromAscii( "Application" );
+
+ sal_uInt16 nRes = 0;
+ sal_Bool bDelInst = sal_Bool( pINST == NULL );
+ StarBASICRef xBasic;
+ if( bDelInst )
+ {
+#ifdef DBG_TRACE_BASIC
+ dbg_InitTrace();
+#endif
+ // #32779: Basic waehrend der Ausfuehrung festhalten
+ xBasic = (StarBASIC*) GetParent();
+
+ pINST = new SbiInstance( (StarBASIC*) GetParent() );
+
+ // Launcher problem
+ // i80726 The Find below will genarate an error in Testtool so we reset it unless there was one before already
+ sal_Bool bWasError = SbxBase::GetError() != 0;
+ SbxVariable* pMSOMacroRuntimeLibVar = Find( aMSOMacroRuntimeLibName, SbxCLASS_OBJECT );
+ if ( !bWasError && (SbxBase::GetError() == SbxERR_PROC_UNDEFINED) )
+ SbxBase::ResetError();
+ if( pMSOMacroRuntimeLibVar )
+ {
+ StarBASIC* pMSOMacroRuntimeLib = PTR_CAST(StarBASIC,pMSOMacroRuntimeLibVar);
+ if( pMSOMacroRuntimeLib )
+ {
+ sal_uInt16 nGblFlag = pMSOMacroRuntimeLib->GetFlags() & SBX_GBLSEARCH;
+ pMSOMacroRuntimeLib->ResetFlag( SBX_GBLSEARCH );
+ SbxVariable* pAppSymbol = pMSOMacroRuntimeLib->Find( aMSOMacroRuntimeAppSymbol, SbxCLASS_METHOD );
+ pMSOMacroRuntimeLib->SetFlag( nGblFlag );
+ if( pAppSymbol )
+ {
+ pMSOMacroRuntimeLib->SetFlag( SBX_EXTSEARCH ); // Could have been disabled before
+ GetSbData()->pMSOMacroRuntimLib = pMSOMacroRuntimeLib;
+ }
+ }
+ }
+
+ // Error-Stack loeschen
+ SbErrorStack*& rErrStack = GetSbData()->pErrStack;
+ delete rErrStack;
+ rErrStack = NULL;
+
+ if( nMaxCallLevel == 0 )
+ {
+#ifdef UNX
+ struct rlimit rl;
+ getrlimit ( RLIMIT_STACK, &rl );
+ // printf( "RLIMIT_STACK = %ld\n", rl.rlim_cur );
+#endif
+#if defined LINUX
+ // Empiric value, 900 = needed bytes/Basic call level
+ // for Linux including 10% safety margin
+ nMaxCallLevel = rl.rlim_cur / 900;
+#elif defined SOLARIS
+ // Empiric value, 1650 = needed bytes/Basic call level
+ // for Solaris including 10% safety margin
+ nMaxCallLevel = rl.rlim_cur / 1650;
+#elif defined WIN32
+ nMaxCallLevel = 5800;
+#else
+ nMaxCallLevel = MAXRECURSION;
+#endif
+ }
+ }
+
+ // Rekursion zu tief?
+ if( ++pINST->nCallLvl <= nMaxCallLevel )
+ {
+ // Globale Variable in allen Mods definieren
+ GlobalRunInit( /* bBasicStart = */ bDelInst );
+
+ // Trat ein Compiler-Fehler auf? Dann starten wir nicht
+ if( GetSbData()->bGlobalInitErr == sal_False )
+ {
+ if( bDelInst )
+ {
+ SendHint( GetParent(), SBX_HINT_BASICSTART, pMeth );
+
+ // 16.10.96: #31460 Neues Konzept fuer StepInto/Over/Out
+ // Erklaerung siehe runtime.cxx bei SbiInstance::CalcBreakCallLevel()
+ // BreakCallLevel ermitteln
+ pINST->CalcBreakCallLevel( pMeth->GetDebugFlags() );
+ }
+
+ SbModule* pOldMod = pMOD;
+ pMOD = this;
+ SbiRuntime* pRt = new SbiRuntime( this, pMeth, pMeth->nStart );
+
+#ifdef DBG_TRACE_BASIC
+ dbg_traceNotifyCall( this, pMeth, pINST->nCallLvl );
+#endif
+
+ pRt->pNext = pINST->pRun;
+ if( pRt->pNext )
+ pRt->pNext->block();
+ pINST->pRun = pRt;
+ if ( mbVBACompat )
+ {
+ pINST->EnableCompatibility( sal_True );
+ }
+ while( pRt->Step() ) {}
+ if( pRt->pNext )
+ pRt->pNext->unblock();
+
+#ifdef DBG_TRACE_BASIC
+ bool bLeave = true;
+ dbg_traceNotifyCall( this, pMeth, pINST->nCallLvl, bLeave );
+#endif
+
+ // #63710 Durch ein anderes Thread-Handling bei Events kann es passieren,
+ // dass show-Aufruf an einem Dialog zurueckkehrt (durch schliessen des
+ // Dialogs per UI), BEVOR ein per Event ausgeloester weitergehender Call,
+ // der in Basic weiter oben im Stack steht und auf einen Basic-Breakpoint
+ // gelaufen ist, zurueckkehrt. Dann wird unten die Instanz zerstoert und
+ // wenn das noch im Call stehende Basic weiterlaeuft, gibt es einen GPF.
+ // Daher muss hier gewartet werden, bis andere Call zurueckkehrt.
+ if( bDelInst )
+ {
+ // Hier mit 1 statt 0 vergleichen, da vor nCallLvl--
+ while( pINST->nCallLvl != 1 )
+ GetpApp()->Yield();
+ }
+
+ nRes = sal_True;
+ pINST->pRun = pRt->pNext;
+ pINST->nCallLvl--; // Call-Level wieder runter
+
+ // Gibt es eine uebergeordnete Runtime-Instanz?
+ // Dann SbDEBUG_BREAK uebernehmen, wenn gesetzt
+ SbiRuntime* pRtNext = pRt->pNext;
+ if( pRtNext && (pRt->GetDebugFlags() & SbDEBUG_BREAK) )
+ pRtNext->SetDebugFlags( SbDEBUG_BREAK );
+
+ delete pRt;
+ pMOD = pOldMod;
+ if( bDelInst )
+ {
+ // #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
+ // beim Programm-Ende freigeben, damit nichts gehalten wird.
+ ClearUnoObjectsInRTL_Impl( xBasic );
+
+ clearNativeObjectWrapperVector();
+
+ DBG_ASSERT(pINST->nCallLvl==0,"BASIC-Call-Level > 0");
+ delete pINST, pINST = NULL, bDelInst = sal_False;
+
+ // #i30690
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ SendHint( GetParent(), SBX_HINT_BASICSTOP, pMeth );
+
+ GlobalRunDeInit();
+
+ // VBA always ensures screenupdating is enabled after completing
+ if ( mbVBACompat )
+ VBAUnlockControllers( PTR_CAST( StarBASIC, GetParent() ) );
+
+#ifdef DBG_TRACE_BASIC
+ dbg_DeInitTrace();
+#endif
+ }
+ }
+ else
+ pINST->nCallLvl--; // Call-Level wieder runter
+ }
+ else
+ {
+ pINST->nCallLvl--; // Call-Level wieder runter
+ StarBASIC::FatalError( SbERR_STACK_OVERFLOW );
+ }
+
+ StarBASIC* pBasic = PTR_CAST(StarBASIC,GetParent());
+ if( bDelInst )
+ {
+ // #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
+ // beim Programm-Ende freigeben, damit nichts gehalten wird.
+ ClearUnoObjectsInRTL_Impl( xBasic );
+
+ delete pINST;
+ pINST = NULL;
+ }
+ if ( pBasic && pBasic->IsDocBasic() && pBasic->IsQuitApplication() && !pINST )
+ {
+ Application::PostUserEvent( LINK( &AsyncQuitHandler::instance(), AsyncQuitHandler, OnAsyncQuit ), NULL );
+ }
+
+ return nRes;
+}
+
+// Ausfuehren der Init-Methode eines Moduls nach dem Laden
+// oder der Compilation
+
+void SbModule::RunInit()
+{
+ if( pImage
+ && !pImage->bInit
+ && pImage->GetFlag( SBIMG_INITCODE ) )
+ {
+ // Flag setzen, dass RunInit aktiv ist (Testtool)
+ GetSbData()->bRunInit = sal_True;
+
+ // sal_Bool bDelInst = sal_Bool( pINST == NULL );
+ // if( bDelInst )
+ // pINST = new SbiInstance( (StarBASIC*) GetParent() );
+ SbModule* pOldMod = pMOD;
+ pMOD = this;
+ // Der Init-Code beginnt immer hier
+ SbiRuntime* pRt = new SbiRuntime( this, NULL, 0 );
+
+#ifdef DBG_TRACE_BASIC
+ dbg_traceNotifyCall( this, NULL, 0 );
+#endif
+
+ pRt->pNext = pINST->pRun;
+ pINST->pRun = pRt;
+ while( pRt->Step() ) {}
+
+#ifdef DBG_TRACE_BASIC
+ bool bLeave = true;
+ dbg_traceNotifyCall( this, NULL, 0, bLeave );
+#endif
+
+ pINST->pRun = pRt->pNext;
+ delete pRt;
+ pMOD = pOldMod;
+ // if( bDelInst )
+ // delete pINST, pINST = NULL;
+ pImage->bInit = sal_True;
+ pImage->bFirstInit = sal_False;
+
+ // RunInit ist nicht mehr aktiv
+ GetSbData()->bRunInit = sal_False;
+ }
+}
+
+// Mit private/dim deklarierte Variablen loeschen
+
+void SbModule::AddVarName( const String& aName )
+{
+ // see if the name is added allready
+ std::vector< String >::iterator it_end = mModuleVariableNames.end();
+ for ( std::vector< String >::iterator it = mModuleVariableNames.begin(); it != it_end; ++it )
+ {
+ if ( aName == *it )
+ return;
+ }
+ mModuleVariableNames.push_back( aName );
+}
+
+void SbModule::RemoveVars()
+{
+ std::vector< String >::iterator it_end = mModuleVariableNames.end();
+ for ( std::vector< String >::iterator it = mModuleVariableNames.begin(); it != it_end; ++it )
+ {
+ // We don't want a Find being called in a derived class ( e.g.
+ // SbUserform because it could trigger say an initialise event
+ // which would cause basic to be re-run in the middle of the init ( and remember RemoveVars is called from compile and we don't want code to run as part of the compile )
+ SbxVariableRef p = SbModule::Find( *it, SbxCLASS_PROPERTY );
+ if( p.Is() )
+ Remove (p);
+ }
+}
+
+void SbModule::ClearPrivateVars()
+{
+ for( sal_uInt16 i = 0 ; i < pProps->Count() ; i++ )
+ {
+ SbProperty* p = PTR_CAST(SbProperty,pProps->Get( i ) );
+ if( p )
+ {
+ // Arrays nicht loeschen, sondern nur deren Inhalt
+ if( p->GetType() & SbxARRAY )
+ {
+ SbxArray* pArray = PTR_CAST(SbxArray,p->GetObject());
+ if( pArray )
+ {
+ for( sal_uInt16 j = 0 ; j < pArray->Count() ; j++ )
+ {
+ SbxVariable* pj = PTR_CAST(SbxVariable,pArray->Get( j ));
+ pj->SbxValue::Clear();
+ /*
+ sal_uInt16 nFlags = pj->GetFlags();
+ pj->SetFlags( (nFlags | SBX_WRITE) & (~SBX_FIXED) );
+ pj->PutEmpty();
+ pj->SetFlags( nFlags );
+ */
+ }
+ }
+ }
+ else
+ {
+ p->SbxValue::Clear();
+ /*
+ sal_uInt16 nFlags = p->GetFlags();
+ p->SetFlags( (nFlags | SBX_WRITE) & (~SBX_FIXED) );
+ p->PutEmpty();
+ p->SetFlags( nFlags );
+ */
+ }
+ }
+ }
+}
+
+void SbModule::implClearIfVarDependsOnDeletedBasic( SbxVariable* pVar, StarBASIC* pDeletedBasic )
+{
+ if( pVar->SbxValue::GetType() != SbxOBJECT || pVar->ISA( SbProcedureProperty ) )
+ return;
+
+ SbxObject* pObj = PTR_CAST(SbxObject,pVar->GetObject());
+ if( pObj != NULL )
+ {
+ SbxObject* p = pObj;
+
+ SbModule* pMod = PTR_CAST( SbModule, p );
+ if( pMod != NULL )
+ pMod->ClearVarsDependingOnDeletedBasic( pDeletedBasic );
+
+ while( (p = p->GetParent()) != NULL )
+ {
+ StarBASIC* pBasic = PTR_CAST( StarBASIC, p );
+ if( pBasic != NULL && pBasic == pDeletedBasic )
+ {
+ pVar->SbxValue::Clear();
+ break;
+ }
+ }
+ }
+}
+
+void SbModule::ClearVarsDependingOnDeletedBasic( StarBASIC* pDeletedBasic )
+{
+ (void)pDeletedBasic;
+
+ for( sal_uInt16 i = 0 ; i < pProps->Count() ; i++ )
+ {
+ SbProperty* p = PTR_CAST(SbProperty,pProps->Get( i ) );
+ if( p )
+ {
+ if( p->GetType() & SbxARRAY )
+ {
+ SbxArray* pArray = PTR_CAST(SbxArray,p->GetObject());
+ if( pArray )
+ {
+ for( sal_uInt16 j = 0 ; j < pArray->Count() ; j++ )
+ {
+ SbxVariable* pVar = PTR_CAST(SbxVariable,pArray->Get( j ));
+ implClearIfVarDependsOnDeletedBasic( pVar, pDeletedBasic );
+ }
+ }
+ }
+ else
+ {
+ implClearIfVarDependsOnDeletedBasic( p, pDeletedBasic );
+ }
+ }
+ }
+}
+
+// Zunaechst in dieses Modul, um 358-faehig zu bleiben
+// (Branch in sb.cxx vermeiden)
+void StarBASIC::ClearAllModuleVars( void )
+{
+ // Eigene Module initialisieren
+ for ( sal_uInt16 nMod = 0; nMod < pModules->Count(); nMod++ )
+ {
+ SbModule* pModule = (SbModule*)pModules->Get( nMod );
+ // Nur initialisieren, wenn der Startcode schon ausgefuehrt wurde
+ if( pModule->pImage && pModule->pImage->bInit && !pModule->isProxyModule() && !pModule->ISA(SbObjModule) )
+ pModule->ClearPrivateVars();
+ }
+
+ /* #88042 This code can delete already used public vars during runtime!
+ // Alle Objekte ueberpruefen, ob es sich um ein Basic handelt
+ // Wenn ja, auch dort initialisieren
+ for ( sal_uInt16 nObj = 0; nObj < pObjs->Count(); nObj++ )
+ {
+ SbxVariable* pVar = pObjs->Get( nObj );
+ StarBASIC* pBasic = PTR_CAST(StarBASIC,pVar);
+ if( pBasic )
+ pBasic->ClearAllModuleVars();
+ }
+ */
+}
+
+// Ausfuehren des Init-Codes aller Module
+void SbModule::GlobalRunInit( sal_Bool bBasicStart )
+{
+ // Wenn kein Basic-Start, nur initialisieren, wenn Modul uninitialisiert
+ if( !bBasicStart )
+ if( !(pImage && !pImage->bInit) )
+ return;
+
+ // GlobalInitErr-Flag fuer Compiler-Error initialisieren
+ // Anhand dieses Flags kann in SbModule::Run() nach dem Aufruf
+ // von GlobalRunInit festgestellt werden, ob beim initialisieren
+ // der Module ein Fehler auftrat. Dann wird nicht gestartet.
+ GetSbData()->bGlobalInitErr = sal_False;
+
+ // Parent vom Modul ist ein Basic
+ StarBASIC *pBasic = PTR_CAST(StarBASIC,GetParent());
+ if( pBasic )
+ {
+ pBasic->InitAllModules();
+
+ SbxObject* pParent_ = pBasic->GetParent();
+ if( pParent_ )
+ {
+ StarBASIC * pParentBasic = PTR_CAST(StarBASIC,pParent_);
+ if( pParentBasic )
+ {
+ pParentBasic->InitAllModules( pBasic );
+
+ // #109018 Parent can also have a parent (library in doc)
+ SbxObject* pParentParent = pParentBasic->GetParent();
+ if( pParentParent )
+ {
+ StarBASIC * pParentParentBasic = PTR_CAST(StarBASIC,pParentParent);
+ if( pParentParentBasic )
+ pParentParentBasic->InitAllModules( pParentBasic );
+ }
+ }
+ }
+ }
+}
+
+void SbModule::GlobalRunDeInit( void )
+{
+ StarBASIC *pBasic = PTR_CAST(StarBASIC,GetParent());
+ if( pBasic )
+ {
+ pBasic->DeInitAllModules();
+
+ SbxObject* pParent_ = pBasic->GetParent();
+ if( pParent_ )
+ pBasic = PTR_CAST(StarBASIC,pParent_);
+ if( pBasic )
+ pBasic->DeInitAllModules();
+ }
+}
+
+// Suche nach dem naechsten STMNT-Befehl im Code. Wird vom STMNT-
+// Opcode verwendet, um die Endspalte zu setzen.
+
+const sal_uInt8* SbModule::FindNextStmnt( const sal_uInt8* p, sal_uInt16& nLine, sal_uInt16& nCol ) const
+{
+ return FindNextStmnt( p, nLine, nCol, sal_False );
+}
+
+const sal_uInt8* SbModule::FindNextStmnt( const sal_uInt8* p, sal_uInt16& nLine, sal_uInt16& nCol,
+ sal_Bool bFollowJumps, const SbiImage* pImg ) const
+{
+ sal_uInt32 nPC = (sal_uInt32) ( p - (const sal_uInt8*) pImage->GetCode() );
+ while( nPC < pImage->GetCodeSize() )
+ {
+ SbiOpcode eOp = (SbiOpcode ) ( *p++ );
+ nPC++;
+ if( bFollowJumps && eOp == _JUMP && pImg )
+ {
+ DBG_ASSERT( pImg, "FindNextStmnt: pImg==NULL with FollowJumps option" );
+ sal_uInt32 nOp1 = *p++; nOp1 |= *p++ << 8;
+ nOp1 |= *p++ << 16; nOp1 |= *p++ << 24;
+ p = (const sal_uInt8*) pImg->GetCode() + nOp1;
+ }
+ else if( eOp >= SbOP1_START && eOp <= SbOP1_END )
+ p += 4, nPC += 4;
+ else if( eOp == _STMNT )
+ {
+ sal_uInt32 nl, nc;
+ nl = *p++; nl |= *p++ << 8;
+ nl |= *p++ << 16 ; nl |= *p++ << 24;
+ nc = *p++; nc |= *p++ << 8;
+ nc |= *p++ << 16 ; nc |= *p++ << 24;
+ nLine = (sal_uInt16)nl; nCol = (sal_uInt16)nc;
+ return p;
+ }
+ else if( eOp >= SbOP2_START && eOp <= SbOP2_END )
+ p += 8, nPC += 8;
+ else if( !( eOp >= SbOP0_START && eOp <= SbOP0_END ) )
+ {
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ break;
+ }
+ }
+ return NULL;
+}
+
+// Testen, ob eine Zeile STMNT-Opcodes enthaelt
+
+sal_Bool SbModule::IsBreakable( sal_uInt16 nLine ) const
+{
+ if( !pImage )
+ return sal_False;
+ const sal_uInt8* p = (const sal_uInt8* ) pImage->GetCode();
+ sal_uInt16 nl, nc;
+ while( ( p = FindNextStmnt( p, nl, nc ) ) != NULL )
+ if( nl == nLine )
+ return sal_True;
+ return sal_False;
+}
+
+size_t SbModule::GetBPCount() const
+{
+ return pBreaks ? pBreaks->size() : 0;
+}
+
+sal_uInt16 SbModule::GetBP( size_t n ) const
+{
+ if( pBreaks && n < pBreaks->size() )
+ return pBreaks->operator[]( n );
+ else
+ return 0;
+}
+
+sal_Bool SbModule::IsBP( sal_uInt16 nLine ) const
+{
+ if( pBreaks )
+ {
+ for( size_t i = 0; i < pBreaks->size(); i++ )
+ {
+ sal_uInt16 b = pBreaks->operator[]( i );
+ if( b == nLine )
+ return sal_True;
+ if( b < nLine )
+ break;
+ }
+ }
+ return sal_False;
+}
+
+sal_Bool SbModule::SetBP( sal_uInt16 nLine )
+{
+ if( !IsBreakable( nLine ) )
+ return sal_False;
+ if( !pBreaks )
+ pBreaks = new SbiBreakpoints;
+ size_t i;
+ for( i = 0; i < pBreaks->size(); i++ )
+ {
+ sal_uInt16 b = pBreaks->operator[]( i );
+ if( b == nLine )
+ return sal_True;
+ if( b < nLine )
+ break;
+ }
+ pBreaks->insert( pBreaks->begin() + i, nLine );
+
+ // #38568: Zur Laufzeit auch hier SbDEBUG_BREAK setzen
+ if( pINST && pINST->pRun )
+ pINST->pRun->SetDebugFlags( SbDEBUG_BREAK );
+
+ return IsBreakable( nLine );
+}
+
+sal_Bool SbModule::ClearBP( sal_uInt16 nLine )
+{
+ sal_Bool bRes = sal_False;
+ if( pBreaks )
+ {
+ for( size_t i = 0; i < pBreaks->size(); i++ )
+ {
+ sal_uInt16 b = pBreaks->operator[]( i );
+ if( b == nLine )
+ {
+ pBreaks->erase( pBreaks->begin() + i );
+ bRes = sal_True;
+ break;
+ }
+ if( b < nLine )
+ break;
+ }
+ if( pBreaks->empty() )
+ delete pBreaks, pBreaks = NULL;
+ }
+ return bRes;
+}
+
+void SbModule::ClearAllBP()
+{
+ delete pBreaks;
+ pBreaks = NULL;
+}
+
+void
+SbModule::fixUpMethodStart( bool bCvtToLegacy, SbiImage* pImg ) const
+{
+ if ( !pImg )
+ pImg = pImage;
+ for( sal_uInt32 i = 0; i < pMethods->Count(); i++ )
+ {
+ SbMethod* pMeth = PTR_CAST(SbMethod,pMethods->Get( (sal_uInt16)i ) );
+ if( pMeth )
+ {
+ //fixup method start positions
+ if ( bCvtToLegacy )
+ pMeth->nStart = pImg->CalcLegacyOffset( pMeth->nStart );
+ else
+ pMeth->nStart = pImg->CalcNewOffset( (sal_uInt16)pMeth->nStart );
+ }
+ }
+
+}
+
+sal_Bool SbModule::LoadData( SvStream& rStrm, sal_uInt16 nVer )
+{
+ Clear();
+ if( !SbxObject::LoadData( rStrm, 1 ) )
+ return sal_False;
+ // Precaution...
+ SetFlag( SBX_EXTSEARCH | SBX_GBLSEARCH );
+ sal_uInt8 bImage;
+ rStrm >> bImage;
+ if( bImage )
+ {
+ SbiImage* p = new SbiImage;
+ sal_uInt32 nImgVer = 0;
+
+ if( !p->Load( rStrm, nImgVer ) )
+ {
+ delete p;
+ return sal_False;
+ }
+ // If the image is in old format, we fix up the method start offsets
+ if ( nImgVer < B_EXT_IMG_VERSION )
+ {
+ fixUpMethodStart( false, p );
+ p->ReleaseLegacyBuffer();
+ }
+ aComment = p->aComment;
+ SetName( p->aName );
+ if( p->GetCodeSize() )
+ {
+ aOUSource = p->aOUSource;
+ // Alte Version: Image weg
+ if( nVer == 1 )
+ {
+ SetSource32( p->aOUSource );
+ delete p;
+ }
+ else
+ pImage = p;
+ }
+ else
+ {
+ SetSource32( p->aOUSource );
+ delete p;
+ }
+ }
+ return sal_True;
+}
+
+sal_Bool SbModule::StoreData( SvStream& rStrm ) const
+{
+ sal_Bool bFixup = ( pImage && !pImage->ExceedsLegacyLimits() );
+ if ( bFixup )
+ fixUpMethodStart( true );
+ sal_Bool bRet = SbxObject::StoreData( rStrm );
+ if ( !bRet )
+ return sal_False;
+
+ if( pImage )
+ {
+ pImage->aOUSource = aOUSource;
+ pImage->aComment = aComment;
+ pImage->aName = GetName();
+ rStrm << (sal_uInt8) 1;
+ // # PCode is saved only for legacy formats only
+ // It should be noted that it probably isn't necessary
+ // It would be better not to store the image ( more flexible with
+ // formats )
+ bool bRes = pImage->Save( rStrm, B_LEGACYVERSION );
+ if ( bFixup )
+ fixUpMethodStart( false ); // restore method starts
+ return bRes;
+
+ }
+ else
+ {
+ SbiImage aImg;
+ aImg.aOUSource = aOUSource;
+ aImg.aComment = aComment;
+ aImg.aName = GetName();
+ rStrm << (sal_uInt8) 1;
+ return aImg.Save( rStrm );
+ }
+}
+
+sal_Bool SbModule::ExceedsLegacyModuleSize()
+{
+ if ( !IsCompiled() )
+ Compile();
+ if ( pImage && pImage->ExceedsLegacyLimits() )
+ return true;
+ return false;
+}
+
+
+// Store only image, no source
+sal_Bool SbModule::StoreBinaryData( SvStream& rStrm )
+{
+ return StoreBinaryData( rStrm, 0 );
+}
+
+sal_Bool SbModule::StoreBinaryData( SvStream& rStrm, sal_uInt16 nVer )
+{
+ sal_Bool bRet = Compile();
+ if( bRet )
+ {
+ sal_Bool bFixup = ( !nVer && !pImage->ExceedsLegacyLimits() );// save in old image format, fix up method starts
+
+ if ( bFixup ) // save in old image format, fix up method starts
+ fixUpMethodStart( true );
+ bRet = SbxObject::StoreData( rStrm );
+ if( bRet )
+ {
+ pImage->aOUSource = ::rtl::OUString();
+ pImage->aComment = aComment;
+ pImage->aName = GetName();
+
+ rStrm << (sal_uInt8) 1;
+ if ( nVer )
+ bRet = pImage->Save( rStrm, B_EXT_IMG_VERSION );
+ else
+ bRet = pImage->Save( rStrm, B_LEGACYVERSION );
+ if ( bFixup )
+ fixUpMethodStart( false ); // restore method starts
+
+ pImage->aOUSource = aOUSource;
+ }
+ }
+ return bRet;
+}
+
+// Called for >= OO 1.0 passwd protected libraries only
+//
+
+sal_Bool SbModule::LoadBinaryData( SvStream& rStrm )
+{
+ ::rtl::OUString aKeepSource = aOUSource;
+ bool bRet = LoadData( rStrm, 2 );
+ LoadCompleted();
+ aOUSource = aKeepSource;
+ return bRet;
+}
+
+
+sal_Bool SbModule::LoadCompleted()
+{
+ SbxArray* p = GetMethods();
+ sal_uInt16 i;
+ for( i = 0; i < p->Count(); i++ )
+ {
+ SbMethod* q = PTR_CAST(SbMethod,p->Get( i ) );
+ if( q )
+ q->pMod = this;
+ }
+ p = GetProperties();
+ for( i = 0; i < p->Count(); i++ )
+ {
+ SbProperty* q = PTR_CAST(SbProperty,p->Get( i ) );
+ if( q )
+ q->pMod = this;
+ }
+ return sal_True;
+}
+
+void SbModule::handleProcedureProperties( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ bool bDone = false;
+
+ const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
+ if( pHint )
+ {
+ SbxVariable* pVar = pHint->GetVar();
+ SbProcedureProperty* pProcProperty = PTR_CAST( SbProcedureProperty, pVar );
+ if( pProcProperty )
+ {
+ bDone = true;
+
+ if( pHint->GetId() == SBX_HINT_DATAWANTED )
+ {
+ String aProcName;
+ aProcName.AppendAscii( "Property Get " );
+ aProcName += pProcProperty->GetName();
+
+ SbxVariable* pMeth = Find( aProcName, SbxCLASS_METHOD );
+ if( pMeth )
+ {
+ SbxValues aVals;
+ aVals.eType = SbxVARIANT;
+
+ SbxArray* pArg = pVar->GetParameters();
+ sal_uInt16 nVarParCount = (pArg != NULL) ? pArg->Count() : 0;
+ if( nVarParCount > 1 )
+ {
+ SbxArrayRef xMethParameters = new SbxArray;
+ xMethParameters->Put( pMeth, 0 ); // Method as parameter 0
+ for( sal_uInt16 i = 1 ; i < nVarParCount ; ++i )
+ {
+ SbxVariable* pPar = pArg->Get( i );
+ xMethParameters->Put( pPar, i );
+ }
+
+ pMeth->SetParameters( xMethParameters );
+ pMeth->Get( aVals );
+ pMeth->SetParameters( NULL );
+ }
+ else
+ {
+ pMeth->Get( aVals );
+ }
+
+ pVar->Put( aVals );
+ }
+ }
+ else if( pHint->GetId() == SBX_HINT_DATACHANGED )
+ {
+ SbxVariable* pMeth = NULL;
+
+ bool bSet = pProcProperty->isSet();
+ if( bSet )
+ {
+ pProcProperty->setSet( false );
+
+ String aProcName;
+ aProcName.AppendAscii( "Property Set " );
+ aProcName += pProcProperty->GetName();
+ pMeth = Find( aProcName, SbxCLASS_METHOD );
+ }
+ if( !pMeth ) // Let
+ {
+ String aProcName;
+ aProcName.AppendAscii( "Property Let " );
+ aProcName += pProcProperty->GetName();
+ pMeth = Find( aProcName, SbxCLASS_METHOD );
+ }
+
+ if( pMeth )
+ {
+ // Setup parameters
+ SbxArrayRef xArray = new SbxArray;
+ xArray->Put( pMeth, 0 ); // Method as parameter 0
+ xArray->Put( pVar, 1 );
+ pMeth->SetParameters( xArray );
+
+ SbxValues aVals;
+ pMeth->Get( aVals );
+ pMeth->SetParameters( NULL );
+ }
+ }
+ }
+ }
+
+ if( !bDone )
+ SbModule::Notify( rBC, rHint );
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+// Implementation SbJScriptModule (Basic-Modul fuer JavaScript-Sourcen)
+SbJScriptModule::SbJScriptModule( const String& rName )
+ :SbModule( rName )
+{
+}
+
+sal_Bool SbJScriptModule::LoadData( SvStream& rStrm, sal_uInt16 nVer )
+{
+ (void)nVer;
+
+ Clear();
+ if( !SbxObject::LoadData( rStrm, 1 ) )
+ return sal_False;
+
+ // Source-String holen
+ String aTmp;
+ rStrm.ReadByteString( aTmp, gsl_getSystemTextEncoding() );
+ aOUSource = aTmp;
+ //rStrm >> aSource;
+ return sal_True;
+}
+
+sal_Bool SbJScriptModule::StoreData( SvStream& rStrm ) const
+{
+ if( !SbxObject::StoreData( rStrm ) )
+ return sal_False;
+
+ // Source-String schreiben
+ String aTmp = aOUSource;
+ rStrm.WriteByteString( aTmp, gsl_getSystemTextEncoding() );
+ //rStrm << aSource;
+ return sal_True;
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+
+SbMethod::SbMethod( const String& r, SbxDataType t, SbModule* p )
+ : SbxMethod( r, t ), pMod( p )
+{
+ bInvalid = sal_True;
+ nStart =
+ nDebugFlags =
+ nLine1 =
+ nLine2 = 0;
+ refStatics = new SbxArray;
+ // AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
+ SetFlag( SBX_NO_MODIFY );
+}
+
+SbMethod::SbMethod( const SbMethod& r )
+ : SvRefBase( r ), SbxMethod( r )
+{
+ pMod = r.pMod;
+ bInvalid = r.bInvalid;
+ nStart = r.nStart;
+ nDebugFlags = r.nDebugFlags;
+ nLine1 = r.nLine1;
+ nLine2 = r.nLine2;
+ refStatics = r.refStatics;
+ SetFlag( SBX_NO_MODIFY );
+}
+
+SbMethod::~SbMethod()
+{
+}
+
+SbxArray* SbMethod::GetLocals()
+{
+ if( pINST )
+ return pINST->GetLocals( this );
+ else
+ return NULL;
+}
+
+void SbMethod::ClearStatics()
+{
+ refStatics = new SbxArray;
+
+}
+SbxArray* SbMethod::GetStatics()
+{
+ return refStatics;
+}
+
+sal_Bool SbMethod::LoadData( SvStream& rStrm, sal_uInt16 nVer )
+{
+ if( !SbxMethod::LoadData( rStrm, 1 ) )
+ return sal_False;
+ sal_Int16 n;
+ rStrm >> n;
+ sal_Int16 nTempStart = (sal_Int16)nStart;
+ // nDebugFlags = n; // AB 16.1.96: Nicht mehr uebernehmen
+ if( nVer == 2 )
+ rStrm >> nLine1 >> nLine2 >> nTempStart >> bInvalid;
+ // AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
+ SetFlag( SBX_NO_MODIFY );
+ nStart = nTempStart;
+ return sal_True;
+}
+
+sal_Bool SbMethod::StoreData( SvStream& rStrm ) const
+{
+ if( !SbxMethod::StoreData( rStrm ) )
+ return sal_False;
+ rStrm << (sal_Int16) nDebugFlags
+ << (sal_Int16) nLine1
+ << (sal_Int16) nLine2
+ << (sal_Int16) nStart
+ << (sal_uInt8) bInvalid;
+ return sal_True;
+}
+
+void SbMethod::GetLineRange( sal_uInt16& l1, sal_uInt16& l2 )
+{
+ l1 = nLine1; l2 = nLine2;
+}
+
+// Kann spaeter mal weg
+
+SbxInfo* SbMethod::GetInfo()
+{
+ return pInfo;
+}
+
+// Schnittstelle zum Ausfuehren einer Methode aus den Applikationen
+// #34191# Mit speziellem RefCounting, damit das Basic nicht durch CloseDocument()
+// abgeschossen werden kann. Rueckgabewert wird als String geliefert.
+ErrCode SbMethod::Call( SbxValue* pRet )
+{
+ // RefCount vom Modul hochzaehlen
+ SbModule* pMod_ = (SbModule*)GetParent();
+ pMod_->AddRef();
+
+ // RefCount vom Basic hochzaehlen
+ StarBASIC* pBasic = (StarBASIC*)pMod_->GetParent();
+ pBasic->AddRef();
+
+ // Values anlegen, um Return-Wert zu erhalten
+ SbxValues aVals;
+ aVals.eType = SbxVARIANT;
+
+ // #104083: Compile BEFORE get
+ if( bInvalid && !pMod_->Compile() )
+ StarBASIC::Error( SbERR_BAD_PROP_VALUE );
+
+ Get( aVals );
+ if ( pRet )
+ pRet->Put( aVals );
+
+ // Gab es einen Error
+ ErrCode nErr = SbxBase::GetError();
+ SbxBase::ResetError();
+
+ // Objekte freigeben
+ pMod_->ReleaseRef();
+ pBasic->ReleaseRef();
+
+ return nErr;
+}
+
+
+// #100883 Own Broadcast for SbMethod
+void SbMethod::Broadcast( sal_uIntPtr nHintId )
+{
+ if( pCst && !IsSet( SBX_NO_BROADCAST ) && StaticIsEnabledBroadcasting() )
+ {
+ // Da die Methode von aussen aufrufbar ist, hier noch einmal
+ // die Berechtigung testen
+ if( nHintId & SBX_HINT_DATAWANTED )
+ if( !CanRead() )
+ return;
+ if( nHintId & SBX_HINT_DATACHANGED )
+ if( !CanWrite() )
+ return;
+
+ if( pMod && !pMod->IsCompiled() )
+ pMod->Compile();
+
+ // Block broadcasts while creating new method
+ SfxBroadcaster* pSave = pCst;
+ pCst = NULL;
+ SbMethod* pThisCopy = new SbMethod( *this );
+ SbMethodRef xHolder = pThisCopy;
+ if( mpPar.Is() )
+ {
+ // this, als Element 0 eintragen, aber den Parent nicht umsetzen!
+ if( GetType() != SbxVOID )
+ mpPar->PutDirect( pThisCopy, 0 );
+ SetParameters( NULL );
+ }
+
+ pCst = pSave;
+ pSave->Broadcast( SbxHint( nHintId, pThisCopy ) );
+
+ sal_uInt16 nSaveFlags = GetFlags();
+ SetFlag( SBX_READWRITE );
+ pCst = NULL;
+ Put( pThisCopy->GetValues_Impl() );
+ pCst = pSave;
+ SetFlags( nSaveFlags );
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+// Implementation SbJScriptMethod (Method-Klasse als Wrapper fuer JavaScript-Funktionen)
+
+SbJScriptMethod::SbJScriptMethod( const String& r, SbxDataType t, SbModule* p )
+ : SbMethod( r, t, p )
+{
+}
+
+SbJScriptMethod::~SbJScriptMethod()
+{}
+
+
+/////////////////////////////////////////////////////////////////////////
+SbObjModule::SbObjModule( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsVbaCompatible )
+ : SbModule( rName, bIsVbaCompatible )
+{
+ SetModuleType( mInfo.ModuleType );
+ if ( mInfo.ModuleType == script::ModuleType::FORM )
+ {
+ SetClassName( rtl::OUString::createFromAscii( "Form" ) );
+ }
+ else if ( mInfo.ModuleObject.is() )
+ SetUnoObject( uno::makeAny( mInfo.ModuleObject ) );
+}
+
+SbObjModule::~SbObjModule()
+{
+}
+
+void
+SbObjModule::SetUnoObject( const uno::Any& aObj ) throw ( uno::RuntimeException )
+{
+ SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,(SbxVariable*)pDocObject);
+ if ( pUnoObj && pUnoObj->getUnoAny() == aObj ) // object is equal, nothing to do
+ return;
+ pDocObject = new SbUnoObject( GetName(), uno::makeAny( aObj ) );
+
+ com::sun::star::uno::Reference< com::sun::star::lang::XServiceInfo > xServiceInfo( aObj, com::sun::star::uno::UNO_QUERY_THROW );
+ if( xServiceInfo->supportsService( rtl::OUString::createFromAscii( "ooo.vba.excel.Worksheet" ) ) )
+ {
+ SetClassName( rtl::OUString::createFromAscii( "Worksheet" ) );
+ }
+ else if( xServiceInfo->supportsService( rtl::OUString::createFromAscii( "ooo.vba.excel.Workbook" ) ) )
+ {
+ SetClassName( rtl::OUString::createFromAscii( "Workbook" ) );
+ }
+}
+
+SbxVariable*
+SbObjModule::GetObject()
+{
+ return pDocObject;
+}
+SbxVariable*
+SbObjModule::Find( const XubString& rName, SbxClassType t )
+{
+ //OSL_TRACE("SbObjectModule find for %s", rtl::OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr() );
+ SbxVariable* pVar = NULL;
+ if ( pDocObject)
+ pVar = pDocObject->Find( rName, t );
+ if ( !pVar )
+ pVar = SbModule::Find( rName, t );
+ return pVar;
+}
+
+void SbObjModule::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType )
+{
+ SbModule::handleProcedureProperties( rBC, rHint );
+}
+
+
+typedef ::cppu::WeakImplHelper2< awt::XTopWindowListener, awt::XWindowListener > FormObjEventListener_BASE;
+
+class FormObjEventListenerImpl : public FormObjEventListener_BASE
+{
+ SbUserFormModule* mpUserForm;
+ uno::Reference< lang::XComponent > mxComponent;
+ bool mbDisposed;
+ sal_Bool mbOpened;
+ sal_Bool mbActivated;
+ sal_Bool mbShowing;
+ FormObjEventListenerImpl(); // not defined
+ FormObjEventListenerImpl(const FormObjEventListenerImpl&); // not defined
+
+public:
+ FormObjEventListenerImpl( SbUserFormModule* pUserForm, const uno::Reference< lang::XComponent >& xComponent ) :
+ mpUserForm( pUserForm ), mxComponent( xComponent) ,
+ mbDisposed( false ), mbOpened( sal_False ), mbActivated( sal_False ), mbShowing( sal_False )
+ {
+ if ( mxComponent.is() )
+ {
+ OSL_TRACE("*********** Registering the listeners");
+ try
+ {
+ uno::Reference< awt::XTopWindow >( mxComponent, uno::UNO_QUERY_THROW )->addTopWindowListener( this );
+ }
+ catch( uno::Exception& ) {}
+ try
+ {
+ uno::Reference< awt::XWindow >( mxComponent, uno::UNO_QUERY_THROW )->addWindowListener( this );
+ }
+ catch( uno::Exception& ) {}
+ }
+ }
+
+ virtual ~FormObjEventListenerImpl()
+ {
+ removeListener();
+ }
+
+ sal_Bool isShowing() const { return mbShowing; }
+
+ void removeListener()
+ {
+ if ( mxComponent.is() && !mbDisposed )
+ {
+ OSL_TRACE("*********** Removing the listeners");
+ try
+ {
+ uno::Reference< awt::XTopWindow >( mxComponent, uno::UNO_QUERY_THROW )->removeTopWindowListener( this );
+ }
+ catch( uno::Exception& ) {}
+ try
+ {
+ uno::Reference< awt::XWindow >( mxComponent, uno::UNO_QUERY_THROW )->removeWindowListener( this );
+ }
+ catch( uno::Exception& ) {}
+ }
+ mxComponent.clear();
+ }
+
+ virtual void SAL_CALL windowOpened( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
+ {
+ if ( mpUserForm )
+ {
+ mbOpened = sal_True;
+ mbShowing = sal_True;
+ if ( mbActivated )
+ {
+ mbOpened = mbActivated = sal_False;
+ mpUserForm->triggerActivateEvent();
+ }
+ }
+ }
+
+ //liuchen 2009-7-21, support Excel VBA Form_QueryClose event
+ virtual void SAL_CALL windowClosing( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
+ {
+#if IN_THE_FUTURE
+ uno::Reference< awt::XDialog > xDialog( e.Source, uno::UNO_QUERY );
+ if ( xDialog.is() )
+ {
+ uno::Reference< awt::XControl > xControl( xDialog, uno::UNO_QUERY );
+ if ( xControl->getPeer().is() )
+ {
+ uno::Reference< document::XVbaMethodParameter > xVbaMethodParameter( xControl->getPeer(), uno::UNO_QUERY );
+ if ( xVbaMethodParameter.is() )
+ {
+ sal_Int8 nCancel = 0;
+ sal_Int8 nCloseMode = 0;
+
+ Sequence< Any > aParams;
+ aParams.realloc(2);
+ aParams[0] <<= nCancel;
+ aParams[1] <<= nCloseMode;
+
+ mpUserForm->triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ),
+ aParams);
+ xVbaMethodParameter->setVbaMethodParameter( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Cancel")), aParams[0]);
+ return;
+
+ }
+ }
+ }
+
+ mpUserForm->triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ) );
+#endif
+ }
+ //liuchen 2009-7-21
+
+ virtual void SAL_CALL windowClosed( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
+ {
+ mbOpened = sal_False;
+ mbShowing = sal_False;
+ }
+
+ virtual void SAL_CALL windowMinimized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
+ {
+ }
+
+ virtual void SAL_CALL windowNormalized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
+ {
+ }
+
+ virtual void SAL_CALL windowActivated( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
+ {
+ if ( mpUserForm )
+ {
+ mbActivated = sal_True;
+ if ( mbOpened )
+ {
+ mbOpened = mbActivated = sal_False;
+ mpUserForm->triggerActivateEvent();
+ }
+ }
+ }
+
+ virtual void SAL_CALL windowDeactivated( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
+ {
+ if ( mpUserForm )
+ mpUserForm->triggerDeactivateEvent();
+ }
+
+ virtual void SAL_CALL windowResized( const awt::WindowEvent& /*e*/ ) throw (uno::RuntimeException)
+ {
+ if ( mpUserForm )
+ {
+ mpUserForm->triggerResizeEvent();
+ mpUserForm->triggerLayoutEvent();
+ }
+ }
+
+ virtual void SAL_CALL windowMoved( const awt::WindowEvent& /*e*/ ) throw (uno::RuntimeException)
+ {
+ if ( mpUserForm )
+ mpUserForm->triggerLayoutEvent();
+ }
+
+ virtual void SAL_CALL windowShown( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
+ {
+ }
+
+ virtual void SAL_CALL windowHidden( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
+ {
+ }
+
+ virtual void SAL_CALL disposing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
+ {
+ OSL_TRACE("** Userform/Dialog disposing");
+ mbDisposed = true;
+ mxComponent.clear();
+ if ( mpUserForm )
+ mpUserForm->ResetApiObj();
+ }
+};
+
+SbUserFormModule::SbUserFormModule( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsCompat )
+ : SbObjModule( rName, mInfo, bIsCompat )
+ , m_mInfo( mInfo )
+ , mbInit( false )
+{
+ m_xModel.set( mInfo.ModuleObject, uno::UNO_QUERY_THROW );
+}
+
+SbUserFormModule::~SbUserFormModule()
+{
+}
+
+void SbUserFormModule::ResetApiObj( bool bTriggerTerminateEvent )
+{
+ if ( bTriggerTerminateEvent && m_xDialog.is() ) // probably someone close the dialog window
+ {
+ triggerTerminateEvent();
+ }
+ pDocObject = NULL;
+ m_xDialog = NULL;
+}
+
+void SbUserFormModule::triggerMethod( const String& aMethodToRun )
+{
+ Sequence< Any > aArguments;
+ triggerMethod( aMethodToRun, aArguments );
+}
+void SbUserFormModule::triggerMethod( const String& aMethodToRun, Sequence< Any >& /*aArguments*/)
+{
+ OSL_TRACE("*** trigger %s ***", rtl::OUStringToOString( aMethodToRun, RTL_TEXTENCODING_UTF8 ).getStr() );
+ // Search method
+ SbxVariable* pMeth = SbObjModule::Find( aMethodToRun, SbxCLASS_METHOD );
+ if( pMeth )
+ {
+#if IN_THE_FUTURE
+ //liuchen 2009-7-21, support Excel VBA UserForm_QueryClose event with parameters
+ if ( aArguments.getLength() > 0 ) // Setup parameters
+ {
+ SbxArrayRef xArray = new SbxArray;
+ xArray->Put( pMeth, 0 ); // Method as parameter 0
+
+ for ( sal_Int32 i = 0; i < aArguments.getLength(); ++i )
+ {
+ SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT );
+ unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), aArguments[i] );
+ xArray->Put( xSbxVar, static_cast< sal_uInt16 >( i ) + 1 );
+
+ // Enable passing by ref
+ if ( xSbxVar->GetType() != SbxVARIANT )
+ xSbxVar->SetFlag( SBX_FIXED );
+ }
+ pMeth->SetParameters( xArray );
+
+ SbxValues aVals;
+ pMeth->Get( aVals );
+
+ for ( sal_Int32 i = 0; i < aArguments.getLength(); ++i )
+ {
+ aArguments[i] = sbxToUnoValue( xArray->Get( static_cast< sal_uInt16 >(i) + 1) );
+ }
+ pMeth->SetParameters( NULL );
+ }
+ else
+//liuchen 2009-7-21
+#endif
+ {
+ SbxValues aVals;
+ pMeth->Get( aVals );
+ }
+ }
+}
+
+void SbUserFormModule::triggerActivateEvent( void )
+{
+ OSL_TRACE("**** entering SbUserFormModule::triggerActivate");
+ triggerMethod( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("UserForm_Activate") ) );
+ OSL_TRACE("**** leaving SbUserFormModule::triggerActivate");
+}
+
+void SbUserFormModule::triggerDeactivateEvent( void )
+{
+ OSL_TRACE("**** SbUserFormModule::triggerDeactivate");
+ triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_Deactivate") ) );
+}
+
+void SbUserFormModule::triggerInitializeEvent( void )
+{
+ if ( mbInit )
+ return;
+ OSL_TRACE("**** SbUserFormModule::triggerInitializeEvent");
+ static String aInitMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Initialize") );
+ triggerMethod( aInitMethodName );
+ mbInit = true;
+}
+
+void SbUserFormModule::triggerTerminateEvent( void )
+{
+ OSL_TRACE("**** SbUserFormModule::triggerTerminateEvent");
+ static String aTermMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Terminate") );
+ triggerMethod( aTermMethodName );
+ mbInit=false;
+}
+
+void SbUserFormModule::triggerLayoutEvent( void )
+{
+ static String aMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Layout") );
+ triggerMethod( aMethodName );
+}
+
+void SbUserFormModule::triggerResizeEvent( void )
+{
+ static String aMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Resize") );
+ triggerMethod( aMethodName );
+}
+
+SbUserFormModuleInstance* SbUserFormModule::CreateInstance()
+{
+ SbUserFormModuleInstance* pInstance = new SbUserFormModuleInstance( this, GetName(), m_mInfo, IsVBACompat() );
+ return pInstance;
+}
+
+SbUserFormModuleInstance::SbUserFormModuleInstance( SbUserFormModule* pParentModule,
+ const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsVBACompat )
+ : SbUserFormModule( rName, mInfo, bIsVBACompat )
+ , m_pParentModule( pParentModule )
+{
+}
+
+sal_Bool SbUserFormModuleInstance::IsClass( const XubString& rName ) const
+{
+ sal_Bool bParentNameMatches = m_pParentModule->GetName().EqualsIgnoreCaseAscii( rName );
+ sal_Bool bRet = bParentNameMatches || SbxObject::IsClass( rName );
+ return bRet;
+}
+
+SbxVariable* SbUserFormModuleInstance::Find( const XubString& rName, SbxClassType t )
+{
+ SbxVariable* pVar = m_pParentModule->Find( rName, t );
+ return pVar;
+}
+
+
+void SbUserFormModule::Load()
+{
+ OSL_TRACE("** load() ");
+ // forces a load
+ if ( !pDocObject )
+ InitObject();
+}
+
+//liuchen 2009-7-21 change to accmordate VBA's beheavior
+void SbUserFormModule::Unload()
+{
+ OSL_TRACE("** Unload() ");
+
+ sal_Int8 nCancel = 0;
+ sal_Int8 nCloseMode = 1;
+
+ Sequence< Any > aParams;
+ aParams.realloc(2);
+ aParams[0] <<= nCancel;
+ aParams[1] <<= nCloseMode;
+
+ triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ), aParams);
+
+ aParams[0] >>= nCancel;
+ if (nCancel == 1)
+ {
+ return;
+ }
+
+ if ( m_xDialog.is() )
+ {
+ triggerTerminateEvent();
+ }
+ // Search method
+ SbxVariable* pMeth = SbObjModule::Find( String( RTL_CONSTASCII_USTRINGPARAM( "UnloadObject" ) ), SbxCLASS_METHOD );
+ if( pMeth )
+ {
+ OSL_TRACE("Attempting too run the UnloadObjectMethod");
+ m_xDialog.clear(); //release ref to the uno object
+ SbxValues aVals;
+ bool bWaitForDispose = true; // assume dialog is showing
+ if ( m_DialogListener.get() )
+ {
+ bWaitForDispose = m_DialogListener->isShowing();
+ OSL_TRACE("Showing %d", bWaitForDispose );
+ }
+ pMeth->Get( aVals);
+ if ( !bWaitForDispose )
+ {
+ // we've either already got a dispose or we'er never going to get one
+ ResetApiObj();
+ } // else wait for dispose
+ OSL_TRACE("UnloadObject completed ( we hope )");
+ }
+}
+//liuchen
+
+void registerComponentToBeDisposedForBasic( Reference< XComponent > xComponent, StarBASIC* pBasic );
+
+void SbUserFormModule::InitObject()
+{
+ try
+ {
+ String aHook( RTL_CONSTASCII_USTRINGPARAM( "VBAGlobals" ) );
+ SbUnoObject* pGlobs = (SbUnoObject*)GetParent()->Find( aHook, SbxCLASS_DONTCARE );
+ if ( m_xModel.is() && pGlobs )
+ {
+
+ uno::Reference< lang::XMultiServiceFactory > xVBAFactory( pGlobs->getUnoAny(), uno::UNO_QUERY_THROW );
+ uno::Reference< lang::XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+ uno::Sequence< uno::Any > aArgs(1);
+ aArgs[ 0 ] <<= m_xModel;
+ rtl::OUString sDialogUrl( RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.script:" ) );
+ rtl::OUString sProjectName( RTL_CONSTASCII_USTRINGPARAM("Standard") );
+ if ( this->GetParent()->GetName().Len() )
+ sProjectName = this->GetParent()->GetName();
+ sDialogUrl = sDialogUrl.concat( sProjectName ).concat( rtl::OUString( '.') ).concat( GetName() ).concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("?location=document") ) );
+
+ uno::Reference< awt::XDialogProvider > xProvider( xFactory->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.DialogProvider")), aArgs ), uno::UNO_QUERY_THROW );
+ m_xDialog = xProvider->createDialog( sDialogUrl );
+
+ // create vba api object
+ aArgs.realloc( 4 );
+ aArgs[ 0 ] = uno::Any();
+ aArgs[ 1 ] <<= m_xDialog;
+ aArgs[ 2 ] <<= m_xModel;
+ aArgs[ 3 ] <<= rtl::OUString( GetParent()->GetName() );
+ pDocObject = new SbUnoObject( GetName(), uno::makeAny( xVBAFactory->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.msforms.UserForm")), aArgs ) ) );
+ uno::Reference< lang::XComponent > xComponent( aArgs[ 1 ], uno::UNO_QUERY_THROW );
+
+ // the dialog must be disposed at the end!
+ if( xComponent.is() )
+ {
+ StarBASIC* pParentBasic = NULL;
+ SbxObject* pCurObject = this;
+ do
+ {
+ SbxObject* pObjParent = pCurObject->GetParent();
+ pParentBasic = PTR_CAST( StarBASIC, pObjParent );
+ pCurObject = pObjParent;
+ }
+ while( pParentBasic == NULL && pCurObject != NULL );
+
+ OSL_ASSERT( pParentBasic != NULL );
+ registerComponentToBeDisposedForBasic( xComponent, pParentBasic );
+ }
+
+
+ // remove old listener if it exists
+ if ( m_DialogListener.get() )
+ m_DialogListener->removeListener();
+ m_DialogListener = new FormObjEventListenerImpl( this, xComponent );
+
+ triggerInitializeEvent();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+}
+
+SbxVariable*
+SbUserFormModule::Find( const XubString& rName, SbxClassType t )
+{
+ if ( !pDocObject && !GetSbData()->bRunInit && pINST )
+ InitObject();
+ return SbObjModule::Find( rName, t );
+}
+/////////////////////////////////////////////////////////////////////////
+
+SbProperty::SbProperty( const String& r, SbxDataType t, SbModule* p )
+ : SbxProperty( r, t ), pMod( p )
+{
+ bInvalid = sal_False;
+}
+
+SbProperty::~SbProperty()
+{}
+
+/////////////////////////////////////////////////////////////////////////
+
+SbProcedureProperty::~SbProcedureProperty()
+{}
+