summaryrefslogtreecommitdiff
path: root/basic
diff options
context:
space:
mode:
Diffstat (limited to 'basic')
-rw-r--r--basic/inc/basic/basicmanagerrepository.hxx146
-rw-r--r--basic/inc/basic/basicrt.hxx79
-rw-r--r--basic/inc/basic/basmgr.hxx261
-rw-r--r--basic/inc/basic/basrdll.hxx59
-rw-r--r--basic/inc/basic/dispdefs.hxx38
-rw-r--r--basic/inc/basic/mybasic.hxx94
-rw-r--r--basic/inc/basic/process.hxx63
-rw-r--r--basic/inc/basic/sbdef.hxx110
-rw-r--r--basic/inc/basic/sberrors.hxx562
-rw-r--r--basic/inc/basic/sbmeth.hxx101
-rw-r--r--basic/inc/basic/sbmod.hxx187
-rw-r--r--basic/inc/basic/sbobjmod.hxx119
-rw-r--r--basic/inc/basic/sbprop.hxx80
-rw-r--r--basic/inc/basic/sbstar.hxx220
-rw-r--r--basic/inc/basic/sbstdobj.hxx145
-rw-r--r--basic/inc/basic/sbuno.hxx47
-rw-r--r--basic/inc/basic/sbx.hxx369
-rw-r--r--basic/inc/basic/sbxbase.hxx60
-rw-r--r--basic/inc/basic/sbxcore.hxx181
-rw-r--r--basic/inc/basic/sbxdef.hxx384
-rw-r--r--basic/inc/basic/sbxfac.hxx48
-rw-r--r--basic/inc/basic/sbxform.hxx181
-rw-r--r--basic/inc/basic/sbxmeth.hxx62
-rw-r--r--basic/inc/basic/sbxmstrm.hxx49
-rw-r--r--basic/inc/basic/sbxobj.hxx125
-rw-r--r--basic/inc/basic/sbxprop.hxx61
-rw-r--r--basic/inc/basic/sbxvar.hxx514
-rw-r--r--basic/inc/basic/testtool.hxx160
-rw-r--r--basic/inc/basic/ttglobal.hrc49
-rw-r--r--basic/inc/basic/ttstrhlp.hxx74
-rw-r--r--basic/inc/basrid.hxx45
-rw-r--r--basic/inc/makefile.mk47
-rw-r--r--basic/inc/modsizeexceeded.hxx61
-rw-r--r--basic/inc/pch/precompiled_basic.cxx29
-rw-r--r--basic/inc/pch/precompiled_basic.hxx288
-rw-r--r--basic/inc/sb.hrc47
-rw-r--r--basic/inc/sb.hxx42
-rw-r--r--basic/inc/svtmsg.hrc115
-rw-r--r--basic/inc/testtool.hrc36
-rw-r--r--basic/inc/ttmsg.hrc111
-rwxr-xr-xbasic/prj/build.lst13
-rw-r--r--basic/prj/d.lst59
-rw-r--r--basic/source/app/app.cxx1948
-rw-r--r--basic/source/app/app.hxx196
-rw-r--r--basic/source/app/appbased.cxx299
-rw-r--r--basic/source/app/appbased.hxx74
-rw-r--r--basic/source/app/appedit.cxx301
-rw-r--r--basic/source/app/appedit.hxx70
-rw-r--r--basic/source/app/apperror.cxx115
-rw-r--r--basic/source/app/apperror.hxx49
-rw-r--r--basic/source/app/appwin.cxx657
-rw-r--r--basic/source/app/appwin.hxx138
-rw-r--r--basic/source/app/basic.hrc184
-rw-r--r--basic/source/app/basic.src1472
-rw-r--r--basic/source/app/basicrt.cxx144
-rw-r--r--basic/source/app/basmsg.hrc45
-rw-r--r--basic/source/app/basmsg.src54
-rw-r--r--basic/source/app/brkpnts.cxx386
-rw-r--r--basic/source/app/brkpnts.hxx94
-rw-r--r--basic/source/app/dataedit.hxx116
-rw-r--r--basic/source/app/dialogs.cxx1507
-rw-r--r--basic/source/app/dialogs.hxx371
-rw-r--r--basic/source/app/makefile.mk101
-rw-r--r--basic/source/app/msgedit.cxx999
-rw-r--r--basic/source/app/msgedit.hxx114
-rw-r--r--basic/source/app/mybasic.cxx304
-rw-r--r--basic/source/app/printer.cxx122
-rw-r--r--basic/source/app/printer.hxx52
-rw-r--r--basic/source/app/process.cxx229
-rw-r--r--basic/source/app/processw.cxx282
-rw-r--r--basic/source/app/processw.hxx90
-rw-r--r--basic/source/app/resids.hrc158
-rw-r--r--basic/source/app/status.cxx125
-rw-r--r--basic/source/app/status.hxx54
-rw-r--r--basic/source/app/svtmsg.src339
-rw-r--r--basic/source/app/testbasi.cxx31
-rw-r--r--basic/source/app/testtool.idl47
-rw-r--r--basic/source/app/testtool.src61
-rw-r--r--basic/source/app/textedit.cxx866
-rw-r--r--basic/source/app/textedit.hxx138
-rw-r--r--basic/source/app/ttbasic.cxx36
-rw-r--r--basic/source/app/ttbasic.hxx32
-rw-r--r--basic/source/app/ttmsg.src160
-rw-r--r--basic/source/basmgr/basicmanagerrepository.cxx641
-rw-r--r--basic/source/basmgr/basmgr.cxx2490
-rw-r--r--basic/source/basmgr/makefile.mk46
-rw-r--r--basic/source/classes/disas.cxx687
-rw-r--r--basic/source/classes/errobject.cxx225
-rw-r--r--basic/source/classes/eventatt.cxx647
-rw-r--r--basic/source/classes/image.cxx544
-rw-r--r--basic/source/classes/makefile.mk76
-rw-r--r--basic/source/classes/propacc.cxx430
-rwxr-xr-xbasic/source/classes/sb.cxx2109
-rw-r--r--basic/source/classes/sb.src681
-rw-r--r--basic/source/classes/sbintern.cxx82
-rwxr-xr-xbasic/source/classes/sbunoobj.cxx4434
-rw-r--r--basic/source/classes/sbxmod.cxx2456
-rw-r--r--basic/source/comp/buffer.cxx250
-rw-r--r--basic/source/comp/codegen.cxx539
-rw-r--r--basic/source/comp/dim.cxx1203
-rw-r--r--basic/source/comp/exprgen.cxx270
-rw-r--r--basic/source/comp/exprnode.cxx488
-rw-r--r--basic/source/comp/exprtree.cxx1136
-rw-r--r--basic/source/comp/io.cxx358
-rw-r--r--basic/source/comp/loops.cxx558
-rw-r--r--basic/source/comp/makefile.mk60
-rw-r--r--basic/source/comp/parser.cxx863
-rwxr-xr-xbasic/source/comp/sbcomp.cxx477
-rw-r--r--basic/source/comp/scanner.cxx582
-rw-r--r--basic/source/comp/symtbl.cxx536
-rw-r--r--basic/source/comp/token.cxx714
-rw-r--r--basic/source/inc/buffer.hxx63
-rw-r--r--basic/source/inc/codegen.hxx92
-rw-r--r--basic/source/inc/collelem.hxx47
-rw-r--r--basic/source/inc/disas.hxx72
-rw-r--r--basic/source/inc/dlgcont.hxx175
-rw-r--r--basic/source/inc/errobject.hxx52
-rw-r--r--basic/source/inc/expr.hxx266
-rw-r--r--basic/source/inc/filefmt.hxx178
-rw-r--r--basic/source/inc/image.hxx110
-rw-r--r--basic/source/inc/iosys.hxx113
-rw-r--r--basic/source/inc/namecont.hxx766
-rw-r--r--basic/source/inc/object.hxx100
-rw-r--r--basic/source/inc/opcodes.hxx172
-rw-r--r--basic/source/inc/parser.hxx153
-rw-r--r--basic/source/inc/propacc.hxx203
-rw-r--r--basic/source/inc/runtime.hxx530
-rw-r--r--basic/source/inc/sbcomp.hxx38
-rw-r--r--basic/source/inc/sbintern.hxx150
-rw-r--r--basic/source/inc/sbjsmeth.hxx53
-rw-r--r--basic/source/inc/sbjsmod.hxx50
-rwxr-xr-xbasic/source/inc/sbtrace.hxx42
-rw-r--r--basic/source/inc/sbunoobj.hxx326
-rw-r--r--basic/source/inc/scanner.hxx146
-rw-r--r--basic/source/inc/scriptcont.hxx199
-rw-r--r--basic/source/inc/stdobj.hxx51
-rw-r--r--basic/source/inc/symtbl.hxx250
-rw-r--r--basic/source/inc/token.hxx183
-rw-r--r--basic/source/runtime/basrdll.cxx104
-rw-r--r--basic/source/runtime/ddectrl.cxx192
-rw-r--r--basic/source/runtime/ddectrl.hxx64
-rw-r--r--basic/source/runtime/dllmgr.cxx738
-rw-r--r--basic/source/runtime/dllmgr.hxx60
-rw-r--r--basic/source/runtime/inputbox.cxx197
-rw-r--r--basic/source/runtime/iosys.cxx1048
-rw-r--r--basic/source/runtime/makefile.mk71
-rw-r--r--basic/source/runtime/methods.cxx4583
-rw-r--r--basic/source/runtime/methods1.cxx2621
-rw-r--r--basic/source/runtime/props.cxx776
-rw-r--r--basic/source/runtime/rtlproto.hxx349
-rwxr-xr-xbasic/source/runtime/runtime.cxx1268
-rw-r--r--basic/source/runtime/stdobj.cxx788
-rw-r--r--basic/source/runtime/stdobj1.cxx551
-rw-r--r--basic/source/runtime/step0.cxx1332
-rw-r--r--basic/source/runtime/step1.cxx574
-rwxr-xr-xbasic/source/runtime/step2.cxx1261
-rw-r--r--basic/source/runtime/wnt-mingw.s53
-rw-r--r--basic/source/runtime/wnt.asm56
-rw-r--r--basic/source/sample/collelem.cxx79
-rw-r--r--basic/source/sample/makefile.mk58
-rw-r--r--basic/source/sample/object.cxx278
-rw-r--r--basic/source/sample/sample.bas39
-rw-r--r--basic/source/sbx/format.src85
-rw-r--r--basic/source/sbx/makefile.mk77
-rw-r--r--basic/source/sbx/sbxarray.cxx857
-rw-r--r--basic/source/sbx/sbxbase.cxx462
-rw-r--r--basic/source/sbx/sbxbool.cxx252
-rw-r--r--basic/source/sbx/sbxbyte.cxx329
-rw-r--r--basic/source/sbx/sbxchar.cxx324
-rw-r--r--basic/source/sbx/sbxcoll.cxx301
-rw-r--r--basic/source/sbx/sbxconv.hxx151
-rw-r--r--basic/source/sbx/sbxcurr.cxx395
-rw-r--r--basic/source/sbx/sbxdate.cxx414
-rw-r--r--basic/source/sbx/sbxdbl.cxx306
-rw-r--r--basic/source/sbx/sbxdec.cxx797
-rw-r--r--basic/source/sbx/sbxdec.hxx122
-rw-r--r--basic/source/sbx/sbxexec.cxx401
-rw-r--r--basic/source/sbx/sbxform.cxx1168
-rw-r--r--basic/source/sbx/sbxint.cxx963
-rw-r--r--basic/source/sbx/sbxlng.cxx341
-rw-r--r--basic/source/sbx/sbxmstrm.cxx39
-rw-r--r--basic/source/sbx/sbxobj.cxx1145
-rw-r--r--basic/source/sbx/sbxres.cxx91
-rw-r--r--basic/source/sbx/sbxres.hxx87
-rw-r--r--basic/source/sbx/sbxscan.cxx968
-rw-r--r--basic/source/sbx/sbxsng.cxx359
-rw-r--r--basic/source/sbx/sbxstr.cxx319
-rw-r--r--basic/source/sbx/sbxuint.cxx331
-rw-r--r--basic/source/sbx/sbxulng.cxx321
-rw-r--r--basic/source/sbx/sbxvals.cxx109
-rw-r--r--basic/source/sbx/sbxvalue.cxx1858
-rw-r--r--basic/source/sbx/sbxvar.cxx644
-rw-r--r--basic/source/uno/dlgcont.cxx658
-rw-r--r--basic/source/uno/makefile.mk49
-rw-r--r--basic/source/uno/modsizeexceeded.cxx68
-rw-r--r--basic/source/uno/namecont.cxx3506
-rw-r--r--basic/source/uno/sbmodule.cxx44
-rw-r--r--basic/source/uno/sbmodule.hxx45
-rw-r--r--basic/source/uno/sbservices.cxx63
-rw-r--r--basic/source/uno/scriptcont.cxx1328
-rw-r--r--basic/util/makefile.mk146
-rw-r--r--basic/win/res/basic.icobin0 -> 766 bytes
-rw-r--r--basic/win/res/testtool.icobin0 -> 766 bytes
-rw-r--r--basic/win/res/work.icobin0 -> 766 bytes
-rw-r--r--basic/workben/basmgr.src31
-rw-r--r--basic/workben/makefile.mk89
-rw-r--r--basic/workben/mgrtest.cxx591
207 files changed, 84017 insertions, 0 deletions
diff --git a/basic/inc/basic/basicmanagerrepository.hxx b/basic/inc/basic/basicmanagerrepository.hxx
new file mode 100644
index 000000000000..c4ff6d515026
--- /dev/null
+++ b/basic/inc/basic/basicmanagerrepository.hxx
@@ -0,0 +1,146 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef BASICMANAGERREPOSITORY_HXX
+#define BASICMANAGERREPOSITORY_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+/** === end UNO includes === **/
+
+class BasicManager;
+
+//........................................................................
+namespace basic
+{
+//........................................................................
+
+ //====================================================================
+ //= BasicManagerRepository
+ //====================================================================
+ /** specifies a callback for instances which are interested in BasicManagers
+ created by the BasicManagerRepository.
+ */
+ class SAL_NO_VTABLE BasicManagerCreationListener
+ {
+ public:
+ /** is called when a BasicManager has been created
+
+ @param _rxForDocument
+ denotes the document for which the BasicManager has been created. If this is <NULL/>,
+ then the BasicManager is the application-wide BasicManager.
+
+ @param _pBasicManager
+ denotes the BasicManager which has been created. The listener might for instance
+ decide to add global variables to it, or otherwise initialize it.
+ */
+ virtual void onBasicManagerCreated(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _rxForDocument,
+ BasicManager& _rBasicManager
+ ) = 0;
+ };
+
+ //====================================================================
+ //= BasicManagerRepository
+ //====================================================================
+ class BasicManagerRepository
+ {
+ public:
+ /** returns the BasicManager belonging to the given document
+
+ If the BasicManager does not yet exist, it is created. In this case, if the application's
+ BasicManager does not yet exist, it is also created. This is necessary since
+ the application's BasicManager acts as parent for all document's BasicManagers.
+
+ If you're interested in this case - the implicit creation of the application's BasicManager -,
+ then you need to register as BasicManagerCreationListener.
+
+ @param _rxDocumentModel
+ denotes the document model whose BasicManager is to be retrieved. Must not be <NULL/>.
+ The document should support the XDocumentInfoSupplier interface, for retrieving
+ its title, which is needed in some error conditions.
+ Also it <em>must</em> support the XStorageBasedDocument interface, since we
+ must be able to retrieve the document's storage. If this interface is <em>not</em>
+ supported, creating a new BasicManager will certainly fail.
+
+ @return
+ the BasicManager for this model.
+
+ @attention
+ The returned BasicManager instances is owned by the repository. In particular,
+ you are not allowed to delete it. Instead, the given model is observed: As soon
+ as it's closed, the associated BasicManager is deleted.
+ */
+ static BasicManager* getDocumentBasicManager(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _rxDocumentModel
+ );
+
+ /** returns the application-wide BasicManager
+
+ @param _bCreate
+ determines whether the BasicManager should be created (<TRUE/>) if it
+ does not yet exist.
+
+ @attention
+ If the BasicManager is newly created, then it is still owned by the repository.
+ In particular, you are not allowed to delete it. Instead, call resetApplicationBasicManager
+ to release the BasicManager.
+ */
+ static BasicManager* getApplicationBasicManager( bool _bCreate );
+
+ /** resets the application-wide BasicManager to <NULL/>
+ */
+ static void resetApplicationBasicManager();
+
+ /** registers a BasicManagerCreationListener instance which is notified whenever
+ the repository creates a BasicManager instance.
+
+ Note that this listener is <em>not</em> called when somebody else
+ creates BasicManager instances.
+
+ If the same listener is registered multiple times, it is also notified
+ multiple times, and needs to be revoked once for each registration.
+ */
+ static void registerCreationListener(
+ BasicManagerCreationListener& _rListener
+ );
+
+ /** reveokes a BasicManagerCreationListener instance which has previously
+ been registered to be notified about created BasicManager instances.
+ */
+ static void revokeCreationListener(
+ BasicManagerCreationListener& _rListener
+ );
+ };
+
+//........................................................................
+} // namespace basic
+//........................................................................
+
+#endif // BASICMANAGERREPOSITORY_HXX
+
diff --git a/basic/inc/basic/basicrt.hxx b/basic/inc/basic/basicrt.hxx
new file mode 100644
index 000000000000..6d50e1cddc07
--- /dev/null
+++ b/basic/inc/basic/basicrt.hxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _BASICRT_HXX
+#define _BASICRT_HXX
+
+#include <tools/string.hxx>
+#include <basic/sbxdef.hxx>
+
+class SbiRuntime;
+class SbErrorStackEntry;
+
+class BasicRuntime
+{
+ SbiRuntime* pRun;
+public:
+ BasicRuntime( SbiRuntime* p ) : pRun ( p ){;}
+ const String GetSourceRevision();
+ const String GetModuleName( SbxNameType nType );
+ const String GetMethodName( SbxNameType nType );
+ xub_StrLen GetLine();
+ xub_StrLen GetCol1();
+ xub_StrLen GetCol2();
+ BOOL IsRun();
+ BOOL IsValid() { return pRun != NULL; }
+ BasicRuntime GetNextRuntime();
+};
+
+class BasicErrorStackEntry
+{
+ SbErrorStackEntry *pEntry;
+public:
+ BasicErrorStackEntry( SbErrorStackEntry *p ) : pEntry ( p ){;}
+ const String GetSourceRevision();
+ const String GetModuleName( SbxNameType nType );
+ const String GetMethodName( SbxNameType nType );
+ xub_StrLen GetLine();
+ xub_StrLen GetCol1();
+ xub_StrLen GetCol2();
+};
+
+class BasicRuntimeAccess
+{
+public:
+ static BasicRuntime GetRuntime();
+ static bool HasRuntime();
+ static USHORT GetStackEntryCount();
+ static BasicErrorStackEntry GetStackEntry( USHORT nIndex );
+ static BOOL HasStack();
+ static void DeleteStack();
+
+ static BOOL IsRunInit();
+};
+
+#endif
+
diff --git a/basic/inc/basic/basmgr.hxx b/basic/inc/basic/basmgr.hxx
new file mode 100644
index 000000000000..5c62c347fbdd
--- /dev/null
+++ b/basic/inc/basic/basmgr.hxx
@@ -0,0 +1,261 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+//
+#ifndef _BASMGR_HXX
+#define _BASMGR_HXX
+
+#include <tools/string.hxx>
+#include <svl/brdcst.hxx>
+#include <basic/sbstar.hxx>
+#include <com/sun/star/script/XStorageBasedLibraryContainer.hpp>
+#include <com/sun/star/script/XStarBasicAccess.hpp>
+
+
+// Basic XML Import/Export
+com::sun::star::uno::Reference< com::sun::star::script::XStarBasicAccess >
+ getStarBasicAccess( BasicManager* pMgr );
+
+
+
+class SotStorage;
+
+#define BASERR_ID_STDLIBOPEN ERRCODE_BASMGR_STDLIBOPEN
+#define BASERR_ID_STDLIBSAVE ERRCODE_BASMGR_STDLIBSAVE
+#define BASERR_ID_LIBLOAD ERRCODE_BASMGR_LIBLOAD
+#define BASERR_ID_LIBCREATE ERRCODE_BASMGR_LIBCREATE
+#define BASERR_ID_LIBSAVE ERRCODE_BASMGR_LIBSAVE
+#define BASERR_ID_LIBDEL ERRCODE_BASMGR_LIBDEL
+#define BASERR_ID_MGROPEN ERRCODE_BASMGR_MGROPEN
+#define BASERR_ID_MGRSAVE ERRCODE_BASMGR_MGRSAVE
+#define BASERR_ID_REMOVELIB ERRCODE_BASMGR_REMOVELIB
+#define BASERR_ID_UNLOADLIB ERRCODE_BASMGR_UNLOADLIB
+
+#define BASERR_REASON_OPENSTORAGE 0x0001
+#define BASERR_REASON_OPENLIBSTORAGE 0x0002
+#define BASERR_REASON_OPENMGRSTREAM 0x0004
+#define BASERR_REASON_OPENLIBSTREAM 0x0008
+#define BASERR_REASON_LIBNOTFOUND 0x0010
+#define BASERR_REASON_STORAGENOTFOUND 0x0020
+#define BASERR_REASON_BASICLOADERROR 0x0040
+#define BASERR_REASON_NOSTORAGENAME 0x0080
+
+#define BASERR_REASON_STDLIB 0x0100
+
+class BasicError
+{
+private:
+ ULONG nErrorId;
+ USHORT nReason;
+ String aErrStr;
+
+public:
+ BasicError();
+ BasicError( const BasicError& rErr );
+ BasicError( ULONG nId, USHORT nR, const String& rErrStr );
+
+ ULONG GetErrorId() const { return nErrorId; }
+ USHORT GetReason() const { return nReason; }
+ String GetErrorStr() { return aErrStr; }
+
+ void SetErrorId( ULONG n ) { nErrorId = n; }
+ void SetReason( USHORT n ) { nReason = n; }
+ void SetErrorStr( const String& rStr) { aErrStr = rStr; }
+};
+
+
+//
+
+class BasicLibs;
+class ErrorManager;
+class BasicLibInfo;
+class BasicErrorManager;
+namespace basic { class BasicManagerCleaner; }
+
+// Library password handling for 5.0 documents
+class OldBasicPassword
+{
+public:
+ virtual void setLibraryPassword( const String& rLibraryName, const String& rPassword ) = 0;
+ virtual String getLibraryPassword( const String& rLibraryName ) = 0;
+ virtual void clearLibraryPassword( const String& rLibraryName ) = 0;
+ virtual sal_Bool hasLibraryPassword( const String& rLibraryName ) = 0;
+};
+
+struct LibraryContainerInfo
+{
+ ::com::sun::star::uno::Reference< com::sun::star::script::XPersistentLibraryContainer > mxScriptCont;
+ ::com::sun::star::uno::Reference< com::sun::star::script::XPersistentLibraryContainer > mxDialogCont;
+ OldBasicPassword* mpOldBasicPassword;
+
+ LibraryContainerInfo()
+ :mpOldBasicPassword( NULL )
+ {
+ }
+
+ LibraryContainerInfo
+ (
+ com::sun::star::uno::Reference< com::sun::star::script::XPersistentLibraryContainer > xScriptCont,
+ com::sun::star::uno::Reference< com::sun::star::script::XPersistentLibraryContainer > xDialogCont,
+ OldBasicPassword* pOldBasicPassword
+ )
+ : mxScriptCont( xScriptCont )
+ , mxDialogCont( xDialogCont )
+ , mpOldBasicPassword( pOldBasicPassword )
+ {}
+};
+
+struct BasicManagerImpl;
+
+
+#define LIB_NOTFOUND 0xFFFF
+
+class BasicManager : public SfxBroadcaster
+{
+ friend class LibraryContainer_Impl;
+ friend class StarBasicAccess_Impl;
+ friend class BasMgrContainerListenerImpl;
+ friend class ::basic::BasicManagerCleaner;
+
+private:
+ BasicLibs* pLibs;
+ BasicErrorManager* pErrorMgr;
+
+ String aName;
+ String maStorageName;
+ BOOL bBasMgrModified;
+ BOOL mbDocMgr;
+
+ BasicManagerImpl* mpImpl;
+
+ void Init();
+
+protected:
+ BOOL ImpLoadLibary( BasicLibInfo* pLibInfo ) const;
+ BOOL ImpLoadLibary( BasicLibInfo* pLibInfo, SotStorage* pCurStorage, BOOL bInfosOnly = FALSE ) const;
+ void ImpCreateStdLib( StarBASIC* pParentFromStdLib );
+ void ImpMgrNotLoaded( const String& rStorageName );
+ BasicLibInfo* CreateLibInfo();
+ void LoadBasicManager( SotStorage& rStorage, const String& rBaseURL, BOOL bLoadBasics = TRUE );
+ void LoadOldBasicManager( SotStorage& rStorage );
+ BOOL ImplLoadBasic( SvStream& rStrm, StarBASICRef& rOldBasic ) const;
+ BOOL ImplEncryptStream( SvStream& rStream ) const;
+ BasicLibInfo* FindLibInfo( StarBASIC* pBasic ) const;
+ void CheckModules( StarBASIC* pBasic, BOOL bReference ) const;
+ void SetFlagToAllLibs( short nFlag, BOOL bSet ) const;
+ BasicManager(); // Nur zum anpassen von Pfaden bei 'Speichern unter'.
+ ~BasicManager();
+
+public:
+ TYPEINFO();
+ BasicManager( SotStorage& rStorage, const String& rBaseURL, StarBASIC* pParentFromStdLib = NULL, String* pLibPath = NULL, BOOL bDocMgr = FALSE );
+ BasicManager( StarBASIC* pStdLib, String* pLibPath = NULL, BOOL bDocMgr = FALSE );
+
+ /** deletes the given BasicManager instance
+
+ This method is necessary since normally, BasicManager instances are owned by the BasicManagerRepository,
+ and expected to be deleted by the repository only. However, there exists quite some legacy code,
+ which needs to explicitly delete a BasicManager itself. This code must not use the (protected)
+ destructor, but LegacyDeleteBasicManager.
+ */
+ static void LegacyDeleteBasicManager( BasicManager*& _rpManager );
+
+ void SetStorageName( const String& rName ) { maStorageName = rName; }
+ String GetStorageName() const { return maStorageName; }
+ void SetName( const String& rName ) { aName = rName; }
+ String GetName() const { return aName; }
+
+
+ USHORT GetLibCount() const;
+ StarBASIC* GetLib( USHORT nLib ) const;
+ StarBASIC* GetLib( const String& rName ) const;
+ USHORT GetLibId( const String& rName ) const;
+
+ String GetLibName( USHORT nLib );
+
+ /** announces the library containers which belong to this BasicManager
+
+ The method will automatically add two global constants, BasicLibraries and DialogLibraries,
+ to the BasicManager.
+ */
+ void SetLibraryContainerInfo( const LibraryContainerInfo& rInfo );
+
+ const ::com::sun::star::uno::Reference< com::sun::star::script::XPersistentLibraryContainer >&
+ GetDialogLibraryContainer() const;
+ const ::com::sun::star::uno::Reference< com::sun::star::script::XPersistentLibraryContainer >&
+ GetScriptLibraryContainer() const;
+
+ BOOL LoadLib( USHORT nLib );
+ BOOL RemoveLib( USHORT nLib, BOOL bDelBasicFromStorage );
+
+ // Modify-Flag wird nur beim Speichern zurueckgesetzt.
+ BOOL IsModified() const;
+ BOOL IsBasicModified() const;
+
+ BOOL HasErrors();
+ void ClearErrors();
+ BasicError* GetFirstError();
+ BasicError* GetNextError();
+
+ /** sets a global constant in the basic library, referring to some UNO object, to a new value.
+
+ If a constant with this name already existed before, its value is changed, and the old constant is
+ returned. If it does not yet exist, it is newly created, and inserted into the basic library.
+ */
+ ::com::sun::star::uno::Any
+ SetGlobalUNOConstant( const sal_Char* _pAsciiName, const ::com::sun::star::uno::Any& _rValue );
+
+ /** retrieves a global constant in the basic library, referring to some UNO object, returns true if a value is found ( value is in aOut ) false otherwise. */
+ bool GetGlobalUNOConstant( const sal_Char* _pAsciiName, ::com::sun::star::uno::Any& aOut );
+ /** determines whether there are password-protected modules whose size exceedes the
+ legacy module size
+ @param _out_rModuleNames
+ takes the names of modules whose size exceeds the legacy limit
+ */
+ bool LegacyPsswdBinaryLimitExceeded( ::com::sun::star::uno::Sequence< rtl::OUString >& _out_rModuleNames );
+
+private:
+ BOOL IsReference( USHORT nLib );
+
+ BOOL SetLibName( USHORT nLib, const String& rName );
+
+ StarBASIC* GetStdLib() const;
+ StarBASIC* AddLib( SotStorage& rStorage, const String& rLibName, BOOL bReference );
+ BOOL RemoveLib( USHORT nLib );
+ BOOL HasLib( const String& rName ) const;
+
+ StarBASIC* CreateLibForLibContainer( const String& rLibName,
+ const com::sun::star::uno::Reference< com::sun::star::script::XLibraryContainer >&
+ xScriptCont );
+ // For XML import/export:
+ StarBASIC* CreateLib( const String& rLibName );
+ StarBASIC* CreateLib( const String& rLibName, const String& Password,
+ const String& LinkTargetURL );
+};
+
+void SetAppBasicManager( BasicManager* pBasMgr );
+
+#endif //_BASMGR_HXX
diff --git a/basic/inc/basic/basrdll.hxx b/basic/inc/basic/basrdll.hxx
new file mode 100644
index 000000000000..aecf55c26a22
--- /dev/null
+++ b/basic/inc/basic/basrdll.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _BASRDLL_HXX
+#define _BASRDLL_HXX
+
+class ResMgr;
+
+#include <vcl/accel.hxx>
+
+class BasicDLL
+{
+private:
+ ResMgr* pSttResMgr;
+ ResMgr* pBasResMgr;
+
+ BOOL bDebugMode;
+ BOOL bBreakEnabled;
+
+public:
+ BasicDLL();
+ ~BasicDLL();
+
+ ResMgr* GetSttResMgr() const { return pSttResMgr; }
+ ResMgr* GetBasResMgr() const { return pBasResMgr; }
+
+ static void BasicBreak();
+
+ static void EnableBreak( BOOL bEnable );
+ static void SetDebugMode( BOOL bDebugMode );
+};
+
+#define BASIC_DLL() (*(BasicDLL**)GetAppData( SHL_BASIC ) )
+
+#endif //_BASRDLL_HXX
diff --git a/basic/inc/basic/dispdefs.hxx b/basic/inc/basic/dispdefs.hxx
new file mode 100644
index 000000000000..3b86d54d6b39
--- /dev/null
+++ b/basic/inc/basic/dispdefs.hxx
@@ -0,0 +1,38 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _BASIC_DISPDEFS_HXX
+#define _BASIC_DISPDEFS_HXX
+
+#define DH_MODE_DATA_VALID 0x0001 // ModeData (for compatibility with old Office)
+
+#define DH_MODE_KURZNAME 0x0002 // View short name instead of UniqueID (if possible)
+#define DH_MODE_LANGNAME 0x0004 // Always view long name
+#define DH_MODE_ALLWIN 0x0008 // View all windows
+#define DH_MODE_SEND_DATA 0x0010 // Send data to Testtool
+
+#endif
+
diff --git a/basic/inc/basic/mybasic.hxx b/basic/inc/basic/mybasic.hxx
new file mode 100644
index 000000000000..02002f43cdd4
--- /dev/null
+++ b/basic/inc/basic/mybasic.hxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _MYBASIC_HXX
+#define _MYBASIC_HXX
+
+#include <basic/sbstar.hxx>
+
+class BasicApp;
+class AppBasEd;
+class ErrorEntry;
+
+class BasicError {
+ AppBasEd* pWin;
+ USHORT nLine, nCol1, nCol2;
+ String aText;
+public:
+ BasicError( AppBasEd*, USHORT, const String&, USHORT, USHORT, USHORT );
+ void Show();
+};
+
+DECLARE_LIST( ErrorList, BasicError* )
+
+#define SBXID_MYBASIC 0x594D // MyBasic: MY
+#define SBXCR_TEST 0x54534554 // TEST
+
+class MyBasic : public StarBASIC
+{
+ SbError nError;
+ virtual BOOL ErrorHdl();
+ virtual USHORT BreakHdl();
+
+protected:
+ Link GenLogHdl();
+ Link GenWinInfoHdl();
+ Link GenModuleWinExistsHdl();
+ Link GenWriteStringHdl();
+
+ virtual void StartListeningTT( SfxBroadcaster &rBroadcaster );
+
+ String GenRealString( const String &aResString );
+
+public:
+ SBX_DECL_PERSIST_NODATA(SBXCR_TEST,SBXID_MYBASIC,1);
+ TYPEINFO();
+ ErrorList aErrors;
+ MyBasic();
+ virtual ~MyBasic();
+ virtual BOOL Compile( SbModule* );
+ void Reset();
+ SbError GetErrors() { return nError; }
+
+ // Do not use #ifdefs here because this header file is both used for testtool and basic
+ SbxObject *pTestObject; // for Testool; otherwise NULL
+
+ virtual void LoadIniFile();
+
+ // Determines the extended symbol type for syntax highlighting
+ virtual SbTextType GetSymbolType( const String &Symbol, BOOL bWasTTControl );
+ virtual const String GetSpechialErrorText();
+ virtual void ReportRuntimeError( AppBasEd *pEditWin );
+ virtual void DebugFindNoErrors( BOOL bDebugFindNoErrors );
+
+ static void SetCompileModule( SbModule *pMod );
+ static SbModule *GetCompileModule();
+};
+
+SV_DECL_IMPL_REF(MyBasic)
+
+#endif
diff --git a/basic/inc/basic/process.hxx b/basic/inc/basic/process.hxx
new file mode 100644
index 000000000000..20cdbe1d4aa4
--- /dev/null
+++ b/basic/inc/basic/process.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _PROCESS_HXX
+#define _PROCESS_HXX
+
+#include <tools/string.hxx>
+#include <vos/process.hxx>
+
+#include <map>
+
+typedef std::map< String, String > Environment;
+typedef Environment::value_type EnvironmentVariable;
+
+class Process
+{
+ // Internal members and methods
+ NAMESPACE_VOS(OArgumentList) *pArgumentList;
+ NAMESPACE_VOS(OEnvironment) *pEnvList;
+ NAMESPACE_VOS(OProcess) *pProcess;
+ BOOL ImplIsRunning();
+ long ImplGetExitCode();
+ BOOL bWasGPF;
+ BOOL bHasBeenStarted;
+
+public:
+ Process();
+ ~Process();
+ // Methoden
+ void SetImage( const String &aAppPath, const String &aAppParams, const Environment *pEnv = NULL );
+ BOOL Start();
+ ULONG GetExitCode();
+ BOOL IsRunning();
+ BOOL WasGPF();
+
+ BOOL Terminate();
+};
+
+#endif
diff --git a/basic/inc/basic/sbdef.hxx b/basic/inc/basic/sbdef.hxx
new file mode 100644
index 000000000000..70512584f9b7
--- /dev/null
+++ b/basic/inc/basic/sbdef.hxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SB_SBDEF_HXX
+#define _SB_SBDEF_HXX
+
+#include <basic/sbxdef.hxx>
+#include <svl/svarray.hxx>
+
+#define _BASIC_TEXTPORTIONS
+
+// Type of a text token (syntax highlighting)
+enum SbTextType
+{
+ SB_KEYWORD = 1, // Keywords
+ SB_SYMBOL, // Symbols
+ SB_STRING, // Strings
+ SB_NUMBER, // Numbers
+ SB_PUNCTUATION, // Brackets, points, etc.
+ SB_COMMENT, // Comments
+ SB_DUMMY = 255 // workaround for #i31479
+};
+
+// Active language
+enum SbLanguageMode
+{
+ SB_LANG_GLOBAL, // As in SbiGlobals struct
+ SB_LANG_BASIC, // StarBasic (Default)
+ SB_LANG_VBSCRIPT, // Visual-Basic-Script
+ SB_LANG_JAVASCRIPT // JavaScript
+};
+
+#ifdef _BASIC_TEXTPORTIONS
+struct SbTextPortion
+{ // Syntax Highlighting: a text portion
+ xub_StrLen nLine; // Line number
+ xub_StrLen nStart, nEnd; // 1st and last column
+ SbTextType eType; // Type of the portion
+};
+
+SV_DECL_VARARR(SbTextPortions, SbTextPortion,16,16)
+#else
+class SbTextPortions;
+#endif
+
+// Returns type name for Basic type, array flag is ignored
+// implementation: basic/source/runtime/methods.cxx
+String getBasicTypeName( SbxDataType eType );
+
+// Returns type name for Basic objects, especially
+// important for SbUnoObj instances
+// implementation: basic/source/classes/sbunoobj.cxx
+class SbxObject;
+String getBasicObjectTypeName( SbxObject* pObj );
+
+// Allows Basic IDE to set watch mode to suppress errors
+// implementation: basic/source/runtime/runtime.cxx
+void setBasicWatchMode( bool bOn );
+
+// Debug Flags:
+#define SbDEBUG_BREAK 0x0001 // Break-Callback
+#define SbDEBUG_STEPINTO 0x0002 // Single Step-Callback
+#define SbDEBUG_STEPOVER 0x0004 // Additional flag Step Over
+#define SbDEBUG_CONTINUE 0x0008 // Do not change flags
+#define SbDEBUG_STEPOUT 0x0010 // Leave Sub
+
+#define SBXID_BASIC 0x6273 // sb: StarBASIC
+#define SBXID_BASICMOD 0x6d62 // bm: StarBASIC Module
+#define SBXID_BASICPROP 0x7262 // pr: StarBASIC Property
+#define SBXID_BASICMETHOD 0x6d65 // me: StarBASIC Method
+#define SBXID_JSCRIPTMOD 0x6a62 // jm: JavaScript Module
+#define SBXID_JSCRIPTMETH 0x6a64 // jm: JavaScript Module
+
+#define SBX_HINT_BASICSTART SFX_HINT_USER04
+#define SBX_HINT_BASICSTOP SFX_HINT_USER05
+
+// #115826
+enum PropertyMode
+{
+ PROPERTY_MODE_NONE,
+ PROPERTY_MODE_GET,
+ PROPERTY_MODE_LET,
+ PROPERTY_MODE_SET
+};
+
+#endif
diff --git a/basic/inc/basic/sberrors.hxx b/basic/inc/basic/sberrors.hxx
new file mode 100644
index 000000000000..c34176e0bde7
--- /dev/null
+++ b/basic/inc/basic/sberrors.hxx
@@ -0,0 +1,562 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SB_SBERRORS_HXX
+#define _SB_SBERRORS_HXX
+
+#include <basic/sbxdef.hxx>
+
+#ifndef __RSC
+typedef ULONG SbError;
+#endif
+
+// Mapping to SbxError
+#define ERRCODE_BASIC_SYNTAX ERRCODE_SBX_SYNTAX // unspecified syntax error
+#define ERRCODE_BASIC_BAD_ARGUMENT ERRCODE_SBX_NOTIMP // Invalid procedure call
+#define ERRCODE_BASIC_MATH_OVERFLOW ERRCODE_SBX_OVERFLOW // Overflow
+#define ERRCODE_BASIC_OUT_OF_RANGE ERRCODE_SBX_BOUNDS // Subscript out of range
+#define ERRCODE_BASIC_ZERODIV ERRCODE_SBX_ZERODIV // Division by zero
+#define ERRCODE_BASIC_CONVERSION ERRCODE_SBX_CONVERSION // Type mismatch
+#define ERRCODE_BASIC_BAD_PARAMETER ERRCODE_SBX_BAD_PARAMETER // Invalid Parameter
+#define ERRCODE_BASIC_PROC_UNDEFINED ERRCODE_SBX_PROC_UNDEFINED // Sub or Function not defined
+#define ERRCODE_BASIC_INTERNAL_ERROR ERRCODE_SBX_ERROR // internal error
+#define ERRCODE_BASIC_NO_OBJECT ERRCODE_SBX_NO_OBJECT // Object variable not set
+#define ERRCODE_BASIC_CANNOT_LOAD ERRCODE_SBX_CANNOT_LOAD // Can't load module
+#define ERRCODE_BASIC_BAD_INDEX ERRCODE_SBX_BAD_INDEX // Invalid object index
+#define ERRCODE_BASIC_NO_ACTIVE_OBJECT ERRCODE_SBX_NO_ACTIVE_OBJECT // No active view or document
+#define ERRCODE_BASIC_BAD_PROP_VALUE ERRCODE_SBX_BAD_PROP_VALUE // Bad property value
+#define ERRCODE_BASIC_PROP_READONLY ERRCODE_SBX_PROP_READONLY // Property is read only
+#define ERRCODE_BASIC_PROP_WRITEONLY ERRCODE_SBX_PROP_WRITEONLY // Property is write only
+#define ERRCODE_BASIC_INVALID_OBJECT ERRCODE_SBX_INVALID_OBJECT // Invalid object reference
+#define ERRCODE_BASIC_NO_METHOD ERRCODE_SBX_NO_METHOD // Property or method not found
+#define ERRCODE_BASIC_INVALID_USAGE_OBJECT ERRCODE_SBX_INVALID_USAGE_OBJECT // Invalid usee of object
+#define ERRCODE_BASIC_NO_OLE ERRCODE_SBX_NO_OLE // Class does not support OLE
+#define ERRCODE_BASIC_BAD_METHOD ERRCODE_SBX_BAD_METHOD // Object doesn't support method
+#define ERRCODE_BASIC_OLE_ERROR ERRCODE_SBX_OLE_ERROR // OLE Automation error
+#define ERRCODE_BASIC_BAD_ACTION ERRCODE_SBX_BAD_ACTION // Object doesn't support this action
+#define ERRCODE_BASIC_NO_NAMED_ARGS ERRCODE_SBX_NO_NAMED_ARGS // Object doesn't support named args
+#define ERRCODE_BASIC_BAD_LOCALE ERRCODE_SBX_BAD_LOCALE // Object doesn't support current locale setting
+#define ERRCODE_BASIC_NAMED_NOT_FOUND ERRCODE_SBX_NAMED_NOT_FOUND // Named argument not found
+#define ERRCODE_BASIC_NOT_OPTIONAL ERRCODE_SBX_NOT_OPTIONAL // Argument not optional
+#define ERRCODE_BASIC_WRONG_ARGS ERRCODE_SBX_WRONG_ARGS // Wrong number of arguments
+#define ERRCODE_BASIC_NOT_A_COLL ERRCODE_SBX_NOT_A_COLL // Object not a collection
+
+// Append Basic specific error messages to ERRCODE_AREA_SBX
+#define ERRCODE_BASIC_NO_GOSUB ((LAST_SBX_ERROR_ID+1UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Return without Gosub
+#define ERRCODE_BASIC_REDO_FROM_START ((LAST_SBX_ERROR_ID+2UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Redo form start (SB internal)
+#define ERRCODE_BASIC_NO_MEMORY ((LAST_SBX_ERROR_ID+3UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Out of memory
+#define ERRCODE_BASIC_ALREADY_DIM ((LAST_SBX_ERROR_ID+4UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Array already dimensioned
+#define ERRCODE_BASIC_DUPLICATE_DEF ((LAST_SBX_ERROR_ID+5UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Duplicate definition
+#define ERRCODE_BASIC_VAR_UNDEFINED ((LAST_SBX_ERROR_ID+6UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Variable undefined (SB)
+#define ERRCODE_BASIC_USER_ABORT ((LAST_SBX_ERROR_ID+7UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // User interrupt occurred
+#define ERRCODE_BASIC_BAD_RESUME ((LAST_SBX_ERROR_ID+8UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Resume without error
+#define ERRCODE_BASIC_STACK_OVERFLOW ((LAST_SBX_ERROR_ID+9UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Out of stack space
+#define ERRCODE_BASIC_BAD_DLL_LOAD ((LAST_SBX_ERROR_ID+10UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Error in loading DLL
+#define ERRCODE_BASIC_BAD_DLL_CALL ((LAST_SBX_ERROR_ID+11UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Bad DLL calling convention
+#define ERRCODE_BASIC_BAD_CHANNEL ((LAST_SBX_ERROR_ID+12UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Bad file name or number
+#define ERRCODE_BASIC_FILE_NOT_FOUND ((LAST_SBX_ERROR_ID+13UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // File not found
+#define ERRCODE_BASIC_BAD_FILE_MODE ((LAST_SBX_ERROR_ID+14UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Bad file mode
+#define ERRCODE_BASIC_FILE_ALREADY_OPEN ((LAST_SBX_ERROR_ID+15UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // File already open
+#define ERRCODE_BASIC_IO_ERROR ((LAST_SBX_ERROR_ID+16UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Device I/O error
+#define ERRCODE_BASIC_FILE_EXISTS ((LAST_SBX_ERROR_ID+17UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // File already exists
+#define ERRCODE_BASIC_BAD_RECORD_LENGTH ((LAST_SBX_ERROR_ID+18UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // bad record length
+#define ERRCODE_BASIC_DISK_FULL ((LAST_SBX_ERROR_ID+19UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // disk full
+#define ERRCODE_BASIC_READ_PAST_EOF ((LAST_SBX_ERROR_ID+20UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Input past end of file
+#define ERRCODE_BASIC_BAD_RECORD_NUMBER ((LAST_SBX_ERROR_ID+21UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Bad record number
+#define ERRCODE_BASIC_TOO_MANY_FILES ((LAST_SBX_ERROR_ID+22UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Too many files
+#define ERRCODE_BASIC_NO_DEVICE ((LAST_SBX_ERROR_ID+23UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Device not available
+#define ERRCODE_BASIC_ACCESS_DENIED ((LAST_SBX_ERROR_ID+24UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Permission denied
+#define ERRCODE_BASIC_NOT_READY ((LAST_SBX_ERROR_ID+25UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Disk not ready
+#define ERRCODE_BASIC_NOT_IMPLEMENTED ((LAST_SBX_ERROR_ID+26UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Feature not implemented
+#define ERRCODE_BASIC_DIFFERENT_DRIVE ((LAST_SBX_ERROR_ID+27UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // No rename with different drive
+#define ERRCODE_BASIC_ACCESS_ERROR ((LAST_SBX_ERROR_ID+28UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Path/File access error
+#define ERRCODE_BASIC_PATH_NOT_FOUND ((LAST_SBX_ERROR_ID+29UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Path not found
+#define ERRCODE_BASIC_BAD_PATTERN ((LAST_SBX_ERROR_ID+30UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Invalid pattern string
+#define ERRCODE_BASIC_IS_NULL ((LAST_SBX_ERROR_ID+31UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Invalid use of Null
+
+// DDE messages from 250-299
+#define ERRCODE_BASIC_DDE_ERROR ((LAST_SBX_ERROR_ID+32UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_WAITINGACK ((LAST_SBX_ERROR_ID+33UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_OUTOFCHANNELS ((LAST_SBX_ERROR_ID+34UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_NO_RESPONSE ((LAST_SBX_ERROR_ID+35UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_MULT_RESPONSES ((LAST_SBX_ERROR_ID+36UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_CHANNEL_LOCKED ((LAST_SBX_ERROR_ID+37UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_NOTPROCESSED ((LAST_SBX_ERROR_ID+38UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_TIMEOUT ((LAST_SBX_ERROR_ID+39UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_USER_INTERRUPT ((LAST_SBX_ERROR_ID+40UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_BUSY ((LAST_SBX_ERROR_ID+41UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_NO_DATA ((LAST_SBX_ERROR_ID+42UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_WRONG_DATA_FORMAT ((LAST_SBX_ERROR_ID+43UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_PARTNER_QUIT ((LAST_SBX_ERROR_ID+44UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_CONV_CLOSED ((LAST_SBX_ERROR_ID+45UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_NO_CHANNEL ((LAST_SBX_ERROR_ID+46UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_INVALID_LINK ((LAST_SBX_ERROR_ID+47UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_QUEUE_OVERFLOW ((LAST_SBX_ERROR_ID+48UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_LINK_ALREADY_EST ((LAST_SBX_ERROR_ID+49UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_LINK_INV_TOPIC ((LAST_SBX_ERROR_ID+50UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+#define ERRCODE_BASIC_DDE_DLL_NOT_FOUND ((LAST_SBX_ERROR_ID+51UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+
+#define ERRCODE_BASIC_NEEDS_OBJECT ((LAST_SBX_ERROR_ID+52UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Object required
+#define ERRCODE_BASIC_BAD_ORDINAL ((LAST_SBX_ERROR_ID+53UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Invalid ordinal
+#define ERRCODE_BASIC_DLLPROC_NOT_FOUND ((LAST_SBX_ERROR_ID+54UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Specified DLL function not found
+#define ERRCODE_BASIC_BAD_CLIPBD_FORMAT ((LAST_SBX_ERROR_ID+55UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Invalid clipboard format
+
+// Debugger messages from 700-799
+
+#define ERRCODE_BASIC_PROPERTY_NOT_FOUND ((LAST_SBX_ERROR_ID+56UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Class not have property
+#define ERRCODE_BASIC_METHOD_NOT_FOUND ((LAST_SBX_ERROR_ID+57UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Class does not have method
+#define ERRCODE_BASIC_ARG_MISSING ((LAST_SBX_ERROR_ID+58UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Missing required argument
+#define ERRCODE_BASIC_BAD_NUMBER_OF_ARGS ((LAST_SBX_ERROR_ID+59UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Bad number of arguments
+#define ERRCODE_BASIC_METHOD_FAILED ((LAST_SBX_ERROR_ID+60UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Method failed
+#define ERRCODE_BASIC_SETPROP_FAILED ((LAST_SBX_ERROR_ID+61UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Unable to set property
+#define ERRCODE_BASIC_GETPROP_FAILED ((LAST_SBX_ERROR_ID+62UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Unable to get property
+
+// Compiler Errors (do not occure at runtime)
+// These IDs can shift at any time
+
+#define ERRCODE_BASIC_UNEXPECTED ((LAST_SBX_ERROR_ID+63UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Unexpected symbol: xx
+// #define ERRCODE_BASIC_COMPILER_BGN ERRCODE_BASIC_UNEXPECTED
+#define ERRCODE_BASIC_EXPECTED ((LAST_SBX_ERROR_ID+64UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Expected: xx
+#define ERRCODE_BASIC_SYMBOL_EXPECTED ((LAST_SBX_ERROR_ID+65UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Symbol expected
+#define ERRCODE_BASIC_VAR_EXPECTED ((LAST_SBX_ERROR_ID+66UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Variable expected
+#define ERRCODE_BASIC_LABEL_EXPECTED ((LAST_SBX_ERROR_ID+67UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Label expected
+#define ERRCODE_BASIC_LVALUE_EXPECTED ((LAST_SBX_ERROR_ID+68UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Lvalue expected
+#define ERRCODE_BASIC_VAR_DEFINED ((LAST_SBX_ERROR_ID+69UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Variable xxx already defined
+#define ERRCODE_BASIC_PROC_DEFINED ((LAST_SBX_ERROR_ID+70UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Procedure xx already defined
+#define ERRCODE_BASIC_LABEL_DEFINED ((LAST_SBX_ERROR_ID+71UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Label xxx already defined
+#define ERRCODE_BASIC_UNDEF_VAR ((LAST_SBX_ERROR_ID+72UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Variable xx undefined
+#define ERRCODE_BASIC_UNDEF_ARRAY ((LAST_SBX_ERROR_ID+73UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Array or function xx undefined
+#define ERRCODE_BASIC_UNDEF_PROC ((LAST_SBX_ERROR_ID+74UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Procedure xxx undefined
+#define ERRCODE_BASIC_UNDEF_LABEL ((LAST_SBX_ERROR_ID+75UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Label xxx undefined
+#define ERRCODE_BASIC_UNDEF_TYPE ((LAST_SBX_ERROR_ID+76UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Unknown user defined type xxx
+#define ERRCODE_BASIC_BAD_EXIT ((LAST_SBX_ERROR_ID+77UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Exit XXX expected
+#define ERRCODE_BASIC_BAD_BLOCK ((LAST_SBX_ERROR_ID+78UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Unterminated statement block: missing XX
+#define ERRCODE_BASIC_BAD_BRACKETS ((LAST_SBX_ERROR_ID+79UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Parentheses do not match
+#define ERRCODE_BASIC_BAD_DECLARATION ((LAST_SBX_ERROR_ID+80UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Symbol xx defined differently
+#define ERRCODE_BASIC_BAD_PARAMETERS ((LAST_SBX_ERROR_ID+81UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Parameters do not match
+#define ERRCODE_BASIC_BAD_CHAR_IN_NUMBER ((LAST_SBX_ERROR_ID+82UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Bad character in number
+#define ERRCODE_BASIC_MUST_HAVE_DIMS ((LAST_SBX_ERROR_ID+83UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Array needs dimensioning
+#define ERRCODE_BASIC_NO_IF ((LAST_SBX_ERROR_ID+84UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Else/Endif without If
+#define ERRCODE_BASIC_NOT_IN_SUBR ((LAST_SBX_ERROR_ID+85UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // xxx not allowed within a sub
+#define ERRCODE_BASIC_NOT_IN_MAIN ((LAST_SBX_ERROR_ID+86UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // xxx not allowed outside a sub
+#define ERRCODE_BASIC_WRONG_DIMS ((LAST_SBX_ERROR_ID+87UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Dimensions do not match
+#define ERRCODE_BASIC_BAD_OPTION ((LAST_SBX_ERROR_ID+88UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Unknown option: xxx
+#define ERRCODE_BASIC_CONSTANT_REDECLARED ((LAST_SBX_ERROR_ID+89UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Constant xx redeclared
+#define ERRCODE_BASIC_PROG_TOO_LARGE ((LAST_SBX_ERROR_ID+90UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Program is too large
+#define ERRCODE_BASIC_NO_STRINGS_ARRAYS ((LAST_SBX_ERROR_ID+91UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER)
+
+#define ERRCODE_BASIC_EXCEPTION ((LAST_SBX_ERROR_ID+92UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME)
+
+#define ERRCODE_BASMGR_STDLIBOPEN (LAST_SBX_ERROR_ID+93UL) | ERRCODE_AREA_SBX
+#define ERRCODE_BASMGR_STDLIBSAVE (LAST_SBX_ERROR_ID+94UL) | ERRCODE_AREA_SBX
+#define ERRCODE_BASMGR_LIBLOAD (LAST_SBX_ERROR_ID+95UL) | ERRCODE_AREA_SBX
+#define ERRCODE_BASMGR_LIBCREATE (LAST_SBX_ERROR_ID+96UL) | ERRCODE_AREA_SBX
+#define ERRCODE_BASMGR_LIBSAVE (LAST_SBX_ERROR_ID+97UL) | ERRCODE_AREA_SBX
+#define ERRCODE_BASMGR_LIBDEL (LAST_SBX_ERROR_ID+98UL) | ERRCODE_AREA_SBX
+#define ERRCODE_BASMGR_MGROPEN (LAST_SBX_ERROR_ID+99UL) | ERRCODE_AREA_SBX
+#define ERRCODE_BASMGR_MGRSAVE (LAST_SBX_ERROR_ID+100UL) | ERRCODE_AREA_SBX
+#define ERRCODE_BASMGR_REMOVELIB (LAST_SBX_ERROR_ID+101UL) | ERRCODE_AREA_SBX
+#define ERRCODE_BASMGR_UNLOADLIB (LAST_SBX_ERROR_ID+102UL) | ERRCODE_AREA_SBX
+
+#define ERRCODE_BASIC_ARRAY_FIX ((LAST_SBX_ERROR_ID+104UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // This array is fixed
+#define ERRCODE_BASIC_STRING_OVERFLOW ((LAST_SBX_ERROR_ID+105UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Out of string space
+#define ERRCODE_BASIC_EXPR_TOO_COMPLEX ((LAST_SBX_ERROR_ID+106UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Expression too complex
+#define ERRCODE_BASIC_OPER_NOT_PERFORM ((LAST_SBX_ERROR_ID+107UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Can't perform requested operation
+#define ERRCODE_BASIC_TOO_MANY_DLL ((LAST_SBX_ERROR_ID+108UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Too many dll application clients
+#define ERRCODE_BASIC_LOOP_NOT_INIT ((LAST_SBX_ERROR_ID+109UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // For loop not initialized
+
+#define ERRCODE_BASIC_COMPAT ((LAST_SBX_ERROR_ID+103UL)| ERRCODE_AREA_SBX | ERRCODE_CLASS_RUNTIME)
+
+// Map old codes to new codes
+#define SbERR_SYNTAX ERRCODE_BASIC_SYNTAX
+#define SbERR_NO_GOSUB ERRCODE_BASIC_NO_GOSUB
+#define SbERR_REDO_FROM_START ERRCODE_BASIC_REDO_FROM_START
+#define SbERR_BAD_ARGUMENT ERRCODE_BASIC_BAD_ARGUMENT
+#define SbERR_MATH_OVERFLOW ERRCODE_BASIC_MATH_OVERFLOW
+#define SbERR_NO_MEMORY ERRCODE_BASIC_NO_MEMORY
+#define SbERR_ALREADY_DIM ERRCODE_BASIC_ALREADY_DIM
+#define SbERR_OUT_OF_RANGE ERRCODE_BASIC_OUT_OF_RANGE
+#define SbERR_DUPLICATE_DEF ERRCODE_BASIC_DUPLICATE_DEF
+#define SbERR_ZERODIV ERRCODE_BASIC_ZERODIV
+#define SbERR_VAR_UNDEFINED ERRCODE_BASIC_VAR_UNDEFINED
+#define SbERR_CONVERSION ERRCODE_BASIC_CONVERSION
+#define SbERR_BAD_PARAMETER ERRCODE_BASIC_BAD_PARAMETER
+#define SbERR_USER_ABORT ERRCODE_BASIC_USER_ABORT
+#define SbERR_BAD_RESUME ERRCODE_BASIC_BAD_RESUME
+#define SbERR_STACK_OVERFLOW ERRCODE_BASIC_STACK_OVERFLOW
+#define SbERR_PROC_UNDEFINED ERRCODE_BASIC_PROC_UNDEFINED
+#define SbERR_BAD_DLL_LOAD ERRCODE_BASIC_BAD_DLL_LOAD
+#define SbERR_BAD_DLL_CALL ERRCODE_BASIC_BAD_DLL_CALL
+#define SbERR_INTERNAL_ERROR ERRCODE_BASIC_INTERNAL_ERROR
+#define SbERR_BAD_CHANNEL ERRCODE_BASIC_BAD_CHANNEL
+#define SbERR_FILE_NOT_FOUND ERRCODE_BASIC_FILE_NOT_FOUND
+#define SbERR_BAD_FILE_MODE ERRCODE_BASIC_BAD_FILE_MODE
+#define SbERR_FILE_ALREADY_OPEN ERRCODE_BASIC_FILE_ALREADY_OPEN
+#define SbERR_IO_ERROR ERRCODE_BASIC_IO_ERROR
+#define SbERR_FILE_EXISTS ERRCODE_BASIC_FILE_EXISTS
+#define SbERR_BAD_RECORD_LENGTH ERRCODE_BASIC_BAD_RECORD_LENGTH
+#define SbERR_DISK_FULL ERRCODE_BASIC_DISK_FULL
+#define SbERR_READ_PAST_EOF ERRCODE_BASIC_READ_PAST_EOF
+#define SbERR_BAD_RECORD_NUMBER ERRCODE_BASIC_BAD_RECORD_NUMBER
+#define SbERR_TOO_MANY_FILES ERRCODE_BASIC_TOO_MANY_FILES
+#define SbERR_NO_DEVICE ERRCODE_BASIC_NO_DEVICE
+#define SbERR_ACCESS_DENIED ERRCODE_BASIC_ACCESS_DENIED
+#define SbERR_NOT_READY ERRCODE_BASIC_NOT_READY
+#define SbERR_NOT_IMPLEMENTED ERRCODE_BASIC_NOT_IMPLEMENTED
+#define SbERR_DIFFERENT_DRIVE ERRCODE_BASIC_DIFFERENT_DRIVE
+#define SbERR_ACCESS_ERROR ERRCODE_BASIC_ACCESS_ERROR
+#define SbERR_PATH_NOT_FOUND ERRCODE_BASIC_PATH_NOT_FOUND
+#define SbERR_NO_OBJECT ERRCODE_BASIC_NO_OBJECT
+#define SbERR_BAD_PATTERN ERRCODE_BASIC_BAD_PATTERN
+#define SBERR_IS_NULL ERRCODE_BASIC_IS_NULL
+#define SbERR_DDE_ERROR ERRCODE_BASIC_DDE_ERROR
+#define SbERR_DDE_WAITINGACK ERRCODE_BASIC_DDE_WAITINGACK
+#define SbERR_DDE_OUTOFCHANNELS ERRCODE_BASIC_DDE_OUTOFCHANNELS
+#define SbERR_DDE_NO_RESPONSE ERRCODE_BASIC_DDE_NO_RESPONSE
+#define SbERR_DDE_MULT_RESPONSES ERRCODE_BASIC_DDE_MULT_RESPONSES
+#define SbERR_DDE_CHANNEL_LOCKED ERRCODE_BASIC_DDE_CHANNEL_LOCKED
+#define SbERR_DDE_NOTPROCESSED ERRCODE_BASIC_DDE_NOTPROCESSED
+#define SbERR_DDE_TIMEOUT ERRCODE_BASIC_DDE_TIMEOUT
+#define SbERR_DDE_USER_INTERRUPT ERRCODE_BASIC_DDE_USER_INTERRUPT
+#define SbERR_DDE_BUSY ERRCODE_BASIC_DDE_BUSY
+#define SbERR_DDE_NO_DATA ERRCODE_BASIC_DDE_NO_DATA
+#define SbERR_DDE_WRONG_DATA_FORMAT ERRCODE_BASIC_DDE_WRONG_DATA_FORMAT
+#define SbERR_DDE_PARTNER_QUIT ERRCODE_BASIC_DDE_PARTNER_QUIT
+#define SbERR_DDE_CONV_CLOSED ERRCODE_BASIC_DDE_CONV_CLOSED
+#define SbERR_DDE_NO_CHANNEL ERRCODE_BASIC_DDE_NO_CHANNEL
+#define SbERR_DDE_INVALID_LINK ERRCODE_BASIC_DDE_INVALID_LINK
+#define SbERR_DDE_QUEUE_OVERFLOW ERRCODE_BASIC_DDE_QUEUE_OVERFLOW
+#define SbERR_DDE_LINK_ALREADY_EST ERRCODE_BASIC_DDE_LINK_ALREADY_EST
+#define SbERR_DDE_LINK_INV_TOPIC ERRCODE_BASIC_DDE_LINK_INV_TOPIC
+#define SbERR_DDE_DLL_NOT_FOUND ERRCODE_BASIC_DDE_DLL_NOT_FOUND
+#define SbERR_CANNOT_LOAD ERRCODE_BASIC_CANNOT_LOAD
+#define SbERR_BAD_INDEX ERRCODE_BASIC_BAD_INDEX
+#define SbERR_NO_ACTIVE_OBJECT ERRCODE_BASIC_NO_ACTIVE_OBJECT
+#define SbERR_BAD_PROP_VALUE ERRCODE_BASIC_BAD_PROP_VALUE
+#define SbERR_PROP_READONLY ERRCODE_BASIC_PROP_READONLY
+#define SbERR_PROP_WRITEONLY ERRCODE_BASIC_PROP_WRITEONLY
+#define SbERR_INVALID_OBJECT ERRCODE_BASIC_INVALID_OBJECT
+#define SbERR_NO_METHOD ERRCODE_BASIC_NO_METHOD
+#define SbERR_NEEDS_OBJECT ERRCODE_BASIC_NEEDS_OBJECT
+#define SbERR_INVALID_USAGE_OBJECT ERRCODE_BASIC_INVALID_USAGE_OBJECT
+#define SbERR_NO_OLE ERRCODE_BASIC_NO_OLE
+#define SbERR_BAD_METHOD ERRCODE_BASIC_BAD_METHOD
+#define SbERR_OLE_ERROR ERRCODE_BASIC_OLE_ERROR
+#define SbERR_BAD_ACTION ERRCODE_BASIC_BAD_ACTION
+#define SbERR_NO_NAMED_ARGS ERRCODE_BASIC_NO_NAMED_ARGS
+#define SbERR_BAD_LOCALE ERRCODE_BASIC_BAD_LOCALE
+#define SbERR_NAMED_NOT_FOUND ERRCODE_BASIC_NAMED_NOT_FOUND
+#define SbERR_NOT_OPTIONAL ERRCODE_BASIC_NOT_OPTIONAL
+#define SbERR_WRONG_ARGS ERRCODE_BASIC_WRONG_ARGS
+#define SbERR_NOT_A_COLL ERRCODE_BASIC_NOT_A_COLL
+#define SbERR_BAD_ORDINAL ERRCODE_BASIC_BAD_ORDINAL
+#define SbERR_DLLPROC_NOT_FOUND ERRCODE_BASIC_DLLPROC_NOT_FOUND
+#define SbERR_BAD_CLIPBD_FORMAT ERRCODE_BASIC_BAD_CLIPBD_FORMAT
+#define SbERR_PROPERTY_NOT_FOUND ERRCODE_BASIC_PROPERTY_NOT_FOUND
+#define SbERR_METHOD_NOT_FOUND ERRCODE_BASIC_METHOD_NOT_FOUND
+#define SbERR_ARG_MISSING ERRCODE_BASIC_ARG_MISSING
+#define SbERR_BAD_NUMBER_OF_ARGS ERRCODE_BASIC_BAD_NUMBER_OF_ARGS
+#define SbERR_METHOD_FAILED ERRCODE_BASIC_METHOD_FAILED
+#define SbERR_SETPROP_FAILED ERRCODE_BASIC_SETPROP_FAILED
+#define SbERR_GETPROP_FAILED ERRCODE_BASIC_GETPROP_FAILED
+// #define SbERR_COMPILER_BGN ERRCODE_BASIC_COMPILER_BGN
+#define SbERR_UNEXPECTED ERRCODE_BASIC_UNEXPECTED
+#define SbERR_EXPECTED ERRCODE_BASIC_EXPECTED
+#define SbERR_SYMBOL_EXPECTED ERRCODE_BASIC_SYMBOL_EXPECTED
+#define SbERR_VAR_EXPECTED ERRCODE_BASIC_VAR_EXPECTED
+#define SbERR_LABEL_EXPECTED ERRCODE_BASIC_LABEL_EXPECTED
+#define SbERR_LVALUE_EXPECTED ERRCODE_BASIC_LVALUE_EXPECTED
+#define SbERR_VAR_DEFINED ERRCODE_BASIC_VAR_DEFINED
+#define SbERR_PROC_DEFINED ERRCODE_BASIC_PROC_DEFINED
+#define SbERR_LABEL_DEFINED ERRCODE_BASIC_LABEL_DEFINED
+#define SbERR_UNDEF_VAR ERRCODE_BASIC_UNDEF_VAR
+#define SbERR_UNDEF_ARRAY ERRCODE_BASIC_UNDEF_ARRAY
+#define SbERR_UNDEF_PROC ERRCODE_BASIC_UNDEF_PROC
+#define SbERR_UNDEF_LABEL ERRCODE_BASIC_UNDEF_LABEL
+#define SbERR_UNDEF_TYPE ERRCODE_BASIC_UNDEF_TYPE
+#define SbERR_BAD_EXIT ERRCODE_BASIC_BAD_EXIT
+#define SbERR_BAD_BLOCK ERRCODE_BASIC_BAD_BLOCK
+#define SbERR_BAD_BRACKETS ERRCODE_BASIC_BAD_BRACKETS
+#define SbERR_BAD_DECLARATION ERRCODE_BASIC_BAD_DECLARATION
+#define SbERR_BAD_PARAMETERS ERRCODE_BASIC_BAD_PARAMETERS
+#define SbERR_BAD_CHAR_IN_NUMBER ERRCODE_BASIC_BAD_CHAR_IN_NUMBER
+#define SbERR_MUST_HAVE_DIMS ERRCODE_BASIC_MUST_HAVE_DIMS
+#define SbERR_NO_IF ERRCODE_BASIC_NO_IF
+#define SbERR_NOT_IN_SUBR ERRCODE_BASIC_NOT_IN_SUBR
+#define SbERR_NOT_IN_MAIN ERRCODE_BASIC_NOT_IN_MAIN
+#define SbERR_WRONG_DIMS ERRCODE_BASIC_WRONG_DIMS
+#define SbERR_BAD_OPTION ERRCODE_BASIC_BAD_OPTION
+#define SbERR_CONSTANT_REDECLARED ERRCODE_BASIC_CONSTANT_REDECLARED
+#define SbERR_PROG_TOO_LARGE ERRCODE_BASIC_PROG_TOO_LARGE
+#define SbERR_NO_STRINGS_ARRAYS ERRCODE_BASIC_NO_STRINGS_ARRAYS
+#define SbERR_BASIC_EXCEPTION ERRCODE_BASIC_EXCEPTION
+#define SbERR_BASIC_COMPAT ERRCODE_BASIC_COMPAT
+#define SbERR_BASIC_ARRAY_FIX ERRCODE_BASIC_ARRAY_FIX
+#define SbERR_BASIC_STRING_OVERFLOW ERRCODE_BASIC_STRING_OVERFLOW
+#define SbERR_BASIC_EXPR_TOO_COMPLEX ERRCODE_BASIC_EXPR_TOO_COMPLEX
+#define SbERR_BASIC_OPER_NOT_PERFORM ERRCODE_BASIC_OPER_NOT_PERFORM
+#define SbERR_BASIC_TOO_MANY_DLL ERRCODE_BASIC_TOO_MANY_DLL
+#define SbERR_BASIC_LOOP_NOT_INIT ERRCODE_BASIC_LOOP_NOT_INIT
+// #define SbERR_COMPILER_END ERRCODE_BASIC_COMPILER_END
+
+/* ALT
+#define SbERR_SYNTAX 2 // unspecified syntax error
+#define SbERR_NO_GOSUB 3 // Return without Gosub
+#define SbERR_REDO_FROM_START 4 // Redo form start (SB internal)
+#define SbERR_BAD_ARGUMENT 5 // Invalid procedure call
+#define SbERR_MATH_OVERFLOW 6 // Overflow
+#define SbERR_NO_MEMORY 7 // Out of memory
+#define SbERR_ALREADY_DIM 8 // Array already dimensioned
+#define SbERR_OUT_OF_RANGE 9 // Subscript out of range
+#define SbERR_DUPLICATE_DEF 10 // Duplicate definition
+#define SbERR_ZERODIV 11 // Division by zero
+#define SbERR_VAR_UNDEFINED 12 // Variable undefined (SB)
+#define SbERR_CONVERSION 13 // Type mismatch
+#define SbERR_BAD_PARAMETER 14 // Invalid Parameter
+#define SbERR_USER_ABORT 18 // User interrupt occurred
+#define SbERR_BAD_RESUME 20 // Resume without error
+#define SbERR_STACK_OVERFLOW 28 // Out of stack space
+#define SbERR_PROC_UNDEFINED 35 // Sub or Function not defined
+#define SbERR_BAD_DLL_LOAD 48 // Error in loading DLL
+#define SbERR_BAD_DLL_CALL 49 // Bad DLL calling convention
+#define SbERR_INTERNAL_ERROR 51 // internal error
+#define SbERR_BAD_CHANNEL 52 // Bad file name or number
+#define SbERR_FILE_NOT_FOUND 53 // File not found
+#define SbERR_BAD_FILE_MODE 54 // Bad file mode
+#define SbERR_FILE_ALREADY_OPEN 55 // File already open
+#define SbERR_IO_ERROR 57 // Device I/O error
+#define SbERR_FILE_EXISTS 58 // File already exists
+#define SbERR_BAD_RECORD_LENGTH 59 // bad record length
+#define SbERR_DISK_FULL 61 // disk full
+#define SbERR_READ_PAST_EOF 62 // Input past end of file
+#define SbERR_BAD_RECORD_NUMBER 63 // Bad record number
+#define SbERR_TOO_MANY_FILES 67 // Too many files
+#define SbERR_NO_DEVICE 68 // Device not available
+#define SbERR_ACCESS_DENIED 70 // Permission denied
+#define SbERR_NOT_READY 71 // Disk not ready
+#define SbERR_NOT_IMPLEMENTED 73 // Feature not implemented
+#define SbERR_DIFFERENT_DRIVE 74 // No rename with different drive
+#define SbERR_ACCESS_ERROR 75 // Path/File access error
+#define SbERR_PATH_NOT_FOUND 76 // Path not found
+#define SbERR_NO_OBJECT 91 // Object variable not set
+#define SbERR_BAD_PATTERN 93 // Invalid pattern string
+#define SBERR_IS_NULL 94 // Invalid use of Null
+
+// DDE messages from 250-299
+#define SbERR_DDE_ERROR 250
+#define SbERR_DDE_WAITINGACK 280
+#define SbERR_DDE_OUTOFCHANNELS 281
+#define SbERR_DDE_NO_RESPONSE 282
+#define SbERR_DDE_MULT_RESPONSES 283
+#define SbERR_DDE_CHANNEL_LOCKED 284
+#define SbERR_DDE_NOTPROCESSED 285
+#define SbERR_DDE_TIMEOUT 286
+#define SbERR_DDE_USER_INTERRUPT 287
+#define SbERR_DDE_BUSY 288
+#define SbERR_DDE_NO_DATA 289
+#define SbERR_DDE_WRONG_DATA_FORMAT 290
+#define SbERR_DDE_PARTNER_QUIT 291
+#define SbERR_DDE_CONV_CLOSED 292
+#define SbERR_DDE_NO_CHANNEL 293
+#define SbERR_DDE_INVALID_LINK 294
+#define SbERR_DDE_QUEUE_OVERFLOW 295
+#define SbERR_DDE_LINK_ALREADY_EST 296
+#define SbERR_DDE_LINK_INV_TOPIC 297
+#define SbERR_DDE_DLL_NOT_FOUND 298
+
+#define SbERR_CANNOT_LOAD 323 // Can't load module
+#define SbERR_BAD_INDEX 341 // Invalid object index
+#define SbERR_NO_ACTIVE_OBJECT 366 // No active view or document
+#define SbERR_BAD_PROP_VALUE 380 // Bad property value
+#define SbERR_PROP_READONLY 382 // Property is read only
+#define SbERR_PROP_WRITEONLY 394 // Property is write only
+#define SbERR_INVALID_OBJECT 420 // Invalid object reference
+#define SbERR_NO_METHOD 423 // Property or method not found
+#define SbERR_NEEDS_OBJECT 424 // Object required
+#define SbERR_INVALID_USAGE_OBJECT 425 // Invalid usee of object
+#define SbERR_NO_OLE 430 // Class does not support OLE
+#define SbERR_BAD_METHOD 438 // Object doesn't support method
+#define SbERR_OLE_ERROR 440 // OLE Automation error
+#define SbERR_BAD_ACTION 445 // Object doesn't support this action
+#define SbERR_NO_NAMED_ARGS 446 // Object doesn't support named args
+#define SbERR_BAD_LOCALE 447 // Object doesn't support current locale setting
+#define SbERR_NAMED_NOT_FOUND 448 // Named argument not found
+#define SbERR_NOT_OPTIONAL 449 // Argument not optional
+#define SbERR_WRONG_ARGS 450 // Wrong number of arguments
+#define SbERR_NOT_A_COLL 451 // Object not a collection
+#define SbERR_BAD_ORDINAL 452 // Invalid ordinal
+#define SbERR_DLLPROC_NOT_FOUND 453 // Specified DLL function not found
+#define SbERR_BAD_CLIPBD_FORMAT 460 // Invalid clipboard format
+
+// Debugger messages from 700-799
+
+#define SbERR_PROPERTY_NOT_FOUND 1000 // Class not have property
+#define SbERR_METHOD_NOT_FOUND 1001 // Class does not have method
+#define SbERR_ARG_MISSING 1002 // Missing required argument
+#define SbERR_BAD_NUMBER_OF_ARGS 1003 // Bad number of arguments
+#define SbERR_METHOD_FAILED 1004 // Method failed
+#define SbERR_SETPROP_FAILED 1005 // Unable to set property
+#define SbERR_GETPROP_FAILED 1006 // Unable to get property
+
+// Compiler Errors (do not happen at runtime)
+// These IDs can shift at any time
+
+#define SbERR_COMPILER_BGN 950
+#define SbERR_UNEXPECTED 951 // Unexpected symbol: xx
+#define SbERR_EXPECTED 952 // Expected: xx
+#define SbERR_SYMBOL_EXPECTED 953 // Symbol expected
+#define SbERR_VAR_EXPECTED 954 // Variable expected
+#define SbERR_LABEL_EXPECTED 955 // Label expected
+#define SbERR_LVALUE_EXPECTED 956 // Lvalue expected
+#define SbERR_VAR_DEFINED 957 // Variable xxx already defined
+#define SbERR_PROC_DEFINED 958 // Procedure xx already defined
+#define SbERR_LABEL_DEFINED 959 // Label xxx already defined
+#define SbERR_UNDEF_VAR 960 // Variable xx undefined
+#define SbERR_UNDEF_ARRAY 961 // Array or function xx undefined
+#define SbERR_UNDEF_PROC 962 // Procedure xxx undefined
+#define SbERR_UNDEF_LABEL 963 // Label xxx undefined
+#define SbERR_UNDEF_TYPE 964 // Unknown user defined type xxx
+#define SbERR_BAD_EXIT 965 // Exit XXX expexted
+#define SbERR_BAD_BLOCK 966 // Unterminated statement block: missing XX
+#define SbERR_BAD_BRACKETS 967 // Parentheses do not match
+#define SbERR_BAD_DECLARATION 968 // Symbol xx defined differently
+#define SbERR_BAD_PARAMETERS 969 // Parameters do not match
+#define SbERR_BAD_CHAR_IN_NUMBER 970 // Bad character in number
+#define SbERR_MUST_HAVE_DIMS 971 // Array needs dimensioning
+#define SbERR_NO_IF 972 // Else/Endif without If
+#define SbERR_NOT_IN_SUBR 973 // xxx not allowed within a sub
+#define SbERR_NOT_IN_MAIN 974 // xxx not allowed outside a sub
+#define SbERR_WRONG_DIMS 975 // Dimensions do not match
+#define SbERR_BAD_OPTION 976 // Unknown option: xxx
+#define SbERR_CONSTANT_REDECLARED 977 // Constant xx redeclared
+#define SbERR_PROG_TOO_LARGE 978 // Program is too large
+#define SbERR_NO_STRINGS_ARRAYS 979
+#define SbERR_COMPILER_END 299
+*/
+
+// Grid messages from 30000-30999
+// OLE messages from 31000-31999
+
+#endif
diff --git a/basic/inc/basic/sbmeth.hxx b/basic/inc/basic/sbmeth.hxx
new file mode 100644
index 000000000000..4e426ffe8552
--- /dev/null
+++ b/basic/inc/basic/sbmeth.hxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SB_SBMETH_HXX
+#define _SB_SBMETH_HXX
+
+#include <tools/errcode.hxx>
+#include <basic/sbxmeth.hxx>
+#include <basic/sbdef.hxx>
+
+class SbModule;
+class SbMethodImpl;
+
+class SbMethod : public SbxMethod
+{
+ friend class SbiRuntime;
+ friend class SbiFactory;
+ friend class SbModule;
+ friend class SbClassModuleObject;
+ friend class SbiCodeGen;
+ friend class SbJScriptMethod;
+ friend class SbIfaceMapperMethod;
+
+ SbMethodImpl* mpSbMethodImpl; // Impl data
+ SbModule* pMod;
+ USHORT nDebugFlags;
+ USHORT nLine1, nLine2;
+ UINT32 nStart;
+ BOOL bInvalid;
+ SbxArrayRef refStatics;
+ SbMethod( const String&, SbxDataType, SbModule* );
+ SbMethod( const SbMethod& );
+ virtual BOOL LoadData( SvStream&, USHORT );
+ virtual BOOL StoreData( SvStream& ) const;
+ virtual ~SbMethod();
+
+public:
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_BASICMETHOD,2);
+ TYPEINFO();
+ virtual SbxInfo* GetInfo();
+ SbxArray* GetLocals();
+ SbxArray* GetStatics();
+ void ClearStatics();
+ SbModule* GetModule() { return pMod; }
+ UINT32 GetId() const { return nStart; }
+ USHORT GetDebugFlags() { return nDebugFlags; }
+ void SetDebugFlags( USHORT n ) { nDebugFlags = n; }
+ void GetLineRange( USHORT&, USHORT& );
+
+ // Schnittstelle zum Ausfuehren einer Methode aus den Applikationen
+ virtual ErrCode Call( SbxValue* pRet = NULL );
+ virtual void Broadcast( ULONG nHintId );
+};
+
+#ifndef __SB_SBMETHODREF_HXX
+#define __SB_SBMETHODREF_HXX
+SV_DECL_IMPL_REF(SbMethod)
+#endif
+
+class SbIfaceMapperMethod : public SbMethod
+{
+ friend class SbiRuntime;
+
+ SbMethodRef mxImplMeth;
+
+public:
+ TYPEINFO();
+ SbIfaceMapperMethod( const String& rName, SbMethod* pImplMeth )
+ : SbMethod( rName, pImplMeth->GetType(), NULL )
+ , mxImplMeth( pImplMeth )
+ {}
+ virtual ~SbIfaceMapperMethod();
+ SbMethod* getImplMethod( void )
+ { return mxImplMeth; }
+};
+
+#endif
diff --git a/basic/inc/basic/sbmod.hxx b/basic/inc/basic/sbmod.hxx
new file mode 100644
index 000000000000..abb482f7bfe5
--- /dev/null
+++ b/basic/inc/basic/sbmod.hxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SB_SBMOD_HXX
+#define _SB_SBMOD_HXX
+
+#include <com/sun/star/script/XInvocation.hpp>
+#include <basic/sbdef.hxx>
+#include <basic/sbxobj.hxx>
+#include <basic/sbxdef.hxx>
+#include <rtl/ustring.hxx>
+#include <vector>
+
+class SbMethod;
+class SbProperty;
+class SbiRuntime;
+class SbiBreakpoints;
+class SbiImage;
+class SbProcedureProperty;
+class SbIfaceMapperMethod;
+class SbClassModuleObject;
+
+struct ClassModuleRunInitItem;
+struct SbClassData;
+class SbModuleImpl;
+
+class SbModule : public SbxObject
+{
+ friend class TestToolObj; // allows module initialisation at runtime
+ friend class SbiCodeGen;
+ friend class SbMethod;
+ friend class SbiRuntime;
+ friend class StarBASIC;
+ friend class SbClassModuleObject;
+
+ SbModuleImpl* mpSbModuleImpl; // Impl data
+ std::vector< String > mModuleVariableNames;
+
+protected:
+ com::sun::star::uno::Reference< com::sun::star::script::XInvocation > mxWrapper;
+ ::rtl::OUString aOUSource;
+ String aComment;
+ SbiImage* pImage; // the Image
+ SbiBreakpoints* pBreaks; // Breakpoints
+ SbClassData* pClassData;
+ BOOL mbVBACompat;
+ INT32 mnType;
+ SbxObjectRef pDocObject; // an impl object ( used by Document Modules )
+ bool bIsProxyModule;
+
+ static void implProcessModuleRunInit( ClassModuleRunInitItem& rItem );
+ void StartDefinitions();
+ SbMethod* GetMethod( const String&, SbxDataType );
+ SbProperty* GetProperty( const String&, SbxDataType );
+ SbProcedureProperty* GetProcedureProperty( const String&, SbxDataType );
+ SbIfaceMapperMethod* GetIfaceMapperMethod( const String&, SbMethod* );
+ void EndDefinitions( BOOL=FALSE );
+ USHORT Run( SbMethod* );
+ void RunInit();
+ void ClearPrivateVars();
+ void GlobalRunInit( BOOL bBasicStart ); // for all modules
+ void GlobalRunDeInit( void );
+ const BYTE* FindNextStmnt( const BYTE*, USHORT&, USHORT& ) const;
+ const BYTE* FindNextStmnt( const BYTE*, USHORT&, USHORT&,
+ BOOL bFollowJumps, const SbiImage* pImg=NULL ) const;
+ virtual BOOL LoadData( SvStream&, USHORT );
+ virtual BOOL StoreData( SvStream& ) const;
+ virtual BOOL LoadCompleted();
+ virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType );
+ virtual ~SbModule();
+public:
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_BASICMOD,2);
+ TYPEINFO();
+ SbModule( const String&, BOOL bCompat = FALSE );
+ virtual void SetParent( SbxObject* );
+ virtual void Clear();
+
+ virtual SbxVariable* Find( const String&, SbxClassType );
+
+ virtual const String& GetSource() const;
+ const ::rtl::OUString& GetSource32() const;
+ const String& GetComment() const { return aComment; }
+ virtual void SetSource( const String& r );
+ void SetSource32( const ::rtl::OUString& r );
+ void SetComment( const String& r );
+
+ virtual BOOL Compile();
+ BOOL Disassemble( String& rText );
+ virtual BOOL IsCompiled() const;
+ const SbxObject* FindType( String aTypeName ) const;
+
+ virtual BOOL IsBreakable( USHORT nLine ) const;
+ virtual USHORT GetBPCount() const;
+ virtual USHORT GetBP( USHORT n ) const;
+ virtual BOOL IsBP( USHORT nLine ) const;
+ virtual BOOL SetBP( USHORT nLine );
+ virtual BOOL ClearBP( USHORT nLine );
+ virtual void ClearAllBP();
+
+ // Lines of Subs
+ virtual SbMethod* GetFunctionForLine( USHORT );
+
+ // Store only image, no source (needed for new password protection)
+ BOOL StoreBinaryData( SvStream& );
+ BOOL StoreBinaryData( SvStream&, USHORT nVer );
+ BOOL LoadBinaryData( SvStream&, USHORT nVer );
+ BOOL LoadBinaryData( SvStream& );
+ BOOL ExceedsLegacyModuleSize();
+ void fixUpMethodStart( bool bCvtToLegacy, SbiImage* pImg = NULL ) const;
+ BOOL IsVBACompat() const;
+ void SetVBACompat( BOOL bCompat );
+ INT32 GetModuleType() { return mnType; }
+ void SetModuleType( INT32 nType ) { mnType = nType; }
+ bool isProxyModule() { return bIsProxyModule; }
+ void AddVarName( const String& aName );
+ void RemoveVars();
+ ::com::sun::star::uno::Reference< ::com::sun::star::script::XInvocation > GetUnoModule();
+ bool createCOMWrapperForIface( ::com::sun::star::uno::Any& o_rRetAny, SbClassModuleObject* pProxyClassModuleObject );
+};
+
+#ifndef __SB_SBMODULEREF_HXX
+#define __SB_SBMODULEREF_HXX
+
+SV_DECL_IMPL_REF(SbModule)
+
+#endif
+
+class SbClassModuleImpl;
+
+// Object class for instances of class modules
+class SbClassModuleObject : public SbModule
+{
+ SbClassModuleImpl* mpSbClassModuleImpl;
+
+ SbModule* mpClassModule;
+ bool mbInitializeEventDone;
+
+public:
+ TYPEINFO();
+ SbClassModuleObject( SbModule* pClassModule );
+ ~SbClassModuleObject();
+
+ // Overridden to support NameAccess etc.
+ virtual SbxVariable* Find( const String&, SbxClassType );
+
+ virtual void SFX_NOTIFY( SfxBroadcaster&, const TypeId&, const SfxHint& rHint, const TypeId& );
+
+ SbModule* getClassModule( void )
+ { return mpClassModule; }
+
+ void triggerInitializeEvent( void );
+ void triggerTerminateEvent( void );
+};
+
+#ifndef __SB_SBCLASSMODULEREF_HXX
+#define __SB_SBCLASSMODULEREF_HXX
+
+SV_DECL_IMPL_REF(SbClassModuleObject);
+
+#endif
+
+#endif
diff --git a/basic/inc/basic/sbobjmod.hxx b/basic/inc/basic/sbobjmod.hxx
new file mode 100644
index 000000000000..9ff46d1931f3
--- /dev/null
+++ b/basic/inc/basic/sbobjmod.hxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: sbobjmod.hxx,v $
+ *
+ * $Revision: 1.4 $
+ *
+ * last change: $Author: $ $Date: 2007/08/27 16:31:39 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef _SB_OBJMOD_HXX
+#define _SB_OBJMOD_HXX
+
+#include <rtl/ref.hxx>
+#include <basic/sbmod.hxx>
+#include <basic/sbstar.hxx>
+#include <com/sun/star/script/ModuleInfo.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/awt/XDialog.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+
+namespace css = ::com::sun::star;
+
+// Basic-Module for excel object.
+
+class SbObjModule : public SbModule
+{
+ SbObjModule( const SbObjModule& );
+ SbObjModule();
+public:
+ TYPEINFO();
+ SbObjModule( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsVbaCompatible );
+ virtual SbxVariable* Find( const XubString& rName, SbxClassType t );
+ using SbxValue::GetObject;
+ SbxVariable* GetObject();
+ void SetUnoObject( const com::sun::star::uno::Any& aObj )throw ( com::sun::star::uno::RuntimeException ) ;
+};
+
+class FormObjEventListenerImpl;
+
+class SbUserFormModule : public SbObjModule
+{
+ com::sun::star::script::ModuleInfo m_mInfo;
+ ::rtl::Reference< FormObjEventListenerImpl > m_DialogListener;
+ css::uno::Reference<css::awt::XDialog> m_xDialog;
+ css::uno::Reference<css::frame::XModel> m_xModel;
+ String sFormName;
+ bool mbInit;
+ SbUserFormModule( const SbUserFormModule& );
+ SbUserFormModule();
+
+//protected:
+ virtual void InitObject();
+public:
+ TYPEINFO();
+ SbUserFormModule( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsVBACompat );
+ virtual ~SbUserFormModule();
+ virtual SbxVariable* Find( const XubString& rName, SbxClassType t );
+ void ResetApiObj();
+ void Unload();
+ void Load();
+ void triggerMethod( const String& );
+ void triggerMethod( const String&, css::uno::Sequence< css::uno::Any >& );
+ void triggerActivateEvent();
+ void triggerDeactivateEvent();
+ void triggerInitializeEvent();
+ void triggerTerminateEvent();
+ void triggerLayoutEvent();
+ void triggerResizeEvent();
+
+ class SbUserFormModuleInstance* CreateInstance();
+};
+
+class SbUserFormModuleInstance : public SbUserFormModule
+{
+ SbUserFormModule* m_pParentModule;
+
+public:
+ SbUserFormModuleInstance( SbUserFormModule* pParentModule, const String& rName,
+ const com::sun::star::script::ModuleInfo& mInfo, bool bIsVBACompat );
+
+ virtual BOOL IsClass( const String& ) const;
+ virtual SbxVariable* Find( const XubString& rName, SbxClassType t );
+};
+
+
+#ifndef __SB_SBOBJMODULEREF_HXX
+#define __SB_SBOBJMODULEREF_HXX
+
+SV_DECL_IMPL_REF(SbObjModule);
+
+#endif
+#endif
+
diff --git a/basic/inc/basic/sbprop.hxx b/basic/inc/basic/sbprop.hxx
new file mode 100644
index 000000000000..60cd9e5353c0
--- /dev/null
+++ b/basic/inc/basic/sbprop.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SB_SBPROPERTY_HXX
+#define _SB_SBPROPERTY_HXX
+
+#include <basic/sbxprop.hxx>
+#include <basic/sbdef.hxx>
+
+class SbModule;
+
+class SbProperty : public SbxProperty
+{
+ friend class SbiFactory;
+ friend class SbModule;
+ friend class SbProcedureProperty;
+ SbModule* pMod;
+ BOOL bInvalid;
+ SbProperty( const String&, SbxDataType, SbModule* );
+ virtual ~SbProperty();
+public:
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_BASICPROP,1);
+ TYPEINFO();
+ SbModule* GetModule() { return pMod; }
+};
+
+#ifndef __SB_SBPROPERTYREF_HXX
+#define __SB_SBPROPERTYREF_HXX
+SV_DECL_IMPL_REF(SbProperty)
+#endif
+
+class SbProcedureProperty : public SbxProperty
+{
+ bool mbSet; // Flag for set command
+
+ virtual ~SbProcedureProperty();
+
+public:
+ SbProcedureProperty( const String& r, SbxDataType t )
+ : SbxProperty( r, t ) // , pMod( p )
+ , mbSet( false )
+ {}
+ TYPEINFO();
+
+ bool isSet( void )
+ { return mbSet; }
+ void setSet( bool bSet )
+ { mbSet = bSet; }
+};
+
+#ifndef __SB_SBPROCEDUREPROPERTYREF_HXX
+#define __SB_SBPROCEDUREPROPERTYREF_HXX
+SV_DECL_IMPL_REF(SbProcedureProperty)
+#endif
+
+#endif
diff --git a/basic/inc/basic/sbstar.hxx b/basic/inc/basic/sbstar.hxx
new file mode 100644
index 000000000000..a234dc206ec7
--- /dev/null
+++ b/basic/inc/basic/sbstar.hxx
@@ -0,0 +1,220 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SB_SBSTAR_HXX
+#define _SB_SBSTAR_HXX
+
+#include <basic/sbx.hxx>
+#include <basic/sbxobj.hxx>
+#ifndef _RTL_USTRING_HXX
+#include <rtl/ustring.hxx>
+#endif
+#include <osl/mutex.hxx>
+
+#include <basic/sbdef.hxx>
+#include <basic/sberrors.hxx>
+#include <com/sun/star/script/ModuleInfo.hpp>
+
+class SbModule; // completed module
+class SbiInstance; // runtime instance
+class SbiRuntime; // currently running procedure
+class SbiImage; // compiled image
+class BasicLibInfo; // info block for basic manager
+class SbiBreakpoints;
+class SbTextPortions;
+class SbMethod;
+class BasicManager;
+
+class StarBASICImpl;
+
+class StarBASIC : public SbxObject
+{
+ friend class SbiScanner;
+ friend class SbiExpression; // Access to RTL
+ friend class SbiInstance;
+ friend class SbiRuntime;
+
+ StarBASICImpl* mpStarBASICImpl;
+
+ SbxArrayRef pModules; // List of all modules
+ SbxObjectRef pRtl; // Runtime Library
+ SbxArrayRef xUnoListeners; // Listener handled by CreateUnoListener
+
+ // Handler-Support:
+ Link aErrorHdl; // Error handler
+ Link aBreakHdl; // Breakpoint handler
+ BOOL bNoRtl; // if TRUE: do not search RTL
+ BOOL bBreak; // if TRUE: Break, otherwise Step
+ BOOL bDocBasic;
+ BOOL bVBAEnabled;
+ BasicLibInfo* pLibInfo; // Info block for basic manager
+ SbLanguageMode eLanguageMode; // LanguageMode of the basic object
+ BOOL bQuit;
+
+ SbxObjectRef pVBAGlobals;
+ SbxObject* getVBAGlobals( );
+
+protected:
+ BOOL CError( SbError, const String&, xub_StrLen, xub_StrLen, xub_StrLen );
+private:
+ BOOL RTError( SbError, xub_StrLen, xub_StrLen, xub_StrLen );
+ BOOL RTError( SbError, const String& rMsg, xub_StrLen, xub_StrLen, xub_StrLen );
+ USHORT BreakPoint( xub_StrLen nLine, xub_StrLen nCol1, xub_StrLen nCol2 );
+ USHORT StepPoint( xub_StrLen nLine, xub_StrLen nCol1, xub_StrLen nCol2 );
+ virtual BOOL LoadData( SvStream&, USHORT );
+ virtual BOOL StoreData( SvStream& ) const;
+
+protected:
+
+ virtual BOOL ErrorHdl();
+ virtual USHORT BreakHdl();
+ virtual ~StarBASIC();
+
+public:
+
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_BASIC,1);
+ TYPEINFO();
+
+ StarBASIC( StarBASIC* pParent = NULL, BOOL bIsDocBasic = FALSE );
+
+ // #51727 SetModified overridden so that the Modfied-State is
+ // not delivered to Parent.
+ virtual void SetModified( BOOL );
+
+ void* operator new( size_t );
+ void operator delete( void* );
+
+ virtual void Insert( SbxVariable* );
+ using SbxObject::Remove;
+ virtual void Remove( SbxVariable* );
+ virtual void Clear();
+
+ BasicLibInfo* GetLibInfo() { return pLibInfo; }
+ void SetLibInfo( BasicLibInfo* p ) { pLibInfo = p; }
+
+ // Compiler-Interface
+ SbModule* MakeModule( const String& rName, const String& rSrc );
+ SbModule* MakeModule32( const String& rName, const ::rtl::OUString& rSrc );
+ SbModule* MakeModule32( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, const ::rtl::OUString& rSrc );
+ BOOL Compile( SbModule* );
+ BOOL Disassemble( SbModule*, String& rText );
+ static void Stop();
+ static void Error( SbError );
+ static void Error( SbError, const String& rMsg );
+ static void FatalError( SbError );
+ static void FatalError( SbError, const String& rMsg );
+ static BOOL IsRunning();
+ static SbError GetErrBasic();
+ // #66536 make additional message accessible by RTL function Error
+ static String GetErrorMsg();
+ static xub_StrLen GetErl();
+ // Highlighting
+ void Highlight( const String& rSrc, SbTextPortions& rList );
+
+ virtual SbxVariable* Find( const String&, SbxClassType );
+ virtual BOOL Call( const String&, SbxArray* = NULL );
+
+ SbxArray* GetModules() { return pModules; }
+ SbxObject* GetRtl() { return pRtl; }
+ SbModule* FindModule( const String& );
+ // Run init code of all modules (including the inserted Doc-Basics)
+ void InitAllModules( StarBASIC* pBasicNotToInit = NULL );
+ void DeInitAllModules( void );
+ void ClearAllModuleVars( void );
+ void ActivateObject( const String*, BOOL );
+ BOOL LoadOldModules( SvStream& );
+
+ // #43011 For TestTool; deletes global vars
+ void ClearGlobalVars( void );
+
+ // Calls for error and break handler
+ static USHORT GetLine();
+ static USHORT GetCol1();
+ static USHORT GetCol2();
+ static void SetErrorData( SbError nCode, USHORT nLine,
+ USHORT nCol1, USHORT nCol2 );
+
+ // Specific to error handler
+ static void MakeErrorText( SbError, const String& aMsg );
+ static const String& GetErrorText();
+ static SbError GetErrorCode();
+ static BOOL IsCompilerError();
+ static USHORT GetVBErrorCode( SbError nError );
+ static SbError GetSfxFromVBError( USHORT nError );
+ static void SetGlobalLanguageMode( SbLanguageMode eLangMode );
+ static SbLanguageMode GetGlobalLanguageMode();
+ // Local settings
+ void SetLanguageMode( SbLanguageMode eLangMode )
+ { eLanguageMode = eLangMode; }
+ SbLanguageMode GetLanguageMode();
+
+ // Specific for break handler
+ BOOL IsBreak() const { return bBreak; }
+
+ static Link GetGlobalErrorHdl();
+ static void SetGlobalErrorHdl( const Link& rNewHdl );
+ Link GetErrorHdl() const { return aErrorHdl; }
+ void SetErrorHdl( const Link& r ) { aErrorHdl = r; }
+
+ static Link GetGlobalBreakHdl();
+ static void SetGlobalBreakHdl( const Link& rNewHdl );
+ Link GetBreakHdl() const { return aBreakHdl; }
+ void SetBreakHdl( const Link& r ) { aBreakHdl = r; }
+
+ SbxArrayRef getUnoListeners( void );
+
+ static SbxBase* FindSBXInCurrentScope( const String& rName );
+ static SbxVariable* FindVarInCurrentScopy
+ ( const String& rName, USHORT& rStatus );
+ static SbMethod* GetActiveMethod( USHORT nLevel = 0 );
+ static SbModule* GetActiveModule();
+ void SetVBAEnabled( BOOL bEnabled );
+ BOOL isVBAEnabled();
+
+ // #60175 TRUE: SFX-Resource is not displayed on basic errors
+ static void StaticSuppressSfxResource( BOOL bSuppress );
+
+ // #91147 TRUE: Reschedule is enabled (default>, FALSE: No reschedule
+ static void StaticEnableReschedule( BOOL bReschedule );
+
+ SbxObjectRef getRTL( void ) { return pRtl; }
+ BOOL IsDocBasic() { return bDocBasic; }
+ SbxVariable* VBAFind( const String& rName, SbxClassType t );
+ bool GetUNOConstant( const sal_Char* _pAsciiName, ::com::sun::star::uno::Any& aOut );
+ void QuitAndExitApplication();
+ BOOL IsQuitApplication() { return bQuit; };
+};
+
+#ifndef __SB_SBSTARBASICREF_HXX
+#define __SB_SBSTARBASICREF_HXX
+
+SV_DECL_IMPL_REF(StarBASIC)
+
+#endif
+
+#endif
+
diff --git a/basic/inc/basic/sbstdobj.hxx b/basic/inc/basic/sbstdobj.hxx
new file mode 100644
index 000000000000..5cc76c8bd9c3
--- /dev/null
+++ b/basic/inc/basic/sbstdobj.hxx
@@ -0,0 +1,145 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBSTDOBJ1_HXX
+#define _SBSTDOBJ1_HXX
+
+#include <basic/sbxobj.hxx>
+#ifndef _GRAPH_HXX //autogen
+#include <vcl/graph.hxx>
+#endif
+#include <basic/sbxfac.hxx>
+class StarBASIC;
+class SbStdFactory;
+
+//--------------------
+// class SbStdFactory
+//--------------------
+class SbStdFactory : public SbxFactory
+{
+public:
+ SbStdFactory();
+
+ virtual SbxObject* CreateObject( const String& rClassName );
+};
+
+//--------------------
+// class SbStdPicture
+//--------------------
+class SbStdPicture : public SbxObject
+{
+protected:
+ Graphic aGraphic;
+
+ ~SbStdPicture();
+ virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType );
+
+ void PropType( SbxVariable* pVar, SbxArray* pPar, BOOL bWrite );
+ void PropWidth( SbxVariable* pVar, SbxArray* pPar, BOOL bWrite );
+ void PropHeight( SbxVariable* pVar, SbxArray* pPar, BOOL bWrite );
+
+public:
+ TYPEINFO();
+
+ SbStdPicture();
+ virtual SbxVariable* Find( const String&, SbxClassType );
+
+ Graphic GetGraphic() const { return aGraphic; }
+ void SetGraphic( const Graphic& rGrf ) { aGraphic = rGrf; }
+};
+
+//-----------------
+// class SbStdFont
+//-----------------
+class SbStdFont : public SbxObject
+{
+protected:
+ BOOL bBold;
+ BOOL bItalic;
+ BOOL bStrikeThrough;
+ BOOL bUnderline;
+ USHORT nSize;
+ String aName;
+
+ ~SbStdFont();
+ virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType );
+
+ void PropBold( SbxVariable* pVar, SbxArray* pPar, BOOL bWrite );
+ void PropItalic( SbxVariable* pVar, SbxArray* pPar, BOOL bWrite );
+ void PropStrikeThrough( SbxVariable* pVar, SbxArray* pPar, BOOL bWrite );
+ void PropUnderline( SbxVariable* pVar, SbxArray* pPar, BOOL bWrite );
+ void PropSize( SbxVariable* pVar, SbxArray* pPar, BOOL bWrite );
+ void PropName( SbxVariable* pVar, SbxArray* pPar, BOOL bWrite );
+
+public:
+ TYPEINFO();
+
+ SbStdFont();
+ virtual SbxVariable* Find( const String&, SbxClassType );
+
+ void SetBold( BOOL bB ) { bBold = bB; }
+ BOOL IsBold() const { return bBold; }
+ void SetItalic( BOOL bI ) { bItalic = bI; }
+ BOOL IsItalic() const { return bItalic; }
+ void SetStrikeThrough( BOOL bS ) { bStrikeThrough = bS; }
+ BOOL IsStrikeThrough() const { return bStrikeThrough; }
+ void SetUnderline( BOOL bU ) { bUnderline = bU; }
+ BOOL IsUnderline() const { return bUnderline; }
+ void SetSize( USHORT nS ) { nSize = nS; }
+ USHORT GetSize() const { return nSize; }
+ void SetFontName( const String& rName ) { aName = rName; }
+ String GetFontName() const { return aName; }
+};
+
+//----------------------
+// class SbStdClipboard
+//----------------------
+class SbStdClipboard : public SbxObject
+{
+protected:
+
+ ~SbStdClipboard();
+ virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType );
+
+ void MethClear( SbxVariable* pVar, SbxArray* pPar_, BOOL bWrite );
+ void MethGetData( SbxVariable* pVar, SbxArray* pPar_, BOOL bWrite );
+ void MethGetFormat( SbxVariable* pVar, SbxArray* pPar_, BOOL bWrite );
+ void MethGetText( SbxVariable* pVar, SbxArray* pPar_, BOOL bWrite );
+ void MethSetData( SbxVariable* pVar, SbxArray* pPar_, BOOL bWrite );
+ void MethSetText( SbxVariable* pVar, SbxArray* pPar_, BOOL bWrite );
+
+public:
+ TYPEINFO();
+
+ SbStdClipboard();
+ virtual SbxVariable* Find( const String&, SbxClassType );
+};
+
+#endif
diff --git a/basic/inc/basic/sbuno.hxx b/basic/inc/basic/sbuno.hxx
new file mode 100644
index 000000000000..d816d424313b
--- /dev/null
+++ b/basic/inc/basic/sbuno.hxx
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SB_SBUNO_HXX
+#define _SB_SBUNO_HXX
+
+#include <basic/sbxobj.hxx>
+
+namespace com { namespace sun { namespace star { namespace uno { class Any; }}}}
+
+// Returns a SbxObject that wrapps an Uno Interface
+// Implementation in basic/source/classes/sbunoobj.cxx
+SbxObjectRef GetSbUnoObject( const String& aName, const com::sun::star::uno::Any& aUnoObj_ );
+
+// Force creation of all properties for debugging
+void createAllObjectProperties( SbxObject* pObj );
+
+::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar );
+
+void unoToSbxValue( SbxVariable* pVar, const ::com::sun::star::uno::Any& aValue );
+
+#endif
+
diff --git a/basic/inc/basic/sbx.hxx b/basic/inc/basic/sbx.hxx
new file mode 100644
index 000000000000..2eb194708739
--- /dev/null
+++ b/basic/inc/basic/sbx.hxx
@@ -0,0 +1,369 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBXCLASS_HXX
+#define _SBXCLASS_HXX
+
+#include "tools/ref.hxx"
+#include "svl/svarray.hxx"
+#include "svl/smplhint.hxx"
+#include "svl/lstner.hxx"
+#include <basic/sbxdef.hxx>
+#include <basic/sbxform.hxx>
+
+#ifndef __SBX_SBXOBJECT_HXX
+#include <basic/sbxobj.hxx>
+#endif
+#include <basic/sbxprop.hxx>
+#include <basic/sbxmeth.hxx>
+
+class BigInt;
+class String;
+class UniString;
+class SvStream;
+class SbxBase;
+class SbxVariable;
+class SbxProperty;
+class SbxMethod;
+class SbxObject;
+class SbxArray;
+class SbxDimArray;
+class SbxFactory;
+struct SbxINT64;
+struct SbxUINT64;
+
+class SfxBroadcaster;
+class SvDispatch;
+
+///////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __SBX_SBXPARAMINFO
+#define __SBX_SBXPARAMINFO
+
+// Parameter information
+struct SbxParamInfo
+{
+ const String aName; // Name of the parameter
+ SbxBaseRef aTypeRef; // Object, if object type
+ SbxDataType eType; // Data type
+ UINT16 nFlags; // Flag-Bits
+ UINT32 nUserData; // IDs etc.
+ SbxParamInfo( const String& s, SbxDataType t, USHORT n, SbxBase* b = NULL )
+ : aName( s ), aTypeRef( b ), eType( t ), nFlags( n ), nUserData( 0 ) {}
+ ~SbxParamInfo() {}
+};
+
+//#if 0 // _SOLAR__PRIVATE
+SV_DECL_PTRARR_DEL(SbxParams,SbxParamInfo*,4,4)
+//#else
+//typedef SvPtrarr SbxParams;
+//#endif
+
+#endif
+
+#ifndef __SBX_SBXINFO
+#define __SBX_SBXINFO
+
+class SbxInfo : public SvRefBase
+{
+ friend class SbxVariable;
+ friend class SbMethod;
+
+ String aComment;
+ String aHelpFile;
+ UINT32 nHelpId;
+ SbxParams aParams;
+
+protected:
+ BOOL LoadData( SvStream&, USHORT );
+ BOOL StoreData( SvStream& ) const;
+ virtual ~SbxInfo();
+public:
+ SbxInfo();
+ SbxInfo( const String&, UINT32 );
+
+ void AddParam( const String&, SbxDataType, USHORT=SBX_READ );
+ void AddParam( const SbxParamInfo& );
+ const SbxParamInfo* GetParam( USHORT n ) const; // index starts with 1!
+ const String& GetComment() const { return aComment; }
+ const String& GetHelpFile() const { return aHelpFile; }
+ UINT32 GetHelpId() const { return nHelpId; }
+
+ void SetComment( const String& r ) { aComment = r; }
+ void SetHelpFile( const String& r ) { aHelpFile = r; }
+ void SetHelpId( UINT32 nId ) { nHelpId = nId; }
+};
+
+#endif
+
+#ifndef __SBX_SBXHINT_HXX
+#define __SBX_SBXHINT_HXX
+
+class SbxHint : public SfxSimpleHint
+{
+ SbxVariable* pVar;
+public:
+ TYPEINFO();
+ SbxHint( ULONG n, SbxVariable* v ) : SfxSimpleHint( n ), pVar( v ) {}
+ SbxVariable* GetVar() const { return pVar; }
+};
+
+#endif
+
+#ifndef __SBX_SBXALIAS_HXX
+#define __SBX_SBXALIAS_HXX
+
+// SbxAlias is an alias for a var or object
+class SbxAlias : public SbxVariable, public SfxListener
+{
+ SbxVariableRef xAlias;
+ virtual ~SbxAlias();
+ virtual void Broadcast( ULONG );
+ virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType );
+public:
+ SbxAlias( const String& rName, SbxVariable* pOriginal );
+ SbxAlias( const SbxAlias& );
+ SbxAlias& operator=( const SbxAlias& );
+};
+
+#endif
+
+#ifndef __SBX_SBXARRAY
+#define __SBX_SBXARRAY
+
+// SbxArray ist ein eindimensionales, dynamisches Array
+// von SbxVariablen. Put()/Insert() konvertieren die Variablen in den
+// angegebenen Datentyp, falls er nicht SbxVARIANT ist.
+
+class SbxVarRefs;
+class SbxVariableRef;
+
+class SbxArrayImpl;
+
+class SbxArray : public SbxBase
+{
+// #100883 Method to set method directly to parameter array
+ friend class SbMethod;
+ friend class SbClassModuleObject;
+ friend SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj );
+ void PutDirect( SbxVariable* pVar, UINT32 nIdx );
+
+ SbxArrayImpl* mpSbxArrayImpl; // Impl data
+ SbxVarRefs* pData; // The variables
+
+protected:
+ SbxDataType eType; // Data type of the array
+ virtual ~SbxArray();
+ virtual BOOL LoadData( SvStream&, USHORT );
+ virtual BOOL StoreData( SvStream& ) const;
+
+public:
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_ARRAY,1);
+ TYPEINFO();
+ SbxArray( SbxDataType=SbxVARIANT );
+ SbxArray( const SbxArray& );
+ SbxArray& operator=( const SbxArray& );
+ virtual void Clear();
+ USHORT Count() const;
+ virtual SbxDataType GetType() const;
+ virtual SbxClassType GetClass() const;
+ SbxVariableRef& GetRef( USHORT );
+ SbxVariable* Get( USHORT );
+ void Put( SbxVariable*, USHORT );
+ void Insert( SbxVariable*, USHORT );
+ void Remove( USHORT );
+ void Remove( SbxVariable* );
+ void Merge( SbxArray* );
+ const String& GetAlias( USHORT );
+ void PutAlias( const String&, USHORT );
+ SbxVariable* FindUserData( UINT32 nUserData );
+ virtual SbxVariable* Find( const String&, SbxClassType );
+
+ // Additional methods for 32-bit indices
+ UINT32 Count32() const;
+ SbxVariableRef& GetRef32( UINT32 );
+ SbxVariable* Get32( UINT32 );
+ void Put32( SbxVariable*, UINT32 );
+ void Insert32( SbxVariable*, UINT32 );
+ void Remove32( UINT32 );
+};
+
+#endif
+
+#ifndef __SBX_SBXDIMARRAY_HXX
+#define __SBX_SBXDIMARRAY_HXX
+
+// SbxDimArray is an array that can dimensioned using BASIC conventions.
+struct SbxDim;
+
+class SbxDimArrayImpl;
+
+class SbxDimArray : public SbxArray
+{
+ SbxDimArrayImpl* mpSbxDimArrayImpl; // Impl data
+
+ SbxDim* pFirst, *pLast; // Links to Dimension table
+ short nDim; // Number of dimensions
+ void AddDimImpl32( INT32, INT32, BOOL bAllowSize0 );
+ bool mbHasFixedSize;
+protected:
+ USHORT Offset( const short* );
+ UINT32 Offset32( const INT32* );
+ USHORT Offset( SbxArray* );
+ UINT32 Offset32( SbxArray* );
+ virtual BOOL LoadData( SvStream&, USHORT );
+ virtual BOOL StoreData( SvStream& ) const;
+ virtual ~SbxDimArray();
+public:
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_DIMARRAY,1);
+ TYPEINFO();
+ SbxDimArray( SbxDataType=SbxVARIANT );
+ SbxDimArray( const SbxDimArray& );
+ SbxDimArray& operator=( const SbxDimArray& );
+ virtual void Clear();
+ using SbxArray::GetRef;
+ SbxVariableRef& GetRef( const short* );
+ using SbxArray::Get;
+ SbxVariable* Get( const short* );
+ using SbxArray::Put;
+ void Put( SbxVariable*, const short* );
+ SbxVariableRef& GetRef( SbxArray* );
+ SbxVariable* Get( SbxArray* );
+ void Put( SbxVariable*, SbxArray* );
+
+ short GetDims() const { return nDim; }
+ void AddDim( short, short );
+ void unoAddDim( short, short );
+ BOOL GetDim( short, short&, short& ) const;
+
+ using SbxArray::GetRef32;
+ SbxVariableRef& GetRef32( const INT32* );
+ using SbxArray::Get32;
+ SbxVariable* Get32( const INT32* );
+ using SbxArray::Put32;
+ void Put32( SbxVariable*, const INT32* );
+ void AddDim32( INT32, INT32 );
+ void unoAddDim32( INT32, INT32 );
+ BOOL GetDim32( INT32, INT32&, INT32& ) const;
+ bool hasFixedSize() { return mbHasFixedSize; };
+ void setHasFixedSize( bool bHasFixedSize ) {mbHasFixedSize = bHasFixedSize; };
+};
+
+#endif
+
+#ifndef __SBX_SBXCOLLECTION_HXX
+#define __SBX_SBXCOLLECTION_HXX
+
+class SbxCollection : public SbxObject
+{
+ void Initialize();
+protected:
+ virtual ~SbxCollection();
+ virtual BOOL LoadData( SvStream&, USHORT );
+ virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType );
+ // Overridable methods (why not pure virtual?):
+ virtual void CollAdd( SbxArray* pPar );
+ virtual void CollItem( SbxArray* pPar );
+ virtual void CollRemove( SbxArray* pPar );
+
+public:
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_COLLECTION,1);
+ TYPEINFO();
+ SbxCollection( const String& rClassname );
+ SbxCollection( const SbxCollection& );
+ SbxCollection& operator=( const SbxCollection& );
+ virtual SbxVariable* FindUserData( UINT32 nUserData );
+ virtual SbxVariable* Find( const String&, SbxClassType );
+ virtual void Clear();
+};
+
+#endif
+
+#ifndef __SBX_SBXSTDCOLLECTION_HXX
+#define __SBX_SBXSTDCOLLECTION_HXX
+
+class SbxStdCollection : public SbxCollection
+{
+protected:
+ String aElemClass;
+ BOOL bAddRemoveOk;
+ virtual ~SbxStdCollection();
+ virtual BOOL LoadData( SvStream&, USHORT );
+ virtual BOOL StoreData( SvStream& ) const;
+ virtual void CollAdd( SbxArray* pPar );
+ virtual void CollRemove( SbxArray* pPar );
+public:
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_FIXCOLLECTION,1);
+ TYPEINFO();
+ SbxStdCollection
+ ( const String& rClassname, const String& rElemClass, BOOL=TRUE );
+ SbxStdCollection( const SbxStdCollection& );
+ SbxStdCollection& operator=( const SbxStdCollection& );
+ virtual void Insert( SbxVariable* );
+ const String& GetElementClass() const { return aElemClass; }
+};
+
+#endif
+
+#ifndef __SBX_SBXREFS_HXX
+#define __SBX_SBXREFS_HXX
+
+SV_IMPL_REF(SbxBase)
+
+SV_IMPL_REF(SbxVariable)
+
+#ifndef SBX_ARRAY_DECL_DEFINED
+#define SBX_ARRAY_DECL_DEFINED
+SV_DECL_REF(SbxArray)
+#endif
+#ifndef SBX_ARRAY_IMPL_DEFINED
+#define SBX_ARRAY_IMPL_DEFINED
+SV_IMPL_REF(SbxArray)
+#endif
+
+#ifndef SBX_INFO_DECL_DEFINED
+#define SBX_INFO_DECL_DEFINED
+SV_DECL_REF(SbxInfo)
+#endif
+#ifndef SBX_INFO_IMPL_DEFINED
+#define SBX_INFO_IMPL_DEFINED
+SV_IMPL_REF(SbxInfo)
+#endif
+
+#ifndef SBX_DIMARRAY_DECL_DEFINED
+#define SBX_DIMARRAY_DECL_DEFINED
+SV_DECL_REF(SbxDimArray)
+#endif
+SV_IMPL_REF(SbxDimArray)
+
+#endif
+
+#endif
diff --git a/basic/inc/basic/sbxbase.hxx b/basic/inc/basic/sbxbase.hxx
new file mode 100644
index 000000000000..0812b2622828
--- /dev/null
+++ b/basic/inc/basic/sbxbase.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBXBASE_HXX
+#define _SBXBASE_HXX
+
+#include <i18npool/lang.h>
+#include "tools/list.hxx"
+#include "svl/svarray.hxx"
+#include <basic/sbxdef.hxx>
+
+class SbxFactory;
+class SbxVariable;
+class SbxBasicFormater;
+
+SV_DECL_PTRARR_DEL(SbxFacs,SbxFactory*,5,5)
+DECLARE_LIST(SbxVarList_Impl, SbxVariable*)
+
+// AppData-Struktur for SBX:
+struct SbxAppData
+{
+ SbxError eSbxError; // Error code
+ SbxFacs aFacs; // Factories
+ SbxVarList_Impl aVars; // for Dump
+ SbxBasicFormater *pBasicFormater; // Pointer to Format()-Command helper class
+
+ LanguageType eBasicFormaterLangType;
+ // It might be useful to store this class 'global' because some string reosurces are saved here
+
+ SbxAppData() : eSbxError( SbxERR_OK ), aFacs(), pBasicFormater( NULL ) {}
+ ~SbxAppData();
+};
+
+SbxAppData* GetSbxData_Impl();
+
+#endif
diff --git a/basic/inc/basic/sbxcore.hxx b/basic/inc/basic/sbxcore.hxx
new file mode 100644
index 000000000000..83e474521cc2
--- /dev/null
+++ b/basic/inc/basic/sbxcore.hxx
@@ -0,0 +1,181 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBXCORE_HXX
+#define _SBXCORE_HXX
+
+#include <tools/rtti.hxx>
+#include <tools/ref.hxx>
+#include <tools/debug.hxx>
+
+#include <basic/sbxdef.hxx>
+
+class SvStream;
+class String;
+class UniString;
+
+// The following Macro defines four (five) necessary methods within a
+// SBX object. LoadPrivateData() and StorePrivateData() must be implemented.
+// They are necessary for loading/storing the data of derived classes.
+// Load() and Store() must not be overridden.
+
+// This version of the Macros does not define Load/StorePrivateData()-methods
+#define SBX_DECL_PERSIST_NODATA( nCre, nSbxId, nVer ) \
+ virtual UINT32 GetCreator() const { return nCre; } \
+ virtual UINT16 GetVersion() const { return nVer; } \
+ virtual UINT16 GetSbxId() const { return nSbxId; }
+
+#define SBX_DECL_PERSIST_NODATA_() \
+ virtual UINT32 GetCreator() const; \
+ virtual UINT16 GetVersion() const; \
+ virtual UINT16 GetSbxId() const;
+
+// This version of the macro defines Load/StorePrivateData()-methods
+#define SBX_DECL_PERSIST( nCre, nSbxId, nVer ) \
+ virtual BOOL LoadPrivateData( SvStream&, USHORT ); \
+ virtual BOOL StorePrivateData( SvStream& ) const; \
+ SBX_DECL_PERSIST_NODATA( nCre, nSbxId, nVer )
+
+#define SBX_DECL_PERSIST_() \
+ virtual BOOL LoadPrivateData( SvStream&, USHORT ); \
+ virtual BOOL StorePrivateData( SvStream& ) const; \
+ SBX_DECL_PERSIST_NODATA_()
+
+#define SBX_IMPL_PERSIST( C, nCre, nSbxId, nVer ) \
+ UINT32 C::GetCreator() const { return nCre; } \
+ UINT16 C::GetVersion() const { return nVer; } \
+ UINT16 C::GetSbxId() const { return nSbxId; }
+
+class SbxBase;
+class SbxFactory;
+class SbxObject;
+
+DBG_NAMEEX(SbxBase)
+
+class SbxBaseImpl;
+
+class SbxBase : virtual public SvRefBase
+{
+ SbxBaseImpl* mpSbxBaseImpl; // Impl data
+
+ virtual BOOL LoadData( SvStream&, USHORT );
+ virtual BOOL StoreData( SvStream& ) const;
+protected:
+ USHORT nFlags; // Flag-Bits
+
+ SbxBase();
+ SbxBase( const SbxBase& );
+ SbxBase& operator=( const SbxBase& );
+ virtual ~SbxBase();
+ SBX_DECL_PERSIST(0,0,0);
+public:
+ TYPEINFO();
+ inline void SetFlags( USHORT n );
+ inline USHORT GetFlags() const;
+ inline void SetFlag( USHORT n );
+ inline void ResetFlag( USHORT n );
+ inline BOOL IsSet( USHORT n ) const;
+ inline BOOL IsReset( USHORT n ) const;
+ inline BOOL CanRead() const;
+ inline BOOL CanWrite() const;
+ inline BOOL IsModified() const;
+ inline BOOL IsConst() const;
+ inline BOOL IsHidden() const;
+ inline BOOL IsVisible() const;
+
+ virtual BOOL IsFixed() const;
+ virtual void SetModified( BOOL );
+
+ virtual SbxDataType GetType() const;
+ virtual SbxClassType GetClass() const;
+
+ virtual void Clear();
+
+ static SbxBase* Load( SvStream& );
+ static void Skip( SvStream& );
+ BOOL Store( SvStream& );
+ virtual BOOL LoadCompleted();
+ virtual BOOL StoreCompleted();
+
+ static SbxError GetError();
+ static void SetError( SbxError );
+ static BOOL IsError();
+ static void ResetError();
+
+ // Set the factory for Load/Store/Create
+ static void AddFactory( SbxFactory* );
+ static void RemoveFactory( SbxFactory* );
+
+ static SbxBase* Create( UINT16, UINT32=SBXCR_SBX );
+ static SbxObject* CreateObject( const String& );
+ // Sbx solution as replacement for SfxBroadcaster::Enable()
+ static void StaticEnableBroadcasting( BOOL bEnable );
+ static BOOL StaticIsEnabledBroadcasting( void );
+};
+
+#ifndef SBX_BASE_DECL_DEFINED
+#define SBX_BASE_DECL_DEFINED
+SV_DECL_REF(SbxBase)
+#endif
+
+inline void SbxBase::SetFlags( USHORT n )
+{ DBG_CHKTHIS( SbxBase, 0 ); nFlags = n; }
+
+inline USHORT SbxBase::GetFlags() const
+{ DBG_CHKTHIS( SbxBase, 0 ); return nFlags; }
+
+inline void SbxBase::SetFlag( USHORT n )
+{ DBG_CHKTHIS( SbxBase, 0 ); nFlags |= n; }
+
+inline void SbxBase::ResetFlag( USHORT n )
+{ DBG_CHKTHIS( SbxBase, 0 ); nFlags &= ~n; }
+
+inline BOOL SbxBase::IsSet( USHORT n ) const
+{ DBG_CHKTHIS( SbxBase, 0 ); return BOOL( ( nFlags & n ) != 0 ); }
+
+inline BOOL SbxBase::IsReset( USHORT n ) const
+{ DBG_CHKTHIS( SbxBase, 0 ); return BOOL( ( nFlags & n ) == 0 ); }
+
+inline BOOL SbxBase::CanRead() const
+{ DBG_CHKTHIS( SbxBase, 0 ); return IsSet( SBX_READ ); }
+
+inline BOOL SbxBase::CanWrite() const
+{ DBG_CHKTHIS( SbxBase, 0 ); return IsSet( SBX_WRITE ); }
+
+inline BOOL SbxBase::IsModified() const
+{ DBG_CHKTHIS( SbxBase, 0 ); return IsSet( SBX_MODIFIED ); }
+
+inline BOOL SbxBase::IsConst() const
+{ DBG_CHKTHIS( SbxBase, 0 ); return IsSet( SBX_CONST ); }
+
+inline BOOL SbxBase::IsHidden() const
+{ DBG_CHKTHIS( SbxBase, 0 ); return IsSet( SBX_HIDDEN ); }
+
+inline BOOL SbxBase::IsVisible() const
+{ DBG_CHKTHIS( SbxBase, 0 ); return IsReset( SBX_INVISIBLE ); }
+
+#endif
diff --git a/basic/inc/basic/sbxdef.hxx b/basic/inc/basic/sbxdef.hxx
new file mode 100644
index 000000000000..89322be776f9
--- /dev/null
+++ b/basic/inc/basic/sbxdef.hxx
@@ -0,0 +1,384 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+
+#ifndef _SBXDEF_HXX
+#define _SBXDEF_HXX
+
+
+#ifndef __RSC
+#ifndef _SOLAR_H
+#include <tools/solar.h>
+#endif
+#include "tools/errcode.hxx"
+
+#ifndef _SBX_CLASS_TYPE
+#define _SBX_CLASS_TYPE
+
+enum SbxClassType { // SBX-class-IDs (order is important!)
+ SbxCLASS_DONTCARE = 1, // don't care (search, not 0 due to StarBASIC)
+ SbxCLASS_ARRAY, // Array of SbxVariables
+ SbxCLASS_VALUE, // simple value
+ SbxCLASS_VARIABLE, // Variable (from here there is Broadcaster)
+ SbxCLASS_METHOD, // Method (Function or Sub)
+ SbxCLASS_PROPERTY, // Property
+ SbxCLASS_OBJECT // Object
+};
+
+#endif
+
+#ifndef _SBX_DATA_TYPE
+#define _SBX_DATA_TYPE
+
+enum SbxDataType {
+ SbxEMPTY = 0, // * Uninitialized
+ SbxNULL = 1, // * Contains no valid data
+ SbxINTEGER = 2, // * Integer (INT16)
+ SbxLONG = 3, // * Long integer (INT32)
+ SbxSINGLE = 4, // * Single-precision floating point number (float)
+ SbxDOUBLE = 5, // * Double-precision floating point number (double)
+ SbxCURRENCY = 6, // Currency (INT64)
+ SbxDATE = 7, // * Date (double)
+ SbxSTRING = 8, // * String (StarView)
+ SbxOBJECT = 9, // * SbxBase object pointer
+ SbxERROR = 10, // * Error (UINT16)
+ SbxBOOL = 11, // * Boolean (0 or -1)
+ SbxVARIANT = 12, // * Anzeige fuer varianten Datentyp
+ SbxDATAOBJECT = 13, // * Common data object w/o ref count
+
+ SbxCHAR = 16, // * signed char
+ SbxBYTE = 17, // * unsigned char
+ SbxUSHORT = 18, // * unsigned short (UINT16)
+ SbxULONG = 19, // * unsigned long (UINT32)
+ SbxLONG64 = 20, // signed 64-bit int
+ SbxULONG64 = 21, // unsigned 64-bit int
+ SbxINT = 22, // * signed machine-dependent int
+ SbxUINT = 23, // * unsigned machine-dependent int
+ SbxVOID = 24, // * no value (= SbxEMPTY)
+ SbxHRESULT = 25, // HRESULT
+ SbxPOINTER = 26, // generic pointer
+ SbxDIMARRAY = 27, // dimensioned array
+ SbxCARRAY = 28, // C style array
+ SbxUSERDEF = 29, // user defined
+ SbxLPSTR = 30, // * null terminated string
+ SbxLPWSTR = 31, // wide null terminated string
+ SbxCoreSTRING = 32, // AB 10.4.97, fuer GetCoreString(), nur zum Konvertieren
+ SbxWSTRING = 33, // AB 4.10.2000 Reimplemented for backwards compatibility (#78919)
+ SbxWCHAR = 34, // AB 4.10.2000 Reimplemented for backwards compatibility (#78919)
+ SbxSALINT64 = 35, // for UNO hyper
+ SbxSALUINT64 = 36, // for UNO unsigned hyper
+ SbxDECIMAL = 37, // for UNO/automation Decimal
+
+ SbxVECTOR = 0x1000, // simple counted array
+ SbxARRAY = 0x2000, // array
+ SbxBYREF = 0x4000, // access by reference
+
+ SbxSV1 = 128, // first defined data type for StarView
+ SbxMEMORYSTREAM, // SvMemoryStream
+ SbxSTORAGE, // SvStorage
+
+ SbxUSER1 = 256, // first user defined data type
+ SbxUSERn = 2047 // last user defined data type
+};
+
+const UINT32 SBX_TYPE_WITH_EVENTS_FLAG = 0x10000;
+const UINT32 SBX_FIXED_LEN_STRING_FLAG = 0x10000; // same value as above as no conflict possible
+
+#endif
+
+#ifndef _SBX_OPERATOR
+#define _SBX_OPERATOR
+
+enum SbxOperator {
+ // Arithmetical:
+ SbxEXP, // this ^ var
+ SbxMUL, // this * var
+ SbxDIV, // this / var
+ SbxMOD, // this MOD var
+ SbxPLUS, // this + var
+ SbxMINUS, // this - var
+ SbxNEG, // -this (var is ignored)
+ SbxIDIV, // this / var (both operands max. INT32!)
+ // Boolean operators (max INT32!):
+ SbxAND, // this & var
+ SbxOR, // this | var
+ SbxXOR, // this ^ var
+ SbxEQV, // ~this ^ var
+ SbxIMP, // ~this | var
+ SbxNOT, // ~this (var is ignored)
+ // String-concat:
+ SbxCAT, // this & var
+ // Comparisons:
+ SbxEQ, // this = var
+ SbxNE, // this <> var
+ SbxLT, // this < var
+ SbxGT, // this > var
+ SbxLE, // this <= var
+ SbxGE // this >= var
+};
+
+#endif
+
+#ifndef _SBX_NAME_TYPE
+#define _SBX_NAME_TYPE
+
+enum SbxNameType { // Type of the questioned name of a variable
+ SbxNAME_NONE, // plain name
+ SbxNAME_SHORT, // Name(A,B)
+ SbxNAME_SHORT_TYPES, // Name%(A%,B$)
+ SbxNAME_LONG_TYPES // Name(A As Integer, B As String) As Integer
+};
+
+#endif
+
+// AB: 20.3.96: New error messages
+typedef ULONG SbxError; // Preserve old type
+
+#endif
+// von #ifndef __RSC
+
+
+// New error codes per define
+#define ERRCODE_SBX_OK ERRCODE_NONE // processed
+#define ERRCODE_SBX_SYNTAX (1UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Syntaxerror in parser (where else could syntax errors happen? ;-)
+#define ERRCODE_SBX_NOTIMP (2UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_NOTSUPPORTED) // not possible
+#define ERRCODE_SBX_OVERFLOW (3UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_SBX) // overflow
+#define ERRCODE_SBX_BOUNDS (4UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_SBX) // Invalid array index
+#define ERRCODE_SBX_ZERODIV (5UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_SBX) // Division by zero
+#define ERRCODE_SBX_CONVERSION (6UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_SBX) // wrong data type
+#define ERRCODE_SBX_BAD_PARAMETER (7UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // invalid Parameter
+#define ERRCODE_SBX_PROC_UNDEFINED (8UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // BASIC-Sub or Function undefined
+#define ERRCODE_SBX_ERROR (9UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_UNKNOWN) // other object-related error
+#define ERRCODE_SBX_NO_OBJECT (10UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Object variable unassigned
+#define ERRCODE_SBX_CANNOT_LOAD (11UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_CREATE) // Object cannot be loaded or initialized
+#define ERRCODE_SBX_BAD_INDEX (12UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_SBX) // Invalid object index
+#define ERRCODE_SBX_NO_ACTIVE_OBJECT (13UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_ACCESS) // Object ist not activated
+#define ERRCODE_SBX_BAD_PROP_VALUE (14UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Bad property value
+#define ERRCODE_SBX_PROP_READONLY (15UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_READ) // Property is read only
+#define ERRCODE_SBX_PROP_WRITEONLY (16UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_WRITE) // Property is write only
+#define ERRCODE_SBX_INVALID_OBJECT (17UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_ACCESS) // Invalid object reference
+#define ERRCODE_SBX_NO_METHOD (18UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Property oder Methode unbekannt
+#define ERRCODE_SBX_INVALID_USAGE_OBJECT (19UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_ACCESS) // Invalid object usage
+#define ERRCODE_SBX_NO_OLE (20UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_ACCESS) // No OLE-Object
+#define ERRCODE_SBX_BAD_METHOD (21UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Method not supported
+#define ERRCODE_SBX_OLE_ERROR (22UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // OLE Automation Error
+#define ERRCODE_SBX_BAD_ACTION (23UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_NOTSUPPORTED) // Action not supported
+#define ERRCODE_SBX_NO_NAMED_ARGS (24UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // No named arguments
+#define ERRCODE_SBX_BAD_LOCALE (25UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_NOTSUPPORTED) // Locale settings not supported
+#define ERRCODE_SBX_NAMED_NOT_FOUND (26UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Unknown named argument
+#define ERRCODE_SBX_NOT_OPTIONAL (27UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Argument not optional
+#define ERRCODE_SBX_WRONG_ARGS (28UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_SBX) // Invalid number of arguments
+#define ERRCODE_SBX_NOT_A_COLL (29UL | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_RUNTIME) // Object contains no elements
+#define LAST_SBX_ERROR_ID 29UL
+
+
+// Less important for resources
+#ifndef __RSC
+
+// Map old codes to new ones
+#define SbxERR_OK ERRCODE_SBX_OK
+#define SbxERR_SYNTAX ERRCODE_SBX_SYNTAX
+#define SbxERR_NOTIMP ERRCODE_SBX_NOTIMP
+#define SbxERR_OVERFLOW ERRCODE_SBX_OVERFLOW
+#define SbxERR_BOUNDS ERRCODE_SBX_BOUNDS
+#define SbxERR_ZERODIV ERRCODE_SBX_ZERODIV
+#define SbxERR_CONVERSION ERRCODE_SBX_CONVERSION
+#define SbxERR_BAD_PARAMETER ERRCODE_SBX_BAD_PARAMETER
+#define SbxERR_PROC_UNDEFINED ERRCODE_SBX_PROC_UNDEFINED
+#define SbxERR_ERROR ERRCODE_SBX_ERROR
+#define SbxERR_NO_OBJECT ERRCODE_SBX_NO_OBJECT
+#define SbxERR_CANNOT_LOAD ERRCODE_SBX_CANNOT_LOAD
+#define SbxERR_BAD_INDEX ERRCODE_SBX_BAD_INDEX
+#define SbxERR_NO_ACTIVE_OBJECT ERRCODE_SBX_NO_ACTIVE_OBJECT
+#define SbxERR_BAD_PROP_VALUE ERRCODE_SBX_BAD_PROP_VALUE
+#define SbxERR_PROP_READONLY ERRCODE_SBX_PROP_READONLY
+#define SbxERR_PROP_WRITEONLY ERRCODE_SBX_PROP_WRITEONLY
+#define SbxERR_INVALID_OBJECT ERRCODE_SBX_INVALID_OBJECT
+#define SbxERR_NO_METHOD ERRCODE_SBX_NO_METHOD
+#define SbxERR_INVALID_USAGE_OBJECT ERRCODE_SBX_INVALID_USAGE_OBJECT
+#define SbxERR_NO_OLE ERRCODE_SBX_NO_OLE
+#define SbxERR_BAD_METHOD ERRCODE_SBX_BAD_METHOD
+#define SbxERR_OLE_ERROR ERRCODE_SBX_OLE_ERROR
+#define SbxERR_BAD_ACTION ERRCODE_SBX_BAD_ACTION
+#define SbxERR_NO_NAMED_ARGS ERRCODE_SBX_NO_NAMED_ARGS
+#define SbxERR_BAD_LOCALE ERRCODE_SBX_BAD_LOCALE
+#define SbxERR_NAMED_NOT_FOUND ERRCODE_SBX_NAMED_NOT_FOUND
+#define SbxERR_NOT_OPTIONAL ERRCODE_SBX_NOT_OPTIONAL
+#define SbxERR_WRONG_ARGS ERRCODE_SBX_WRONG_ARGS
+#define SbxERR_NOT_A_COLL ERRCODE_SBX_NOT_A_COLL
+
+
+/* Old codes with VB error codes
+enum SbxError { // Ergebnis einer Rechenoperation/Konversion
+ SbxERR_OK = 0, // durchgefuehrt
+ SbxERR_SYNTAX = 2, // Syntaxfehler im Parser
+ SbxERR_NOTIMP = 5, // nicht moeglich
+ SbxERR_OVERFLOW = 6, // Ueberlauf
+ SbxERR_BOUNDS = 9, // Array-Index ungueltig
+ SbxERR_ZERODIV = 11, // Division durch Null
+ SbxERR_CONVERSION = 13, // falscher Datentyp
+ SbxERR_BAD_PARAMETER = 14, // ungltiger Parameter
+ SbxERR_PROC_UNDEFINED = 35, // BASIC-Sub oder Function undefiniert
+ SbxERR_ERROR = 51, // andere Fehler
+ // Objektbezogene Fehler
+ SbxERR_NO_OBJECT = 91, // Objektvariable nicht belegt
+ SbxERR_CANNOT_LOAD = 323, // Objekt kann nicht geladen/eingerichtet werden
+ SbxERR_BAD_INDEX = 341, // Invalid object index
+ SbxERR_NO_ACTIVE_OBJECT=366,// Objekt ist nicht aktiviert
+ SbxERR_BAD_PROP_VALUE = 380,// Bad property value
+ SbxERR_PROP_READONLY = 382, // Property is read only
+ SbxERR_PROP_WRITEONLY = 394,// Property is write only
+ SbxERR_INVALID_OBJECT = 420,// Invalid object reference
+ SbxERR_NO_METHOD = 423, // Property oder Methode unbekannt
+ SbxERR_INVALID_USAGE_OBJECT=425,// Falsche Verwendung eines Objekts
+ SbxERR_NO_OLE = 430, // Kein OLE-Objekt
+ SbxERR_BAD_METHOD = 438, // Methode nicht untersttzt
+ SbxERR_OLE_ERROR = 440, // OLE Automation-Fehler
+ SbxERR_BAD_ACTION = 445, // Aktion nicht untersttzt
+ SbxERR_NO_NAMED_ARGS = 446, // Keine benannten Argumente
+ SbxERR_BAD_LOCALE = 447, // Laenderspezifische Einstellungen nicht untersttzt
+ SbxERR_NAMED_NOT_FOUND = 448,// Unbekanntes benanntes Argument
+ SbxERR_NOT_OPTIONAL = 449, // Argument nicht optional
+ SbxERR_WRONG_ARGS = 450, // Falsche Zahl von Argumenten
+ SbxERR_NOT_A_COLL = 451 // Objekt enth„lt keine Elemente
+};
+*/
+
+// Flag-Bits:
+#define SBX_READ 0x0001 // Read permission
+#define SBX_WRITE 0x0002 // Write permission
+#define SBX_READWRITE 0x0003 // Read/Write permission
+#define SBX_DONTSTORE 0x0004 // Don't store object
+#define SBX_MODIFIED 0x0008 // Object was changed
+#define SBX_FIXED 0x0010 // Fixed data type (SbxVariable)
+#define SBX_CONST 0x0020 // Definition of const value
+#define SBX_OPTIONAL 0x0040 // Parameter is optional
+#define SBX_HIDDEN 0x0080 // Element is invisible
+#define SBX_INVISIBLE 0x0100 // Element is not found by Find()
+#define SBX_EXTSEARCH 0x0200 // Object is searched completely
+#define SBX_EXTFOUND 0x0400 // Variable was found through extended search
+#define SBX_GBLSEARCH 0x0800 // Global search via Parents
+#define SBX_RESERVED 0x1000 // reserved
+#define SBX_PRIVATE 0x1000 // #110004, #112015, cannot conflict with SBX_RESERVED
+#define SBX_NO_BROADCAST 0x2000 // No broadcast on Get/Put
+#define SBX_REFERENCE 0x4000 // Parameter is Reference (DLL-call)
+#define SBX_NO_MODIFY 0x8000 // SetModified is suppressed
+#define SBX_WITH_EVENTS 0x0080 // Same value as unused SBX_HIDDEN
+
+// Broadcaster-IDs:
+#define SBX_HINT_DYING SFX_HINT_DYING
+#define SBX_HINT_DATAWANTED SFX_HINT_USER00
+#define SBX_HINT_DATACHANGED SFX_HINT_DATACHANGED
+#define SBX_HINT_CONVERTED SFX_HINT_USER01
+#define SBX_HINT_INFOWANTED SFX_HINT_USER02
+#define SBX_HINT_OBJECTCHANGED SFX_HINT_USER03
+
+// List of all creators for Load/Store
+
+#define SBXCR_SBX 0x20584253 // SBX(blank)
+
+// List of predefined SBX-IDs. New SBX-IDs must be precisly defined so that
+// they are unique within the Stream and appropriate Factory.
+
+#define SBXID_VALUE 0x4E4E // NN: SbxValue
+#define SBXID_VARIABLE 0x4156 // VA: SbxVariable
+#define SBXID_ARRAY 0x5241 // AR: SbxArray
+#define SBXID_DIMARRAY 0x4944 // DI: SbxDimArray
+#define SBXID_OBJECT 0x424F // OB: SbxObject
+#define SBXID_COLLECTION 0x4F43 // CO: SbxCollection
+#define SBXID_FIXCOLLECTION 0x4346 // FC: SbxStdCollection
+#define SBXID_METHOD 0x454D // ME: SbxMethod
+#define SBXID_PROPERTY 0x5250 // PR: SbxProperty
+
+// StarBASIC restricts the base data type to different intervals.
+// These intervals are fixed due to portability and independent
+// of the implementation. Only type double is greedy and takes
+// what it gets.
+
+#define SbxMAXCHAR ((sal_Unicode)65535)
+#define SbxMINCHAR (0)
+#define SbxMAXBYTE ( 255)
+#define SbxMAXINT ( 32767)
+#define SbxMININT (-32768)
+#define SbxMAXUINT ((UINT16) 65535)
+#define SbxMAXLNG ( 2147483647)
+#define SbxMINLNG ((INT32)(-2147483647-1))
+#define SbxMAXULNG ((UINT32) 0xffffffff)
+
+#define SbxMAXSALINT64 SAL_MAX_INT64
+#define SbxMINSALINT64 SAL_MIN_INT64
+#define SbxMAXSALUINT64 SAL_MAX_UINT64
+
+#define SbxMAXSNG ( 3.402823e+38)
+#define SbxMINSNG (-3.402823e+38)
+#define SbxMAXSNG2 ( 1.175494351e-38)
+#define SbxMINSNG2 (-1.175494351e-38)
+#define SbxMAXCURR ( 922337203685477.5807)
+#define SbxMINCURR (-922337203685477.5808)
+#define CURRENCY_FACTOR 10000
+#define SbxMAXCURRLNG (SbxMAXLNG/CURRENCY_FACTOR)
+#define SbxMINCURRLNG (SbxMINLNG/CURRENCY_FACTOR)
+
+// Max valid offset index of a Sbx-Array (due to 64K limit)
+#define SBX_MAXINDEX 0x3FF0
+#define SBX_MAXINDEX32 SbxMAXLNG
+
+// The numeric values of TRUE and FALSE
+enum SbxBOOL { SbxFALSE = 0, SbxTRUE = -1 };
+
+#endif // __RSC
+
+#endif
diff --git a/basic/inc/basic/sbxfac.hxx b/basic/inc/basic/sbxfac.hxx
new file mode 100644
index 000000000000..f72cebd8d979
--- /dev/null
+++ b/basic/inc/basic/sbxfac.hxx
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __SBX_SBX_FACTORY_HXX
+#define __SBX_SBX_FACTORY_HXX
+
+#include <basic/sbxdef.hxx>
+
+class SbxBase;
+class SbxObject;
+class String;
+class UniString;
+
+class SbxFactory
+{
+ BOOL bHandleLast; // TRUE: Factory is asked at last because of its expensiveness
+public:
+ SbxFactory( BOOL bLast=FALSE ) { bHandleLast = bLast; }
+ BOOL IsHandleLast( void ) { return bHandleLast; }
+ virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX );
+ virtual SbxObject* CreateObject( const String& );
+};
+
+#endif
diff --git a/basic/inc/basic/sbxform.hxx b/basic/inc/basic/sbxform.hxx
new file mode 100644
index 000000000000..0e8ab2466271
--- /dev/null
+++ b/basic/inc/basic/sbxform.hxx
@@ -0,0 +1,181 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBXFORM_HXX
+#define _SBXFORM_HXX
+
+//====================================================================
+// Implementation class for Basic command: Format$( d,formatStr )
+//====================================================================
+/*
+ Grammar of format string (a try):
+ -----------------------------------------------
+
+ format_string := {\special_char} general_format | scientific_format {\special_char} {;format_string}
+ general_format := {#[,]}{0[,]}[.{0}{#}]
+ scientific_format := {0}[.{0}{#}](e | E)(+ | -){#}{0}
+
+ percent_char := '%'
+ special_char := \char | + | - | ( | ) | $ | space_char
+ char := all_ascii_chars
+ space_char := ' '
+
+ {} repeated multiple times (incl. zero times)
+ [] exactly one or zero times
+ () parenthesis, e.g. (e | E) means e or E times
+
+ Additional predefined formats for the format string:
+ "General Number"
+ "Currency"
+ "Fixed"
+ "Standard"
+ "Percent"
+ "Scientific"
+ "Yes/No"
+ "True/False"
+ "On/Off"
+
+ Note: invalid format string are ignored just as in VisualBasic, the output is
+ probably 'undefined'. ASCII letters are outputted directly.
+
+ Constraints in VisualBasic:
+ - the exponent (scientific syntax) has a maximum of three digits!
+
+ Constraints of new implementation:
+ - the '+' sign is not allowed as wildcard in the mantissa
+
+ TODO:
+ - Date formatting
+ Wildcards are: 'h', 'm', 's', 'y'
+ predefined String-Constants/Commands:
+ "AMPM", "Long Date", "Long Time"
+*/
+
+/*
+ There are two possibilities to get the number of digits of a number:
+
+ a) use sprintf()
+ b) use log10() and pow() digit
+*/
+#define _with_sprintf // use a)
+
+#include <tools/string.hxx>
+
+class SbxBasicFormater {
+ public:
+ // Constructor takes signs for decimal point, thousand separation sign
+ // and necessary resource strings.
+ SbxBasicFormater( sal_Unicode _cDecPoint, sal_Unicode _cThousandSep,
+ String _sOnStrg,
+ String _sOffStrg,
+ String _sYesStrg,
+ String _sNoStrg,
+ String _sTrueStrg,
+ String _sFalseStrg,
+ String _sCurrencyStrg,
+ String _sCurrencyFormatStrg );
+
+ /* Basic command: Format$( number,format-string )
+
+ Parameter:
+ dNumber : number to be formated
+ sFormatStrg : the Format-String, e.g. ###0.0###
+
+ Return value:
+ String containing the formatted output
+ */
+ String BasicFormat( double dNumber, String sFormatStrg );
+ String BasicFormatNull( String sFormatStrg );
+
+ static BOOL isBasicFormat( String sFormatStrg );
+
+ private:
+ //*** some helper methods ***
+ //void ShowError( char *sErrMsg );
+ inline void ShiftString( String& sStrg, USHORT nStartPos );
+ inline void StrAppendChar( String& sStrg, sal_Unicode ch );
+ void AppendDigit( String& sStrg, short nDigit );
+ void LeftShiftDecimalPoint( String& sStrg );
+ void StrRoundDigit( String& sStrg, short nPos, BOOL& bOverflow );
+ void StrRoundDigit( String& sStrg, short nPos );
+ void ParseBack( String& sStrg, const String& sFormatStrg,
+ short nFormatPos );
+#ifdef _with_sprintf
+ // Methods for string conversion with sprintf():
+ void InitScan( double _dNum );
+ void InitExp( double _dNewExp );
+ short GetDigitAtPosScan( short nPos, BOOL& bFoundFirstDigit );
+ short GetDigitAtPosExpScan( double dNewExponent, short nPos,
+ BOOL& bFoundFirstDigit );
+ short GetDigitAtPosExpScan( short nPos, BOOL& bFoundFirstDigit );
+#else
+ // Methods for direct 'calculation' with log10() and pow():
+ short GetDigitAtPos( double dNumber, short nPos, double& dNextNumber,
+ BOOL& bFoundFirstDigit );
+ short RoundDigit( double dNumber );
+#endif
+ String GetPosFormatString( const String& sFormatStrg, BOOL & bFound );
+ String GetNegFormatString( const String& sFormatStrg, BOOL & bFound );
+ String Get0FormatString( const String& sFormatStrg, BOOL & bFound );
+ String GetNullFormatString( const String& sFormatStrg, BOOL & bFound );
+ short AnalyseFormatString( const String& sFormatStrg,
+ short& nNoOfDigitsLeft, short& nNoOfDigitsRight,
+ short& nNoOfOptionalDigitsLeft,
+ short& nNoOfExponentDigits,
+ short& nNoOfOptionalExponentDigits,
+ BOOL& bPercent, BOOL& bCurrency, BOOL& bScientific,
+ BOOL& bGenerateThousandSeparator,
+ short& nMultipleThousandSeparators );
+ void ScanFormatString( double dNumber, const String& sFormatStrg,
+ String& sReturnStrg, BOOL bCreateSign );
+
+ //*** Data ***
+ sal_Unicode cDecPoint; // sign for the decimal point
+ sal_Unicode cThousandSep; // sign for thousand delimiter
+ // Text for output:
+ String sOnStrg;
+ String sOffStrg;
+ String sYesStrg;
+ String sNoStrg;
+ String sTrueStrg;
+ String sFalseStrg;
+ String sCurrencyStrg;
+ String sCurrencyFormatStrg;
+
+ //*** temporary data for scan loop ***
+ //-----------------------------------------------
+ // String containing the number in scientific format
+ String sSciNumStrg;
+ // String containing the exponent of the number
+ String sNumExpStrg;
+ double dNum; // the number that is scanned
+ short nNumExp; // the exponent of the number
+ short nExpExp; // the number of digits in the exponent
+};
+
+#endif
+
diff --git a/basic/inc/basic/sbxmeth.hxx b/basic/inc/basic/sbxmeth.hxx
new file mode 100644
index 000000000000..5cc9af6f877a
--- /dev/null
+++ b/basic/inc/basic/sbxmeth.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __SBX_SBXMETHOD_HXX
+#define __SBX_SBXMETHOD_HXX
+
+#include <basic/sbxvar.hxx>
+
+class SbxMethodImpl;
+
+class SbxMethod : public SbxVariable
+{
+ SbxMethodImpl* mpSbxMethodImpl; // Impl data
+
+public:
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_METHOD,1);
+ TYPEINFO();
+ SbxMethod( const String& r, SbxDataType t )
+ : SbxVariable( t ) { SetName( r ); }
+ SbxMethod( const SbxMethod& r ) : SvRefBase( r ), SbxVariable( r ) {}
+ SbxMethod& operator=( const SbxMethod& r )
+ { SbxVariable::operator=( r ); return *this; }
+ BOOL Run( SbxValues* pValues = NULL );
+ virtual SbxClassType GetClass() const;
+};
+
+#ifndef __SBX_SBXMETHODREF_HXX
+#define __SBX_SBXMETHODREF_HXX
+
+#ifndef SBX_METHOD_DECL_DEFINED
+#define SBX_METHOD_DECL_DEFINED
+SV_DECL_REF(SbxMethod)
+#endif
+SV_IMPL_REF(SbxMethod)
+
+#endif
+#endif
+
diff --git a/basic/inc/basic/sbxmstrm.hxx b/basic/inc/basic/sbxmstrm.hxx
new file mode 100644
index 000000000000..ebd6a2b93484
--- /dev/null
+++ b/basic/inc/basic/sbxmstrm.hxx
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBXMSTRM_HXX
+#define _SBXMSTRM_HXX 1
+
+#include <tools/stream.hxx>
+#include <basic/sbxdef.hxx>
+#include <basic/sbxcore.hxx>
+
+SV_DECL_REF(SbxMemoryStream)
+
+class SbxMemoryStream : public SbxBase, public SvMemoryStream
+{
+ public:
+ SbxMemoryStream(ULONG nInitSize_=512, ULONG nResize_=64) :
+ SvMemoryStream(nInitSize_,nResize_) {}
+ ~SbxMemoryStream();
+
+ virtual SbxDataType GetType() const;
+};
+
+SV_IMPL_REF(SbxMemoryStream)
+
+#endif
diff --git a/basic/inc/basic/sbxobj.hxx b/basic/inc/basic/sbxobj.hxx
new file mode 100644
index 000000000000..a1ed962502cd
--- /dev/null
+++ b/basic/inc/basic/sbxobj.hxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBX_SBXOBJECT_HXX
+#define _SBX_SBXOBJECT_HXX
+
+#include <svl/lstner.hxx>
+#include <basic/sbxvar.hxx>
+
+///////////////////////////////////////////////////////////////////////////
+
+class SbxProperty;
+class SvDispatch;
+
+class SbxObjectImpl;
+
+class SbxObject : public SbxVariable, public SfxListener
+{
+ SbxObjectImpl* mpSbxObjectImpl; // Impl data
+
+ SbxArray* FindVar( SbxVariable*, USHORT& );
+ // AB 23.3.1997, special method for VCPtrRemove (see below)
+ SbxArray* VCPtrFindVar( SbxVariable*, USHORT& );
+protected:
+ SbxArrayRef pMethods; // Methods
+ SbxArrayRef pProps; // Properties
+ SbxArrayRef pObjs; // Objects
+ SbxProperty* pDfltProp; // Default-Property
+ String aClassName; // Classname
+ String aDfltPropName;
+ virtual BOOL LoadData( SvStream&, USHORT );
+ virtual BOOL StoreData( SvStream& ) const;
+ virtual ~SbxObject();
+ virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType );
+public:
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_OBJECT,1);
+ TYPEINFO();
+ SbxObject( const String& rClassname );
+ SbxObject( const SbxObject& );
+ SbxObject& operator=( const SbxObject& );
+ virtual SbxDataType GetType() const;
+ virtual SbxClassType GetClass() const;
+ virtual void Clear();
+
+ virtual BOOL IsClass( const String& ) const;
+ const String& GetClassName() const { return aClassName; }
+ void SetClassName( const String &rNew ) { aClassName = rNew; }
+ // Default-Property
+ SbxProperty* GetDfltProperty();
+ void SetDfltProperty( const String& r );
+ void SetDfltProperty( SbxProperty* );
+ // Search for an element
+ virtual SbxVariable* FindUserData( UINT32 nUserData );
+ virtual SbxVariable* Find( const String&, SbxClassType );
+ SbxVariable* FindQualified( const String&, SbxClassType );
+ // Quick-Call-Interface for Methods
+ virtual BOOL Call( const String&, SbxArray* = NULL );
+ // Execution of DDE-Commands
+ SbxVariable* Execute( const String& );
+ // Manage elements
+ virtual BOOL GetAll( SbxClassType ) { return TRUE; }
+ SbxVariable* Make( const String&, SbxClassType, SbxDataType );
+ virtual SbxObject* MakeObject( const String&, const String& );
+ virtual void Insert( SbxVariable* );
+ // AB 23.4.1997, Optimization, Insertion without check for duplicate Entries and
+ // without Broadcasts, only used in SO2/auto.cxx
+ void QuickInsert( SbxVariable* );
+ // AB 23.3.1997, Special-Method, allow corresponding controls
+ void VCPtrInsert( SbxVariable* );
+ virtual void Remove( const String&, SbxClassType );
+ virtual void Remove( SbxVariable* );
+ // AB 23.3.1997, deletion per pointer for controls (duplicate names!)
+ void VCPtrRemove( SbxVariable* );
+ void SetPos( SbxVariable*, USHORT );
+
+ // Macro-Recording
+ virtual String GenerateSource( const String &rLinePrefix,
+ const SbxObject *pRelativeTo );
+ // Direct access on arrays
+ SbxArray* GetMethods() { return pMethods; }
+ SbxArray* GetProperties() { return pProps; }
+ SbxArray* GetObjects() { return pObjs; }
+ // Hooks
+ virtual SvDispatch* GetSvDispatch();
+ // Debugging
+ void Dump( SvStream&, BOOL bDumpAll=FALSE );
+
+ static void GarbageCollection( ULONG nObjects = 0 /* ::= all */ );
+};
+
+#ifndef __SBX_SBXOBJECTREF_HXX
+
+#ifndef SBX_OBJECT_DECL_DEFINED
+#define SBX_OBJECT_DECL_DEFINED
+SV_DECL_REF(SbxObject)
+#endif
+SV_IMPL_REF(SbxObject)
+
+#endif /* __SBX_SBXOBJECTREF_HXX */
+#endif /* _SBX_SBXOBJECT_HXX */
diff --git a/basic/inc/basic/sbxprop.hxx b/basic/inc/basic/sbxprop.hxx
new file mode 100644
index 000000000000..467b86ee604c
--- /dev/null
+++ b/basic/inc/basic/sbxprop.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __SBX_SBXPROPERTY_HXX
+#define __SBX_SBXPROPERTY_HXX
+
+#include <basic/sbxvar.hxx>
+
+class SbxPropertyImpl;
+
+class SbxProperty : public SbxVariable
+{
+ SbxPropertyImpl* mpSbxPropertyImpl; // Impl data
+
+public:
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_PROPERTY,1);
+ TYPEINFO();
+ SbxProperty( const String& r, SbxDataType t )
+ : SbxVariable( t ) { SetName( r ); }
+ SbxProperty( const SbxProperty& r ) : SvRefBase( r ), SbxVariable( r ) {}
+ SbxProperty& operator=( const SbxProperty& r )
+ { SbxVariable::operator=( r ); return *this; }
+ virtual SbxClassType GetClass() const;
+};
+
+#ifndef __SBX_SBXPROPERTYREF_HXX
+#define __SBX_SBXPROPERTYREF_HXX
+
+#ifndef SBX_PROPERTY_DECL_DEFINED
+#define SBX_PROPERTY_DECL_DEFINED
+SV_DECL_REF(SbxProperty)
+#endif
+SV_IMPL_REF(SbxProperty)
+
+#endif
+
+#endif
diff --git a/basic/inc/basic/sbxvar.hxx b/basic/inc/basic/sbxvar.hxx
new file mode 100644
index 000000000000..0cddcbdf8d17
--- /dev/null
+++ b/basic/inc/basic/sbxvar.hxx
@@ -0,0 +1,514 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBXVAR_HXX
+#define _SBXVAR_HXX
+
+#include <rtl/ustring.hxx>
+#include <tools/string.hxx>
+#include <com/sun/star/bridge/oleautomation/Decimal.hpp>
+#include <basic/sbxcore.hxx>
+
+#ifndef __SBX_64
+#define __SBX_64
+
+struct SbxINT64
+{
+ INT32 nHigh; UINT32 nLow;
+
+#if FALSE
+ SbxINT64() : nHigh( 0 ), nLow( 0 ) {}
+ SbxINT64( UINT8 n ) : nHigh( 0 ), nLow( n ) {}
+ SbxINT64( UINT16 n ) : nHigh( 0 ), nLow( n ) {}
+ SbxINT64( UINT32 n ) : nHigh( 0 ), nLow( n ) {}
+ SbxINT64( unsigned int n ) : nHigh( 0 ), nLow( n ) {}
+ SbxINT64( INT8 n ) : nHigh( n < 0 ? -1 : 0 ), nLow( n ) {}
+ SbxINT64( INT16 n ) : nHigh( n < 0 ? -1 : 0 ), nLow( n ) {}
+ SbxINT64( INT32 n ) : nHigh( n < 0 ? -1 : 0 ), nLow( n ) {}
+ SbxINT64( int n ) : nHigh( n < 0 ? -1 : 0 ), nLow( n ) {}
+ SbxINT64( SbxINT64 &r ) : nHigh( r.nHigh ), nLow( r.nLow ) {}
+
+ SbxINT64( BigInt &r );
+ SbxINT64( double n );
+#endif
+ void CHS()
+ {
+ nLow ^= (UINT32)-1;
+ nHigh ^= -1;
+ nLow++;
+ if( !nLow )
+ nHigh++;
+ }
+
+ // blc/os2i do not like operator =
+ void Set(double n)
+ {
+ if( n >= 0 )
+ {
+ nHigh = (INT32)(n / (double)4294967296.0);
+ nLow = (UINT32)(n - ((double)nHigh * (double)4294967296.0) + 0.5);
+ }
+ else {
+ nHigh = (INT32)(-n / (double)4294967296.0);
+ nLow = (UINT32)(-n - ((double)nHigh * (double)4294967296.0) + 0.5);
+ CHS();
+ }
+ }
+ void Set(INT32 n) { nHigh = n < 0 ? -1 : 0; nLow = n; }
+
+ void SetMax() { nHigh = 0x7FFFFFFF; nLow = 0xFFFFFFFF; }
+ void SetMin() { nHigh = 0x80000000; nLow = 0x00000000; }
+ void SetNull() { nHigh = 0x00000000; nLow = 0x00000000; }
+
+ int operator ! () const { return !nHigh && !nLow; }
+
+ SbxINT64 &operator -= ( const SbxINT64 &r );
+ SbxINT64 &operator += ( const SbxINT64 &r );
+ SbxINT64 &operator /= ( const SbxINT64 &r );
+ SbxINT64 &operator %= ( const SbxINT64 &r );
+ SbxINT64 &operator *= ( const SbxINT64 &r );
+ SbxINT64 &operator &= ( const SbxINT64 &r );
+ SbxINT64 &operator |= ( const SbxINT64 &r );
+ SbxINT64 &operator ^= ( const SbxINT64 &r );
+
+ friend SbxINT64 operator - ( const SbxINT64 &l, const SbxINT64 &r );
+ friend SbxINT64 operator + ( const SbxINT64 &l, const SbxINT64 &r );
+ friend SbxINT64 operator / ( const SbxINT64 &l, const SbxINT64 &r );
+ friend SbxINT64 operator % ( const SbxINT64 &l, const SbxINT64 &r );
+ friend SbxINT64 operator * ( const SbxINT64 &l, const SbxINT64 &r );
+ friend SbxINT64 operator & ( const SbxINT64 &l, const SbxINT64 &r );
+ friend SbxINT64 operator | ( const SbxINT64 &l, const SbxINT64 &r );
+ friend SbxINT64 operator ^ ( const SbxINT64 &l, const SbxINT64 &r );
+
+ friend SbxINT64 operator - ( const SbxINT64 &r );
+ friend SbxINT64 operator ~ ( const SbxINT64 &r );
+
+ static double GetMin() { return ((double)0x7FFFFFFF*(double)4294967296.0
+ + (double)0xFFFFFFFF)
+ / CURRENCY_FACTOR; }
+ static double GetMax() { return ((double)0x80000000*(double)4294967296.0
+ + (double)0xFFFFFFFF)
+ / CURRENCY_FACTOR; }
+};
+
+struct SbxUINT64
+{
+ UINT32 nHigh; UINT32 nLow;
+ void Set(double n)
+ {
+ nHigh = (UINT32)(n / (double)4294967296.0);
+ nLow = (UINT32)(n - ((double)nHigh * (double)4294967296.0));
+ }
+
+ void Set(UINT32 n) { nHigh = 0; nLow = n; }
+
+ void SetMax() { nHigh = 0xFFFFFFFF; nLow = 0xFFFFFFFF; }
+ void SetMin() { nHigh = 0x00000000; nLow = 0x00000000; }
+ void SetNull() { nHigh = 0x00000000; nLow = 0x00000000; }
+
+ int operator ! () const { return !nHigh && !nLow; }
+
+ SbxUINT64 &operator -= ( const SbxUINT64 &r );
+ SbxUINT64 &operator += ( const SbxUINT64 &r );
+ SbxUINT64 &operator /= ( const SbxUINT64 &r );
+ SbxUINT64 &operator %= ( const SbxUINT64 &r );
+ SbxUINT64 &operator *= ( const SbxUINT64 &r );
+ SbxUINT64 &operator &= ( const SbxUINT64 &r );
+ SbxUINT64 &operator |= ( const SbxUINT64 &r );
+ SbxUINT64 &operator ^= ( const SbxUINT64 &r );
+
+ friend SbxUINT64 operator - ( const SbxUINT64 &l, const SbxUINT64 &r );
+ friend SbxUINT64 operator + ( const SbxUINT64 &l, const SbxUINT64 &r );
+ friend SbxUINT64 operator / ( const SbxUINT64 &l, const SbxUINT64 &r );
+ friend SbxUINT64 operator % ( const SbxUINT64 &l, const SbxUINT64 &r );
+ friend SbxUINT64 operator * ( const SbxUINT64 &l, const SbxUINT64 &r );
+ friend SbxUINT64 operator & ( const SbxUINT64 &l, const SbxUINT64 &r );
+ friend SbxUINT64 operator | ( const SbxUINT64 &l, const SbxUINT64 &r );
+ friend SbxUINT64 operator ^ ( const SbxUINT64 &l, const SbxUINT64 &r );
+
+ friend SbxUINT64 operator ~ ( const SbxUINT64 &r );
+};
+
+#endif
+
+#ifndef __SBX_SBXVALUES_HXX
+#define __SBX_SBXVALUES_HXX
+
+class BigInt;
+class SbxDecimal;
+
+struct SbxValues
+{
+ union {
+ sal_Unicode nChar;
+ BYTE nByte;
+ INT16 nInteger;
+ INT32 nLong;
+ UINT16 nUShort;
+ UINT32 nULong;
+ float nSingle;
+ double nDouble;
+ SbxINT64 nLong64;
+ SbxUINT64 nULong64;
+ sal_Int64 nInt64;
+ sal_uInt64 uInt64;
+ int nInt;
+ unsigned int nUInt;
+ ::rtl::OUString* pOUString;
+ SbxDecimal* pDecimal;
+
+ SbxBase* pObj;
+ sal_Unicode* pChar;
+ BYTE* pByte;
+ INT16* pInteger;
+ INT32* pLong;
+ UINT16* pUShort;
+ UINT32* pULong;
+ float* pSingle;
+ double* pDouble;
+ SbxINT64* pLong64;
+ SbxUINT64* pULong64;
+ sal_Int64* pnInt64;
+ sal_uInt64* puInt64;
+ int* pInt;
+ unsigned int* pUInt;
+ void* pData;
+ };
+ SbxDataType eType;
+
+ SbxValues(): pData( NULL ), eType(SbxEMPTY) {}
+ SbxValues( SbxDataType e ): eType(e) {}
+ SbxValues( char _nChar ): nChar( _nChar ), eType(SbxCHAR) {}
+ SbxValues( BYTE _nByte ): nByte( _nByte ), eType(SbxBYTE) {}
+ SbxValues( short _nInteger ): nInteger( _nInteger ), eType(SbxINTEGER ) {}
+ SbxValues( long _nLong ): nLong( _nLong ), eType(SbxLONG) {}
+ SbxValues( USHORT _nUShort ): nUShort( _nUShort ), eType(SbxUSHORT) {}
+ SbxValues( ULONG _nULong ): nULong( _nULong ), eType(SbxULONG) {}
+ SbxValues( float _nSingle ): nSingle( _nSingle ), eType(SbxSINGLE) {}
+ SbxValues( double _nDouble ): nDouble( _nDouble ), eType(SbxDOUBLE) {}
+ SbxValues( int _nInt ): nInt( _nInt ), eType(SbxINT) {}
+ SbxValues( unsigned int _nUInt ): nUInt( _nUInt ), eType(SbxUINT) {}
+ SbxValues( const ::rtl::OUString* _pString ): pOUString( (::rtl::OUString*)_pString ), eType(SbxSTRING) {}
+ SbxValues( SbxBase* _pObj ): pObj( _pObj ), eType(SbxOBJECT) {}
+ SbxValues( sal_Unicode* _pChar ): pChar( _pChar ), eType(SbxLPSTR) {}
+ SbxValues( void* _pData ): pData( _pData ), eType(SbxPOINTER) {}
+ SbxValues( const BigInt &rBig );
+};
+
+#endif
+
+#ifndef __SBX_SBXVALUE
+#define __SBX_SBXVALUE
+
+struct SbxValues;
+
+class SbxValueImpl;
+
+class SbxValue : public SbxBase
+{
+ SbxValueImpl* mpSbxValueImplImpl; // Impl data
+
+ // #55226 Transport additional infos
+ SbxValue* TheRealValue( BOOL bObjInObjError ) const;
+ SbxValue* TheRealValue() const;
+protected:
+ SbxValues aData; // Data
+ ::rtl::OUString aPic; // Picture-String
+ String aToolString; // tool string copy
+
+ virtual void Broadcast( ULONG ); // Broadcast-Call
+ virtual ~SbxValue();
+ virtual BOOL LoadData( SvStream&, USHORT );
+ virtual BOOL StoreData( SvStream& ) const;
+public:
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_VALUE,1);
+ TYPEINFO();
+ SbxValue();
+ SbxValue( SbxDataType, void* = NULL );
+ SbxValue( const SbxValue& );
+ SbxValue& operator=( const SbxValue& );
+ virtual void Clear();
+ virtual BOOL IsFixed() const;
+
+ BOOL IsInteger() const { return BOOL( GetType() == SbxINTEGER ); }
+ BOOL IsLong() const { return BOOL( GetType() == SbxLONG ); }
+ BOOL IsSingle() const { return BOOL( GetType() == SbxSINGLE ); }
+ BOOL IsDouble() const { return BOOL( GetType() == SbxDOUBLE ); }
+ BOOL IsString() const { return BOOL( GetType() == SbxSTRING ); }
+ BOOL IsDate() const { return BOOL( GetType() == SbxDATE ); }
+ BOOL IsCurrency()const { return BOOL( GetType() == SbxCURRENCY ); }
+ BOOL IsObject() const { return BOOL( GetType() == SbxOBJECT ); }
+ BOOL IsDataObject()const{return BOOL( GetType() == SbxDATAOBJECT);}
+ BOOL IsBool() const { return BOOL( GetType() == SbxBOOL ); }
+ BOOL IsErr() const { return BOOL( GetType() == SbxERROR ); }
+ BOOL IsEmpty() const { return BOOL( GetType() == SbxEMPTY ); }
+ BOOL IsNull() const { return BOOL( GetType() == SbxNULL ); }
+ BOOL IsChar() const { return BOOL( GetType() == SbxCHAR ); }
+ BOOL IsByte() const { return BOOL( GetType() == SbxBYTE ); }
+ BOOL IsUShort() const { return BOOL( GetType() == SbxUSHORT ); }
+ BOOL IsULong() const { return BOOL( GetType() == SbxULONG ); }
+ BOOL IsInt() const { return BOOL( GetType() == SbxINT ); }
+ BOOL IsUInt() const { return BOOL( GetType() == SbxUINT ); }
+ BOOL IspChar() const { return BOOL( GetType() == SbxLPSTR ); }
+ BOOL IsNumeric() const;
+ BOOL IsNumericRTL() const; // #41692 Interface for Basic
+ BOOL ImpIsNumeric( BOOL bOnlyIntntl ) const; // Implementation
+
+ virtual SbxClassType GetClass() const;
+ virtual SbxDataType GetType() const;
+ SbxDataType GetFullType() const;
+ BOOL SetType( SbxDataType );
+
+ virtual BOOL Get( SbxValues& ) const;
+ BOOL GetNoBroadcast( SbxValues& );
+ const SbxValues& GetValues_Impl() const { return aData; }
+ virtual BOOL Put( const SbxValues& );
+
+ inline SbxValues * data() { return &aData; }
+
+ SbxINT64 GetCurrency() const;
+ SbxINT64 GetLong64() const;
+ SbxUINT64 GetULong64() const;
+ sal_Int64 GetInt64() const;
+ sal_uInt64 GetUInt64() const;
+ INT16 GetInteger() const;
+ INT32 GetLong() const;
+ float GetSingle() const;
+ double GetDouble() const;
+ double GetDate() const;
+ BOOL GetBool() const;
+ UINT16 GetErr() const;
+ const String& GetString() const;
+ const String& GetCoreString() const;
+ ::rtl::OUString GetOUString() const;
+ SbxDecimal* GetDecimal() const;
+ SbxBase* GetObject() const;
+ BOOL HasObject() const;
+ void* GetData() const;
+ sal_Unicode GetChar() const;
+ BYTE GetByte() const;
+ UINT16 GetUShort() const;
+ UINT32 GetULong() const;
+ int GetInt() const;
+
+ BOOL PutCurrency( const SbxINT64& );
+ BOOL PutLong64( const SbxINT64& );
+ BOOL PutULong64( const SbxUINT64& );
+ BOOL PutInt64( sal_Int64 );
+ BOOL PutUInt64( sal_uInt64 );
+ BOOL PutInteger( INT16 );
+ BOOL PutLong( INT32 );
+ BOOL PutSingle( float );
+ BOOL PutDouble( double );
+ BOOL PutDate( double );
+ BOOL PutBool( BOOL );
+ BOOL PutErr( USHORT );
+ BOOL PutStringExt( const ::rtl::OUString& ); // with extended analysis (International, "TRUE"/"FALSE")
+ BOOL PutString( const ::rtl::OUString& );
+ BOOL PutString( const sal_Unicode* ); // Type = SbxSTRING
+ BOOL PutpChar( const sal_Unicode* ); // Type = SbxLPSTR
+ BOOL PutDecimal( SbxDecimal* pDecimal );
+ BOOL PutObject( SbxBase* );
+ BOOL PutData( void* );
+ BOOL PutChar( sal_Unicode );
+ BOOL PutByte( BYTE );
+ BOOL PutUShort( UINT16 );
+ BOOL PutULong( UINT32 );
+ BOOL PutInt( int );
+ BOOL PutEmpty();
+ BOOL PutNull();
+
+ // Special decimal methods
+ BOOL PutDecimal( com::sun::star::bridge::oleautomation::Decimal& rAutomationDec );
+ BOOL fillAutomationDecimal( com::sun::star::bridge::oleautomation::Decimal& rAutomationDec );
+
+ virtual BOOL Convert( SbxDataType );
+ virtual BOOL Compute( SbxOperator, const SbxValue& );
+ virtual BOOL Compare( SbxOperator, const SbxValue& ) const;
+ BOOL Scan( const String&, USHORT* = NULL );
+ void Format( String&, const String* = NULL ) const;
+
+ // Interface for CDbl in Basic
+ static SbxError ScanNumIntnl( const String& rSrc, double& nVal, BOOL bSingle=FALSE );
+
+ // The following operators are definied for easier handling.
+ // Error conditions (overflow, conversions) are not
+ // taken into consideration.
+
+ inline int operator ==( const SbxValue& ) const;
+ inline int operator !=( const SbxValue& ) const;
+ inline int operator <( const SbxValue& ) const;
+ inline int operator >( const SbxValue& ) const;
+ inline int operator <=( const SbxValue& ) const;
+ inline int operator >=( const SbxValue& ) const;
+
+ inline SbxValue& operator *=( const SbxValue& );
+ inline SbxValue& operator /=( const SbxValue& );
+ inline SbxValue& operator %=( const SbxValue& );
+ inline SbxValue& operator +=( const SbxValue& );
+ inline SbxValue& operator -=( const SbxValue& );
+ inline SbxValue& operator &=( const SbxValue& );
+ inline SbxValue& operator |=( const SbxValue& );
+ inline SbxValue& operator ^=( const SbxValue& );
+};
+
+inline int SbxValue::operator==( const SbxValue& r ) const
+{ return Compare( SbxEQ, r ); }
+
+inline int SbxValue::operator!=( const SbxValue& r ) const
+{ return Compare( SbxNE, r ); }
+
+inline int SbxValue::operator<( const SbxValue& r ) const
+{ return Compare( SbxLT, r ); }
+
+inline int SbxValue::operator>( const SbxValue& r ) const
+{ return Compare( SbxGT, r ); }
+
+inline int SbxValue::operator<=( const SbxValue& r ) const
+{ return Compare( SbxLE, r ); }
+
+inline int SbxValue::operator>=( const SbxValue& r ) const
+{ return Compare( SbxGE, r ); }
+
+inline SbxValue& SbxValue::operator*=( const SbxValue& r )
+{ Compute( SbxMUL, r ); return *this; }
+
+inline SbxValue& SbxValue::operator/=( const SbxValue& r )
+{ Compute( SbxDIV, r ); return *this; }
+
+inline SbxValue& SbxValue::operator%=( const SbxValue& r )
+{ Compute( SbxMOD, r ); return *this; }
+
+inline SbxValue& SbxValue::operator+=( const SbxValue& r )
+{ Compute( SbxPLUS, r ); return *this; }
+
+inline SbxValue& SbxValue::operator-=( const SbxValue& r )
+{ Compute( SbxMINUS, r ); return *this; }
+
+inline SbxValue& SbxValue::operator&=( const SbxValue& r )
+{ Compute( SbxAND, r ); return *this; }
+
+inline SbxValue& SbxValue::operator|=( const SbxValue& r )
+{ Compute( SbxOR, r ); return *this; }
+
+inline SbxValue& SbxValue::operator^=( const SbxValue& r )
+{ Compute( SbxXOR, r ); return *this; }
+
+#endif
+
+#ifndef __SBX_SBXVARIABLE_HXX
+#define __SBX_SBXVARIABLE_HXX
+
+class SbxArray;
+class SbxInfo;
+
+#ifndef SBX_ARRAY_DECL_DEFINED
+#define SBX_ARRAY_DECL_DEFINED
+SV_DECL_REF(SbxArray)
+#endif
+
+#ifndef SBX_INFO_DECL_DEFINED
+#define SBX_INFO_DECL_DEFINED
+SV_DECL_REF(SbxInfo)
+#endif
+
+class SfxBroadcaster;
+
+class SbxVariableImpl;
+
+class SbxVariable : public SbxValue
+{
+ friend class SbMethod;
+
+ SbxVariableImpl* mpSbxVariableImpl; // Impl data
+ SfxBroadcaster* pCst; // Broadcaster, if needed
+ String maName; // Name, if available
+ SbxArrayRef mpPar; // Parameter-Array, if set
+ USHORT nHash; // Hash-ID for search
+
+ SbxVariableImpl* getImpl( void );
+
+protected:
+ SbxInfoRef pInfo; // Probably called information
+ sal_uIntPtr nUserData; // User data for Call()
+ SbxObject* pParent; // Currently attached object
+ virtual ~SbxVariable();
+ virtual BOOL LoadData( SvStream&, USHORT );
+ virtual BOOL StoreData( SvStream& ) const;
+public:
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_VARIABLE,2);
+ TYPEINFO();
+ SbxVariable();
+ SbxVariable( SbxDataType, void* = NULL );
+ SbxVariable( const SbxVariable& );
+ SbxVariable& operator=( const SbxVariable& );
+
+ void Dump( SvStream&, BOOL bDumpAll=FALSE );
+
+ virtual void SetName( const String& );
+ virtual const String& GetName( SbxNameType = SbxNAME_NONE ) const;
+ USHORT GetHashCode() const { return nHash; }
+
+ virtual void SetModified( BOOL );
+
+ sal_uIntPtr GetUserData() const { return nUserData; }
+ void SetUserData( sal_uIntPtr n ) { nUserData = n; }
+
+ virtual SbxDataType GetType() const;
+ virtual SbxClassType GetClass() const;
+
+ // Parameter-Interface
+ virtual SbxInfo* GetInfo();
+ void SetInfo( SbxInfo* p );
+ void SetParameters( SbxArray* p );
+ SbxArray* GetParameters() const { return mpPar; }
+
+ // Sfx-Broadcasting-Support:
+ // Due to data reduction and better DLL-hierarchie currently via casting
+ SfxBroadcaster& GetBroadcaster();
+ BOOL IsBroadcaster() const { return BOOL( pCst != NULL ); }
+ virtual void Broadcast( ULONG nHintId );
+
+ inline const SbxObject* GetParent() const { return pParent; }
+ inline SbxObject* GetParent() { return pParent; }
+ virtual void SetParent( SbxObject* );
+
+ const String& GetDeclareClassName( void );
+ void SetDeclareClassName( const String& );
+ void SetComListener( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xComListener );
+
+ static USHORT MakeHashCode( const String& rName );
+};
+
+#ifndef SBX_VARIABLE_DECL_DEFINED
+#define SBX_VARIABLE_DECL_DEFINED
+SV_DECL_REF(SbxVariable)
+#endif
+
+#endif
+
+#endif // _SBXVAR_HXX
diff --git a/basic/inc/basic/testtool.hxx b/basic/inc/basic/testtool.hxx
new file mode 100644
index 000000000000..37e90bb5cd68
--- /dev/null
+++ b/basic/inc/basic/testtool.hxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _BASIC_TESTTOOL_HXX_
+#define _BASIC_TESTTOOL_HXX_
+
+#include <svl/smplhint.hxx>
+#include <tools/string.hxx>
+
+#define TESTTOOL_DEFAULT_PORT 12479
+#define UNO_DEFAULT_PORT 12480
+#define DEFAULT_HOST "localhost"
+
+#define TT_SIGNATURE_FOR_UNICODE_TEXTFILES "'encoding UTF-8 Do not remove or change this line!"
+
+#define ASSERTION_STACK_PREFIX "Backtrace:"
+
+// #94145# Due to a tab in TT_SIGNATURE_FOR_UNICODE_TEXTFILES which is changed to blanks by some editors
+// this routine became necessary
+BOOL IsTTSignatureForUnicodeTextfile( String aLine );
+
+//#include "testapp.hxx"
+#define ADD_ERROR_QUIET(nNr, aStr) \
+{ \
+ ErrorEntry *pErr; \
+ if ( BasicRuntimeAccess::HasRuntime() ) \
+ { \
+ BasicRuntime aRun = BasicRuntimeAccess::GetRuntime(); \
+ xub_StrLen aErrLn = StarBASIC::GetErl(); \
+ if ( 0 == aErrLn ) \
+ aErrLn = aRun.GetLine(); \
+ pErr = new ErrorEntry(nNr, aStr, \
+ aErrLn, aRun.GetCol1(), aRun.GetCol2()); \
+ } \
+ else \
+ { \
+ pErr = new ErrorEntry(nNr, aStr); \
+ } \
+ P_FEHLERLISTE->C40_INSERT(ErrorEntry, pErr, P_FEHLERLISTE->Count());\
+}
+// ??? Irgendwann noch was mit der UID anfangen !!
+#define ADD_ERROR(nNr, aStr) { \
+ if ( !SbxBase::IsError() ) \
+ SbxBase::SetError( nNr ); \
+ ADD_ERROR_QUIET(nNr, aStr); \
+}
+
+#define POP_ERROR() P_FEHLERLISTE->DeleteAndDestroy(0)
+#define GET_ERROR() P_FEHLERLISTE->GetObject(0)
+#define IS_ERROR() ( P_FEHLERLISTE->Count() > 0 )
+
+// Transmission of error logs
+enum TTLogType { LOG_RUN, LOG_TEST_CASE, LOG_ERROR, LOG_CALL_STACK, LOG_MESSAGE, LOG_WARNING, LOG_ASSERTION, LOG_QA_ERROR, LOG_ASSERTION_STACK };
+
+struct TTDebugData
+{
+public:
+ TTLogType aLogType;
+ String aMsg;
+ String aFilename;
+ xub_StrLen nLine;
+ xub_StrLen nCol1;
+ xub_StrLen nCol2;
+};
+
+struct TTLogMsg
+{
+public:
+ String aLogFileName;
+ TTDebugData aDebugData;
+};
+
+// For transmission of window information from the Testapp
+struct WinInfoRec
+{
+public:
+ String aUId;
+ String aKurzname;
+ String aSlotname;
+ String aLangname;
+ USHORT nRType;
+ String aRName;
+ BOOL bIsReset;
+};
+
+// Defines for syntax Highlighting
+#define TT_KEYWORD ((SbTextType)100) // Including locally executed commands like 'use' ...
+#define TT_REMOTECMD ((SbTextType)101) // Remotely executed commands like 'nodebug'
+#define TT_LOCALCMD ((SbTextType)102) // Locally executed commands like 'use'
+#define TT_CONTROL ((SbTextType)103) // Possibly available control loaded by 'use'
+#define TT_SLOT ((SbTextType)104) // Available Slots loaded by 'use'
+#define TT_METHOD ((SbTextType)105) // Possibly allowed Method for controls
+#define TT_NOMETHOD ((SbTextType)106) // No Possibly allowed Method for controls
+
+#define FILELIST1 ((SbTextType)111) // Symbols in file 1
+#define FILELIST2 ((SbTextType)112) // Symbols in file 2
+#define FILELIST3 ((SbTextType)113) // Symbols in file 3
+#define FILELIST4 ((SbTextType)114) // Symbols in file 4
+
+/// defines for hints from TestToolObj to the Application
+#define SBX_HINT_LANGUAGE_EXTENSION_LOADED SFX_HINT_USER06
+#define SBX_HINT_EXECUTION_STATUS_INFORMATION SFX_HINT_USER07
+
+#define TT_EXECUTION_ENTERWAIT 0x01
+#define TT_EXECUTION_LEAVEWAIT 0x02
+#define TT_EXECUTION_SHOW_ACTION 0x03
+#define TT_EXECUTION_HIDE_ACTION 0x04
+
+class TTExecutionStatusHint : public SfxSimpleHint
+{
+private:
+ USHORT mnType;
+ String maExecutionStatus;
+ String maAdditionalExecutionStatus;
+
+public:
+ TYPEINFO();
+ TTExecutionStatusHint( USHORT nType, sal_Char *pExecutionStatus, const sal_Char *pAdditionalExecutionStatus = "" )
+ : SfxSimpleHint(SBX_HINT_EXECUTION_STATUS_INFORMATION)
+ , mnType( nType )
+ , maExecutionStatus( pExecutionStatus, RTL_TEXTENCODING_ASCII_US )
+ , maAdditionalExecutionStatus( pAdditionalExecutionStatus, RTL_TEXTENCODING_ASCII_US )
+ {;}
+
+ TTExecutionStatusHint( USHORT nType, const String &aExecutionStatus = String(), const String &aAdditionalExecutionStatus = String() )
+ : SfxSimpleHint(SBX_HINT_EXECUTION_STATUS_INFORMATION)
+ , mnType( nType )
+ , maExecutionStatus( aExecutionStatus )
+ , maAdditionalExecutionStatus( aAdditionalExecutionStatus )
+ {;}
+
+ const String& GetExecutionStatus() const { return maExecutionStatus; }
+ const String& GetAdditionalExecutionStatus() const { return maAdditionalExecutionStatus; }
+ USHORT GetType(){ return mnType; }
+};
+
+#endif // _BASIC_TESTTOOL_HXX_
diff --git a/basic/inc/basic/ttglobal.hrc b/basic/inc/basic/ttglobal.hrc
new file mode 100644
index 000000000000..0248a06c7247
--- /dev/null
+++ b/basic/inc/basic/ttglobal.hrc
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _TTGLOBAL_HXX
+#define _TTGLOBAL_HXX
+
+///////////////////////////////
+// Error message that go to the Resultfile.
+// *********************
+// *** !!ATTENTION!! ***
+// *********************
+// Theses numbers MUST NOT change ever!
+// Because they are stored in the Resultfiles and if you showed them again
+// the appropriate new or no Strings are viewed.
+///////////////////////////////
+
+// Start of Ressources for the Testtool (own file)
+// > 256 and > 9100 (Biggest res in TT itself)
+#define TT_START 20000 // Messages from /basic/source/testtool
+#define BAS_START 21000 // Messages from /basic/source/app
+#define SVT_START 22000 // Messages from /svtools/source/plugapp
+
+
+#endif
+
diff --git a/basic/inc/basic/ttstrhlp.hxx b/basic/inc/basic/ttstrhlp.hxx
new file mode 100644
index 000000000000..1827d013c492
--- /dev/null
+++ b/basic/inc/basic/ttstrhlp.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _BASIC_TTSTRHLP_HXX
+#define _BASIC_TTSTRHLP_HXX
+
+#include <tools/string.hxx>
+
+#define CByteString( constAsciiStr ) ByteString( RTL_CONSTASCII_STRINGPARAM ( constAsciiStr ) )
+#define CUniString( constAsciiStr ) UniString( RTL_CONSTASCII_USTRINGPARAM ( constAsciiStr ) )
+
+#define StartKenn CUniString("%")
+#define EndKenn CUniString("%")
+#define UIdKenn ( StartKenn.AppendAscii("UId") )
+#define MethodKenn ( StartKenn.AppendAscii("Method") )
+#define TypeKenn ( StartKenn.AppendAscii("RType") )
+#define SlotKenn ( StartKenn.AppendAscii("SlotId") )
+#define RcKenn ( StartKenn.AppendAscii("RCommand") )
+#define TabKenn ( StartKenn.AppendAscii("Tab") )
+#define MakeStringParam(Type,aText) ( Type.AppendAscii("=").Append( aText ).Append( EndKenn ) )
+#define MakeStringNumber(Type,nNumber) MakeStringParam (Type, UniString::CreateFromInt32(nNumber))
+#define UIdString(aID) MakeStringParam(UIdKenn,aID.GetText())
+#define MethodString(nNumber) MakeStringNumber(MethodKenn,nNumber)
+#define TypeString(nNumber) MakeStringNumber(TypeKenn,nNumber)
+#define SlotString(nNumber) MakeStringNumber(SlotKenn,nNumber)
+#define RcString(nNumber) MakeStringNumber(RcKenn,nNumber)
+#define TabString(nNumber) MakeStringNumber(TabKenn,nNumber)
+
+#define ResKenn ( StartKenn.AppendAscii("ResId") )
+#define BaseArgKenn ( StartKenn.AppendAscii("Arg") )
+#define ArgKenn(nNumber) ( BaseArgKenn.Append( UniString::CreateFromInt32(nNumber) ) )
+#define ResString(nNumber) MakeStringNumber(ResKenn,nNumber)
+#define ArgString(nNumber, aText) MakeStringParam(ArgKenn(nNumber),aText)
+
+UniString GEN_RES_STR0( ULONG nResId );
+UniString GEN_RES_STR1( ULONG nResId, const String &Text1 );
+UniString GEN_RES_STR2( ULONG nResId, const String &Text1, const String &Text2 );
+UniString GEN_RES_STR3( ULONG nResId, const String &Text1, const String &Text2, const String &Text3 );
+
+#define GEN_RES_STR1c( nResId, Text1 ) GEN_RES_STR1( nResId, CUniString(Text1) )
+#define GEN_RES_STR2c2( nResId, Text1, Text2 ) GEN_RES_STR2( nResId, Text1, CUniString(Text2) )
+#define GEN_RES_STR3c3( nResId, Text1, Text2, Text3 ) GEN_RES_STR3( nResId, Text1, Text2, CUniString(Text3) )
+
+#define IMPL_GEN_RES_STR \
+UniString GEN_RES_STR0( ULONG nResId ) { return ResString( nResId ); } \
+UniString GEN_RES_STR1( ULONG nResId, const UniString &Text1 ) { return GEN_RES_STR0( nResId ).Append( ArgString( 1, Text1 ) ); } \
+UniString GEN_RES_STR2( ULONG nResId, const UniString &Text1, const UniString &Text2 ) { return GEN_RES_STR1( nResId, Text1 ).Append( ArgString( 2, Text2 ) ); } \
+UniString GEN_RES_STR3( ULONG nResId, const UniString &Text1, const UniString &Text2, const UniString &Text3 ) { return GEN_RES_STR2( nResId, Text1, Text2 ).Append( ArgString( 3, Text3 ) );}
+
+#endif
+
diff --git a/basic/inc/basrid.hxx b/basic/inc/basrid.hxx
new file mode 100644
index 000000000000..d12d05c3436a
--- /dev/null
+++ b/basic/inc/basrid.hxx
@@ -0,0 +1,45 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _BASRID_HXX
+#define _BASRID_HXX
+
+#include <tools/resid.hxx>
+
+class SttResId : public ResId
+{
+ public:
+ SttResId( sal_uInt32 nId );
+};
+
+class BasResId : public ResId
+{
+ public:
+ BasResId( sal_uInt32 nId );
+};
+
+#endif //_BASRID_HXX
diff --git a/basic/inc/makefile.mk b/basic/inc/makefile.mk
new file mode 100644
index 000000000000..1b56b6774806
--- /dev/null
+++ b/basic/inc/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# 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=inc
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.IF "$(ENABLE_PCH)"!=""
+ALLTAR : \
+ $(SLO)$/precompiled.pch \
+ $(SLO)$/precompiled_ex.pch
+
+.ENDIF # "$(ENABLE_PCH)"!=""
+
diff --git a/basic/inc/modsizeexceeded.hxx b/basic/inc/modsizeexceeded.hxx
new file mode 100644
index 000000000000..e2d716259f09
--- /dev/null
+++ b/basic/inc/modsizeexceeded.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _BASIC_MODSIZEEXCEEDED_HXX
+#define _BASIC_MODSIZEEXCEEDED_HXX
+
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+class ModuleSizeExceeded : public ::cppu::WeakImplHelper1< ::com::sun::star::task::XInteractionRequest >
+{
+ // C++ interface
+ public:
+ ModuleSizeExceeded( const com::sun::star::uno::Sequence< ::rtl::OUString>& sModules );
+
+ sal_Bool isAbort() const;
+ sal_Bool isApprove() const;
+
+ // UNO interface
+ public:
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< com::sun::star::task::XInteractionContinuation > > SAL_CALL getContinuations() throw( ::com::sun::star::uno::RuntimeException ) { return m_lContinuations; }
+ com::sun::star::uno::Any SAL_CALL getRequest() throw( com::sun::star::uno::RuntimeException )
+ {
+ return m_aRequest;
+ }
+
+ // member
+ private:
+ rtl::OUString m_sMods;
+ com::sun::star::uno::Any m_aRequest;
+ com::sun::star::uno::Sequence< com::sun::star::uno::Reference< com::sun::star::task::XInteractionContinuation > > m_lContinuations;
+ com::sun::star::uno::Reference< com::sun::star::task::XInteractionContinuation > m_xAbort;
+ com::sun::star::uno::Reference< com::sun::star::task::XInteractionContinuation> m_xApprove;
+};
+
+#endif
+
diff --git a/basic/inc/pch/precompiled_basic.cxx b/basic/inc/pch/precompiled_basic.cxx
new file mode 100644
index 000000000000..c27c1c7a66a6
--- /dev/null
+++ b/basic/inc/pch/precompiled_basic.cxx
@@ -0,0 +1,29 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include "precompiled_basic.hxx"
+
diff --git a/basic/inc/pch/precompiled_basic.hxx b/basic/inc/pch/precompiled_basic.hxx
new file mode 100644
index 000000000000..e8f9e004ca6a
--- /dev/null
+++ b/basic/inc/pch/precompiled_basic.hxx
@@ -0,0 +1,288 @@
+/*************************************************************************
+ *
+ * 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): Generated on 2006-09-01 17:49:31.374198
+
+#ifdef PRECOMPILED_HEADERS
+
+//---MARKER---
+
+#include "com/sun/star/awt/XControl.hpp"
+#include "com/sun/star/awt/XControlContainer.hpp"
+#include "com/sun/star/awt/XControlModel.hpp"
+#include "com/sun/star/awt/XDialog.hpp"
+#include "com/sun/star/awt/XWindow.hpp"
+#include "com/sun/star/beans/MethodConcept.hpp"
+#include "com/sun/star/beans/PropertyAttribute.hpp"
+#include "com/sun/star/beans/PropertyConcept.hpp"
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/beans/XExactName.hpp"
+#include "com/sun/star/beans/XIntrospection.hpp"
+#include "com/sun/star/beans/XIntrospectionAccess.hpp"
+#include "com/sun/star/beans/XMaterialHolder.hpp"
+#include "com/sun/star/beans/XPropertyAccess.hpp"
+#include "com/sun/star/beans/XPropertyContainer.hpp"
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include "com/sun/star/beans/XPropertySetInfo.hpp"
+#include "com/sun/star/bridge/XBridge.hpp"
+#include "com/sun/star/bridge/XBridgeFactory.hpp"
+#include "com/sun/star/bridge/oleautomation/Currency.hpp"
+#include "com/sun/star/bridge/oleautomation/Date.hpp"
+#include "com/sun/star/bridge/oleautomation/Decimal.hpp"
+#include "com/sun/star/bridge/oleautomation/NamedArgument.hpp"
+#include "com/sun/star/container/XContainer.hpp"
+#include "com/sun/star/container/XEnumeration.hpp"
+#include "com/sun/star/container/XEnumerationAccess.hpp"
+#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
+#include "com/sun/star/container/XIndexAccess.hpp"
+#include "com/sun/star/container/XNameAccess.hpp"
+#include "com/sun/star/container/XNameContainer.hpp"
+#include "com/sun/star/document/XDocumentInfoSupplier.hpp"
+#include "com/sun/star/document/XStorageBasedDocument.hpp"
+#include "com/sun/star/embed/ElementModes.hpp"
+#include "com/sun/star/embed/XEncryptionProtectedSource.hpp"
+#include "com/sun/star/embed/XStorage.hpp"
+#include "com/sun/star/embed/XTransactedObject.hpp"
+#include "com/sun/star/frame/XModel.hpp"
+#include "com/sun/star/i18n/XCalendar.hpp"
+#include "com/sun/star/io/XActiveDataSource.hpp"
+#include "com/sun/star/io/XInputStream.hpp"
+#include "com/sun/star/io/XOutputStream.hpp"
+#include "com/sun/star/io/XSeekable.hpp"
+#include "com/sun/star/io/XStream.hpp"
+#include "com/sun/star/io/XTextOutputStream.hpp"
+#include "com/sun/star/lang/Locale.hpp"
+#include "com/sun/star/lang/XComponent.hpp"
+#include "com/sun/star/lang/XInitialization.hpp"
+#include "com/sun/star/lang/XMultiServiceFactory.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XSingleServiceFactory.hpp"
+#include "com/sun/star/lang/XTypeProvider.hpp"
+#include "com/sun/star/reflection/XIdlArray.hpp"
+#include "com/sun/star/reflection/XIdlClass.hpp"
+#include "com/sun/star/reflection/XIdlClassProvider.hpp"
+#include "com/sun/star/reflection/XIdlReflection.hpp"
+#include "com/sun/star/reflection/XTypeDescription.hpp"
+#include "com/sun/star/registry/XImplementationRegistration.hpp"
+#include "com/sun/star/script/ArrayWrapper.hpp"
+#include "com/sun/star/script/BasicErrorException.hpp"
+#include "com/sun/star/script/ScriptEventDescriptor.hpp"
+#include "com/sun/star/script/XAllListener.hpp"
+#include "com/sun/star/script/XDefaultMethod.hpp"
+#include "com/sun/star/script/XDefaultProperty.hpp"
+#include "com/sun/star/script/XEventAttacher.hpp"
+#include "com/sun/star/script/XInvocation.hpp"
+#include "com/sun/star/script/XInvocationAdapterFactory.hpp"
+#include "com/sun/star/script/XLibraryContainer.hpp"
+#include "com/sun/star/script/XLibraryContainer2.hpp"
+#include "com/sun/star/script/XLibraryContainerExport.hpp"
+#include "com/sun/star/script/XLibraryContainerPassword.hpp"
+#include "com/sun/star/script/XScriptEventsAttacher.hpp"
+#include "com/sun/star/script/XScriptEventsSupplier.hpp"
+#include "com/sun/star/script/XStarBasicAccess.hpp"
+#include "com/sun/star/script/XStarBasicDialogInfo.hpp"
+#include "com/sun/star/script/XStarBasicLibraryInfo.hpp"
+#include "com/sun/star/script/XStarBasicModuleInfo.hpp"
+#include "com/sun/star/script/XTypeConverter.hpp"
+#include "com/sun/star/script/provider/XScriptProvider.hpp"
+#include "com/sun/star/script/provider/XScriptProviderFactory.hpp"
+#include "com/sun/star/script/provider/XScriptProviderSupplier.hpp"
+#include "com/sun/star/task/ErrorCodeIOException.hpp"
+#include "com/sun/star/ucb/XContentProvider.hpp"
+#include "com/sun/star/ucb/XContentProviderManager.hpp"
+#include "com/sun/star/ucb/XSimpleFileAccess.hpp"
+#include "com/sun/star/ucb/XSimpleFileAccess3.hpp"
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/DeploymentException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/util/DateTime.hpp"
+#include "com/sun/star/util/XMacroExpander.hpp"
+#include "com/sun/star/util/XStringSubstitution.hpp"
+#include "com/sun/star/xml/sax/InputSource.hpp"
+#include "com/sun/star/xml/sax/XDocumentHandler.hpp"
+#include "com/sun/star/xml/sax/XExtendedDocumentHandler.hpp"
+#include "com/sun/star/xml/sax/XParser.hpp"
+
+#include "comphelper/anytostring.hxx"
+#include "comphelper/componentmodule.hxx"
+#include "comphelper/processfactory.hxx"
+#include "comphelper/regpathhelper.hxx"
+#include "comphelper/stl_types.hxx"
+#include "comphelper/storagehelper.hxx"
+
+#include "cppuhelper/basemutex.hxx"
+#include "cppuhelper/component.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/implbase5.hxx"
+#include "cppuhelper/interfacecontainer.hxx"
+#include "cppuhelper/servicefactory.hxx"
+#include "cppuhelper/typeprovider.hxx"
+
+#include "i18npool/lang.h"
+
+#include "osl/file.hxx"
+#include "osl/module.h"
+#include "osl/mutex.hxx"
+#include "osl/process.h"
+#include "osl/security.h"
+#include "osl/time.h"
+
+#include "rtl/byteseq.hxx"
+#include "rtl/digest.h"
+#include "rtl/instance.hxx"
+#include "rtl/math.hxx"
+#include "rtl/strbuf.hxx"
+#include "rtl/textenc.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.hxx"
+
+#include "sal/alloca.h"
+#include "sal/types.h"
+
+#include "sot/storage.hxx"
+#include "sot/storinfo.hxx"
+
+#include "svl/brdcst.hxx"
+#include "svtools/ctrlbox.hxx"
+#include "svtools/ctrltool.hxx"
+#include "svtools/ehdl.hxx"
+#include "svtools/filedlg.hxx"
+#include "svl/hint.hxx"
+#include "svl/lstner.hxx"
+#include "unotools/pathoptions.hxx"
+#include "svtools/sfxecode.hxx"
+#include "svl/smplhint.hxx"
+#include "svl/solar.hrc"
+#include "svtools/stringtransfer.hxx"
+#include "svl/svarray.hxx"
+#include "svl/svdde.hxx"
+#include "svtools/svmedit.hxx"
+#include "svl/svstdarr.hxx"
+#include "svtools/svtdata.hxx"
+#include "svtools/svtools.hrc"
+#include "svtools/svtreebx.hxx"
+#include "unotools/syslocale.hxx"
+#include "svtools/taskbar.hxx"
+#include "svtools/textdata.hxx"
+#include "svtools/texteng.hxx"
+#include "svtools/textview.hxx"
+#include "svtools/transfer.hxx"
+#include "svtools/txtattr.hxx"
+#include "svl/undo.hxx"
+#include "svl/zforlist.hxx"
+#include "svl/zformat.hxx"
+
+
+#include "tools/color.hxx"
+#include "tools/config.hxx"
+#include "tools/date.hxx"
+#include "tools/debug.hxx"
+#include "tools/diagnose_ex.h"
+#include "tools/errcode.hxx"
+#include "tools/errinf.hxx"
+#include "tools/fsys.hxx"
+#include "tools/gen.hxx"
+#include "tools/link.hxx"
+#include "tools/list.hxx"
+#include "tools/rc.hxx"
+#include "tools/rcid.h"
+#include "tools/ref.hxx"
+#include "tools/resid.hxx"
+#include "tools/rtti.hxx"
+#include "tools/shl.hxx"
+#include "tools/solar.h"
+#include "tools/stream.hxx"
+#include "tools/string.hxx"
+#include "tools/table.hxx"
+#include "tools/tenccvt.hxx"
+#include "tools/time.hxx"
+#include "tools/urlobj.hxx"
+#include "tools/wldcrd.hxx"
+
+#include "ucbhelper/configurationkeys.hxx"
+#include "ucbhelper/content.hxx"
+#include "ucbhelper/contentbroker.hxx"
+
+#include "unotools/charclass.hxx"
+#include "unotools/eventlisteneradapter.hxx"
+#include "unotools/localedatawrapper.hxx"
+#include "unotools/streamwrap.hxx"
+#include "unotools/transliterationwrapper.hxx"
+#include "unotools/ucbstreamhelper.hxx"
+
+
+#include "vcl/accel.hxx"
+#include "vcl/button.hxx"
+#include "vcl/decoview.hxx"
+#include "vcl/dialog.hxx"
+#include "vcl/dockwin.hxx"
+#include "vcl/edit.hxx"
+#include "vcl/field.hxx"
+#include "vcl/fixed.hxx"
+#include "vcl/floatwin.hxx"
+#include "vcl/font.hxx"
+#include "vcl/gradient.hxx"
+#include "vcl/graph.hxx"
+#include "vcl/help.hxx"
+#include "vcl/image.hxx"
+#include "vcl/jobset.hxx"
+#include "vcl/lstbox.hxx"
+#include "vcl/mapmod.hxx"
+#include "vcl/menu.hxx"
+#include "vcl/metric.hxx"
+#include "vcl/msgbox.hxx"
+#include "vcl/print.hxx"
+#include "vcl/scrbar.hxx"
+#include "vcl/settings.hxx"
+#include "vcl/sound.hxx"
+#include "vcl/splitwin.hxx"
+#include "vcl/status.hxx"
+#include "vcl/svapp.hxx"
+#include "vcl/tabctrl.hxx"
+#include "vcl/tabdlg.hxx"
+#include "vcl/tabpage.hxx"
+#include "vcl/timer.hxx"
+#include "vcl/toolbox.hxx"
+#include "vcl/window.hxx"
+#include "vcl/wintypes.hxx"
+#include "vcl/wrkwin.hxx"
+
+#include "vos/diagnose.hxx"
+#include "vos/macros.hxx"
+#include "vos/mutex.hxx"
+#include "vos/process.hxx"
+
+#include "xmlscript/xmldlg_imexp.hxx"
+#include "xmlscript/xmllib_imexp.hxx"
+#include "xmlscript/xmlmod_imexp.hxx"
+//---MARKER---
+
+#endif
diff --git a/basic/inc/sb.hrc b/basic/inc/sb.hrc
new file mode 100644
index 000000000000..c371d2abc046
--- /dev/null
+++ b/basic/inc/sb.hrc
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SB_HRC
+#define _SB_HRC
+
+#include <svl/solar.hrc>
+
+#ifndef IDS_SBERR_START
+ #define IDS_SBERR_START RID_BASIC_START
+#endif
+
+#define IDS_SBERR_TERMINATED IDS_SBERR_START+2000
+#define IDS_SBERR_STOREREF IDS_SBERR_START+2001
+
+// #define IDS_SBERR_LIBLOAD IDS_SBERR_START+2002
+// #define IDS_SBERR_LIBSAVE IDS_SBERR_START+2003
+// #define IDS_SBERR_MGROPEN IDS_SBERR_START+2004
+// #define IDS_SBERR_MGRSAVE IDS_SBERR_START+2005
+// #define IDS_SBERR_REMOVELIB IDS_SBERR_START+2006
+// #define IDS_SBERR_UNLOADLIB IDS_SBERR_START+2007
+
+#endif
diff --git a/basic/inc/sb.hxx b/basic/inc/sb.hxx
new file mode 100644
index 000000000000..ecc85bfa4000
--- /dev/null
+++ b/basic/inc/sb.hxx
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SB_HXX
+#define _SB_HXX
+
+#ifndef _SBERRORS_HXX
+ #include <basic/sberrors.hxx>
+#endif
+
+
+#include <basic/sbdef.hxx>
+#include <basic/sbmeth.hxx>
+#include <basic/sbmod.hxx>
+#include <basic/sbprop.hxx>
+#include <basic/sbstar.hxx>
+
+#endif
diff --git a/basic/inc/svtmsg.hrc b/basic/inc/svtmsg.hrc
new file mode 100644
index 000000000000..ff215d3fc9cb
--- /dev/null
+++ b/basic/inc/svtmsg.hrc
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#include "basic/ttglobal.hrc"
+
+
+// Here are the messages of /basic/source/app included
+
+///////////////////////////////
+// Error message that go to the Resultfile.
+// *********************
+// *** !!ATTENTION!! ***
+// *********************
+// Theses numbers MUST NOT change ever!
+// Because they are stored in the Resultfiles and if you showed them again
+// the appropriate new or no Strings are viewed.
+///////////////////////////////
+
+#define S_GPF_ABORT ( SVT_START + 0 )
+#define S_APP_SHUTDOWN ( SVT_START + 1 )
+#define S_SID_EXECUTE_FAILED_NO_DISPATCHER ( SVT_START + 2 )
+#define S_SID_EXECUTE_FAILED ( SVT_START + 3 )
+#define S_UNO_PROPERTY_NITIALIZE_FAILED ( SVT_START + 4 )
+#define S_RESETAPPLICATION_FAILED_COMPLEX ( SVT_START + 5 )
+#define S_RESETAPPLICATION_FAILED_UNKNOWN ( SVT_START + 6 )
+#define S_NO_ACTIVE_WINDOW ( SVT_START + 7 )
+#define S_NO_DIALOG_IN_GETACTIVE ( SVT_START + 8 )
+#define S_NO_POPUP ( SVT_START + 9 )
+#define S_NO_SUBMENU ( SVT_START + 10 )
+#define S_CONTROLTYPE_NOT_SUPPORTED ( SVT_START + 11 )
+#define S_SELECTION_BY_ATTRIBUTE_ONLY_DIRECTORIES ( SVT_START + 12 )
+#define S_NO_MORE_FILES ( SVT_START + 13 )
+#define S_UNKNOWN_METHOD ( SVT_START + 14 )
+#define S_INVALID_PARAMETERS ( SVT_START + 15 )
+#define S_POINTER_OUTSIDE_APPWIN ( SVT_START + 16 )
+#define S_UNKNOWN_COMMAND ( SVT_START + 17 )
+#define S_WIN_NOT_FOUND ( SVT_START + 18 )
+#define S_WIN_INVISIBLE ( SVT_START + 19 )
+#define S_WIN_DISABLED ( SVT_START + 20 )
+#define S_NUMBER_TOO_BIG ( SVT_START + 21 )
+#define S_NUMBER_TOO_SMALL ( SVT_START + 22 )
+#define S_WINDOW_DISAPPEARED ( SVT_START + 23 )
+#define S_ERROR_SAVING_IMAGE ( SVT_START + 24 )
+#define S_INVALID_POSITION ( SVT_START + 25 )
+#define S_SPLITWIN_NOT_FOUND ( SVT_START + 26 )
+#define S_INTERNAL_ERROR ( SVT_START + 27 )
+#define S_NO_STATUSBAR ( SVT_START + 28 )
+#define S_ITEMS_INVISIBLE ( SVT_START + 29 )
+#define S_TABPAGE_NOT_FOUND ( SVT_START + 30 )
+#define S_TRISTATE_NOT_ALLOWED ( SVT_START + 31 )
+#define S_ERROR_IN_SET_TEXT ( SVT_START + 32 )
+#define S_ATTEMPT_TO_WRITE_READONLY ( SVT_START + 33 )
+#define S_NO_SELECT_FALSE ( SVT_START + 34 )
+#define S_ENTRY_NOT_FOUND ( SVT_START + 35 )
+#define S_METHOD_FAILED ( SVT_START + 36 )
+#define S_HELPID_ON_TOOLBOX_NOT_FOUND ( SVT_START + 37 )
+#define S_BUTTON_DISABLED_ON_TOOLBOX ( SVT_START + 38 )
+#define S_BUTTON_HIDDEN_ON_TOOLBOX ( SVT_START + 39 )
+#define S_CANNOT_MAKE_BUTTON_VISIBLE_IN_TOOLBOX ( SVT_START + 40 )
+#define S_TEAROFF_FAILED ( SVT_START + 41 )
+#define S_NO_SELECTED_ENTRY_DEPRECATED ( SVT_START + 42 ) // Has to stay in for old res files
+#define S_SELECT_DESELECT_VIA_STRING_NOT_IMPLEMENTED ( SVT_START + 43 )
+#define S_ALLOWED_ONLY_IN_FLOATING_MODE ( SVT_START + 44 )
+#define S_ALLOWED_ONLY_IN_DOCKING_MODE ( SVT_START + 45 )
+#define S_SIZE_NOT_CHANGEABLE ( SVT_START + 46 )
+#define S_NO_OK_BUTTON ( SVT_START + 47 )
+#define S_NO_CANCEL_BUTTON ( SVT_START + 48 )
+#define S_NO_YES_BUTTON ( SVT_START + 49 )
+#define S_NO_NO_BUTTON ( SVT_START + 50 )
+#define S_NO_RETRY_BUTTON ( SVT_START + 51 )
+#define S_NO_HELP_BUTTON ( SVT_START + 52 )
+#define S_NO_DEFAULT_BUTTON ( SVT_START + 53 )
+#define S_BUTTON_ID_NOT_THERE ( SVT_START + 54 )
+#define S_BUTTONID_REQUIRED ( SVT_START + 55 )
+#define S_UNKNOWN_TYPE ( SVT_START + 56 )
+#define S_UNPACKING_STORAGE_FAILED ( SVT_START + 57 )
+#define S_NO_LIST_BOX_BUTTON ( SVT_START + 58 )
+#define S_UNO_URL_EXECUTE_FAILED_NO_DISPATCHER ( SVT_START + 59 )
+#define S_UNO_URL_EXECUTE_FAILED_NO_FRAME ( SVT_START + 60 )
+#define S_NO_MENU ( SVT_START + 61 )
+#define S_NO_SELECTED_ENTRY ( SVT_START + 62 )
+#define S_UNO_URL_EXECUTE_FAILED_DISABLED ( SVT_START + 63 )
+#define S_NO_SCROLLBAR ( SVT_START + 64 )
+#define S_NO_SAX_PARSER ( SVT_START + 65 )
+#define S_CANNOT_CREATE_DIRECTORY ( SVT_START + 66 )
+#define S_DIRECTORY_NOT_EMPTY ( SVT_START + 67 )
+#define S_DEPRECATED ( SVT_START + 68 )
+#define S_SIZE_BELOW_MINIMUM ( SVT_START + 69 )
+#define S_CANNOT_FIND_FLOATING_WIN ( SVT_START + 70 )
+#define S_NO_LIST_BOX_STRING ( SVT_START + 71 )
+#define S_SLOT_IN_EXECUTE ( SVT_START + 72 )
+#define S_MENU_NOT_CLOSING ( SVT_START + 73 )
diff --git a/basic/inc/testtool.hrc b/basic/inc/testtool.hrc
new file mode 100644
index 000000000000..075b462944c9
--- /dev/null
+++ b/basic/inc/testtool.hrc
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * 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 S_INVALID_KEYCODE 257
+#define S_MANDATORY_FILE 258
+#define S_READING_LONGNAMES 259
+#define S_READING_SLOT_IDS 260
+#define S_READING_CONTROLS 261
+#define S_READING_BASIC_MODULE 262
+#define S_STARTING_APPLICATION 263
+
+
+
diff --git a/basic/inc/ttmsg.hrc b/basic/inc/ttmsg.hrc
new file mode 100644
index 000000000000..26f250bc6a6a
--- /dev/null
+++ b/basic/inc/ttmsg.hrc
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#include "basic/ttglobal.hrc"
+
+
+// Here are the messages of directory /basic/source/testtool included
+
+///////////////////////////////
+// Error message that go to the Resultfile.
+// *********************
+// *** !!ATTENTION!! ***
+// *********************
+// Theses numbers MUST NOT change ever!
+// Because they are stored in the Resultfiles and if you showed them again
+// the appropriate new or no Strings are viewed.
+///////////////////////////////
+
+#define S_NAME_NOT_THERE ( TT_START + 0 )
+#define S_DOUBLE_NAME ( TT_START + 1 )
+#define S_READING_FILE ( TT_START + 2 )
+#define S_CANNOT_OPEN_FILE ( TT_START + 3 )
+#define S_INVALID_LINE ( TT_START + 4 )
+#define S_SHORTNAME_UNKNOWN ( TT_START + 5 )
+#define S_LONGNAME_UNKNOWN ( TT_START + 6 )
+#define S_FIRST_SHORTNAME_REQ_ASTRX ( TT_START + 7 )
+#define S_TIMOUT_WAITING ( TT_START + 8 )
+#define S_APPLICATION_RESTARTED ( TT_START + 9 )
+#define S_APPLICATION_START_FAILED ( TT_START + 10 )
+#define S_TIMOUT_SENDING ( TT_START + 11 )
+#define S_NO_CONNECTION ( TT_START + 12 )
+#define S_NO_FILES_FOUND ( TT_START + 13 ) // Not used anymore. needed only for old *.res files
+#define S_ERRORS_DETECTED ( TT_START + 14 )
+#define S_NO_ERRORS_DETECTED ( TT_START + 15 )
+#define S_WARNINGS_DETECTED ( TT_START + 16 )
+#define S_NO_WARNINGS_DETECTED ( TT_START + 17 )
+#define S_UNKNOWN_SLOT_CONTROL ( TT_START + 18 )
+#define S_RETURN_SEQUENCE_MISSMATCH ( TT_START + 19 )
+#define S_RETURNED_VALUE_ID_MISSMATCH ( TT_START + 20 )
+#define S_RETURNED_VALUE_NO_RECEIVER ( TT_START + 21 )
+#define S_UNKNOWN_METHOD ( TT_START + 22 )
+#define S_INCLUDE_FILE_WARNINGS_DETECTED ( TT_START + 23 )
+#define S_NO_INCLUDE_FILE_WARNINGS_DETECTED ( TT_START + 24 )
+
+// Strings
+
+
+/*
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+#define S_ ( TT_START + 0 )
+*/
diff --git a/basic/prj/build.lst b/basic/prj/build.lst
new file mode 100755
index 000000000000..c00a3d8412d3
--- /dev/null
+++ b/basic/prj/build.lst
@@ -0,0 +1,13 @@
+sb basic : l10n offuh oovbaapi svtools xmlscript framework salhelper NULL
+sb basic usr1 - all sb_mkout NULL
+sb basic\inc nmake - all sb_inc NULL
+sb basic\source\app nmake - all sb_app sb_class sb_inc NULL
+sb basic\source\basmgr nmake - all sb_mgr sb_inc NULL
+sb basic\source\classes nmake - all sb_class sb_inc NULL
+sb basic\source\comp nmake - all sb_comp sb_inc NULL
+sb basic\source\runtime nmake - all sb_rt sb_inc sb_class NULL
+sb basic\source\sample nmake - all sb_samp sb_inc NULL
+sb basic\source\sbx nmake - all sb_sbx sb_inc NULL
+sb basic\source\uno nmake - all sb_uno sb_inc NULL
+sb basic\util nmake - all sb_util sb_app sb_class sb_comp sb_mgr sb_rt sb_samp sb_sbx sb_uno NULL
+
diff --git a/basic/prj/d.lst b/basic/prj/d.lst
new file mode 100644
index 000000000000..d2a083ebcb1e
--- /dev/null
+++ b/basic/prj/d.lst
@@ -0,0 +1,59 @@
+mkdir: %COMMON_DEST%\bin%_EXT%\hid
+mkdir: %COMMON_DEST%\res%_EXT%
+
+..\%COMMON_OUTDIR%\misc\*.hid %COMMON_DEST%\bin%_EXT%\hid\*.hid
+..\%__SRC%\lib\basic.lib %_DEST%\lib%_EXT%\basic.lib
+..\%__SRC%\lib\lib*.so %_DEST%\lib%_EXT%
+..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*.dylib
+..\%__SRC%\lib\*.a %_DEST%\lib%_EXT%\*.a
+..\%__SRC%\slb\sb.lib %_DEST%\lib%_EXT%\xsb.lib
+..\%__SRC%\srs\classes.srs %_DEST%\res%_EXT%\basic.srs
+..\%COMMON_OUTDIR%\srs\classes_srs.hid %COMMON_DEST%\res%_EXT%\basic_srs.hid
+..\%__SRC%\bin\sb?????.dll %_DEST%\bin%_EXT%\sb?????.dll
+..\%__SRC%\bin\sb?????.sym %_DEST%\bin%_EXT%\sb?????.sym
+..\%__SRC%\misc\sb?????.map %_DEST%\bin%_EXT%\sb?????.map
+..\%__SRC%\bin\stt*.res %_DEST%\bin%_EXT%\stt*.res
+..\%__SRC%\bin\sb*.res %_DEST%\bin%_EXT%\sb*.res
+..\%__SRC%\lib\app.lib %_DEST%\lib%_EXT%\app.lib
+..\%__SRC%\lib\libapp.a %_DEST%\lib%_EXT%\libapp.a
+..\%__SRC%\lib\sample.lib %_DEST%\lib%_EXT%\sample.lib
+..\%__SRC%\lib\libsample.a %_DEST%\lib%_EXT%\libsample.a
+
+mkdir: %_DEST%\inc%_EXT%\basic
+..\inc\testtool.hrc %_DEST%\inc%_EXT%\basic\testtool.hrc
+..\inc\ttmsg.hrc %_DEST%\inc%_EXT%\basic\ttmsg.hrc
+..\inc\basic\ttglobal.hrc %_DEST%\inc%_EXT%\basic\ttglobal.hrc
+..\inc\svtmsg.hrc %_DEST%\inc%_EXT%\basic\svtmsg.hrc
+
+..\inc\basic\sbdef.hxx %_DEST%\inc%_EXT%\basic\sbdef.hxx
+..\inc\basic\sbmod.hxx %_DEST%\inc%_EXT%\basic\sbmod.hxx
+..\inc\basic\sbjsmod.hxx %_DEST%\inc%_EXT%\basic\sbjsmod.hxx
+..\inc\basic\sbmeth.hxx %_DEST%\inc%_EXT%\basic\sbmeth.hxx
+..\inc\basic\sbprop.hxx %_DEST%\inc%_EXT%\basic\sbprop.hxx
+..\inc\basic\sbstar.hxx %_DEST%\inc%_EXT%\basic\sbstar.hxx
+..\inc\basic\sbuno.hxx %_DEST%\inc%_EXT%\basic\sbuno.hxx
+..\inc\basic\basmgr.hxx %_DEST%\inc%_EXT%\basic\basmgr.hxx
+..\inc\basic\sberrors.hxx %_DEST%\inc%_EXT%\basic\sberrors.hxx
+..\inc\basic\basrdll.hxx %_DEST%\inc%_EXT%\basic\basrdll.hxx
+..\inc\basic\sbstdobj.hxx %_DEST%\inc%_EXT%\basic\sbstdobj.hxx
+..\inc\basic\process.hxx %_DEST%\inc%_EXT%\basic\process.hxx
+..\inc\basic\mybasic.hxx %_DEST%\inc%_EXT%\basic\mybasic.hxx
+..\inc\basic\testtool.hxx %_DEST%\inc%_EXT%\basic\testtool.hxx
+..\inc\basic\basicrt.hxx %_DEST%\inc%_EXT%\basic\basicrt.hxx
+..\inc\basic\dispdefs.hxx %_DEST%\inc%_EXT%\basic\dispdefs.hxx
+..\inc\basic\ttstrhlp.hxx %_DEST%\inc%_EXT%\basic\ttstrhlp.hxx
+
+..\inc\basic\sbx.hxx %_DEST%\inc%_EXT%\basic\sbx.hxx
+..\inc\basic\sbxcore.hxx %_DEST%\inc%_EXT%\basic\sbxcore.hxx
+..\inc\basic\sbxdef.hxx %_DEST%\inc%_EXT%\basic\sbxdef.hxx
+..\inc\basic\sbxform.hxx %_DEST%\inc%_EXT%\basic\sbxform.hxx
+..\inc\basic\sbxmeth.hxx %_DEST%\inc%_EXT%\basic\sbxmeth.hxx
+..\inc\basic\sbxobj.hxx %_DEST%\inc%_EXT%\basic\sbxobj.hxx
+..\inc\basic\sbxprop.hxx %_DEST%\inc%_EXT%\basic\sbxprop.hxx
+..\inc\basic\sbxvar.hxx %_DEST%\inc%_EXT%\basic\sbxvar.hxx
+..\inc\basic\sbxbase.hxx %_DEST%\inc%_EXT%\basic\sbxbase.hxx
+..\inc\basic\sbxfac.hxx %_DEST%\inc%_EXT%\basic\sbxfac.hxx
+..\inc\basic\sbxmstrm.hxx %_DEST%\inc%_EXT%\basic\sbxmstrm.hxx
+
+..\inc\basic\basicmanagerrepository.hxx %_DEST%\inc%_EXT%\basic\basicmanagerrepository.hxx
+..\inc\modsizeexceeded.hxx %_DEST%\inc%_EXT%\basic\modsizeexceeded.hxx
diff --git a/basic/source/app/app.cxx b/basic/source/app/app.cxx
new file mode 100644
index 000000000000..fd613a81673f
--- /dev/null
+++ b/basic/source/app/app.cxx
@@ -0,0 +1,1948 @@
+/*************************************************************************
+ *
+ * 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"
+
+#ifndef _MSGBOX_HXX //autogen
+#include <vcl/msgbox.hxx>
+#endif
+#include <tools/fsys.hxx>
+#ifndef _SV_FILEDLG_HXX //autogen
+#include <svtools/filedlg.hxx>
+#endif
+#include <tools/config.hxx>
+
+#include <vcl/font.hxx>
+
+#ifndef _BASIC_TTRESHLP_HXX
+#include <basic/ttstrhlp.hxx>
+#endif
+#include <basic/sbx.hxx>
+#include <svtools/filedlg.hxx>
+
+#include <osl/module.h>
+
+#include "basic.hrc"
+#include "app.hxx"
+#include "printer.hxx"
+#include "status.hxx"
+#include "appedit.hxx"
+#include "appbased.hxx"
+#include "apperror.hxx"
+#include <basic/mybasic.hxx>
+#include "ttbasic.hxx"
+#include "dialogs.hxx"
+#include <basic/basrdll.hxx>
+#include "basrid.hxx"
+
+#ifndef _RUNTIME_HXX
+#include "runtime.hxx"
+#endif
+#include "sbintern.hxx"
+
+#ifdef _USE_UNO
+#include <ucbhelper/contentbroker.hxx>
+#include <ucbhelper/configurationkeys.hxx>
+#include <comphelper/regpathhelper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <cppuhelper/bootstrap.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ucb/XContentProviderManager.hpp>
+
+#include <ucbhelper/content.hxx>
+#include <unotools/syslocale.hxx>
+
+using namespace comphelper;
+using namespace cppu;
+using namespace rtl;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::beans;
+
+#endif /* _USE_UNO */
+
+IMPL_GEN_RES_STR;
+
+#ifdef DBG_UTIL
+// filter Messages generated due to missing configuration Bug:#83887#
+void TestToolDebugMessageFilter( const sal_Char *pString, BOOL bIsOsl )
+{
+ static BOOL static_bInsideFilter = FALSE;
+
+ // Ignore messages during filtering to avoid endless recursions
+ if ( static_bInsideFilter )
+ return;
+
+ static_bInsideFilter = TRUE;
+
+ ByteString aMessage( pString );
+
+ BOOL bIgnore = FALSE;
+
+ if ( bIsOsl )
+ {
+ // OSL
+ if ( aMessage.Search( CByteString("Cannot open Configuration: Connector: unknown delegatee com.sun.star.connection.Connector.portal") ) != STRING_NOTFOUND )
+ bIgnore = TRUE;
+ }
+ else
+ {
+ // DBG
+#if ! (OSL_DEBUG_LEVEL > 1)
+ if ( aMessage.Search( CByteString("SelectAppIconPixmap") ) != STRING_NOTFOUND )
+ bIgnore = TRUE;
+#endif
+ if ( aMessage.Search( CByteString("PropertySetRegistry::") ) != STRING_NOTFOUND )
+ bIgnore = TRUE;
+ if ( aMessage.Search( CByteString("property value missing") ) != STRING_NOTFOUND )
+ bIgnore = TRUE;
+ if ( aMessage.Search( CByteString("getDateFormatsImpl") ) != STRING_NOTFOUND
+ && aMessage.Search( CByteString("no date formats") ) != STRING_NOTFOUND )
+ bIgnore = TRUE;
+ if ( aMessage.Search( CByteString("ucb::configureUcb(): Bad arguments") ) != STRING_NOTFOUND )
+ bIgnore = TRUE;
+ if ( aMessage.Search( CByteString("CreateInstance with arguments exception") ) != STRING_NOTFOUND )
+ bIgnore = TRUE;
+ if ( aMessage.Search( CByteString("AcquireTree failed") ) != STRING_NOTFOUND )
+ bIgnore = TRUE;
+ }
+
+
+ if ( bIgnore )
+ {
+ static_bInsideFilter = FALSE;
+ return;
+ }
+
+ if ( bIsOsl )
+ {
+ // due to issue #i36895 only print on console
+ // unfortunately the osl assertions deadlock by design :-( on recursive calls of assertions
+ printf("%s\n", pString );
+ }
+ else
+ {
+ try
+ {
+ aBasicApp.DbgPrintMsgBox( pString );
+ }
+ catch ( ... )
+
+ {
+ printf("DbgPrintMsgBox failed: %s\n", pString );
+ }
+ }
+/* DBG_INSTOUTERROR( DBG_OUT_MSGBOX )
+ DBG_ERROR( pString );
+ DBG_INSTOUTERROR( DBG_OUT_TESTTOOL )*/
+ static_bInsideFilter = FALSE;
+}
+void SAL_CALL DBG_TestToolDebugMessageFilter( const sal_Char *pString )
+{
+ TestToolDebugMessageFilter( pString, FALSE );
+}
+extern "C" void SAL_CALL osl_TestToolDebugMessageFilter( const sal_Char *pString )
+{
+ if ( !getenv( "DISABLE_SAL_DBGBOX" ) )
+ TestToolDebugMessageFilter( pString, TRUE );
+}
+#endif
+
+// #94145# Due to a tab in TT_SIGNATURE_FOR_UNICODE_TEXTFILES which is changed to blanks by some editors
+// this routine became necessary
+BOOL IsTTSignatureForUnicodeTextfile( String aLine )
+{
+ aLine.SearchAndReplace( '\t', ' ' );
+ String ThreeBlanks = CUniString(" ");
+ String TwoBlanks = CUniString(" ");
+ while ( aLine.SearchAndReplace( ThreeBlanks, TwoBlanks ) != STRING_NOTFOUND )
+ {}
+ return aLine.EqualsAscii( TT_SIGNATURE_FOR_UNICODE_TEXTFILES );
+}
+
+BasicApp aBasicApp; // Application instance
+
+uno::Reference< XContentProviderManager > InitializeUCB( void )
+{
+ uno::Reference< XMultiServiceFactory > xSMgr;
+ try
+ {
+ xSMgr = uno::Reference< XMultiServiceFactory >(
+ defaultBootstrap_InitialComponentContext()->getServiceManager(),
+ UNO_QUERY_THROW);
+ }
+ catch( com::sun::star::uno::Exception & exc )
+ {
+ fprintf( stderr, "Couldn't bootstrap uno servicemanager for reason : %s\n" ,
+ OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ InfoBox( NULL, String( exc.Message ) ).Execute();
+ throw ;
+ }
+
+
+ //////////////////////////////////////////////////////////////////////
+ // set global factory
+ setProcessServiceFactory( xSMgr );
+
+/* // Create simple ConfigManager
+ Sequence< Any > aConfArgs(3);
+ aConfArgs[0] <<= PropertyValue( OUString::createFromAscii("servertype"), 0, makeAny( OUString::createFromAscii("local") ), ::com::sun::star::beans::PropertyState_DIRECT_VALUE );
+ aConfArgs[1] <<= PropertyValue( OUString::createFromAscii("sourcepath"), 0, makeAny( OUString::createFromAscii("g:\\") ), ::com::sun::star::beans::PropertyState_DIRECT_VALUE );
+ aConfArgs[2] <<= PropertyValue( OUString::createFromAscii("updatepath"), 0, makeAny( OUString::createFromAscii("g:\\") ), ::com::sun::star::beans::PropertyState_DIRECT_VALUE );
+
+ uno::Reference< XContentProvider > xConfProvider
+ ( xSMgr->createInstanceWithArguments( OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" ), aConfArgs), UNO_QUERY );
+*/
+
+
+// Create unconfigured Ucb:
+/* Sequence< Any > aArgs(1);
+ aArgs[1] = makeAny ( xConfProvider );*/
+ Sequence< Any > aArgs;
+ ::ucbhelper::ContentBroker::initialize( xSMgr, aArgs );
+ uno::Reference< XContentProviderManager > xUcb =
+ ::ucbhelper::ContentBroker::get()->getContentProviderManagerInterface();
+
+ uno::Reference< XContentProvider > xFileProvider
+ ( xSMgr->createInstance( OUString::createFromAscii( "com.sun.star.ucb.FileContentProvider" ) ), UNO_QUERY );
+ xUcb->registerContentProvider( xFileProvider, OUString::createFromAscii( "file" ), sal_True );
+
+
+/* uno::Reference< XContentProvider > xPackageProvider
+ ( xSMgr->createInstance( OUString::createFromAscii( "com.sun.star.ucb.PackageContentProvider" ) ), UNO_QUERY );
+ xUcb->registerContentProvider( xPackageProvider, OUString::createFromAscii( "vnd.sun.star.pkg" ), sal_True );
+ */
+
+ return xUcb;
+}
+
+static void ReplaceStringHookProc( UniString& rStr )
+{
+ static String aTestToolName( RTL_CONSTASCII_USTRINGPARAM( "VCLTestTool" ) ); // HACK, should be read from ressources
+
+ if ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND )
+ {
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTNAME", aTestToolName );
+ /*
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTVERSION", rVersion );
+ rStr.SearchAndReplaceAllAscii( "%ABOUTBOXPRODUCTVERSION", rAboutBoxVersion );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTEXTENSION", rExtension );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTXMLFILEFORMATNAME", rXMLFileFormatName );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTXMLFILEFORMATVERSION", rXMLFileFormatVersion );
+ */
+ }
+}
+
+void BasicApp::Main( )
+{
+#ifdef DBG_UTIL
+// Install filter for OSLAsserts
+ DbgPrintMsgBox = DbgGetPrintMsgBox();
+ DbgSetPrintTestTool( DBG_TestToolDebugMessageFilter );
+ DBG_INSTOUTERROR( DBG_OUT_TESTTOOL );
+
+ if ( osl_setDebugMessageFunc( osl_TestToolDebugMessageFilter ) )
+ DBG_ERROR("osl_setDebugMessageFunc returns non NULL pointer");
+#endif
+
+ ResMgr::SetReadStringHook( ReplaceStringHookProc );
+
+ try
+ {
+#ifdef _USE_UNO
+ uno::Reference< XContentProviderManager > xUcb = InitializeUCB();
+#endif
+
+ {
+ DirEntry aIniPath( Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ) );
+ if ( !aIniPath.Exists() )
+ { // look for it besides the executable
+ DirEntry aAppFileName( GetAppFileName() );
+ String aAppDir ( aAppFileName.GetPath().GetFull() );
+
+// DirEntry aDefIniPath( Config::GetConfigName( aAppDir, CUniString("testtool") ) );
+// Do not use Config::GetConfigName here because is uses a hidden file for UNIX
+
+ DirEntry aDefIniPath( aAppDir );
+ ByteString aFileName;
+#ifdef UNX
+ aFileName = "testtoolrc";
+#else
+ aFileName = "testtool.ini";
+#endif
+ aDefIniPath += DirEntry( aFileName );
+
+ if ( aDefIniPath.Exists() )
+ {
+ aDefIniPath.CopyTo( aIniPath, FSYS_ACTION_COPYFILE );
+ FileStat::SetReadOnlyFlag( aIniPath, FALSE );
+ }
+ }
+ }
+
+ {
+ LanguageType aRequestedLanguage;
+ Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
+
+ // 1033 = LANGUAGE_ENGLISH_US
+ // 1031 = LANGUAGE_GERMAN
+ aConf.SetGroup("Misc");
+ ByteString aLang = aConf.ReadKey( "Language", ByteString::CreateFromInt32( LANGUAGE_SYSTEM ) );
+ aRequestedLanguage = LanguageType( aLang.ToInt32() );
+
+ AllSettings aSettings = GetSettings();
+ aSettings.SetUILanguage( aRequestedLanguage );
+ aSettings.SetLanguage( aRequestedLanguage );
+// International aInternational;
+// aInternational = GetSettings().GetInternational();
+// aInternational = International( aRequestedLanguage );
+// aSettings.SetInternational( aInternational );
+ SetSettings( aSettings );
+// aInternational = GetSettings().GetInternational();
+ }
+
+// ResMgr::CreateResMgr( CREATEVERSIONRESMGR( stt ), )
+//const char* ResMgr::GetLang( LanguageType& nType, USHORT nPrio )
+
+// ResMgr::CreateResMgr( CREATEVERSIONRESMGR( stt )
+// ResMgr *pRes = new ResMgr( "testtool.res" );
+// Resource::SetResManager( pRes );
+
+ BasicDLL aBasicDLL;
+ nWait = 0;
+
+ // Hilfe:
+// pHelp = new Help;
+// SetHelp( pHelp );
+// Help::EnableContextHelp();
+// Help::EnableExtHelp();
+// DeactivateExtHelp();
+
+ // Acceleratoren
+ Accelerator aAccel( SttResId( MAIN_ACCEL ) );
+ InsertAccel( &aAccel );
+ pMainAccel = &aAccel;
+
+ // Frame Window:
+ pFrame = new BasicFrame;
+ aAccel.SetSelectHdl( LINK( pFrame, BasicFrame, Accel ) );
+
+ pFrame->Show();
+
+ SetSystemWindowMode( SYSTEMWINDOW_MODE_NOAUTOMODE );
+ SetSystemWindowMode( SYSTEMWINDOW_MODE_DIALOG );
+
+ // Instantiate a SvtSysLocale to avoid permant instatiation
+ // and deletion of SvtSysLocale_Impl in SvtSysLocale Ctor/Dtor
+ // because in the testtool szenario Basic is the only instance
+ // instatiating SvtSysLocale (#107417).
+ SvtSysLocale aSysLocale;
+
+ PostUserEvent( LINK( this, BasicApp, LateInit ) );
+ Execute();
+
+// delete pHelp;
+ delete pFrame;
+
+ RemoveAccel( pMainAccel );
+
+ }
+ catch( class Exception & rEx)
+ {
+ printf( "Exception not caught: %s\n", ByteString( String(rEx.Message), RTL_TEXTENCODING_ASCII_US ).GetBuffer() );
+ String aMsg( String::CreateFromAscii( "Exception not caught: " ) );
+ aMsg.Append( String( rEx.Message ) );
+ InfoBox( NULL, aMsg ).Execute();
+ throw;
+ }
+ catch( ... )
+ {
+ printf( "unknown Exception not caught\n" );
+ InfoBox( NULL, String::CreateFromAscii( "unknown Exception not caught" ) ).Execute();
+ throw;
+ }
+}
+
+void BasicApp::LoadIniFile()
+{
+ pFrame->LoadIniFile();
+}
+
+void BasicApp::SetFocus()
+{
+ if( pFrame->pWork && pFrame->pWork->ISA(AppEdit) )
+ ((AppEdit*)pFrame->pWork)->pDataEdit->GrabFocus();
+}
+
+IMPL_LINK( BasicApp, LateInit, void *, pDummy )
+{
+ (void) pDummy; /* avoid warning about unused parameter */
+ USHORT i;
+ for ( i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
+ {
+ if ( Application::GetCommandLineParam( i ).Copy(0,4).CompareIgnoreCaseToAscii("-run") == COMPARE_EQUAL
+#ifndef UNX
+ || Application::GetCommandLineParam( i ).Copy(0,4).CompareIgnoreCaseToAscii("/run") == COMPARE_EQUAL
+#endif
+ )
+ pFrame->SetAutoRun( TRUE );
+ else if ( Application::GetCommandLineParam( i ).Copy(0,7).CompareIgnoreCaseToAscii("-result") == COMPARE_EQUAL
+#ifndef UNX
+ || Application::GetCommandLineParam( i ).Copy(0,7).CompareIgnoreCaseToAscii("/result") == COMPARE_EQUAL
+#endif
+ )
+ {
+ if ( (i+1) < Application::GetCommandLineParamCount() )
+ {
+ if ( ByteString( Application::GetCommandLineParam( i+1 ), osl_getThreadTextEncoding() ).IsNumericAscii() )
+ {
+ MsgEdit::SetMaxLogLen( sal::static_int_cast< USHORT >( Application::GetCommandLineParam( i+1 ).ToInt32() ) );
+ }
+ i++;
+ }
+ }
+ }
+
+ // now load the files after the switches have been set. Espechially -run is of interest sunce it changes the behavior
+ for ( i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
+ {
+ if ( Application::GetCommandLineParam( i ).Copy(0,1).CompareToAscii("-") != COMPARE_EQUAL
+#ifndef UNX
+ && Application::GetCommandLineParam( i ).Copy(0,1).CompareToAscii("/") != COMPARE_EQUAL
+#endif
+ )
+ {
+ pFrame->LoadFile( Application::GetCommandLineParam( i ) );
+ }
+ else if ( Application::GetCommandLineParam( i ).Copy(0,7).CompareIgnoreCaseToAscii("-result") == COMPARE_EQUAL
+#ifndef UNX
+ || Application::GetCommandLineParam( i ).Copy(0,7).CompareIgnoreCaseToAscii("/result") == COMPARE_EQUAL
+#endif
+ )
+ { // Increment count to skip the parameter. This works even if it is not given
+ i++;
+ }
+ }
+
+ pFrame->pStatus->SetStatusSize( pFrame->pStatus->GetStatusSize()+1 );
+ pFrame->pStatus->SetStatusSize( pFrame->pStatus->GetStatusSize()-1 );
+
+ if ( pFrame->IsAutoRun() )
+ {
+ pFrame->Command( RID_RUNSTART );
+ }
+
+ if ( pFrame->IsAutoRun() )
+ pFrame->Command( RID_QUIT );
+
+ return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+class FloatingExecutionStatus : public FloatingWindow
+{
+public:
+ FloatingExecutionStatus( Window * pParent );
+ void SetStatus( String aW );
+ void SetAdditionalInfo( String aF );
+
+private:
+ Timer aAusblend;
+ DECL_LINK(HideNow, FloatingExecutionStatus* );
+ FixedText aStatus;
+ FixedText aAdditionalInfo;
+};
+
+
+FloatingExecutionStatus::FloatingExecutionStatus( Window * pParent )
+ : FloatingWindow( pParent, SttResId(LOAD_CONF) ),
+ aStatus( this, SttResId( WORK ) ),
+ aAdditionalInfo( this, SttResId( FILENAME ) )
+{
+ FreeResource();
+ aAusblend.SetTimeoutHdl( LINK(this, FloatingExecutionStatus, HideNow ) );
+ aAusblend.SetTimeout(5000); // in ms
+ aAusblend.Start();
+}
+
+void FloatingExecutionStatus::SetStatus( String aW )
+{
+ Show( TRUE, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
+ ToTop( TOTOP_NOGRABFOCUS );
+ aAusblend.Start();
+ aStatus.SetText( aW );
+}
+
+void FloatingExecutionStatus::SetAdditionalInfo( String aF )
+{
+ Show( TRUE, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
+ ToTop( TOTOP_NOGRABFOCUS );
+ aAusblend.Start();
+ aAdditionalInfo.SetText( aF );
+}
+
+IMPL_LINK(FloatingExecutionStatus, HideNow, FloatingExecutionStatus*, pFLC )
+{
+ (void) pFLC; /* avoid warning about unused parameter */
+ Hide();
+ return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(TTExecutionStatusHint, SfxSimpleHint);
+
+BasicFrame::BasicFrame() : WorkWindow( NULL,
+ WinBits( WB_APP | WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE ) )
+, bIsAutoRun( FALSE )
+, pDisplayHidDlg( NULL )
+, pEditVar ( 0 )
+, bAutoReload( FALSE )
+, bAutoSave( TRUE )
+, pBasic( NULL )
+, pExecutionStatus( NULL )
+, pStatus( NULL )
+, pList( NULL )
+, pWork( NULL )
+, pPrn( NULL )
+{
+
+ Application::SetDefDialogParent( this );
+ AlwaysEnableInput( TRUE );
+ pBasic = TTBasic::CreateMyBasic(); // depending on what was linked to the executable
+ bInBreak = FALSE;
+ bDisas = FALSE;
+ nFlags = 0;
+// Icon aAppIcon;
+
+ if ( pBasic->pTestObject ) // Are we the testtool?
+ {
+// aAppIcon = Icon( ResId( RID_APPICON2 ) );
+ aAppName = String( SttResId( IDS_APPNAME2 ) );
+ }
+ else
+ {
+// aAppIcon = Icon( ResId( RID_APPICON ) );
+ aAppName = String( SttResId( IDS_APPNAME ) );
+ }
+
+ // Menu:
+ MenuBar *pBar = new MenuBar( SttResId( RID_APPMENUBAR ) );
+ SetMenuBar( pBar );
+
+ pBar->SetHighlightHdl( LINK( this, BasicFrame, HighlightMenu ) );
+
+
+ // Menu Handler:
+ PopupMenu* pFileMenu = pBar->GetPopupMenu( RID_APPFILE );
+ pFileMenu->SetSelectHdl( LINK( this, BasicFrame, MenuCommand ) );
+ pFileMenu->SetHighlightHdl( LINK( this, BasicFrame, HighlightMenu ) );
+ pFileMenu->SetActivateHdl( LINK( this, BasicFrame, InitMenu ) );
+ pFileMenu->SetDeactivateHdl( LINK( this, BasicFrame, DeInitMenu ) );
+ if (Basic().pTestObject ) // Are we TestTool?
+ {
+ pFileMenu->RemoveItem( pFileMenu->GetItemPos( RID_FILELOADLIB ) -1 ); // Separator before
+ pFileMenu->RemoveItem( pFileMenu->GetItemPos( RID_FILELOADLIB ) );
+ pFileMenu->RemoveItem( pFileMenu->GetItemPos( RID_FILESAVELIB ) );
+ }
+
+ PopupMenu* pEditMenu = pBar->GetPopupMenu( RID_APPEDIT );
+ pEditMenu->SetSelectHdl( LINK( this, BasicFrame, MenuCommand ) );
+ pEditMenu->SetHighlightHdl( LINK( this, BasicFrame, HighlightMenu ) );
+ pEditMenu->SetActivateHdl( LINK( this, BasicFrame, InitMenu ) );
+ pEditMenu->SetDeactivateHdl( LINK( this, BasicFrame, DeInitMenu ) );
+ PopupMenu* pRunMenu = pBar->GetPopupMenu( RID_APPRUN );
+ pRunMenu->SetSelectHdl( LINK( this, BasicFrame, MenuCommand ) );
+ pRunMenu->SetHighlightHdl( LINK( this, BasicFrame, HighlightMenu ) );
+ pRunMenu->SetActivateHdl( LINK( this, BasicFrame, InitMenu ) );
+ pRunMenu->SetDeactivateHdl( LINK( this, BasicFrame, DeInitMenu ) );
+ if (Basic().pTestObject ) // Are we TestTool?
+ {
+ pRunMenu->RemoveItem( pRunMenu->GetItemPos( RID_RUNDISAS ) );
+ pRunMenu->RemoveItem( pRunMenu->GetItemPos( RID_RUNCOMPILE ) );
+ }
+
+ PopupMenu *pExtras;
+ if (Basic().pTestObject ) // Are we TestTool?
+ {
+ pExtras = new PopupMenu( SttResId( RID_TT_EXTRAS ) );
+ pBar->InsertItem( RID_TT_EXTRAS, String( SttResId( RID_TT_EXTRAS_NAME ) ), 0, pBar->GetItemPos( RID_APPWINDOW ) );
+ pBar->SetPopupMenu( RID_TT_EXTRAS, pExtras );
+
+ pExtras->SetSelectHdl( LINK( this, BasicFrame, MenuCommand ) );
+ pExtras->SetHighlightHdl( LINK( this, BasicFrame, HighlightMenu ) );
+ pExtras->SetDeactivateHdl( LINK( this, BasicFrame, DeInitMenu ) );
+ }
+
+ PopupMenu* pWinMenu = pBar->GetPopupMenu( RID_APPWINDOW );
+ pWinMenu->SetSelectHdl( LINK( this, BasicFrame, MenuCommand ) );
+ pWinMenu->SetHighlightHdl( LINK( this, BasicFrame, HighlightMenu ) );
+ pWinMenu->SetDeactivateHdl( LINK( this, BasicFrame, DeInitMenu ) );
+ PopupMenu* pHelpMenu = pBar->GetPopupMenu( RID_APPHELP );
+ pHelpMenu->SetSelectHdl( LINK( this, BasicFrame, MenuCommand ) );
+ pHelpMenu->SetHighlightHdl( LINK( this, BasicFrame, HighlightMenu ) );
+ pHelpMenu->SetActivateHdl( LINK( this, BasicFrame, InitMenu ) );
+ pHelpMenu->SetDeactivateHdl( LINK( this, BasicFrame, DeInitMenu ) );
+
+#ifndef UNX
+ pPrn = new BasicPrinter;
+#else
+ pPrn = NULL;
+#endif
+ pList = new EditList;
+ pStatus = new StatusLine( this );
+
+ LoadIniFile();
+
+ UpdateTitle();
+// SetIcon( aAppIcon );
+
+ // Size: half width, 0.75 * height - 2 * IconSize
+ {
+ Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
+ aConf.SetGroup("WinGeom");
+ SetWindowState( aConf.ReadKey("WinParams", "") );
+ }
+
+// pWork = new AppEdit( this, NULL );
+// pWork->Show();
+// pWork->Close();
+
+ aLineNum.SetTimeoutHdl( LINK( this, BasicFrame, ShowLineNr ) );
+ aLineNum.SetTimeout(200);
+ aLineNum.Start();
+
+
+ aCheckFiles.SetTimeout( 10000 );
+ aCheckFiles.SetTimeoutHdl( LINK( this, BasicFrame, CheckAllFiles ) );
+ aCheckFiles.Start();
+
+ GetMenuBar()->SetCloserHdl( LINK( this, BasicFrame, CloseButtonClick ) );
+ GetMenuBar()->SetFloatButtonClickHdl( LINK( this, BasicFrame, FloatButtonClick ) );
+ GetMenuBar()->SetHideButtonClickHdl( LINK( this, BasicFrame, HideButtonClick ) );
+}
+
+const ByteString ProfilePrefix("_profile_");
+const USHORT ProfilePrefixLen = ProfilePrefix.Len();
+
+void BasicFrame::LoadIniFile()
+{
+ USHORT i;
+ Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
+
+ for ( i = 0 ; i < aConf.GetGroupCount() ; i++ )
+ {
+ aConf.SetGroup( ByteString( aConf.GetGroupName( i ) ) );
+ if ( ( aConf.ReadKey( "Aktuell" ).Len() || aConf.ReadKey( "Alle" ).Len() )
+ &&( !aConf.ReadKey( "Current" ).Len() && !aConf.ReadKey( "All" ).Len() ) )
+ {
+ aConf.WriteKey( "Current", aConf.ReadKey( "Aktuell" ) );
+ aConf.WriteKey( "All", aConf.ReadKey( "Alle" ) );
+ }
+ }
+
+ aConf.SetGroup("Misc");
+ ByteString aTemp;
+ ByteString aCurrentProfile = aConf.ReadKey( "CurrentProfile", "Misc" );
+
+ pStatus->SetProfileName( String( aCurrentProfile.Copy( ProfilePrefixLen ), RTL_TEXTENCODING_UTF8 ) );
+
+ aConf.SetGroup( aCurrentProfile );
+ aTemp = aConf.ReadKey( "AutoReload", "0" );
+ bAutoReload = ( aTemp.CompareTo("1") == COMPARE_EQUAL );
+ aTemp = aConf.ReadKey( "AutoSave", "0" );
+ bAutoSave = ( aTemp.CompareTo("1") == COMPARE_EQUAL );
+
+ LoadLRU();
+
+ if ( pBasic )
+ pBasic->LoadIniFile();
+
+ for ( i = 0 ; i < pList->Count() ; i++ )
+ pList->GetObject( i )->LoadIniFile();
+}
+
+BasicFrame::~BasicFrame()
+{
+ AppWin* p = pList->First();
+ DBG_ASSERT( !p, "Still open FileWindows");
+ if( p )
+ while( (p = pList->Remove() ) != NULL )
+ delete p;
+
+ MenuBar *pBar = GetMenuBar();
+ SetMenuBar( NULL );
+ delete pBar;
+
+ delete pStatus;
+ delete pPrn;
+ delete pList;
+// delete pExecutionStatus;
+// delete pBasic;
+ pBasic.Clear();
+}
+
+void BasicFrame::Command( const CommandEvent& rCEvt )
+{
+ switch( rCEvt.GetCommand() ) {
+ case COMMAND_SHOWDIALOG:
+ {
+ const CommandDialogData* pData = rCEvt.GetDialogData();
+ if ( pData)
+ {
+ const int nCommand = pData->GetDialogId();
+
+ switch (nCommand)
+ {
+ case SHOWDIALOG_ID_PREFERENCES :
+ Command( RID_OPTIONS );
+ break;
+
+ case SHOWDIALOG_ID_ABOUT :
+ Command( RID_HELPABOUT );
+ break;
+
+ default :
+ ;
+ }
+ }
+ }
+ break;
+ }
+}
+
+void BasicFrame::UpdateTitle()
+{
+ String aTitle;
+ aTitle += aAppName;
+ if ( aAppMode.Len() )
+ {
+ aTitle.AppendAscii(" [");
+ aTitle += aAppMode;
+ aTitle.AppendAscii("]");
+ }
+ aTitle.AppendAscii(" - ");
+ aTitle += aAppFile;
+ SetText( aTitle );
+}
+
+IMPL_LINK( BasicFrame, CheckAllFiles, Timer*, pTimer )
+{
+ if ( pWork )
+ {
+ AppWin* pStartWin = pWork;
+ Window* pFocusWin = Application::GetFocusWindow();
+ for ( int i = pList->Count()-1 ; i >= 0 ; i-- )
+ pList->GetObject( i )->CheckReload();
+
+ if ( pWork != pStartWin )
+ {
+ pWork = pStartWin;
+ pWork->ToTop();
+ }
+ if ( pFocusWin )
+ pFocusWin->GrabFocus();
+ }
+ pTimer->Start();
+ return 0;
+}
+
+BOOL BasicFrame::IsAutoRun()
+{
+ return bIsAutoRun;
+}
+
+void BasicFrame::SetAutoRun( BOOL bAuto )
+{
+ bIsAutoRun = bAuto;
+}
+
+void BasicFrame::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( TTExecutionStatusHint ) )
+ {
+ TTExecutionStatusHint *pStatusHint = ( TTExecutionStatusHint* )&rHint;
+ switch ( pStatusHint->GetType() )
+ {
+ case TT_EXECUTION_ENTERWAIT:
+ {
+ EnterWait();
+ }
+ break;
+ case TT_EXECUTION_LEAVEWAIT:
+ {
+ LeaveWait();
+ }
+ break;
+ case TT_EXECUTION_SHOW_ACTION:
+ {
+ String aTotalStatus( pStatusHint->GetExecutionStatus() );
+ aTotalStatus.AppendAscii( " " );
+ aTotalStatus.Append( pStatusHint->GetAdditionalExecutionStatus() );
+ pStatus->Message( aTotalStatus );
+/* if ( !pExecutionStatus )
+ pExecutionStatus = new FloatingExecutionStatus( this );
+ pExecutionStatus->SetStatus( pStatusHint->GetExecutionStatus() );
+ pExecutionStatus->SetAdditionalInfo( pStatusHint->GetAdditionalExecutionStatus() );*/
+ }
+ break;
+ case TT_EXECUTION_HIDE_ACTION:
+ {
+/* if ( pExecutionStatus )
+ {
+ delete pExecutionStatus;
+ pExecutionStatus = NULL;
+ }*/
+ }
+ break;
+ }
+ }
+
+
+ Broadcast( rHint );
+}
+
+void BasicFrame::Resize()
+{
+ Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
+ aConf.SetGroup("WinGeom");
+ aConf.WriteKey("WinParams",GetWindowState());
+
+ // Statusbar
+ Size aOutSize = GetOutputSizePixel();
+ Size aStatusSize = pStatus->GetSizePixel();
+ Point aStatusPos( 0, aOutSize.Height() - aStatusSize.Height() );
+ aStatusSize.Width() = aOutSize.Width();
+
+ pStatus->SetPosPixel( aStatusPos );
+ pStatus->SetSizePixel( aStatusSize );
+
+
+ // Resize possibly maximized window
+ ULONG i;
+ for( i = pList->Count(); i > 0 ; i-- )
+ {
+ if ( pList->GetObject( i-1 )->GetWinState() == TT_WIN_STATE_MAX )
+ pList->GetObject( i-1 )->Maximize();
+ }
+}
+
+void BasicFrame::Move()
+{
+ Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
+ aConf.SetGroup("WinGeom");
+ aConf.WriteKey("WinParams",GetWindowState());
+}
+
+void BasicFrame::GetFocus()
+{
+ if ( pWork )
+ pWork->GrabFocus();
+}
+
+IMPL_LINK( BasicFrame, CloseButtonClick, void*, EMPTYARG )
+{
+ AppWin* p;
+ for ( p = pList->Last() ; p && p->GetWinState() != TT_WIN_STATE_MAX ; p = pList->Prev() )
+ {};
+ if ( p )
+ p->GrabFocus();
+ return Command( RID_FILECLOSE, FALSE );
+}
+
+IMPL_LINK( BasicFrame, FloatButtonClick, void*, EMPTYARG )
+{
+ AppWin* p;
+ for ( p = pList->Last() ; p && p->GetWinState() != TT_WIN_STATE_MAX ; p = pList->Prev() )
+ {};
+ if ( p )
+ p->TitleButtonClick( TITLE_BUTTON_DOCKING );
+ return 1;
+}
+
+IMPL_LINK( BasicFrame, HideButtonClick, void*, EMPTYARG )
+{
+ AppWin* p;
+ for ( p = pList->Last() ; p && p->GetWinState() != TT_WIN_STATE_MAX ; p = pList->Prev() )
+ {};
+ if ( p )
+ p->TitleButtonClick( TITLE_BUTTON_HIDE );
+ return 1;
+}
+
+void BasicFrame::WinShow_Hide()
+{
+ if ( !pList->Count() )
+ return;
+
+ AppWin* p;
+ BOOL bWasFullscreen = FALSE;
+ for ( p = pList->Last() ; p ; p = pList->Prev() )
+ {
+ if ( p->pDataEdit )
+ {
+ if ( p->GetWinState() & TT_WIN_STATE_HIDE // Hidden
+ || ( bWasFullscreen && ( !p->IsPined() || p->GetWinState() & TT_WIN_STATE_MAX ))
+ )
+ p->Hide( SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
+ else
+ p->Show( TRUE, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
+ }
+ bWasFullscreen |= p->GetWinState() == TT_WIN_STATE_MAX;
+ }
+}
+
+void BasicFrame::WinMax_Restore()
+{
+ // The application buttons
+ AppWin* p;
+ BOOL bHasFullscreenWin = FALSE;
+ for( p = pList->First(); p && !bHasFullscreenWin ; p = pList->Next() )
+ bHasFullscreenWin |= ( p->GetWinState() == TT_WIN_STATE_MAX );
+ GetMenuBar()->ShowButtons( bHasFullscreenWin, FALSE, FALSE );
+ WinShow_Hide();
+}
+
+void BasicFrame::RemoveWindow( AppWin *pWin )
+{
+// delete pIcon;
+ pList->Remove( pWin );
+ pWork = pList->Last();
+
+ WinShow_Hide();
+
+ if ( pWork )
+ pWork->ToTop();
+
+ WinMax_Restore();
+
+ Menu* pMenu = GetMenuBar();
+ if( pList->Count() == 0 ) {
+ pMenu->EnableItem( RID_APPEDIT, FALSE );
+ pMenu->EnableItem( RID_APPRUN, FALSE );
+ pMenu->EnableItem( RID_APPWINDOW, FALSE );
+ }
+
+ PopupMenu* pWinMenu = pMenu->GetPopupMenu( RID_APPWINDOW );
+
+ pWinMenu->RemoveItem( pWinMenu->GetItemPos( pWin->GetWinId() ) );
+
+ // Remove separator
+ if ( pWinMenu->GetItemType( pWinMenu->GetItemCount() - 1 ) == MENUITEM_SEPARATOR )
+ pWinMenu->RemoveItem( pWinMenu->GetItemCount() - 1 );
+
+ pStatus->LoadTaskToolBox();
+}
+
+void BasicFrame::AddWindow( AppWin *pWin )
+{
+ pList->Insert( pWin, LIST_APPEND );
+ pWork = pWin;
+
+ WinMax_Restore();
+
+ // Enable main menu
+ MenuBar* pMenu = GetMenuBar();
+ if( pList->Count() > 0 ) {
+ pMenu->EnableItem( RID_APPEDIT, TRUE );
+ pMenu->EnableItem( RID_APPRUN, TRUE );
+ pMenu->EnableItem( RID_APPWINDOW, TRUE );
+ }
+
+ PopupMenu* pWinMenu = pMenu->GetPopupMenu( RID_APPWINDOW );
+ USHORT nLastID = pWinMenu->GetItemId( pWinMenu->GetItemCount() - 1 );
+
+ // Separator necessary
+ if ( nLastID < RID_WIN_FILE1 && pWinMenu->GetItemType( pWinMenu->GetItemCount() - 1 ) != MENUITEM_SEPARATOR )
+ pWinMenu->InsertSeparator();
+
+ // Find free ID
+ USHORT nFreeID = RID_WIN_FILE1;
+ while ( pWinMenu->GetItemPos( nFreeID ) != MENU_ITEM_NOTFOUND && nFreeID < RID_WIN_FILEn )
+ nFreeID++;
+
+ pWin->SetWinId( nFreeID );
+ pWinMenu->InsertItem( nFreeID, pWin->GetText() );
+}
+
+void BasicFrame::WindowRenamed( AppWin *pWin )
+{
+ MenuBar* pMenu = GetMenuBar();
+ PopupMenu* pWinMenu = pMenu->GetPopupMenu( RID_APPWINDOW );
+
+ pWinMenu->SetItemText( pWin->GetWinId(), pWin->GetText() );
+
+ pStatus->LoadTaskToolBox();
+
+ aAppFile = pWin->GetText();
+ UpdateTitle();
+}
+
+void BasicFrame::FocusWindow( AppWin *pWin )
+{
+ pWork = pWin;
+ pList->Remove( pWin );
+ pList->Insert( pWin, LIST_APPEND );
+ pWin->Minimize( FALSE );
+
+ aAppFile = pWin->GetText();
+ UpdateTitle();
+
+ WinShow_Hide();
+ pStatus->LoadTaskToolBox();
+}
+
+BOOL BasicFrame::Close()
+{
+ if( bInBreak || Basic().IsRunning() )
+ if( RET_NO == QueryBox( this, SttResId( IDS_RUNNING ) ).Execute() )
+ return FALSE;
+
+ StarBASIC::Stop();
+ bInBreak = FALSE;
+ if( CloseAll() )
+ {
+ aLineNum.Stop();
+
+ // Close remaining dialogs to avoid assertions
+ while ( GetWindow( WINDOW_OVERLAP )->GetWindow( WINDOW_FIRSTOVERLAP ) )
+ {
+ delete GetWindow( WINDOW_OVERLAP )->GetWindow( WINDOW_FIRSTOVERLAP )->GetWindow( WINDOW_CLIENT );
+ }
+
+ Application::SetDefDialogParent( NULL );
+ WorkWindow::Close();
+
+ return TRUE;
+ } else return FALSE;
+}
+
+BOOL BasicFrame::CloseAll()
+{
+ while ( pList->Count() )
+ if ( !pList->Last()->Close() )
+ return FALSE;
+ return TRUE;
+}
+
+BOOL BasicFrame::CompileAll()
+{
+ AppWin* p;
+ for( p = pList->First(); p; p = pList->Next() )
+ if( p->ISA(AppBasEd) && !((AppBasEd*)p)->Compile() ) return FALSE;
+ return TRUE;
+}
+
+// Setup menu
+#define MENU2FILENAME( Name ) Name.Copy( Name.SearchAscii(" ") +1).EraseAllChars( '~' )
+#define LRUNr( nNr ) CByteString("LRU").Append( ByteString::CreateFromInt32( nNr ) )
+String FILENAME2MENU( USHORT nNr, String aName )
+{
+ String aRet;
+ if ( nNr <= 9 )
+ aRet = CUniString("~").Append( UniString::CreateFromInt32( nNr ) );
+ else if ( nNr == 10 )
+ aRet = CUniString("1~0");
+ else
+ aRet = UniString::CreateFromInt32( nNr );
+
+ return aRet.AppendAscii(" ").Append( aName );
+}
+
+void BasicFrame::AddToLRU(String const& aFile)
+{
+ Config aConfig(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
+ PopupMenu *pPopup = GetMenuBar()->GetPopupMenu(RID_APPFILE);
+
+ aConfig.SetGroup("LRU");
+ USHORT nMaxLRU = (USHORT)aConfig.ReadKey("MaxLRU","4").ToInt32();
+ DirEntry aFileEntry( aFile );
+ USHORT i,nLastMove = nMaxLRU;
+
+ for ( i = 1 ; i<nMaxLRU && nLastMove == nMaxLRU ; i++ )
+ {
+ if ( DirEntry( UniString( aConfig.ReadKey(LRUNr(i),""), RTL_TEXTENCODING_UTF8 ) ) == aFileEntry )
+ nLastMove = i;
+ }
+
+ if ( pPopup->GetItemPos( IDM_FILE_LRU1 ) == MENU_ITEM_NOTFOUND )
+ pPopup->InsertSeparator();
+ for ( i = nLastMove ; i>1 ; i-- )
+ {
+ if ( aConfig.ReadKey(LRUNr(i-1),"").Len() )
+ {
+ aConfig.WriteKey(LRUNr(i), aConfig.ReadKey(LRUNr(i-1),""));
+ if ( pPopup->GetItemPos( IDM_FILE_LRU1 + i-1 ) == MENU_ITEM_NOTFOUND )
+ pPopup->InsertItem(IDM_FILE_LRU1 + i-1, FILENAME2MENU( i, MENU2FILENAME( pPopup->GetItemText(IDM_FILE_LRU1 + i-1-1) ) ));
+ else
+ pPopup->SetItemText(IDM_FILE_LRU1 + i-1,FILENAME2MENU( i, MENU2FILENAME( pPopup->GetItemText(IDM_FILE_LRU1 + i-1-1) ) ));
+ }
+ }
+ aConfig.WriteKey(LRUNr(1), ByteString( aFile, RTL_TEXTENCODING_UTF8 ) );
+ if ( pPopup->GetItemPos( IDM_FILE_LRU1 ) == MENU_ITEM_NOTFOUND )
+ pPopup->InsertItem(IDM_FILE_LRU1,FILENAME2MENU( 1, aFile));
+ else
+ pPopup->SetItemText(IDM_FILE_LRU1,FILENAME2MENU( 1, aFile));
+}
+
+void BasicFrame::LoadLRU()
+{
+ Config aConfig(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
+ PopupMenu *pPopup = GetMenuBar()->GetPopupMenu(RID_APPFILE);
+ BOOL bAddSep = TRUE;
+
+ aConfig.SetGroup("LRU");
+ USHORT nMaxLRU = (USHORT)aConfig.ReadKey("MaxLRU","4").ToInt32();
+
+ if ( pPopup )
+ bAddSep = pPopup->GetItemPos( IDM_FILE_LRU1 ) == MENU_ITEM_NOTFOUND;
+
+ USHORT i;
+ for ( i = 1; i <= nMaxLRU && pPopup != NULL; i++)
+ {
+ String aFile = UniString( aConfig.ReadKey(LRUNr(i)), RTL_TEXTENCODING_UTF8 );
+
+ if (aFile.Len() != 0)
+ {
+ if (bAddSep)
+ {
+ pPopup->InsertSeparator();
+ bAddSep = FALSE;
+ }
+
+ if ( pPopup->GetItemPos( IDM_FILE_LRU1 + i-1 ) == MENU_ITEM_NOTFOUND )
+ pPopup->InsertItem(IDM_FILE_LRU1 + i-1, FILENAME2MENU( i, aFile ));
+ else
+ pPopup->SetItemText(IDM_FILE_LRU1 + i-1, FILENAME2MENU( i, aFile ));
+ }
+ }
+ i = nMaxLRU+1;
+ while ( pPopup->GetItemPos( IDM_FILE_LRU1 + i-1 ) != MENU_ITEM_NOTFOUND )
+ {
+ pPopup->RemoveItem( pPopup->GetItemPos( IDM_FILE_LRU1 + i-1 ) );
+ i++;
+ }
+}
+
+IMPL_LINK( BasicFrame, InitMenu, Menu *, pMenu )
+{
+ BOOL bNormal = BOOL( !bInBreak );
+ pMenu->EnableItem( RID_RUNCOMPILE, bNormal );
+
+ BOOL bHasEdit = BOOL( /*bNormal &&*/ pWork != NULL );
+
+// pMenu->EnableItem( RID_FILENEW, bNormal ); // always possible
+// pMenu->EnableItem( RID_FILEOPEN, bNormal );
+ pMenu->EnableItem( RID_FILECLOSE, bHasEdit );
+ pMenu->EnableItem( RID_FILESAVE, bHasEdit );
+ pMenu->EnableItem( RID_FILESAVEAS, bHasEdit );
+ pMenu->EnableItem( RID_FILEPRINT, bHasEdit );
+ pMenu->EnableItem( RID_FILESETUP, bHasEdit );
+ pMenu->EnableItem( RID_FILELOADLIB, bNormal );
+ pMenu->EnableItem( RID_FILESAVELIB, bHasEdit );
+
+ BOOL bHasErr = BOOL( bNormal && pBasic->GetErrors() != 0 );
+ BOOL bNext = bHasErr & bNormal;
+ BOOL bPrev = bHasErr & bNormal;
+ if( bHasErr )
+ {
+ ULONG n = pBasic->aErrors.GetCurPos();
+ if( n == 0 )
+ bPrev = FALSE;
+ if( USHORT(n+1) == pBasic->GetErrors() )
+ bNext = FALSE;
+ }
+ pMenu->EnableItem( RID_RUNNEXTERR, bNext );
+ pMenu->EnableItem( RID_RUNPREVERR, bPrev );
+ pMenu->CheckItem( RID_RUNDISAS, bDisas );
+ if( pWork )
+ pWork->InitMenu( pMenu );
+
+ return TRUE;
+}
+
+IMPL_LINK_INLINE_START( BasicFrame, DeInitMenu, Menu *, pMenu )
+{
+ (void) pMenu; /* avoid warning about unused parameter */
+/* pMenu->EnableItem( RID_RUNCOMPILE );
+
+ pMenu->EnableItem( RID_FILECLOSE );
+ pMenu->EnableItem( RID_FILESAVE );
+ pMenu->EnableItem( RID_FILESAVEAS );
+ pMenu->EnableItem( RID_FILEPRINT );
+ pMenu->EnableItem( RID_FILESETUP );
+ pMenu->EnableItem( RID_FILELOADLIB );
+ pMenu->EnableItem( RID_FILESAVELIB );
+
+ pMenu->EnableItem( RID_RUNNEXTERR );
+ pMenu->EnableItem( RID_RUNPREVERR );
+ if( pWork ) pWork->DeInitMenu( pMenu );
+*/
+ SetAutoRun( FALSE );
+ String aString;
+ pStatus->Message( aString );
+ return 0L;
+}
+IMPL_LINK_INLINE_END( BasicFrame, DeInitMenu, Menu *, pMenu )
+
+IMPL_LINK_INLINE_START( BasicFrame, HighlightMenu, Menu *, pMenu )
+{
+ String s = pMenu->GetHelpText( pMenu->GetCurItemId() );
+ pStatus->Message( s );
+ return 0L;
+}
+IMPL_LINK_INLINE_END( BasicFrame, HighlightMenu, Menu *, pMenu )
+
+IMPL_LINK_INLINE_START( BasicFrame, MenuCommand, Menu *, pMenu )
+{
+ USHORT nId = pMenu->GetCurItemId();
+ BOOL bChecked = pMenu->IsItemChecked( nId );
+ return Command( nId, bChecked );
+}
+IMPL_LINK_INLINE_END( BasicFrame, MenuCommand, Menu *, pMenu )
+
+IMPL_LINK_INLINE_START( BasicFrame, Accel, Accelerator*, pAcc )
+{
+ SetAutoRun( FALSE );
+ return Command( pAcc->GetCurItemId() );
+}
+IMPL_LINK_INLINE_END( BasicFrame, Accel, Accelerator*, pAcc )
+
+IMPL_LINK_INLINE_START( BasicFrame, ShowLineNr, AutoTimer *, pTimer )
+{
+ (void) pTimer; /* avoid warning about unused parameter */
+ String aPos;
+ if ( pWork && pWork->ISA(AppBasEd))
+ {
+ aPos = String::CreateFromInt32(pWork->GetLineNr());
+ }
+ pStatus->Pos( aPos );
+ return 0L;
+}
+IMPL_LINK_INLINE_END( BasicFrame, ShowLineNr, AutoTimer *, pTimer )
+
+
+MsgEdit* BasicFrame::GetMsgTree( String aLogFileName )
+{
+ if ( FindErrorWin( aLogFileName ) )
+ {
+ return FindErrorWin( aLogFileName )->GetMsgTree();
+ }
+ else
+ { // create new Window on the fly
+ AppError *pNewWindow = new AppError( this, aLogFileName );
+ pNewWindow->Show();
+ pNewWindow->GrabFocus();
+ return pNewWindow->GetMsgTree();
+ }
+}
+
+IMPL_LINK( BasicFrame, Log, TTLogMsg *, pLogMsg )
+{
+ GetMsgTree( pLogMsg->aLogFileName )->AddAnyMsg( pLogMsg );
+ return 0L;
+}
+
+IMPL_LINK( BasicFrame, WinInfo, WinInfoRec*, pWinInfo )
+{
+ if ( !pDisplayHidDlg )
+ pDisplayHidDlg = new DisplayHidDlg( this );
+ if ( pDisplayHidDlg )
+ {
+ pDisplayHidDlg->AddData( pWinInfo );
+ pDisplayHidDlg->Show();
+ }
+ return 0;
+}
+
+AppBasEd* BasicFrame::CreateModuleWin( SbModule* pMod )
+{
+ String aModName = pMod->GetName();
+ if ( aModName.Copy(0,2).CompareToAscii("--") == COMPARE_EQUAL )
+ aModName.Erase(0,2);
+ pMod->SetName(aModName);
+ AppBasEd* p = new AppBasEd( this, pMod );
+ p->Show();
+ p->GrabFocus();
+ p->ToTop();
+ return p;
+}
+
+BOOL BasicFrame::LoadFile( String aFilename )
+{
+ BOOL bIsResult = DirEntry( aFilename ).GetExtension().CompareIgnoreCaseToAscii("RES") == COMPARE_EQUAL;
+ BOOL bIsBasic = DirEntry( aFilename ).GetExtension().CompareIgnoreCaseToAscii("BAS") == COMPARE_EQUAL;
+ bIsBasic |= DirEntry( aFilename ).GetExtension().CompareIgnoreCaseToAscii("INC") == COMPARE_EQUAL;
+
+ AppWin* p;
+ BOOL bSuccess = TRUE;
+ if ( bIsResult )
+ {
+ p = new AppError( this, aFilename );
+ }
+ else if ( bIsBasic )
+ {
+ p = new AppBasEd( this, NULL );
+ bSuccess = p->Load( aFilename );
+ }
+ else
+ {
+ p = new AppEdit( this );
+ bSuccess = p->Load( aFilename );
+ }
+ if ( bSuccess )
+ {
+ p->Show();
+ p->GrabFocus();
+ }
+ else
+ delete p;
+
+ return bSuccess;
+}
+
+// Execute command
+long BasicFrame::Command( short nID, BOOL bChecked )
+{
+ BasicError* pErr;
+
+ switch( nID ) {
+ case RID_FILENEW: {
+ AppBasEd* p = new AppBasEd( this, NULL );
+ p->Show();
+ p->GrabFocus();
+ // InitMenu(GetMenuBar()->GetPopupMenu( RID_APPRUN ));
+ } break;
+ case RID_FILEOPEN:
+ {
+ String s;
+ if( QueryFileName( s, FT_BASIC_SOURCE | FT_RESULT_FILE, FALSE ) ) {
+ AddToLRU( s );
+ LoadFile( s );
+// InitMenu(GetMenuBar()->GetPopupMenu( RID_APPRUN ));
+ }
+ } break;
+ case RID_FILELOADLIB:
+ LoadLibrary();
+ break;
+ case RID_FILESAVELIB:
+ SaveLibrary();
+ break;
+ case RID_FILECLOSE:
+ if( pWork && pWork->Close() ){};
+// InitMenu(GetMenuBar()->GetPopupMenu( RID_APPRUN ));
+ break;
+ case RID_FILEPRINT:
+ if( pWork )
+ pPrn->Print( pWork->GetText(), pWork->pDataEdit->GetText(), this );
+ break;
+ case RID_FILESETUP:
+ break;
+ case RID_QUIT:
+ if( Close() ) aBasicApp.Quit();
+ break;
+
+
+ case RID_RUNSTART:
+ nFlags = SbDEBUG_BREAK;
+ goto start;
+ case RID_RUNSTEPOVER:
+ nFlags = SbDEBUG_STEPINTO | SbDEBUG_STEPOVER;
+ goto start;
+ case RID_RUNSTEPINTO:
+ nFlags = SbDEBUG_STEPINTO;
+ goto start;
+ case RID_RUNTOCURSOR:
+ if ( pWork && pWork->ISA(AppBasEd) && ((AppBasEd*)pWork)->GetModule()->SetBP(pWork->GetLineNr()) )
+ {
+ SbModule *pModule = ((AppBasEd*)pWork)->GetModule();
+#if OSL_DEBUG_LEVEL > 1
+ USHORT x;
+ x = pWork->GetLineNr();
+ x = ((AppBasEd*)pWork)->GetModule()->GetBPCount();
+ if ( !x )
+ x = pModule->SetBP(pWork->GetLineNr());
+ x = pModule->GetBPCount();
+#endif
+
+ for ( USHORT nMethod = 0; nMethod < pModule->GetMethods()->Count(); nMethod++ )
+ {
+ SbMethod* pMethod = (SbMethod*)pModule->GetMethods()->Get( nMethod );
+ DBG_ASSERT( pMethod, "Methode nicht gefunden! (NULL)" );
+ pMethod->SetDebugFlags( pMethod->GetDebugFlags() | SbDEBUG_BREAK );
+ }
+ }
+ nFlags = SbDEBUG_BREAK;
+ goto start;
+ start: {
+// InitMenu(GetMenuBar()->GetPopupMenu( RID_APPRUN ));
+ if ( !Basic().IsRunning() || bInBreak )
+ {
+ AppBasEd* p = NULL;
+ if( pWork && pWork->ISA(AppBasEd) )
+ {
+ p = ((AppBasEd*)pWork);
+ p->ToTop();
+ }
+ else
+ {
+ AppWin *w = NULL;
+ for ( w = pList->Last() ; w ? !w->ISA(AppBasEd) : FALSE ; w = pList->Prev() ) ;
+ if ( w )
+ {
+ p = ((AppBasEd*)w);
+ p->ToTop();
+ }
+ else
+ if ( IsAutoRun() )
+ printf( "No file loaded to run.\n" );
+ }
+
+ if( bInBreak )
+ // Reset the flag
+ bInBreak = FALSE;
+ else
+ {
+ if( IsAutoSave() && !SaveAll() ) break;
+ if( !CompileAll() ) break;
+ String aString;
+ pStatus->Message( aString );
+ if( p )
+ {
+ BasicDLL::SetDebugMode( TRUE );
+ Basic().ClearGlobalVars();
+ p->Run();
+ BasicDLL::SetDebugMode( FALSE );
+ // If cancelled during Interactive=FALSE
+// BasicDLL::EnableBreak( TRUE );
+ }
+ }}
+ }
+// InitMenu(GetMenuBar()->GetPopupMenu( RID_APPRUN )); // after run
+ break;
+ case RID_RUNCOMPILE:
+ if( pWork && pWork->ISA(AppBasEd) && SaveAll() )
+ {
+ ((AppBasEd*)pWork)->Compile();
+ pWork->ToTop();
+ pWork->GrabFocus();
+ }
+ break;
+ case RID_RUNDISAS:
+ bDisas = BOOL( !bChecked );
+ break;
+ case RID_RUNBREAK:
+ if ( Basic().IsRunning() && !bInBreak )
+ {
+// pINST->CalcBreakCallLevel(SbDEBUG_STEPINTO);
+ pINST->nBreakCallLvl = pINST->nCallLvl;
+ }
+ break;
+ case RID_RUNSTOP:
+ Basic().Stop();
+ bInBreak = FALSE;
+ break;
+ case RID_RUNNEXTERR:
+ pErr = pBasic->aErrors.Next();
+ if( pErr ) pErr->Show();
+ break;
+ case RID_RUNPREVERR:
+ pErr = pBasic->aErrors.Prev();
+ if( pErr ) pErr->Show();
+ break;
+
+ case RID_OPTIONS:
+ {
+ OptionsDialog *pOptions = new OptionsDialog( this, SttResId(IDD_OPTIONS_DLG) );
+ pOptions->Show();
+ }
+ break;
+ case RID_DECLARE_HELPER:
+ InfoBox( this, SttResId( IDS_NOT_YET_IMPLEMENTED ) ).Execute();
+ break;
+
+ case RID_WINTILE:
+ {
+ WindowArrange aArange;
+ for ( ULONG i = 0 ; i < pList->Count() ; i++ )
+ {
+ aArange.AddWindow( pList->GetObject( i ) );
+ pList->GetObject( i )->Restore();
+ }
+
+
+ sal_Int32 nTitleHeight;
+ {
+ sal_Int32 nDummy1, nDummy2, nDummy3;
+ GetBorder( nDummy1, nTitleHeight, nDummy2, nDummy3 );
+ }
+
+ Size aSize = GetOutputSizePixel();
+ aSize.Height() -= nTitleHeight;
+ Rectangle aRect( Point( 0, nTitleHeight ), aSize );
+
+ aArange.Arrange( WINDOWARRANGE_TILE, aRect );
+
+ }
+ break;
+ case RID_WINTILEHORZ:
+ {
+ WindowArrange aArange;
+ for ( ULONG i = 0 ; i < pList->Count() ; i++ )
+ {
+ aArange.AddWindow( pList->GetObject( i ) );
+ pList->GetObject( i )->Restore();
+ }
+
+
+ sal_Int32 nTitleHeight;
+ {
+ sal_Int32 nDummy1, nDummy2, nDummy3;
+ GetBorder( nDummy1, nTitleHeight, nDummy2, nDummy3 );
+ }
+
+ Size aSize = GetOutputSizePixel();
+ aSize.Height() -= nTitleHeight;
+ Rectangle aRect( Point( 0, nTitleHeight ), aSize );
+
+ aArange.Arrange( WINDOWARRANGE_HORZ, aRect );
+
+ }
+ break;
+ case RID_WINTILEVERT:
+//#define WINDOWARRANGE_TILE 1
+//#define WINDOWARRANGE_HORZ 2
+//#define WINDOWARRANGE_VERT 3
+//#define WINDOWARRANGE_CASCADE 4
+ {
+ WindowArrange aArange;
+ for ( ULONG i = 0 ; i < pList->Count() ; i++ )
+ {
+ aArange.AddWindow( pList->GetObject( i ) );
+ pList->GetObject( i )->Restore();
+ }
+
+
+ sal_Int32 nTitleHeight;
+ {
+ sal_Int32 nDummy1, nDummy2, nDummy3;
+ GetBorder( nDummy1, nTitleHeight, nDummy2, nDummy3 );
+ }
+
+ Size aSize = GetOutputSizePixel();
+ aSize.Height() -= nTitleHeight;
+ Rectangle aRect( Point( 0, nTitleHeight ), aSize );
+
+ aArange.Arrange( WINDOWARRANGE_VERT, aRect );
+
+ }
+ break;
+ case RID_WINCASCADE:
+ {
+ for ( USHORT i = 0 ; i < pList->Count() ; i++ )
+ {
+ pList->GetObject( i )->Cascade( i );
+ }
+ }
+ break;
+
+/* case RID_HELPTOPIC:
+ if( pWork ) pWork->Help();
+ break;
+ case RID_HELPKEYS:
+ aBasicApp.pHelp->Start( CUniString( "Keyboard" ) );
+ break;
+ case RID_HELPINDEX:
+ aBasicApp.pHelp->Start( OOO_HELP_INDEX );
+ break;
+ case RID_HELPINTRO:
+ aBasicApp.pHelp->Start( OOO_HELP_HELPONHELP );
+ break;
+*/ case RID_HELPABOUT:
+ {
+ SttResId aResId( IDD_ABOUT_DIALOG );
+ if ( Basic().pTestObject ) // Are we TestTool?
+ aResId = SttResId( IDD_TT_ABOUT_DIALOG );
+ else
+ aResId = SttResId( IDD_ABOUT_DIALOG );
+ AboutDialog aAbout( this, aResId );
+ aAbout.Execute();
+ }
+ break;
+ case RID_POPUPEDITVAR:
+ {
+ new VarEditDialog( this, pEditVar );
+ }
+ break;
+ default:
+ if ( nID >= RID_WIN_FILE1 && nID <= RID_WIN_FILEn )
+ {
+ MenuBar* pMenu = GetMenuBar();
+ PopupMenu* pWinMenu = pMenu->GetPopupMenu( RID_APPWINDOW );
+ String aName = pWinMenu->GetItemText( nID );
+ aName.EraseAllChars( L'~' );
+ AppWin* pWin = FindWin( aName );
+ if ( pWin )
+ pWin->ToTop();
+ }
+ else if ( nID >= IDM_FILE_LRU1 && nID <= IDM_FILE_LRUn )
+ {
+ String s = MENU2FILENAME( GetMenuBar()->GetPopupMenu(RID_APPFILE)->GetItemText(nID) );
+
+ AddToLRU( s );
+ LoadFile( s );
+// InitMenu(GetMenuBar()->GetPopupMenu( RID_APPRUN ));
+ }
+ else
+ {
+// InitMenu(GetMenuBar()->GetPopupMenu( RID_APPEDIT )); // So daß Delete richtig ist
+ if( pWork )
+ pWork->Command( CommandEvent( Point(), nID ) );
+// InitMenu(GetMenuBar()->GetPopupMenu( RID_APPEDIT )); // So daß Delete richtig ist
+ }
+ }
+ return TRUE;
+}
+
+BOOL BasicFrame::SaveAll()
+{
+ AppWin* p, *q = pWork;
+ for( p = pList->First(); p; p = pList->Next() )
+ {
+ USHORT nRes = p->QuerySave( QUERY_DISK_CHANGED );
+ if( (( nRes == SAVE_RES_ERROR ) && QueryBox(this,SttResId(IDS_ASKSAVEERROR)).Execute() == RET_NO )
+ || ( nRes == SAVE_RES_CANCEL ) )
+ return FALSE;
+ }
+ if ( q )
+ q->ToTop();
+ return TRUE;
+}
+
+IMPL_LINK( BasicFrame, ModuleWinExists, String*, pFilename )
+{
+ return FindModuleWin( *pFilename ) != NULL;
+}
+
+AppBasEd* BasicFrame::FindModuleWin( const String& rName )
+{
+ AppWin* p;
+ for( p = pList->First(); p; p = pList->Next() )
+ {
+ if( p->ISA(AppBasEd) && ((AppBasEd*)p)->GetModName() == rName )
+ return ((AppBasEd*)p);
+ }
+ return NULL;
+}
+
+AppError* BasicFrame::FindErrorWin( const String& rName )
+{
+ AppWin* p;
+ for( p = pList->First(); p; p = pList->Next() )
+ {
+ if( p->ISA(AppError) && ((AppError*)p)->GetText() == rName )
+ return ((AppError*)p);
+ }
+ return NULL;
+}
+
+AppWin* BasicFrame::FindWin( const String& rName )
+{
+ AppWin* p;
+ for( p = pList->First(); p; p = pList->Next() )
+ {
+ if( p->GetText() == rName )
+ return p;
+ }
+ return NULL;
+}
+
+AppWin* BasicFrame::FindWin( USHORT nWinId )
+{
+ AppWin* p;
+ for( p = pList->First(); p; p = pList->Next() )
+ {
+ if( p->GetWinId() == nWinId )
+ return p;
+ }
+ return NULL;
+}
+
+AppWin* BasicFrame::IsWinValid( AppWin* pMaybeWin )
+{
+ AppWin* p;
+ for( p = pList->First(); p; p = pList->Next() )
+ {
+ if( p == pMaybeWin )
+ return p;
+ }
+ return NULL;
+}
+
+IMPL_LINK( BasicFrame, WriteString, String*, pString )
+{
+ if ( pList->Last() )
+ {
+ pList->Last()->pDataEdit->ReplaceSelected( *pString );
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+class NewFileDialog : public FileDialog
+{
+private:
+ String aLastPath;
+public:
+ ByteString aFilterType;
+ NewFileDialog( Window* pParent, WinBits nWinStyle ):FileDialog( pParent, nWinStyle ){};
+ virtual short Execute();
+ virtual void FilterSelect();
+};
+
+void NewFileDialog::FilterSelect()
+{
+ String aTemp = GetPath();
+ if ( aLastPath.Len() == 0 )
+ aLastPath = DirEntry( GetPath() ).GetPath().GetFull();
+ if ( aLastPath.CompareIgnoreCaseToAscii( DirEntry( GetPath() ).GetPath().GetFull() ) != COMPARE_EQUAL )
+ return; // User decides after he has changed the path
+
+ String aCurFilter = GetCurFilter();
+ USHORT nFilterNr = 0;
+ while ( nFilterNr < GetFilterCount() && aCurFilter != GetFilterName( nFilterNr ) )
+ {
+ nFilterNr++;
+ }
+ aFilterType = ByteString( GetFilterType( nFilterNr ), RTL_TEXTENCODING_UTF8 );
+
+ Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
+ aConf.SetGroup( "Misc" );
+ ByteString aCurrentProfile = aConf.ReadKey( "CurrentProfile", "Path" );
+ aConf.SetGroup( aCurrentProfile );
+ aLastPath = UniString( aConf.ReadKey( aFilterType, aConf.ReadKey( "BaseDir" ) ), RTL_TEXTENCODING_UTF8 );
+ SetPath( aLastPath );
+// if ( IsInExecute() )
+// SetPath( "" );
+}
+
+short NewFileDialog::Execute()
+{
+ BOOL bRet = (BOOL)FileDialog::Execute();
+ if ( bRet )
+ {
+ Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
+ aConf.SetGroup( "Misc" );
+ ByteString aCurrentProfile = aConf.ReadKey( "CurrentProfile", "Path" );
+ aConf.SetGroup( aCurrentProfile );
+ aConf.WriteKey( aFilterType, ByteString( DirEntry( GetPath() ).GetPath().GetFull(), RTL_TEXTENCODING_UTF8 ) );
+ aConf.WriteKey( "LastFilterName", ByteString( GetCurFilter(), RTL_TEXTENCODING_UTF8 ) );
+ }
+ return bRet;
+}
+
+BOOL BasicFrame::QueryFileName
+ (String& rName, FileType nFileType, BOOL bSave )
+{
+ NewFileDialog aDlg( this, bSave ? WinBits( WB_SAVEAS ) :
+ WinBits( WB_OPEN ) );
+ aDlg.SetText( String( SttResId( bSave ? IDS_SAVEDLG : IDS_LOADDLG ) ) );
+
+ if ( nFileType & FT_RESULT_FILE )
+ {
+ aDlg.SetDefaultExt( String( SttResId( IDS_RESFILE ) ) );
+ aDlg.AddFilter( String( SttResId( IDS_RESFILTER ) ), String( SttResId( IDS_RESFILE ) ) );
+ aDlg.AddFilter( String( SttResId( IDS_TXTFILTER ) ), String( SttResId( IDS_TXTFILE ) ) );
+ aDlg.SetCurFilter( SttResId( IDS_RESFILTER ) );
+ }
+
+ if ( nFileType & FT_BASIC_SOURCE )
+ {
+ aDlg.SetDefaultExt( String( SttResId( IDS_NONAMEFILE ) ) );
+ aDlg.AddFilter( String( SttResId( IDS_BASFILTER ) ), String( SttResId( IDS_NONAMEFILE ) ) );
+ aDlg.AddFilter( String( SttResId( IDS_INCFILTER ) ), String( SttResId( IDS_INCFILE ) ) );
+ aDlg.SetCurFilter( SttResId( IDS_BASFILTER ) );
+ }
+
+ if ( nFileType & FT_BASIC_LIBRARY )
+ {
+ aDlg.SetDefaultExt( String( SttResId( IDS_LIBFILE ) ) );
+ aDlg.AddFilter( String( SttResId( IDS_LIBFILTER ) ), String( SttResId( IDS_LIBFILE ) ) );
+ aDlg.SetCurFilter( SttResId( IDS_LIBFILTER ) );
+ }
+
+ Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
+ aConf.SetGroup( "Misc" );
+ ByteString aCurrentProfile = aConf.ReadKey( "CurrentProfile", "Path" );
+ aConf.SetGroup( aCurrentProfile );
+ ByteString aFilter( aConf.ReadKey( "LastFilterName") );
+ if ( aFilter.Len() )
+ aDlg.SetCurFilter( String( aFilter, RTL_TEXTENCODING_UTF8 ) );
+ else
+ aDlg.SetCurFilter( String( SttResId( IDS_BASFILTER ) ) );
+
+ aDlg.FilterSelect(); // Selects the last used path
+// if ( bSave )
+ if ( rName.Len() > 0 )
+ aDlg.SetPath( rName );
+
+ if( aDlg.Execute() )
+ {
+ rName = aDlg.GetPath();
+/* rExtension = aDlg.GetCurrentFilter();
+ var i:integer;
+ for ( i = 0 ; i < aDlg.GetFilterCount() ; i++ )
+ if ( rExtension == aDlg.GetFilterName( i ) )
+ rExtension = aDlg.GetFilterType( i );
+*/
+ return TRUE;
+ } else return FALSE;
+}
+
+USHORT BasicFrame::BreakHandler()
+{
+ bInBreak = TRUE;
+// InitMenu(GetMenuBar()->GetPopupMenu( RID_APPRUN ));
+// MenuBar aBar( ResId( RID_APPMENUBAR ) );
+// aBar.EnableItem( RID_APPEDIT, FALSE );
+ SetAppMode( String( SttResId ( IDS_APPMODE_BREAK ) ) );
+ while( bInBreak )
+ GetpApp()->Yield();
+ SetAppMode( String( SttResId ( IDS_APPMODE_RUN ) ) );
+// aBar.EnableItem( RID_APPEDIT, TRUE );
+// InitMenu(GetMenuBar()->GetPopupMenu( RID_APPRUN ));
+ return nFlags;
+}
+
+void BasicFrame::LoadLibrary()
+{
+ String s;
+ if( QueryFileName( s, FT_BASIC_LIBRARY, FALSE ) )
+ {
+ CloseAll();
+ SvFileStream aStrm( s, STREAM_STD_READ );
+ MyBasic* pNew = (MyBasic*) SbxBase::Load( aStrm );
+ if( pNew && pNew->ISA( MyBasic ) )
+ {
+ pBasic = pNew;
+ // Show all contents if existing
+ SbxArray* pMods = pBasic->GetModules();
+ for( USHORT i = 0; i < pMods->Count(); i++ )
+ {
+ SbModule* pMod = (SbModule*) pMods->Get( i );
+ AppWin* p = new AppBasEd( this, pMod );
+ p->Show();
+ }
+ }
+ else
+ {
+ delete pNew;
+ ErrorBox( this, SttResId( IDS_READERROR ) ).Execute();
+ }
+ }
+}
+
+void BasicFrame::SaveLibrary()
+{
+ String s;
+ if( QueryFileName( s, FT_BASIC_LIBRARY, TRUE ) )
+ {
+ SvFileStream aStrm( s, STREAM_STD_WRITE );
+ if( !Basic().Store( aStrm ) )
+ ErrorBox( this, SttResId( IDS_WRITEERROR ) ).Execute();
+ }
+}
+
+String BasicFrame::GenRealString( const String &aResString )
+{
+ xub_StrLen nStart,nGleich = 0,nEnd = 0,nStartPos = 0;
+ String aType,aValue,aResult(aResString);
+ String aString;
+ xub_StrLen nInsertPos = 0;
+ BOOL bFound;
+ bFound = FALSE;
+
+ while ( (nStart = aResult.Search(StartKenn,nStartPos)) != STRING_NOTFOUND &&
+ (nGleich = aResult.SearchAscii("=",nStart+StartKenn.Len())) != STRING_NOTFOUND &&
+ (nEnd = aResult.Search(EndKenn,nGleich+1)) != STRING_NOTFOUND)
+ {
+ aType = aResult.Copy(nStart,nGleich-nStart);
+ aValue = aResult.Copy(nGleich+1,nEnd-nGleich-1);
+ if ( aType.CompareTo(ResKenn) == COMPARE_EQUAL )
+ {
+ if ( bFound )
+ {
+ // insert results of previous resource
+ DBG_ASSERT( aString.SearchAscii( "($Arg" ) == STRING_NOTFOUND, "Argument missing in String");
+ aResult.Insert( aString, nInsertPos );
+ nStart = nStart + aString.Len();
+ nEnd = nEnd + aString.Len();
+ aString.Erase();
+ }
+// if ( Resource::GetResManager()->IsAvailable( ResId( aValue ) ) )
+ aString = String( SttResId( (USHORT)(aValue.ToInt32()) ) );
+// else
+ {
+// DBG_ERROR( "Could not load resource!" );
+// return aResString;
+ }
+ nInsertPos = nStart;
+ nStartPos = nStart;
+ aResult.Erase( nStart, nEnd-nStart+1 );
+ bFound = TRUE;
+ }
+ else if ( aType.Search(BaseArgKenn) == 0 ) // Starts with BaseArgKenn
+ {
+ // TODO: What the hell is that for??
+ USHORT nArgNr = USHORT( aType.Copy( BaseArgKenn.Len() ).ToInt32() );
+ DBG_ASSERT( aString.Search( CUniString("($Arg").Append( String::CreateFromInt32(nArgNr) ).AppendAscii(")") ) != STRING_NOTFOUND, "Extra Argument given in String");
+ aString.SearchAndReplace( CUniString("($Arg").Append( String::CreateFromInt32(nArgNr) ).AppendAscii(")"), aValue );
+ nStartPos = nStart;
+ aResult.Erase( nStart, nEnd-nStart+1 );
+ }
+ else
+ {
+ DBG_ERROR( CByteString("Unknown replacement in String: ").Append( ByteString( aResult.Copy(nStart,nEnd-nStart), RTL_TEXTENCODING_UTF8 ) ).GetBuffer() );
+ nStartPos = nStartPos + StartKenn.Len();
+ }
+ }
+ if ( bFound )
+ {
+ DBG_ASSERT( aString.SearchAscii( "($Arg" ) == STRING_NOTFOUND, "Argument missing in String");
+ aResult.Insert( aString, nInsertPos );
+ }
+ return aResult;
+}
+
+
diff --git a/basic/source/app/app.hxx b/basic/source/app/app.hxx
new file mode 100644
index 000000000000..cd76b6481def
--- /dev/null
+++ b/basic/source/app/app.hxx
@@ -0,0 +1,196 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _BASICAPP_HXX
+#define _BASICAPP_HXX
+
+#include <vcl/svapp.hxx>
+#ifndef _HELP_HXX //autogen
+#include <vcl/help.hxx>
+#endif
+#ifndef _MENU_HXX //autogen
+#include <vcl/menu.hxx>
+#endif
+#ifndef _WRKWIN_HXX //autogen
+#include <vcl/wrkwin.hxx>
+#endif
+#include <vcl/timer.hxx>
+#include <svl/brdcst.hxx>
+#include <svl/lstner.hxx>
+
+class BasicFrame;
+#include <basic/mybasic.hxx>
+
+class EditList;
+class AppWin;
+class AppEdit;
+class AppBasEd;
+class MsgEdit;
+class AppError;
+class StatusLine;
+class BasicPrinter;
+struct TTLogMsg;
+
+class BasicApp : public Application {
+ short nWait; // Wait-Zaehler
+public:
+// Help* pHelp; // Hilfesystem
+ BasicFrame* pFrame; // Frame Window
+// MenuBar* pMainMenu; // Hauptmenue
+ Accelerator* pMainAccel; // Acceleratoren
+
+ void Main( );
+
+ void LoadIniFile();
+ void SetFocus();
+ void Wait( BOOL );
+ DECL_LINK( LateInit, void * );
+
+#ifdef DBG_UTIL
+ DbgPrintLine DbgPrintMsgBox;
+#endif
+};
+
+
+typedef USHORT FileType;
+
+#define FT_NO_FILE (FileType)0x00 // An error has occurred ...
+#define FT_BASIC_SOURCE (FileType)0x01
+#define FT_BASIC_INCLUDE (FileType)0x02
+#define FT_RESULT_FILE (FileType)0x04
+#define FT_RESULT_FILE_TXT (FileType)0x08
+#define FT_BASIC_LIBRARY (FileType)0x10
+
+struct WinInfoRec;
+class DisplayHidDlg;
+
+class FloatingExecutionStatus;
+
+class BasicFrame : public WorkWindow, public SfxBroadcaster, public SfxListener
+{
+using SystemWindow::Notify;
+using Window::Command;
+
+virtual BOOL Close();
+ BOOL CloseAll(); // Close all windows
+ BOOL CompileAll(); // Compile all texts
+ AutoTimer aLineNum; // Show the line numbers
+virtual void Resize();
+virtual void Move();
+virtual void GetFocus();
+ void LoadLibrary();
+ void SaveLibrary();
+ BOOL bIsAutoRun;
+ DisplayHidDlg* pDisplayHidDlg;
+
+// BreakPoint *pRunToCursorBP;
+
+ SbxVariable *pEditVar;
+
+
+
+ Timer aCheckFiles; // Checks the files for changes
+ BOOL bAutoReload;
+ BOOL bAutoSave;
+ DECL_LINK( CheckAllFiles, Timer* );
+
+ MyBasicRef pBasic; // BASIC-Engine
+
+ String aAppName; // Title bar content
+ String aAppFile; // AppName AppFile [AppMode]
+ String aAppMode;
+ void UpdateTitle();
+ DECL_LINK( CloseButtonClick, void* );
+ DECL_LINK( FloatButtonClick, void* );
+ DECL_LINK( HideButtonClick, void* );
+
+ FloatingExecutionStatus *pExecutionStatus;
+
+public:
+ BOOL IsAutoRun();
+ void SetAutoRun( BOOL bAuto );
+ BOOL bInBreak; // TRUE if in Break-Handler
+ StatusLine* pStatus; // Status line
+ EditList* pList; // List of edit windows
+ AppWin* pWork; // Current edit window
+ BasicPrinter* pPrn; // Printer
+ BOOL bDisas; // TRUE: disassemble
+ USHORT nFlags; // Debugging-Flags
+ USHORT nMaximizedWindows; // Number of maximized windows
+ void FocusWindow( AppWin *pWin );
+ void WinMax_Restore();
+ void WinShow_Hide();
+ void RemoveWindow( AppWin *pWin );
+ void AddWindow( AppWin *pWin );
+ void WindowRenamed( AppWin *pWin );
+
+ BasicFrame();
+ ~BasicFrame();
+ MyBasic& Basic() { return *pBasic; }
+ void AddToLRU(String const& aFile);
+ void LoadLRU();
+ DECL_LINK( InitMenu, Menu * );
+ DECL_LINK( DeInitMenu, Menu * );
+ DECL_LINK( HighlightMenu, Menu * );
+ DECL_LINK( MenuCommand, Menu * );
+ DECL_LINK( Accel, Accelerator * );
+ DECL_LINK( ShowLineNr, AutoTimer * );
+ MsgEdit* GetMsgTree( String aLogFileName );
+ DECL_LINK( Log, TTLogMsg * );
+ DECL_LINK( WinInfo, WinInfoRec * );
+ BOOL LoadFile( String aFilename );
+ long Command( short,BOOL=FALSE ); // Command handler
+ virtual void Command( const CommandEvent& rCEvt ); // Command handler
+ BOOL SaveAll(); // Save all windows
+ BOOL QueryFileName( String& rName, FileType nFileType, BOOL bSave ); // Query for filename
+ DECL_LINK( ModuleWinExists, String* );
+ DECL_LINK( WriteString, String* );
+ AppBasEd* CreateModuleWin( SbModule* pMod );
+ AppBasEd* FindModuleWin( const String& );
+ AppError* FindErrorWin( const String& );
+ AppWin* FindWin( const String& );
+ AppWin* FindWin( USHORT nWinId );
+ AppWin* IsWinValid( AppWin* pMaybeWin );
+ USHORT BreakHandler(); // Break-Handler-Callback
+
+ void SetEditVar( SbxVariable *pVar ){ pEditVar = pVar;}
+ SbxVariable* GetEditVar(){ return pEditVar;}
+ BOOL IsAutoReload() { return bAutoReload; }
+ BOOL IsAutoSave() { return bAutoSave; }
+ void LoadIniFile();
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ void SetAppMode( const String &aNewMode ){ aAppMode = aNewMode; UpdateTitle(); }
+
+ String GenRealString( const String &aResString );
+
+};
+
+extern BasicApp aBasicApp;
+
+#endif
diff --git a/basic/source/app/appbased.cxx b/basic/source/app/appbased.cxx
new file mode 100644
index 000000000000..847a2fde02ec
--- /dev/null
+++ b/basic/source/app/appbased.cxx
@@ -0,0 +1,299 @@
+/*************************************************************************
+ *
+ * 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"
+
+#ifndef _MSGBOX_HXX //autogen
+#include <vcl/msgbox.hxx>
+#endif
+#include <basic/sbx.hxx>
+#include <svtools/texteng.hxx>
+#include <svtools/textview.hxx>
+#include <basic/sbmeth.hxx>
+#include <svtools/stringtransfer.hxx>
+
+#ifndef _BASIC_TTRESHLP_HXX
+#include <basic/ttstrhlp.hxx>
+#endif
+
+#include "basic.hrc"
+#include "status.hxx"
+#include "appbased.hxx"
+#include "brkpnts.hxx"
+#include <basic/testtool.hxx> // defines for Syntaxhighlighting
+#include "basrid.hxx"
+
+
+TYPEINIT1(AppBasEd,AppEdit);
+AppBasEd::AppBasEd( BasicFrame* pParent, SbModule* p )
+: AppEdit( pParent )
+, pBreakpoints( NULL )
+{
+ pBreakpoints = new BreakpointWindow( this );
+ pBreakpoints->SetFont( ((TextEdit*)pDataEdit)->GetTextEditImp().pTextEngine->GetFont() );
+
+ pBreakpoints->Show();
+
+
+ ((TextEdit*)pDataEdit)->GetTextEditImp().pTextView->SetAutoIndentMode( TRUE );
+ ((TextEdit*)pDataEdit)->GetTextEditImp().pTextEngine->SetMaxTextLen( STRING_MAXLEN );
+// ((TextEdit*)pDataEdit)->GetTextEditImp().pTextEngine->SetWordDelimiters( CUniString(" ,.;:(){}[]\"'+-*/<>^\\") );
+ ((TextEdit*)pDataEdit)->GetTextEditImp().SyntaxHighlight( TRUE );
+ ((TextEdit*)pDataEdit)->SaveAsUTF8( TRUE );
+
+ String aEmpty;
+
+ pMod = p;
+ if( !pMod )
+ {
+ String aModName = *pNoName;
+ aModName += String::CreateFromInt32( nCount );
+ pMod = pFrame->Basic().MakeModule( aModName, aEmpty );
+ }
+ bCompiled = pMod->IsCompiled();
+
+ pBreakpoints->SetModule( pMod );
+
+ // Define icon:
+// pIcon = new Icon( ResId( RID_WORKICON ) );
+// if( pIcon ) SetIcon( *pIcon );
+
+ SetText( pMod->GetName() );
+ pDataEdit->SetText( pMod->GetSource() );
+
+ // If a module was given, load the source from harddisk
+ if ( p )
+ LoadSource();
+
+ // Dispatch event AFTER loading the sourcecode
+ ((TextEdit*)pDataEdit)->SetBreakpointWindow( pBreakpoints );
+
+ // Touch compile flag
+ pDataEdit->SetModifyHdl( LINK( this, AppBasEd, EditChange ) );
+
+}
+
+AppBasEd::~AppBasEd()
+{
+ pBreakpoints->SaveBreakpoints( GetText() );
+ delete pBreakpoints;
+ pMod->SetName( CUniString("--").Append( pMod->GetName() ) );
+}
+
+void AppBasEd::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ const SfxSimpleHint* p = PTR_CAST(SfxSimpleHint,&rHint);
+ if( p )
+ {
+ ULONG nHintId = p->GetId();
+ if( nHintId == SBX_HINT_LANGUAGE_EXTENSION_LOADED )
+ {
+ ((TextEdit*)pDataEdit)->GetTextEditImp().InvalidateSyntaxHighlight();
+ }
+ }
+}
+
+FileType AppBasEd::GetFileType()
+{
+ return FT_BASIC_SOURCE;
+}
+
+IMPL_LINK_INLINE_START( AppBasEd, EditChange, void *, p )
+{
+ (void) p; /* avoid warning about unused parameter */
+ bCompiled = FALSE;
+ return TRUE;
+}
+IMPL_LINK_INLINE_END( AppBasEd, EditChange, void *, p )
+
+// Set up the menu
+long AppBasEd::InitMenu( Menu* pMenu )
+{
+ AppEdit::InitMenu (pMenu );
+ BOOL bRunning = pFrame->Basic().IsRunning();
+ pMenu->EnableItem( RID_RUNCOMPILE, !bCompiled && !bRunning );
+ return TRUE;
+}
+
+long AppBasEd::DeInitMenu( Menu* pMenu )
+{
+ AppEdit::DeInitMenu (pMenu );
+ pMenu->EnableItem( RID_RUNCOMPILE );
+ return TRUE;
+}
+
+// Menu Handler
+void AppBasEd::Command( const CommandEvent& rCEvt )
+{
+ switch( rCEvt.GetCommand() ) {
+ case RID_TOGLEBRKPNT:
+ ((TextEdit*)pDataEdit)->GetBreakpointWindow()->ToggleBreakpoint( pDataEdit->GetLineNr() );
+ break;
+ default:
+ AppEdit::Command( rCEvt );
+ }
+}
+
+void AppBasEd::Resize()
+{
+ if( pDataEdit )
+ {
+ AppEdit::Resize();
+
+ // Insert breakpoint window
+ Size aEditSize = pDataEdit->GetSizePixel();
+ Point aEditPos = pDataEdit->GetPosPixel();
+
+ pBreakpoints->SetPosPixel( aEditPos );
+
+ aEditPos.X() += BREAKPOINTSWIDTH;
+ pDataEdit->SetPosPixel( aEditPos );
+ aEditSize.Width() -= BREAKPOINTSWIDTH;
+ pDataEdit->SetSizePixel( aEditSize );
+
+ aEditSize.Width() = BREAKPOINTSWIDTH;
+ pBreakpoints->SetSizePixel( aEditSize );
+ }
+}
+
+void AppBasEd::PostLoad()
+{
+ pMod->SetName( GetText() );
+ pMod->Clear();
+ pMod->SetSource( pDataEdit->GetText() );
+ bCompiled = FALSE; // because the code might have changed in the meantime
+ AppEdit::PostLoad();
+
+ pBreakpoints->LoadBreakpoints( GetText() );
+}
+
+USHORT AppBasEd::ImplSave()
+{
+ pBreakpoints->SaveBreakpoints( GetText() );
+ return AppEdit::ImplSave();
+}
+
+void AppBasEd::Reload()
+{
+ TextSelection aSelMemo = pDataEdit->GetSelection();
+ LoadSource();
+ pDataEdit->SetSelection( aSelMemo );
+}
+
+// Reload source code file after change
+void AppBasEd::LoadSource()
+{
+ BOOL bErr;
+
+// if( pDataEdit->GetText().Len() != 0 ) return;
+ String aName = pMod->GetName();
+ bErr = !pDataEdit->Load( aName );
+ pBreakpoints->LoadBreakpoints( GetText() );
+ if( bErr )
+ ErrorBox( this, SttResId( IDS_READERROR ) ).Execute();
+ else
+ UpdateFileInfo( HAS_BEEN_LOADED );
+ bCompiled = FALSE; // because the code might have changed in the meantime
+}
+
+// Save as (new name)
+void AppBasEd::PostSaveAs()
+{
+ pMod->SetName( GetText() );
+ AppEdit::PostSaveAs();
+}
+
+// Compile
+BOOL AppBasEd::Compile()
+{
+ if( !pDataEdit->HasText() || bCompiled )
+ return TRUE;
+ pMod->SetSource( pDataEdit->GetText() );
+ BOOL bRes = FALSE;
+ if( pFrame->Basic().Compile( pMod ) )
+ {
+ bRes = TRUE;
+ if( pFrame->bDisas )
+ Disassemble();
+ TextSelection aSel( pDataEdit->GetSelection() );
+ String aString;
+ pFrame->pStatus->Message( aString );
+ if( aSel.HasRange() )
+ aSel.GetStart() = aSel.GetEnd(), pDataEdit->SetSelection( aSel );
+
+ pBreakpoints->SetBPsInModule();
+ }
+ else
+ {
+ BasicError* pErr = pFrame->Basic().aErrors.First();
+ if( pErr ) pErr->Show();
+ }
+ return bCompiled = bRes;
+}
+
+void AppBasEd::Disassemble()
+{
+ String aText;
+ if( pFrame->Basic().Disassemble( pMod, aText ) )
+ ::svt::OStringTransfer::CopyString( aText, this );
+}
+
+void AppBasEd::Run()
+{
+ pFrame->Basic().Reset();
+ SbxArray* pAllModules = pFrame->Basic().GetModules();
+ for (USHORT i = 0; i < pAllModules->Count(); i++)
+ {
+ if ( (pAllModules->Get(i)->GetName()).Copy(0,2).CompareToAscii( "--" ) == COMPARE_EQUAL )
+ {
+ // Little hack to get around basic
+ SbxVariableRef pRMod = pAllModules->Get(i);
+ pFrame->Basic().Remove(pRMod);
+ i--;
+ }
+ }
+
+ SbMethod* pMain = (SbMethod*) pMod->Find( CUniString("Main"), SbxCLASS_METHOD );
+ if( pMain )
+ {
+ pMain->SetDebugFlags( pFrame->nFlags );
+ // Triggers a call!
+ pFrame->SetAppMode( String( SttResId( IDS_APPMODE_RUN ) ) );
+ pMain->Run();
+ if (aBasicApp.pFrame)
+ {
+ BasicError* pErr = aBasicApp.pFrame->Basic().aErrors.First();
+ if( pErr )
+ pErr->Show();
+ aBasicApp.pFrame->SetAppMode( String() );
+ }
+ pMain->SetDebugFlags( 0 );
+ }
+}
+
+
diff --git a/basic/source/app/appbased.hxx b/basic/source/app/appbased.hxx
new file mode 100644
index 000000000000..339f0c1a3d18
--- /dev/null
+++ b/basic/source/app/appbased.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _APPBASED_HXX
+#define _APPBASED_HXX
+
+#include <basic/sbmod.hxx>
+#ifndef _SB_APPEDIT_HXX
+#include "appedit.hxx"
+#endif
+#ifndef _SB_TEXTEDIT_HXX
+#include "textedit.hxx"
+#endif
+
+class BasicFrame;
+class BreakpointWindow;
+
+class AppBasEd : public AppEdit { // Editor-Window:
+using DockingWindow::Notify;
+
+ SbModuleRef pMod; // compile module
+ BOOL bCompiled; // TRUE if compiled
+protected:
+ DECL_LINK( EditChange, void * );
+#define BREAKPOINTSWIDTH 15
+ BreakpointWindow *pBreakpoints;
+ virtual USHORT ImplSave(); // Save file
+
+public:
+ TYPEINFO();
+ AppBasEd( BasicFrame*, SbModule* );
+ ~AppBasEd();
+ FileType GetFileType(); // Returns Filetype
+ SbModule* GetModule() { return pMod; }
+ long InitMenu( Menu* ); // Initialision of the menus
+ virtual long DeInitMenu( Menu* ); // Reset to enable all shortcuts
+ virtual void Command( const CommandEvent& rCEvt ); // Command handler
+ virtual void Resize(); // Includes the breakpoint bar
+ virtual void PostLoad(); // Set source of module
+ virtual void PostSaveAs(); // Postprocess of module...
+ void Reload();
+ void LoadSource(); // Load source for object
+ BOOL Compile(); // Compile text
+ void Run(); // Run image
+ void Disassemble(); // Disassemble image
+ const String& GetModName() const { return pMod->GetName(); }
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+};
+
+#endif
diff --git a/basic/source/app/appedit.cxx b/basic/source/app/appedit.cxx
new file mode 100644
index 000000000000..d5769f3acb31
--- /dev/null
+++ b/basic/source/app/appedit.cxx
@@ -0,0 +1,301 @@
+/*************************************************************************
+ *
+ * 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/config.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svtools/textview.hxx>
+#include <svtools/texteng.hxx>
+#include <svl/undo.hxx>
+
+#ifndef _BASIC_TTRESHLP_HXX
+#include <basic/ttstrhlp.hxx>
+#endif
+
+#include "basic.hrc"
+#include "appedit.hxx"
+#include "brkpnts.hxx"
+
+TYPEINIT1(AppEdit,AppWin);
+AppEdit::AppEdit( BasicFrame* pParent )
+: AppWin( pParent )
+, pVScroll( NULL )
+, pHScroll( NULL )
+, nCurTextWidth(5)
+{
+ String aEmpty;
+ // perhaps load the Untitled-String:
+
+ pDataEdit = new TextEdit( this, WB_LEFT );
+ LoadIniFile();
+ // define Icon:
+// pIcon = new Icon( ResId( RID_WORKICON ) );
+// if( pIcon ) SetIcon( *pIcon );
+
+ pDataEdit->SetText( aEmpty );
+
+ pDataEdit->Show();
+
+ pVScroll = new ScrollBar( this, WB_VSCROLL|WB_DRAG );
+ pVScroll->Show();
+ pVScroll->SetScrollHdl( LINK( this, AppEdit, Scroll ) );
+ pHScroll = new ScrollBar( this, WB_HSCROLL|WB_DRAG );
+ pHScroll->Show();
+ pHScroll->SetScrollHdl( LINK( this, AppEdit, Scroll ) );
+
+ InitScrollBars();
+}
+
+AppEdit::~AppEdit()
+{
+ DataEdit *pHold = pDataEdit;
+ pDataEdit = NULL;
+ delete pHold;
+ delete pHScroll;
+ delete pVScroll;
+}
+
+void AppEdit::LoadIniFile()
+{
+ TextView *pTextView = ((TextEdit*)pDataEdit)->aEdit.pTextView;
+ BOOL bWasModified = pTextView->GetTextEngine()->IsModified();
+ pTextView->GetTextEngine()->SetModified( FALSE );
+
+ FontList aFontList( pFrame ); // Just some Window is needed
+ Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
+ aConf.SetGroup("Misc");
+ String aFontName = String( aConf.ReadKey( "ScriptFontName", "Courier" ), RTL_TEXTENCODING_UTF8 );
+ String aFontStyle = String( aConf.ReadKey( "ScriptFontStyle", "normal" ), RTL_TEXTENCODING_UTF8 );
+ String aFontSize = String( aConf.ReadKey( "ScriptFontSize", "12" ), RTL_TEXTENCODING_UTF8 );
+ Font aFont = aFontList.Get( aFontName, aFontStyle );
+// ULONG nFontSize = aFontSize.GetValue( FUNIT_POINT );
+ ULONG nFontSize = aFontSize.ToInt32();
+// aFont.SetSize( Size( nFontSize, nFontSize ) );
+ aFont.SetHeight( nFontSize );
+
+#if OSL_DEBUG_LEVEL > 1
+ {
+ Font aFont2( OutputDevice::GetDefaultFont( DEFAULTFONT_FIXED, Application::GetSettings().GetUILanguage(), 0, pFrame ));
+ }
+#endif
+ aFont.SetTransparent( FALSE );
+// aFont.SetAlign( ALIGN_BOTTOM );
+// aFont.SetHeight( aFont.GetHeight()+2 );
+ pDataEdit->SetFont( aFont );
+
+ if ( ((TextEdit*)pDataEdit)->GetBreakpointWindow() )
+ {
+ ((TextEdit*)pDataEdit)->GetBreakpointWindow()->SetFont( aFont );
+ ((TextEdit*)pDataEdit)->GetBreakpointWindow()->Invalidate();
+ }
+
+ pTextView->GetTextEngine()->SetModified( bWasModified ); // Perhaps reset the flag
+}
+
+void AppEdit::Command( const CommandEvent& rCEvt )
+{
+ switch( rCEvt.GetCommand() ) {
+ case COMMAND_WHEEL:
+ {
+ HandleScrollCommand( rCEvt, pHScroll, pVScroll );
+ }
+ break;
+ default:
+ AppWin::Command( rCEvt );
+ }
+}
+
+
+IMPL_LINK( AppEdit, Scroll, ScrollBar*, pScroll )
+{
+ (void) pScroll; /* avoid warning about unused parameter */
+ if ( !pHScroll || !pVScroll )
+ return 0;
+
+ TextView *pTextView = ((TextEdit*)pDataEdit)->aEdit.pTextView;
+ pTextView->SetStartDocPos( Point( pHScroll->GetThumbPos(), pVScroll->GetThumbPos() ) );
+ pTextView->Invalidate();
+
+ if ( ((TextEdit*)pDataEdit)->GetBreakpointWindow() )
+ ((TextEdit*)pDataEdit)->GetBreakpointWindow()->Scroll( 0, ((TextEdit*)pDataEdit)->GetBreakpointWindow()->GetCurYOffset() - pTextView->GetStartDocPos().Y() );
+
+ return 0L;
+}
+
+
+void AppEdit::InitScrollBars()
+{
+ if ( !pHScroll || !pVScroll )
+ return;
+
+ TextView *pTextView = ((TextEdit*)pDataEdit)->aEdit.pTextView;
+
+ SetScrollBarRanges();
+
+ Size aOutSz( pTextView->GetWindow()->GetOutputSizePixel() );
+ pVScroll->SetVisibleSize( aOutSz.Height() );
+ pVScroll->SetPageSize( aOutSz.Height() * 8 / 10 );
+ pVScroll->SetLineSize( GetTextHeight() +2 ); // +2 is empirical. don't know why
+ pVScroll->SetThumbPos( pTextView->GetStartDocPos().Y() );
+ pVScroll->Show();
+
+ pHScroll->SetVisibleSize( aOutSz.Width() );
+ pHScroll->SetPageSize( aOutSz.Width() * 8 / 10 );
+ pHScroll->SetLineSize( GetTextWidth( CUniString("x") ) );
+ pHScroll->SetThumbPos( pTextView->GetStartDocPos().X() );
+ pHScroll->Show();
+}
+
+void AppEdit::SetScrollBarRanges()
+{
+ // Extra-Method, not InitScrollBars, but for EditEngine-Events.
+
+ if ( !pHScroll || !pVScroll )
+ return;
+
+ pHScroll->SetRange( Range( 0, nCurTextWidth ) );
+ pVScroll->SetRange( Range( 0, ((TextEdit*)pDataEdit)->aEdit.pTextEngine->GetTextHeight() ) );
+}
+
+
+
+USHORT AppEdit::GetLineNr()
+{
+ return pDataEdit->GetLineNr();
+}
+
+FileType AppEdit::GetFileType()
+{
+ return FT_BASIC_SOURCE;
+}
+
+// Set up the menu
+long AppEdit::InitMenu( Menu* pMenu )
+{
+ AppWin::InitMenu (pMenu );
+
+ if( pDataEdit )
+ {
+ USHORT UndoCount = ((TextEdit*)pDataEdit)->aEdit.pTextEngine->GetUndoManager().GetUndoActionCount();
+ USHORT RedoCount = ((TextEdit*)pDataEdit)->aEdit.pTextEngine->GetUndoManager().GetRedoActionCount();
+
+ pMenu->EnableItem( RID_EDITUNDO, UndoCount > 0 );
+ pMenu->EnableItem( RID_EDITREDO, RedoCount > 0 );
+ }
+
+ return TRUE;
+}
+
+long AppEdit::DeInitMenu( Menu* pMenu )
+{
+ AppWin::DeInitMenu (pMenu );
+
+ pMenu->EnableItem( RID_EDITUNDO );
+ pMenu->EnableItem( RID_EDITREDO );
+
+ return TRUE;
+}
+
+void AppEdit::Resize()
+{
+ if( !pDataEdit )
+ return;
+
+ Point rHStart,rVStart;
+ Size rHSize,rVSize;
+ Size rNewSize( GetOutputSizePixel() );
+
+ if ( pHScroll )
+ {
+ rHSize = pHScroll->GetSizePixel();
+ ULONG nHieght = rHSize.Height();
+ rNewSize.Height() -= nHieght;
+ rHStart.Y() = rNewSize.Height();
+ }
+
+ if ( pVScroll )
+ {
+ rVSize = pVScroll->GetSizePixel();
+ ULONG nWidth = rVSize.Width();
+ rNewSize.Width() -= nWidth;
+ rVStart.X() = rNewSize.Width();
+ }
+
+ rHSize.Width() = rNewSize.Width();
+ rVSize.Height() = rNewSize.Height();
+
+ if ( pHScroll )
+ {
+ pHScroll->SetPosPixel( rHStart );
+ pHScroll->SetSizePixel( rHSize );
+ }
+
+ if ( pVScroll )
+ {
+ pVScroll->SetPosPixel( rVStart );
+ pVScroll->SetSizePixel( rVSize );
+ }
+ pDataEdit->SetPosPixel( Point() );
+ pDataEdit->SetSizePixel( rNewSize );
+
+
+ TextView *pTextView = ((TextEdit*)pDataEdit)->aEdit.pTextView;
+ long nVisY = pTextView->GetStartDocPos().Y();
+ pTextView->ShowCursor();
+ Size aOutSz( pTextView->GetWindow()->GetOutputSizePixel() );
+ long nMaxVisAreaStart = pTextView->GetTextEngine()->GetTextHeight() - aOutSz.Height();
+ if ( nMaxVisAreaStart < 0 )
+ nMaxVisAreaStart = 0;
+ if ( pTextView->GetStartDocPos().Y() > nMaxVisAreaStart )
+ {
+ Point aStartDocPos( pTextView->GetStartDocPos() );
+ aStartDocPos.Y() = nMaxVisAreaStart;
+ pTextView->SetStartDocPos( aStartDocPos );
+ pTextView->ShowCursor();
+// pModulWindow->GetBreakPointWindow().GetCurYOffset() = aStartDocPos.Y();
+ }
+ InitScrollBars();
+ if ( nVisY != pTextView->GetStartDocPos().Y() )
+ pTextView->GetWindow()->Invalidate();
+
+}
+
+void AppEdit::PostLoad()
+{
+}
+
+void AppEdit::PostSaveAs()
+{
+}
+
+void AppEdit::Highlight( USHORT nLine, USHORT nCol1, USHORT nCol2 )
+{
+ ((TextEdit*)pDataEdit)->Highlight( nLine, nCol1, nCol2 );
+ ToTop();
+}
+
diff --git a/basic/source/app/appedit.hxx b/basic/source/app/appedit.hxx
new file mode 100644
index 000000000000..4a003bd0482d
--- /dev/null
+++ b/basic/source/app/appedit.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _APPEDIT_HXX
+#define _APPEDIT_HXX
+
+#ifndef _SCRBAR_HXX //autogen
+#include <vcl/scrbar.hxx>
+#endif
+
+#include "appwin.hxx"
+#include "textedit.hxx"
+
+class BasicFrame;
+
+class AppEdit : public AppWin { // Editor window
+using Window::Scroll;
+
+public:
+ ScrollBar *pVScroll;
+ ScrollBar *pHScroll;
+ void SetScrollBarRanges();
+ ULONG nCurTextWidth;
+private:
+ void InitScrollBars();
+protected:
+ DECL_LINK( Scroll, ScrollBar* );
+public:
+ TYPEINFO();
+ AppEdit( BasicFrame* );
+ ~AppEdit();
+ USHORT GetLineNr(); // Current line number
+ FileType GetFileType(); // Returns the file type
+ virtual long InitMenu( Menu* ); // Inits the menu
+ virtual long DeInitMenu( Menu* ); // Reset to enable all Shortcuts
+ virtual void Command( const CommandEvent& rCEvt ); // Command Handler
+ void Resize();
+ void PostLoad();
+ void PostSaveAs();
+ void Mark( short, short, short ); // Select text
+ void Highlight( USHORT nLine, USHORT nCol1, USHORT nCol2 );
+ virtual BOOL ReloadAllowed(){ return !StarBASIC::IsRunning(); }
+ virtual void LoadIniFile(); // (re)load ini file after change
+};
+
+#endif
diff --git a/basic/source/app/apperror.cxx b/basic/source/app/apperror.cxx
new file mode 100644
index 000000000000..001c77a38146
--- /dev/null
+++ b/basic/source/app/apperror.cxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * 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/config.hxx>
+#include <svtools/ctrltool.hxx>
+#ifndef _BASIC_TTRESHLP_HXX
+#include <basic/ttstrhlp.hxx>
+#endif
+#include "basic.hrc"
+#include "apperror.hxx"
+
+TYPEINIT1(AppError,AppWin);
+AppError::AppError( BasicFrame* pParent, String aFileName )
+: AppWin( pParent )
+{
+ SetText( aFileName ); // Call before MsgEdit!!
+ pDataEdit = new MsgEdit( this, pParent, WB_HSCROLL | WB_VSCROLL | WB_LEFT );
+ LoadIniFile();
+ bHasFile = pDataEdit->Load( aFileName );
+ DirEntry aEntry( aFileName );
+ UpdateFileInfo( HAS_BEEN_LOADED );
+ // Define icon
+// pIcon = new Icon( ResId( RID_WORKICON ) );
+// if( pIcon ) SetIcon( *pIcon );
+
+ pDataEdit->Show();
+ GrabFocus();
+}
+
+AppError::~AppError()
+{
+ DataEdit* pTemp = pDataEdit;
+ pDataEdit = NULL;
+ delete pTemp;
+}
+
+// Set up the menu
+long AppError::InitMenu( Menu* pMenu )
+{
+ AppWin::InitMenu (pMenu );
+
+ pMenu->EnableItem( RID_EDITUNDO, FALSE );
+ pMenu->EnableItem( RID_EDITREDO, FALSE );
+
+ return TRUE;
+}
+
+long AppError::DeInitMenu( Menu* pMenu )
+{
+ AppWin::DeInitMenu (pMenu );
+
+ pMenu->EnableItem( RID_EDITUNDO );
+ pMenu->EnableItem( RID_EDITREDO );
+
+ return TRUE;
+}
+
+USHORT AppError::GetLineNr(){ return pDataEdit->GetLineNr(); }
+
+FileType AppError::GetFileType()
+{
+ return FT_RESULT_FILE;
+}
+
+void AppError::LoadIniFile()
+{
+ Config aConf(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
+ aConf.SetGroup("Misc");
+ ByteString aCurrentProfile = aConf.ReadKey( "CurrentProfile", "Path" );
+ aConf.SetGroup( aCurrentProfile );
+ aBaseDir = DirEntry( aConf.ReadKey("BaseDir") );
+
+
+ FontList aFontList( pFrame ); // Just some Window is needed
+ aConf.SetGroup("Misc");
+ String aFontName = String( aConf.ReadKey( "ScriptFontName", "Courier" ), RTL_TEXTENCODING_UTF8 );
+ String aFontStyle = String( aConf.ReadKey( "ScriptFontStyle", "normal" ), RTL_TEXTENCODING_UTF8 );
+ String aFontSize = String( aConf.ReadKey( "ScriptFontSize", "12" ), RTL_TEXTENCODING_UTF8 );
+ Font aFont = aFontList.Get( aFontName, aFontStyle );
+// ULONG nFontSize = aFontSize.GetValue( FUNIT_POINT );
+ ULONG nFontSize = aFontSize.ToInt32();
+// aFont.SetSize( Size( nFontSize, nFontSize ) );
+ aFont.SetHeight( nFontSize );
+
+ aFont.SetTransparent( FALSE );
+// aFont.SetAlign( ALIGN_BOTTOM );
+// aFont.SetHeight( aFont.GetHeight()+2 );
+ pDataEdit->SetFont( aFont );
+}
diff --git a/basic/source/app/apperror.hxx b/basic/source/app/apperror.hxx
new file mode 100644
index 000000000000..c5be8836efd9
--- /dev/null
+++ b/basic/source/app/apperror.hxx
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include <appwin.hxx>
+#include <msgedit.hxx>
+
+class AppError : public AppWin
+{
+protected:
+ DECL_LINK( EditChange, MsgEdit * );
+public:
+ TYPEINFO();
+ AppError( BasicFrame*, String );
+ ~AppError();
+// long Command( short nID );
+ virtual long InitMenu( Menu* );
+ virtual long DeInitMenu( Menu* );
+ USHORT GetLineNr();
+ FileType GetFileType();
+ MsgEdit* GetMsgTree() { return ((MsgEdit*)pDataEdit); }
+ virtual BOOL ReloadAllowed(){ return !StarBASIC::IsRunning(); }
+ virtual void LoadIniFile(); // (re)load ini file after change
+ DirEntry aBaseDir;
+};
+
diff --git a/basic/source/app/appwin.cxx b/basic/source/app/appwin.cxx
new file mode 100644
index 000000000000..b0a6c07ec956
--- /dev/null
+++ b/basic/source/app/appwin.cxx
@@ -0,0 +1,657 @@
+/*************************************************************************
+ *
+ * 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>
+#ifndef _MSGBOX_HXX //autogen
+#include <vcl/msgbox.hxx>
+#endif
+#include <tools/fsys.hxx>
+#include <svtools/stringtransfer.hxx>
+
+#include "basic.hrc"
+#include "app.hxx"
+#include <basic/mybasic.hxx>
+#include "status.hxx"
+#include "appwin.hxx"
+#include "dataedit.hxx"
+#include "dialogs.hxx"
+#include "basrid.hxx"
+
+String *AppWin::pNoName = NULL; // contains the "Untitled"-String
+short AppWin::nNumber = 0; // consecutive number
+short AppWin::nCount = 0; // number of edit windows
+
+TYPEINIT0(AppWin);
+AppWin::AppWin( BasicFrame* pParent )
+: DockingWindow( pParent, WB_SIZEMOVE | WB_CLOSEABLE | WB_PINABLE )
+, nSkipReload(0)
+, bHasFile( FALSE )
+, bReloadAborted( FALSE )
+, pFrame( pParent )
+, bFind( TRUE )
+, pDataEdit(NULL)
+{
+ // Load the Untitled string if not yet loaded
+ if( !pNoName )
+ pNoName = new String( SttResId( IDS_NONAME ) );
+ nCount++;
+
+ // Get maximized state from current window
+ USHORT nInitialWinState;
+ if ( pFrame->pWork )
+ {
+ nInitialWinState = pFrame->pWork->GetWinState();
+ nInitialWinState &= TT_WIN_STATE_MAX | TT_WIN_STATE_FLOAT;
+ }
+ else
+ nInitialWinState = TT_WIN_STATE_MAX;
+
+ StartListening( *pFrame );
+ pFrame->AddWindow( this );
+
+ ShowTitleButton( TITLE_BUTTON_DOCKING );
+ ShowTitleButton( TITLE_BUTTON_HIDE );
+ SetActivateMode( ACTIVATE_MODE_GRABFOCUS );
+
+ Cascade( nCount );
+ if ( TT_WIN_STATE_MAX == nInitialWinState )
+ Maximize();
+}
+
+AppWin::~AppWin()
+{
+ nCount--;
+ pFrame->RemoveWindow( this );
+ pFrame = NULL; // Set to stop setting window text after BasicRun
+}
+
+void AppWin::SetText( const XubString& rStr )
+{
+ DockingWindow::SetText( rStr );
+ pFrame->WindowRenamed( this );
+}
+
+void AppWin::TitleButtonClick( USHORT nButton )
+{
+ if ( TITLE_BUTTON_DOCKING == nButton )
+ if ( TT_WIN_STATE_MAX != nWinState )
+ Maximize();
+ else
+ Restore();
+ else // if ( TITLE_BUTTON_HIDE == nButton )
+ Minimize( TRUE );
+}
+
+void AppWin::Maximize()
+{
+ if ( TT_WIN_STATE_MAX != nWinState )
+ {
+ nNormalPos = GetPosPixel();
+ nNormalSize = GetSizePixel();
+
+ SetFloatingMode( FALSE );
+
+ pFrame->nMaximizedWindows++;
+ nWinState = TT_WIN_STATE_MAX;
+ }
+ sal_Int32 nTitleHeight;
+ {
+ sal_Int32 nDummy1, nDummy2, nDummy3;
+ pFrame->GetBorder( nDummy1, nTitleHeight, nDummy2, nDummy3 );
+ }
+
+ Size aSize = pFrame->GetOutputSizePixel();
+ aSize.Height() -= nTitleHeight;
+ aSize.Height() -= 2;
+ aSize.Width() -= 2;
+ SetSizePixel( aSize );
+ SetPosPixel( Point( 1,1 ) );
+ pFrame->WinMax_Restore();
+}
+
+void AppWin::Restore()
+{
+ SetFloatingMode( TRUE );
+ SetPosSizePixel( nNormalPos, nNormalSize );
+
+ if ( TT_WIN_STATE_MAX == nWinState )
+ pFrame->nMaximizedWindows--;
+
+ nWinState = TT_WIN_STATE_FLOAT;
+ pFrame->WinMax_Restore();
+}
+
+void AppWin::Minimize( BOOL bMinimize )
+{
+ if ( bMinimize )
+ nWinState |= TT_WIN_STATE_HIDE;
+ else
+ nWinState &= ~TT_WIN_STATE_HIDE;
+ pFrame->WinMax_Restore();
+}
+
+void AppWin::Cascade( USHORT nNr )
+{
+ Restore();
+
+ nNr--;
+ nNr %= 10;
+ nNr++;
+
+ sal_Int32 nTitleHeight;
+ {
+ sal_Int32 nDummy1, nDummy2, nDummy3;
+ pFrame->GetBorder( nDummy1, nTitleHeight, nDummy2, nDummy3 );
+ }
+
+ Size aWinSize = pFrame->GetOutputSizePixel();
+ aWinSize.Width() -= aWinSize.Width() / 5; // reduce to 80 %
+ aWinSize.Height() -= nTitleHeight * nNr; // snip height to appropriate value
+ aWinSize.Height() -= 2;
+
+ Point nPos( nTitleHeight * nNr, nTitleHeight * nNr );
+
+ SetPosSizePixel( nPos, aWinSize );
+}
+
+void AppWin::RequestHelp( const HelpEvent& )
+{
+ Help();
+}
+
+void AppWin::Help()
+{
+ String s = pDataEdit->GetSelected();
+ if( s.Len() > 0 )
+ {
+ // Trim leading whitespaces
+ while( s.GetChar(0) == ' ' )
+ s.Erase( 0, 1 );
+// aBasicApp.pHelp->Start( s );
+ }
+ else
+ {
+// aBasicApp.pHelp->Start( OOO_HELP_INDEX );
+ }
+}
+
+void AppWin::Resize()
+{
+ if( pDataEdit )
+ {
+ pDataEdit->SetPosPixel( Point( 0, 0 ) );
+ pDataEdit->SetSizePixel( GetOutputSizePixel() );
+ }
+}
+
+void AppWin::GetFocus()
+{
+ pFrame->FocusWindow( this );
+ if( pDataEdit ) // GetFocus is called by the destructor, so this check
+ {
+ pDataEdit->GrabFocus();
+// InitMenu(GetpApp()->GetAppMenu()->GetPopupMenu( RID_APPEDIT ));
+ }
+}
+
+long AppWin::PreNotify( NotifyEvent& rNEvt )
+{
+
+ if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
+ Activate();
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ if ( pFrame->pList->Last() != this )
+ Activate();
+ return FALSE; // Der event soll weiter verarbeitet werden
+}
+
+void AppWin::Activate()
+{
+ GrabFocus();
+}
+
+// Set up the menu
+long AppWin::InitMenu( Menu* pMenu )
+{
+
+ ::rtl::OUString aTemp;
+ BOOL bMarked;
+ if( pDataEdit )
+ {
+ TextSelection r = pDataEdit->GetSelection();
+ bMarked = r.HasRange();
+ }
+ else
+ bMarked = FALSE;
+ pMenu->EnableItem( RID_EDITREPEAT, (aFind.Len() != 0 ) );
+ pMenu->EnableItem( RID_EDITCUT, bMarked );
+ pMenu->EnableItem( RID_EDITCOPY, bMarked );
+ pMenu->EnableItem( RID_EDITPASTE, ( ::svt::OStringTransfer::PasteString( aTemp, this ) ) );
+ pMenu->EnableItem( RID_EDITDEL, bMarked );
+// pMenu->EnableItem( RID_HELPTOPIC, bMarked );
+
+ BOOL bHasText;
+ if( pDataEdit )
+ bHasText = pDataEdit->HasText();
+ else
+ bHasText = FALSE;
+ BOOL bRunning = pFrame->Basic().IsRunning();
+ BOOL bCanExecute = BOOL( (!bRunning && bHasText) || pFrame->bInBreak );
+ pMenu->EnableItem( RID_RUNSTART, bCanExecute );
+ pMenu->EnableItem( RID_RUNBREAK, bRunning && !pFrame->bInBreak);
+ pMenu->EnableItem( RID_RUNSTOP, bRunning );
+ pMenu->EnableItem( RID_RUNTOCURSOR, bCanExecute );
+ pMenu->EnableItem( RID_RUNSTEPINTO, bCanExecute );
+ pMenu->EnableItem( RID_RUNSTEPOVER, bCanExecute );
+ return TRUE;
+}
+
+long AppWin::DeInitMenu( Menu* pMenu )
+{
+ pMenu->EnableItem( RID_EDITREPEAT );
+ pMenu->EnableItem( RID_EDITCUT );
+ pMenu->EnableItem( RID_EDITCOPY );
+ pMenu->EnableItem( RID_EDITPASTE );
+ pMenu->EnableItem( RID_EDITDEL );
+
+ pMenu->EnableItem( RID_RUNSTART );
+ pMenu->EnableItem( RID_RUNBREAK );
+ pMenu->EnableItem( RID_RUNSTOP );
+ pMenu->EnableItem( RID_RUNTOCURSOR );
+ pMenu->EnableItem( RID_RUNSTEPINTO );
+ pMenu->EnableItem( RID_RUNSTEPOVER );
+ return TRUE;
+}
+
+// Menu Handler
+
+void AppWin::Command( const CommandEvent& rCEvt )
+{
+ TextSelection r = pDataEdit->GetSelection();
+ BOOL bHasMark = r.HasRange();
+ switch( rCEvt.GetCommand() ) {
+ case RID_FILESAVE:
+ QuerySave( QUERY_DISK_CHANGED | SAVE_NOT_DIRTY ); break;
+ case RID_FILESAVEAS:
+ SaveAs(); break;
+ case RID_EDITSEARCH:
+ Find(); break;
+ case RID_EDITREPLACE:
+ Replace(); break;
+ case RID_EDITREPEAT:
+ Repeat(); break;
+ case RID_EDITCUT:
+ if( bHasMark )
+ pDataEdit->Cut();
+ break;
+ case RID_EDITCOPY:
+ if( bHasMark )
+ pDataEdit->Copy();
+ break;
+ case RID_EDITPASTE:
+ {
+ ::rtl::OUString aTemp;
+ if( ::svt::OStringTransfer::PasteString( aTemp, this ) )
+ pDataEdit->Paste();
+ }
+ break;
+ case RID_EDITDEL:
+ /*if( bHasMark ) */pDataEdit->Delete();
+ break;
+ case RID_EDITUNDO:
+ pDataEdit->Undo();
+ break;
+ case RID_EDITREDO:
+ pDataEdit->Redo();
+ break;
+ case COMMAND_CONTEXTMENU:
+ {
+ PopupMenu *pKontext = NULL;
+ pDataEdit->BuildKontextMenu( pKontext );
+ if ( pKontext )
+ {
+ USHORT nRes = pKontext->Execute( this, GetPointerPosPixel() );
+ if ( nRes )
+ pFrame->Command( nRes );
+ delete pKontext;
+ }
+ }
+ break;
+ }
+}
+
+
+BOOL AppWin::IsSkipReload()
+{
+ return nSkipReload != 0;
+}
+
+void AppWin::SkipReload( BOOL bSkip )
+{
+ DBG_ASSERT( bSkip || nSkipReload, "SkipReload aufgehoben ohne es zu aktivieren");
+ if ( bSkip )
+ nSkipReload++;
+ else
+ nSkipReload--;
+}
+
+BOOL AppWin::DiskFileChanged( USHORT nWhat )
+{
+ if ( !bHasFile )
+ return FALSE;
+
+ switch ( nWhat )
+ {
+ case SINCE_LAST_LOAD:
+ {
+ if ( bReloadAborted )
+ return TRUE;
+ else
+ return DiskFileChanged( SINCE_LAST_ASK_RELOAD );
+ }
+// uncomment to avoid compiler warning
+// break;
+ case SINCE_LAST_ASK_RELOAD:
+ {
+ String aFilename( GetText() );
+
+ DirEntry aFile( aFilename );
+ FileStat aStat( aFile );
+
+ return ( !aLastAccess.GetError() != !aStat.GetError() )
+ || aLastAccess.IsYounger( aStat ) || aStat.IsYounger( aLastAccess );
+ }
+// uncomment to avoid compiler warning
+// break;
+ default:
+ DBG_ERROR("Not Implemented in AppWin::DiskFileChanged");
+ }
+ return TRUE;
+}
+
+void AppWin::UpdateFileInfo( USHORT nWhat )
+{
+ switch ( nWhat )
+ {
+ case HAS_BEEN_LOADED:
+ {
+ bReloadAborted = FALSE;
+ UpdateFileInfo( ASKED_RELOAD );
+
+ }
+ break;
+ case ASKED_RELOAD:
+ {
+ String aFilename( GetText() );
+
+ DirEntry aFile( aFilename );
+ aLastAccess.Update( aFile );
+ }
+ break;
+ default:
+ DBG_ERROR("Not Implemented in AppWin::UpdateFileInfo");
+ }
+}
+
+void AppWin::CheckReload()
+{
+ if ( IsSkipReload() || !bHasFile )
+ return;
+
+ String aFilename( GetText() );
+ DirEntry aFile( aFilename );
+ if ( !aFilename.Len() )
+ return;
+
+ if ( !aFile.Exists() )
+ return;
+
+// FileStat aStat( aFile );
+
+ if ( DiskFileChanged( SINCE_LAST_ASK_RELOAD ) && ReloadAllowed() )
+ {
+ UpdateFileInfo( ASKED_RELOAD );
+ ToTop();
+ Update();
+ if ( (IsModified() && QueryBox( this, SttResId( IDS_ASKDIRTYRELOAD ) ).Execute() == RET_YES )
+ || ( !IsModified() && ( pFrame->IsAutoReload() || QueryBox( this, SttResId( IDS_ASKRELOAD ) ).Execute() == RET_YES ) ) )
+ {
+ Reload();
+ }
+ else
+ {
+ bReloadAborted = TRUE;
+ }
+ }
+}
+
+void AppWin::Reload()
+{
+ SkipReload();
+ TextSelection aSelMemo = pDataEdit->GetSelection();
+ Load( GetText() );
+ pDataEdit->SetSelection( aSelMemo );
+ SkipReload( FALSE );
+}
+
+// Load file
+BOOL AppWin::Load( const String& aName )
+{
+ SkipReload();
+ BOOL bErr;
+
+// if( !QuerySave() )
+// return;
+ bErr = !pDataEdit->Load( aName );
+ if( bErr )
+ {
+ ErrorBox aBox( this, SttResId( IDS_READERROR ) );
+ String aMsg = aBox.GetMessText();
+ aMsg.AppendAscii("\n\"");
+ aMsg.Append( aName );
+ aMsg.AppendAscii("\"");
+ if ( pFrame->IsAutoRun() )
+ {
+ printf( "%s\n", ByteString( aMsg, osl_getThreadTextEncoding() ).GetBuffer() );
+ }
+ else
+ {
+ aBox.SetMessText( aMsg );
+ aBox.Execute();
+ }
+ }
+ else
+ {
+ DirEntry aEntry( aName );
+ String aModName = aEntry.GetFull();
+ SetText( aModName );
+ UpdateFileInfo( HAS_BEEN_LOADED );
+ PostLoad();
+ bHasFile = TRUE;
+ }
+ SkipReload( FALSE );
+ return !bErr;
+}
+
+// Save file
+USHORT AppWin::ImplSave()
+{
+ SkipReload();
+ USHORT nResult = SAVE_RES_NOT_SAVED;
+ String s1 = *pNoName;
+ String s2 = GetText().Copy( 0, s1.Len() );
+ if( s1 == s2 )
+ nResult = SaveAs();
+ else {
+ String aName = GetText();
+ if ( pDataEdit->Save( aName ) )
+ {
+ nResult = SAVE_RES_SAVED;
+ bHasFile = TRUE;
+ }
+ else
+ {
+ nResult = SAVE_RES_ERROR;
+ ErrorBox( this, SttResId( IDS_WRITEERROR ) ).Execute();
+ }
+ UpdateFileInfo( HAS_BEEN_LOADED );
+ }
+ SkipReload( FALSE );
+ return nResult;
+}
+
+// Save to new file name
+USHORT AppWin::SaveAs()
+{
+ SkipReload();
+ String s1 = *pNoName;
+ String s2 = GetText().Copy( 0, s1.Len() );
+ if( s1 == s2 ) s2.Erase();
+ else s2 = GetText();
+ if( pFrame->QueryFileName( s2, GetFileType(), TRUE ) )
+ {
+ SetText( s2 );
+ PostSaveAs();
+ SkipReload( FALSE );
+ return ImplSave();
+ }
+ else
+ {
+ SkipReload( FALSE );
+ return SAVE_RES_CANCEL;
+ }
+}
+
+// Should we save the file?
+USHORT AppWin::QuerySave( QueryBits nBits )
+{
+ BOOL bQueryDirty = ( nBits & QUERY_DIRTY ) != 0;
+ BOOL bQueryDiskChanged = ( nBits & QUERY_DISK_CHANGED ) != 0;
+ BOOL bSaveNotDirty = ( nBits & SAVE_NOT_DIRTY ) != 0;
+
+ SkipReload();
+ short nResult;
+ if ( IsModified() || bSaveNotDirty )
+ nResult = RET_YES;
+ else
+ nResult = RET_NO;
+
+ BOOL bAlwaysEnableInput = pFrame->IsAlwaysEnableInput();
+ pFrame->AlwaysEnableInput( FALSE );
+ if( ( ( IsModified() || bSaveNotDirty ) && bQueryDirty ) || ( DiskFileChanged( SINCE_LAST_LOAD ) && bQueryDiskChanged ) )
+ {
+ ToTop();
+ if ( ( ( IsModified() && bQueryDirty ) && DiskFileChanged( SINCE_LAST_LOAD ) )
+ || ( IsModified() && ( DiskFileChanged( SINCE_LAST_LOAD ) && bQueryDiskChanged ) ) )
+ nResult = QueryBox( this, SttResId( IDS_ASK_DIRTY_AND_DISKCHANGE_SAVE ) ).Execute();
+ else if ( ( IsModified() && bQueryDirty ) )
+ nResult = QueryBox( this, SttResId( IDS_ASK_DIRTY_SAVE ) ).Execute();
+ else
+ nResult = QueryBox( this, SttResId( IDS_ASK_DISKCHANGE_SAVE ) ).Execute();
+ }
+ pFrame->AlwaysEnableInput( bAlwaysEnableInput );
+
+ USHORT nReturn;
+ switch( nResult )
+ {
+ case RET_YES:
+ nReturn = ImplSave();
+ break;
+ case RET_NO:
+ nReturn = SAVE_RES_NOT_SAVED;
+ break;
+ case RET_CANCEL:
+ nReturn = SAVE_RES_CANCEL;
+ break;
+ default:
+ DBG_ERROR("switch default where no default should be: Internal error");
+ nReturn = SAVE_RES_CANCEL;
+ }
+ SkipReload( FALSE );
+ return nReturn;
+}
+
+BOOL AppWin::Close()
+{
+ switch ( QuerySave( QUERY_DIRTY ) )
+ {
+ case SAVE_RES_NOT_SAVED:
+ case SAVE_RES_SAVED:
+ {
+ DockingWindow::Close();
+ delete this;
+ return TRUE;
+ }
+// uncomment to avoid compiler warning
+// break;
+ case SAVE_RES_ERROR:
+ return FALSE;
+// uncomment to avoid compiler warning
+// break;
+ case SAVE_RES_CANCEL:
+ return FALSE;
+// uncomment to avoid compiler warning
+// break;
+ default:
+ DBG_ERROR("Not Implemented in AppWin::Close");
+ return FALSE;
+ }
+}
+
+// Search and find text
+void AppWin::Find()
+{
+ SttResId aResId( IDD_FIND_DIALOG );
+ FindDialog aDlg( this, aResId, aFind );
+ if( aDlg.Execute() ) {
+ bFind = TRUE;
+ Repeat();
+ }
+}
+
+// Replace text
+void AppWin::Replace()
+{
+ SttResId aResId( IDD_REPLACE_DIALOG );
+ ReplaceDialog* pDlg = new ReplaceDialog
+ (this, aResId, aFind, aReplace );
+ if( pDlg->Execute() ) {
+ bFind = FALSE;
+ Repeat();
+ }
+}
+
+// Repeat search/replace operation
+void AppWin::Repeat()
+{
+ if( (aFind.Len() != 0 ) && ( pDataEdit->Find( aFind ) || (ErrorBox(this,SttResId(IDS_PATTERNNOTFOUND)).Execute() && FALSE) ) && !bFind )
+ pDataEdit->ReplaceSelected( aReplace );
+}
+
diff --git a/basic/source/app/appwin.hxx b/basic/source/app/appwin.hxx
new file mode 100644
index 000000000000..0e864e69eef9
--- /dev/null
+++ b/basic/source/app/appwin.hxx
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _APPWIN_HXX
+#define _APPWIN_HXX
+
+//#include <sb.hxx>
+#include <vcl/dockwin.hxx>
+#include <tools/fsys.hxx>
+
+#include "app.hxx"
+#include "dataedit.hxx"
+
+typedef USHORT QueryBits;
+#define QUERY_NONE ( QueryBits ( 0x00 ) )
+#define QUERY_DIRTY ( QueryBits ( 0x01 ) )
+#define QUERY_DISK_CHANGED ( QueryBits ( 0x02 ) )
+#define QUERY_ALL ( QUERY_DIRTY | QUERY_DISK_CHANGED )
+#define SAVE_NOT_DIRTY ( QueryBits ( 0x04 ) )
+
+#define SAVE_RES_SAVED TRUE
+#define SAVE_RES_NOT_SAVED FALSE
+#define SAVE_RES_ERROR 3
+#define SAVE_RES_CANCEL 4
+
+
+#define SINCE_LAST_LOAD 1
+#define SINCE_LAST_ASK_RELOAD 2
+
+#define HAS_BEEN_LOADED 1 // includes ASKED_RELOAD
+#define ASKED_RELOAD 2
+
+
+#define TT_WIN_STATE_MAX 0x01
+#define TT_WIN_STATE_FLOAT 0x02
+#define TT_WIN_STATE_HIDE 0x04
+
+class BasicFrame;
+
+class AppWin : public DockingWindow, public SfxListener // Document window
+{
+ friend class MsgEdit;
+protected:
+ static short nNumber; // serial number
+ static short nCount; // number of edit windows
+ static String *pNoName; // "Untitled"
+ FileStat aLastAccess; // Last access time of loaded file
+ USHORT nSkipReload; // Sometimes there must not be a reload
+ BOOL bHasFile; // Otherwise reload does not make sense
+ BOOL bReloadAborted; // Is set if reload was cancelled so that we can ask again wehn closing
+
+ short nId; // ID-Nummer( "Unnamed n" )
+ BasicFrame* pFrame; // Parent-Window
+// Icon* pIcon; // Document icon
+ String aFind; // Search string
+ String aReplace; // Replace string
+ BOOL bFind; // TRUE if search not replace
+ void RequestHelp( const HelpEvent& ); // Help handler
+ void GetFocus(); // activate
+ virtual USHORT ImplSave(); // Save file
+ USHORT nWinState; // Maximized, Iconized or Normal
+ Point nNormalPos; // Position if normal
+ Size nNormalSize; // Size if Normal
+ virtual long PreNotify( NotifyEvent& rNEvt );
+ USHORT nWinId;
+
+public:
+ TYPEINFO();
+ AppWin( BasicFrame* );
+ ~AppWin();
+ DataEdit* pDataEdit; // Data area
+ virtual USHORT GetLineNr()=0; // Current line number
+ virtual long InitMenu( Menu* ); // Init of the menu
+ virtual long DeInitMenu( Menu* ); // reset to enable all shortcuts
+ virtual void Command( const CommandEvent& rCEvt ); // Command handler
+ virtual void Resize();
+ virtual void Help();
+ virtual BOOL Load( const String& ); // Load file
+ virtual void PostLoad(){} // Set source at module
+ virtual USHORT SaveAs(); // Save file as
+ virtual void PostSaveAs(){}
+ virtual void Find(); // find text
+ virtual void Replace(); // replace text
+ virtual void Repeat(); // repeat find/replace
+ virtual BOOL Close(); // close window
+ virtual void Activate(); // window was activated
+ virtual FileType GetFileType()=0; // returns the filetype
+ virtual BOOL ReloadAllowed(){ return TRUE; }
+ virtual void Reload(); // Reload after change on disk
+ virtual void LoadIniFile(){;} // (re)load ini file after change
+ void CheckReload(); // Checks and asks if reload should performed
+ BOOL DiskFileChanged( USHORT nWhat ); // Checks file for changes
+ void UpdateFileInfo( USHORT nWhat ); // Remembers last file state
+ BOOL IsSkipReload(); // Should we test reload?
+ void SkipReload( BOOL bSkip = TRUE );
+ USHORT GetWinState(){ return nWinState; }
+ void Maximize();
+ void Restore();
+ void Minimize( BOOL bMinimize );
+ void Cascade( USHORT nNr );
+
+ USHORT QuerySave( QueryBits nBits = QUERY_ALL );
+ BOOL IsModified() { return pDataEdit->IsModified(); }
+ BasicFrame* GetBasicFrame() { return pFrame; }
+ virtual void TitleButtonClick( USHORT nButton );
+ virtual void SetText( const XubString& rStr );
+
+ USHORT GetWinId() { return nWinId; }
+ void SetWinId( USHORT nWId ) { nWinId = nWId; }
+};
+
+DECLARE_LIST( EditList, AppWin* )
+
+#endif
diff --git a/basic/source/app/basic.hrc b/basic/source/app/basic.hrc
new file mode 100644
index 000000000000..e4a69d9d2942
--- /dev/null
+++ b/basic/source/app/basic.hrc
@@ -0,0 +1,184 @@
+/*************************************************************************
+ *
+ * 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 RID_OPTLIST 101
+#define RID_OPTLINES 102
+#define RID_OPTPACKS 103
+#define RID_OPTPACKD 104
+#define RID_OPTWARN1 105
+#define RID_OPTWARN2 106
+#define RID_OPTVIRT 107
+#define RID_PARAMS 108
+#define RID_RETTYPE 109
+#define RID_RETVAL 110
+//#define RID_APPICON 500
+//#define RID_APPICON2 501
+//#define RID_WORKICON 502
+//#define RID_LOADICON 503
+//#define RID_SAVEICON 504
+#define RID_APPMENUBAR 1000
+#define RID_APPFILE 1001
+#define RID_APPEDIT 1002
+#define RID_APPRUN 1003
+#define RID_APPWINDOW 1004
+#define RID_APPHELP 1005
+#define RID_FILE 1100
+#define RID_FILENEW 1101
+#define RID_FILEOPEN 1102
+#define RID_FILECLOSE 1103
+#define RID_FILESAVE 1104
+#define RID_FILESAVEAS 1105
+#define RID_FILELOADLIB 1106
+#define RID_FILESAVELIB 1107
+#define RID_FILEPRINT 1109
+#define RID_FILESETUP 1110
+#define RID_QUIT 1111
+#define IDM_FILE_LRU1 1112
+#define IDM_FILE_LRUn 1199
+#define RID_EDIT 1200
+#define RID_EDITUNDO 1201
+#define RID_EDITREDO 1202
+#define RID_EDITCUT 1203
+#define RID_EDITCOPY 1204
+#define RID_EDITPASTE 1205
+#define RID_EDITDEL 1206
+#define RID_EDITSEARCH 1207
+#define RID_EDITREPLACE 1208
+#define RID_EDITREPEAT 1209
+#define RID_RUN 1300
+#define RID_RUNCOMPILE 1301
+#define RID_RUNSTART 1302
+#define RID_RUNBREAK 1304
+#define RID_RUNSTOP 1303
+#define RID_RUNNEXTERR 1307
+#define RID_RUNPREVERR 1308
+#define RID_RUNDISAS 1310
+#define RID_RUNSTEPINTO 1311
+#define RID_RUNSTEPOVER 1312
+#define RID_RUNTOCURSOR 1313
+#define RID_TOGLEBRKPNT 1314
+#define RID_TT_EXTRAS_NAME 1400
+#define RID_TT_EXTRAS 1401
+#define RID_OPTIONS 1402
+#define RID_DECLARE_HELPER 1403
+#define RID_WINDOW 1501
+#define RID_WINTILE 1502
+#define RID_WINTILEHORZ 1503
+#define RID_WINTILEVERT 1504
+#define RID_WINCASCADE 1505
+#define RID_WIN_FILE1 1520
+#define RID_WIN_FILEn 1599
+
+#define RID_HELP 1601
+//#define RID_HELPINDEX 1602
+//#define RID_HELPKEYS 1603
+//#define RID_HELPINTRO 1604
+//#define RID_HELPTOPIC 1605
+#define RID_HELPABOUT 1606
+#define RID_POPUP 1700
+#define RID_POPUPEDITVAR 1701
+
+
+
+#define IDS_APPNAME 2000
+#define IDS_APPNAME2 2001
+#define IDS_APPMODE_BREAK 2002
+#define IDS_APPMODE_RUN 2003
+#define IDS_NONAME 2100
+#define IDS_NONAMEFILE 2101
+#define IDS_INCFILE 2102
+#define IDS_LIBFILE 2103
+#define IDS_RESFILE 2104
+#define IDS_TXTFILE 2105
+#define IDS_READERROR 2103
+#define IDS_WRITEERROR 2104
+#define IDS_COMPERROR 2105
+#define IDS_CONTINUE 2106
+#define IDS_CANCEL 2107
+#define IDS_NOPRINTERERROR 2108
+#define IDS_PATTERNNOTFOUND 2109
+#define IDS_INVALID_VALUE 2110
+#define IDS_ASK_DIRTY_SAVE 2200
+#define IDS_ASK_DISKCHANGE_SAVE 2201
+#define IDS_ASK_DIRTY_AND_DISKCHANGE_SAVE 2202
+#define IDS_ASKSAVEERROR 2203
+#define IDS_ASKRELOAD 2204
+#define IDS_ASKDIRTYRELOAD 2205
+#define IDS_LOADDLG 2300
+#define IDS_SAVEDLG 2301
+#define IDS_BASFILTER 2304
+#define IDS_LIBFILTER 2305
+#define IDS_INCFILTER 2306
+#define IDS_RESFILTER 2307
+#define IDS_TXTFILTER 2308
+#define IDS_PAGE 2401
+#define IDS_PRINTMSG 2402
+#define IDS_CANTLOAD 2501
+#define IDS_CANTSAVE 2502
+#define IDS_ERROR1 2601
+#define IDS_ERROR2 2602
+#define IDS_WARNING1 2603
+#define IDS_NO_LONGNAME 2604
+#define IDS_WARNING_PREFIX 2605
+#define IDS_OBJECT 2606
+#define IDS_EDIT_VAR 2607
+
+#define IDS_NOMAINPGM 2701
+#define IDS_DISASWIN 2702
+#define IDS_RUNNING 2703
+#define IDS_NOT_YET_IMPLEMENTED 2704
+#define IDS_LOSS_OF_INFORMATION 2705
+
+#define RID_ACCEL 3000
+
+#define IDD_LOADSAVE_DIALOG 4001
+#define IDD_ABOUT_DIALOG 4002
+#define IDD_TT_ABOUT_DIALOG 4003
+#define IDD_FIND_DIALOG 4004
+#define IDD_REPLACE_DIALOG 4005
+#define IDD_PRINT_DIALOG 4006
+#define IDD_OPTIONS_DLG 4007
+#define RID_TP_PROFILE 4008
+#define RID_TP_CRASH 4009
+#define RID_TP_MISC 4010
+#define RID_TP_FONT 4011
+#define RID_TP_GENERIC 4012
+#define IDD_DISPLAY_HID 4013
+#define IDD_EDIT_VAR 4014
+
+
+//#define RID_APPFONT 5000
+//#define RID_APPEDITFONT 5001
+//#define RID_DLGBRUSH 5002
+#define RID_CALLDLG 6001
+#define MBP_PLUS 8001
+#define MBP_MINUS 8002
+#define RID_IMGLST_LAYOUT 8005
+#define MAIN_ACCEL 9001
+
+#define LOAD_CONF 10001
+#define WORK 10002
+#define FILENAME 10003
diff --git a/basic/source/app/basic.src b/basic/source/app/basic.src
new file mode 100644
index 000000000000..0713fd859f56
--- /dev/null
+++ b/basic/source/app/basic.src
@@ -0,0 +1,1472 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include "basic.hrc"
+#include "resids.hrc"
+
+ModalDialog RID_CALLDLG {
+ PosSize = MAP_SYSFONT (18,18,142,142);
+ SVLook = TRUE;
+ MOVEABLE = TRUE;
+ CLOSEABLE = TRUE;
+// WinChilds = {
+// FixedText {
+// Text = "Aktuelle Parameter";
+// PosSize = MAP_SYSFONT (10,10,120,8);
+// };
+// };
+ FixedText RID_RETTYPE {
+ PosSize = MAP_SYSFONT (10,70,120,8);
+ };
+ Edit RID_RETVAL {
+ PosSize = MAP_SYSFONT (10,85,120,12);
+ Border = TRUE;
+ TabStop = TRUE;
+ };
+ ListBox RID_PARAMS {
+ PosSize = MAP_SYSFONT (10,25,120,40);
+ TabStop = TRUE;
+ Border = TRUE;
+ };
+ OKButton RID_OK {
+ PosSize = MAP_SYSFONT (50,105,40,14);
+ TabStop = TRUE;
+ DefButton = TRUE;
+ };
+ Text[ en-US ] = "Dynamic Link No. ";
+};
+
+ModalDialog IDD_ABOUT_DIALOG {
+ Pos = MAP_APPFONT( 58, 17 );
+ Size = MAP_APPFONT( 155, 106 );
+ SVLook = TRUE;
+/*
+ WINCHILDS = {
+ FixedText {
+ Pos = MAP_APPFONT( 40, 5 );
+ Size = MAP_APPFONT( 110, 10 );
+ TEXT = "Testtool";
+ CENTER = TRUE;
+ };
+ FixedText {
+ Pos = MAP_APPFONT( 40, 20 );
+ Size = MAP_APPFONT( 110, 20 );
+ TEXT = "Ojektorientiertes BASIC-Entwicklungssystem";
+ CENTER = TRUE;
+ };
+ FixedText {
+ Pos = MAP_APPFONT( 40, 45 );
+ Size = MAP_APPFONT( 110, 10 );
+ TEXT = "Version 2.0 May 2002";
+ CENTER = TRUE;
+ };
+ FixedText {
+ Pos = MAP_APPFONT( 40, 60 );
+ Size = MAP_APPFONT( 110, 10 );
+ TEXT = "®1995-2010 Oracle";
+ CENTER = TRUE;
+ };
+ };
+*/
+// FixedIcon RID_ICON {
+// Pos = MAP_APPFONT( 20, 26 );
+// Size = MAP_APPFONT( 20, 20 );
+// FIXED = Icon {
+// FILE = "basic.ico";
+// };
+// };
+ OKButton RID_OK {
+ Pos = MAP_APPFONT( 55, 80 );
+ Size = MAP_APPFONT( 40, 14 );
+ DefButton = TRUE;
+ };
+};
+
+ModalDialog IDD_TT_ABOUT_DIALOG {
+ Pos = MAP_APPFONT( 58, 17 );
+ Size = MAP_APPFONT( 120, 81 );
+ SVLook = TRUE;
+ MOVEABLE = TRUE;
+ FixedText 1 {
+ Pos = MAP_APPFONT( 5, 10 );
+ Size = MAP_APPFONT( 110, 10 );
+ CENTER = TRUE;
+ TEXT[ en-US ] = "VCLTestTool";
+ };
+ FixedText RID_VERSIONSTRING {
+ Pos = MAP_APPFONT( 5, 25 );
+ Size = MAP_APPFONT( 110, 10 );
+ Text = UPDVER;
+ CENTER = TRUE;
+ };
+ FixedText 4 {
+ Pos = MAP_APPFONT( 5, 40 );
+ Size = MAP_APPFONT( 110, 10 );
+ CENTER = TRUE;
+ TEXT[ en-US ] = "©1995-2010 Oracle";
+ };
+ OKButton RID_OK {
+ Pos = MAP_APPFONT( 40, 60 );
+ Size = MAP_APPFONT( 40, 14 );
+ DefButton = TRUE;
+ };
+ TEXT[ en-US ] = "About VCLTestTool";
+};
+
+ModalDialog IDD_FIND_DIALOG {
+ Pos = MAP_APPFONT( 69, 30 );
+ Size = MAP_APPFONT( 185, 70 );
+ SVLook = TRUE;
+ MOVEABLE = TRUE;
+ // CLOSEABLE = TRUE; // Hat cancelbutton
+
+ FixedText RID_FIXEDTEXT1 {
+ Pos = MAP_APPFONT( 5, 10 );
+ Size = MAP_APPFONT( 30, 10 );
+ TEXT[ en-US ] = "~Text";
+ };
+ Edit RID_FIND {
+ BORDER = TRUE;
+ Pos = MAP_APPFONT( 40, 8 );
+ Size = MAP_APPFONT( 135, 12 );
+ TABSTOP = TRUE;
+ };
+ OKButton RID_OK {
+ Pos = MAP_APPFONT( 30, 30 );
+ Size = MAP_APPFONT( 50, 14 );
+ TABSTOP = TRUE;
+ DefButton = TRUE;
+ TEXT[ en-US ] = "~Find";
+ };
+ CancelButton RID_CANCEL {
+ Pos = MAP_APPFONT( 105, 30 );
+ Size = MAP_APPFONT( 50, 14 );
+ TABSTOP = TRUE;
+ TEXT[ en-US ] = "~Cancel";
+ };
+ TEXT[ en-US ] = "Testtool: Find Text";
+};
+
+ModalDialog IDD_REPLACE_DIALOG {
+ Pos = MAP_APPFONT( 69, 30 );
+ Size = MAP_APPFONT( 185, 88 );
+ SVLook = TRUE;
+ MOVEABLE = TRUE;
+ // CLOSEABLE = TRUE; // Hat cancelbutton
+ FixedText RID_FIXEDTEXT1 {
+ Pos = MAP_APPFONT( 5, 10 );
+ Size = MAP_APPFONT( 55, 10 );
+ TEXT[ en-US ] = "~Search for";
+ };
+ FixedText RID_FIXEDTEXT2 {
+ Pos = MAP_APPFONT( 5, 30 );
+ Size = MAP_APPFONT( 55, 10 );
+ TEXT[ en-US ] = "~Replace by";
+ };
+ Edit RID_FIND {
+ BORDER = TRUE;
+ Pos = MAP_APPFONT( 65, 8 );
+ Size = MAP_APPFONT( 110, 12 );
+ TABSTOP = TRUE;
+ };
+ Edit RID_REPLACE {
+ BORDER = TRUE;
+ Pos = MAP_APPFONT( 65, 28 );
+ Size = MAP_APPFONT( 110, 12 );
+ TABSTOP = TRUE;
+ };
+ OKButton RID_OK {
+ Pos = MAP_APPFONT( 30, 50 );
+ Size = MAP_APPFONT( 50, 14 );
+ TABSTOP = TRUE;
+ DefButton = TRUE;
+ TEXT[ en-US ] = "~Replace";
+ };
+ CancelButton RID_CANCEL {
+ Pos = MAP_APPFONT( 105, 50 );
+ Size = MAP_APPFONT( 50, 14 );
+ TABSTOP = TRUE;
+ TEXT[ en-US ] = "~Cancel";
+ };
+ TEXT[ en-US ] = "Testtool: Replace Text";
+};
+
+InfoBox IDS_NOPRINTERERROR {
+ MESSAGE[ en-US ] = "The print function is not available!";
+};
+ErrorBox IDS_CANTLOAD {
+ MESSAGE[ en-US ] = "Library cannot be loaded!";
+ Title[ en-US ] = "Testtool Error";
+};
+ErrorBox IDS_CANTSAVE {
+ MESSAGE[ en-US ] = "Library cannot be saved!";
+ Title[ en-US ] = "Testtool Error";
+};
+ErrorBox IDS_NOMAINPGM {
+ MESSAGE[ en-US ] = "This window does not contain a main program!";
+ Title[ en-US ] = "Testtool Error";
+};
+ErrorBox IDS_READERROR {
+ MESSAGE[ en-US ] = "File cannot be read!";
+ Title[ en-US ] = "Testtool Error";
+};
+ErrorBox IDS_WRITEERROR {
+ MESSAGE[ en-US ] = "File cannot be saved!";
+ Title[ en-US ] = "Testtool Error";
+};
+ErrorBox IDS_PATTERNNOTFOUND {
+ MESSAGE[ en-US ] = "Search key not found!";
+ Title[ en-US ] = "Testtool Error";
+};
+ErrorBox IDS_INVALID_VALUE {
+ MESSAGE[ en-US ] = "The value is invalid and cannot be set.";
+ Title[ en-US ] = "Testtool Error";
+};
+
+QueryBox IDS_ASKSAVEERROR {
+ TITLE = "Testtool";
+ BUTTONS = WB_YES_NO;
+ MESSAGE[ en-US ] = "Error saving files! Run anyway?";
+ Title[ en-US ] = "Testtool";
+};
+QueryBox IDS_ASK_DIRTY_SAVE {
+ TITLE = "Testtool";
+ BUTTONS = WB_YES_NO_CANCEL;
+ MESSAGE[ en-US ] = "File has been changed. Save?";
+ Title[ en-US ] = "Testtool";
+};
+QueryBox IDS_ASK_DIRTY_AND_DISKCHANGE_SAVE {
+ TITLE = "Testtool";
+ BUTTONS = WB_YES_NO_CANCEL;
+ MESSAGE[ en-US ] = "File has been changed on data medium\nand in the Editor. Save?";
+ Title[ en-US ] = "Testtool";
+};
+QueryBox IDS_ASK_DISKCHANGE_SAVE {
+ TITLE = "Testtool";
+ BUTTONS = WB_YES_NO_CANCEL;
+ MESSAGE[ en-US ] = "File has been changed on data medium.\nOverwrite?";
+ Title[ en-US ] = "Testtool";
+};
+QueryBox IDS_ASKRELOAD {
+ TITLE = "Testtool";
+ BUTTONS = WB_YES_NO;
+ MESSAGE[ en-US ] = "File has been changed on data medium. Reload?";
+ Title[ en-US ] = "Testtool";
+};
+QueryBox IDS_ASKDIRTYRELOAD {
+ TITLE = "Testtool";
+ BUTTONS = WB_YES_NO;
+ MESSAGE[ en-US ] = "File has been changed on data medium\nand in the Editor. Reload?";
+ Title[ en-US ] = "Testtool";
+};
+QueryBox IDS_RUNNING {
+ TITLE = "Testtool";
+ BUTTONS = WB_YES_NO;
+ MESSAGE[ en-US ] = "BASIC is still running! Exit anyway?";
+ Title[ en-US ] = "Testtool";
+};
+QueryBox IDS_LOSS_OF_INFORMATION {
+ TITLE = "Testtool";
+ BUTTONS = WB_OK_CANCEL;
+ MESSAGE[ en-US ] = "Saving in an external format causes information loss.";
+ Title[ en-US ] = "Testtool";
+};
+
+InfoBox IDS_NOT_YET_IMPLEMENTED
+{
+ MESSAGE[ en-US ] = "Not yet implemented";
+};
+
+
+String IDS_WARNING1 {
+ TEXT[ en-US ] = "Warning ";
+};
+String IDS_ERROR1 {
+ TEXT[ en-US ] = "Error ";
+};
+String IDS_ERROR2 {
+ TEXT[ en-US ] = " in line ";
+};
+String IDS_NO_LONGNAME {
+ TEXT[ en-US ] = "No entries in Hid.Lst";
+};
+String IDS_WARNING_PREFIX
+{
+ Text[ en-US ] = "Warning: ";
+};
+String IDS_OBJECT
+{
+ Text[ en-US ] = "Object";
+};
+String IDS_EDIT_VAR
+{
+ Text[ en-US ] = "Edit ($Arg1)";
+};
+
+String IDS_APPNAME {
+ TEXT[ en-US ] = "Testtool";
+};
+String IDS_APPNAME2 {
+ TEXT[ en-US ] = "VCLTestTool";
+};
+String IDS_APPMODE_BREAK {
+ text[ en-US ] = "Break";
+};
+String IDS_APPMODE_RUN {
+ text[ en-US ] = "Run";
+};
+String IDS_NONAME {
+ TEXT[ en-US ] = "Unnamed";
+};
+
+String IDS_NONAMEFILE {
+#if defined ( UNX )
+TEXT = "*.bas";
+#else
+TEXT = "*.BAS";
+#endif
+};
+String IDS_INCFILE {
+#if defined ( UNX )
+TEXT = "*.inc";
+#else
+TEXT = "*.INC";
+#endif
+};
+String IDS_LIBFILE {
+#if defined ( UNX )
+TEXT = "*.sb";
+#else
+TEXT = "*.SB";
+#endif
+};
+String IDS_RESFILE {
+#if defined ( UNX )
+TEXT = "*.res";
+#else
+TEXT = "*.RES";
+#endif
+};
+String IDS_TXTFILE {
+#if defined ( UNX )
+TEXT = "*.txt";
+#else
+TEXT = "*.TXT";
+#endif
+};
+
+String IDS_LOADDLG {
+ TEXT[ en-US ] = "Testtool: Load File";
+};
+String IDS_SAVEDLG {
+ TEXT[ en-US ] = "Testtool: Save File";
+};
+String IDS_BASFILTER {
+ TEXT[ en-US ] = "Source files (*.BAS)";
+};
+String IDS_INCFILTER {
+ TEXT[ en-US ] = "Include files (*.INC)";
+};
+String IDS_LIBFILTER {
+ TEXT[ en-US ] = "Libraries (*.SB)";
+};
+String IDS_RESFILTER {
+ TEXT[ en-US ] = "Result files (*.RES)";
+};
+String IDS_TXTFILTER {
+ TEXT[ en-US ] = "Results as text file (*.TXT)";
+};
+String IDS_PAGE {
+ TEXT[ en-US ] = "Page ";
+};
+String IDS_PRINTMSG {
+ TEXT[ en-US ] = "Printout of ";
+};
+String IDS_CONTINUE {
+ TEXT[ en-US ] = "Continue";
+};
+String IDS_CANCEL {
+ TEXT[ en-US ] = "Cancel";
+};
+String IDS_DISASWIN {
+ TEXT[ en-US ] = "Disassembly";
+};
+//Icon RID_APPICON {
+// FILE = "basic.ico";
+//};
+//Icon RID_APPICON2 {
+// FILE = "testtool.ico";
+//};
+//Icon RID_WORKICON {
+// FILE = "work.ico";
+//};
+
+Bitmap MBP_PLUS {
+ File = "plus.bmp";
+};
+Bitmap MBP_MINUS {
+ File = "minus.bmp";
+};
+
+Menu RID_APPMENUBAR {
+ ItemList = {
+ MenuItem {
+ Identifier = RID_APPFILE;
+ SUBMENU = Menu ,RID_FILE;
+ TEXT[ en-US ] = "~File";
+ };
+ MenuItem {
+ Identifier = RID_APPEDIT;
+ SUBMENU = Menu ,RID_EDIT;
+ TEXT[ en-US ] = "~Edit";
+ };
+ MenuItem {
+ Identifier = RID_APPRUN;
+ SUBMENU = Menu ,RID_RUN;
+ TEXT[ en-US ] = "~Program";
+ };
+ MenuItem {
+ Identifier = RID_APPWINDOW;
+ SUBMENU = Menu ,RID_WINDOW;
+ TEXT[ en-US ] = "~Window";
+ };
+ MenuItem {
+ SEPARATOR = TRUE;
+ };
+ MenuItem {
+ HELP = TRUE;
+ Identifier = RID_APPHELP;
+ SUBMENU = Menu ,RID_HELP;
+ TEXT[ en-US ] = "~Help";
+ };
+ };
+};
+Menu RID_FILE {
+ ITEMLIST = {
+ MenuItem {
+ Identifier = RID_FILENEW;
+ TEXT[ en-US ] = "~New";
+ AccelKey = KeyCode { Function = KEYFUNC_NEW; };
+ };
+ MenuItem {
+ Identifier = RID_FILEOPEN;
+ TEXT[ en-US ] = "~Open...";
+ AccelKey = KeyCode { Function = KEYFUNC_OPEN; };
+ };
+ MenuItem {
+ SEPARATOR = TRUE;
+ };
+ MenuItem {
+ Identifier = RID_FILECLOSE;
+ TEXT[ en-US ] = "~Close";
+ AccelKey = KeyCode { Function = KEYFUNC_CLOSE; };
+ };
+ MenuItem {
+ Identifier = RID_FILESAVE;
+ TEXT[ en-US ] = "~Save";
+ AccelKey = KeyCode { Function = KEYFUNC_SAVE; };
+ };
+ MenuItem {
+ Identifier = RID_FILESAVEAS;
+ TEXT[ en-US ] = "Save~ As...";
+ AccelKey = KeyCode { Function = KEYFUNC_SAVEAS; };
+ };
+ MenuItem {
+ SEPARATOR = TRUE;
+ };
+ MenuItem {
+ Identifier = RID_FILELOADLIB;
+ TEXT[ en-US ] = "~Load Library...";
+ };
+ MenuItem {
+ Identifier = RID_FILESAVELIB;
+ TEXT[ en-US ] = "Save Li~brary...";
+ };
+ MenuItem {
+ SEPARATOR = TRUE;
+ };
+ MenuItem {
+ Identifier = RID_FILEPRINT;
+ TEXT[ en-US ] = "~Print";
+ };
+ MenuItem {
+ Identifier = RID_FILESETUP;
+ TEXT[ en-US ] = "P~rinter Setting...";
+ };
+ MenuItem {
+ SEPARATOR = TRUE;
+ };
+ MenuItem {
+ Identifier = RID_QUIT;
+ TEXT[ en-US ] = "~Exit";
+ AccelKey = KeyCode { Function = KEYFUNC_QUIT; };
+ };
+ };
+};
+Menu RID_EDIT {
+ ITEMLIST = {
+ MenuItem {
+ Identifier = RID_EDITUNDO;
+ TEXT[ en-US ] = "~Undo";
+// AccelKey = KeyCode { Function = KEYFUNC_CUT; };
+ };
+ MenuItem {
+ Identifier = RID_EDITREDO;
+ TEXT[ en-US ] = "~Redo";
+// AccelKey = KeyCode { Function = KEYFUNC_CUT; };
+ };
+ MenuItem {
+ SEPARATOR = TRUE;
+ };
+ MenuItem {
+ Identifier = RID_EDITCUT;
+ TEXT[ en-US ] = "~Cut";
+ AccelKey = KeyCode { Function = KEYFUNC_CUT; };
+ };
+ MenuItem {
+ Identifier = RID_EDITCOPY;
+ TEXT[ en-US ] = "~Copy";
+ AccelKey = KeyCode { Function = KEYFUNC_COPY; };
+ };
+ MenuItem {
+ Identifier = RID_EDITPASTE;
+ TEXT[ en-US ] = "~Paste";
+ AccelKey = KeyCode { Function = KEYFUNC_PASTE; };
+ };
+ MenuItem {
+ Identifier = RID_EDITDEL;
+ TEXT[ en-US ] = "~Delete";
+ AccelKey = KeyCode { Function = KEYFUNC_DELETE; };
+ };
+ MenuItem {
+ SEPARATOR = TRUE;
+ };
+ MenuItem {
+ Identifier = RID_EDITSEARCH;
+ TEXT[ en-US ] = "~Find...";
+ AccelKey = KeyCode { Function = KEYFUNC_FIND; };
+ };
+ MenuItem {
+ Identifier = RID_EDITREPLACE;
+ TEXT[ en-US ] = "~Replace...";
+ };
+ MenuItem {
+ Identifier = RID_EDITREPEAT;
+ TEXT[ en-US ] = "Repeat S~earch";
+ AccelKey = KeyCode { Code = KEY_F3; };
+// AccelKey = KeyCode { Function = KEYFUNC_REPEAT; };
+ };
+ };
+};
+Menu RID_RUN {
+ ITEMLIST = {
+ MenuItem {
+ Identifier = RID_RUNCOMPILE;
+ TEXT[ en-US ] = "~Compile";
+ };
+ MenuItem {
+ Identifier = RID_RUNDISAS;
+ TEXT[ en-US ] = "~Disassemble";
+ };
+ MenuItem {
+ Identifier = RID_RUNSTART;
+ TEXT[ en-US ] = "~Start";
+ AccelKey = KeyCode { Code = KEY_F5; };
+ };
+ MenuItem {
+ Identifier = RID_RUNSTEPINTO;
+ TEXT[ en-US ] = "~Single Step";
+ AccelKey = KeyCode { Code = KEY_F8; };
+ };
+ MenuItem {
+ Identifier = RID_RUNSTEPOVER;
+ TEXT[ en-US ] = "Si~ngle Step over Procedure";
+ AccelKey = KeyCode { Code = KEY_F10; };
+ };
+// MenuItem {
+// Identifier = RID_RUNTOCURSOR;
+// TEXT = "Run to cursor";
+// AccelKey = KeyCode { Code = KEY_F7; };
+// };
+ MenuItem {
+ Identifier = RID_TOGLEBRKPNT;
+ TEXT[ en-US ] = "Set / Delete Break Point";
+ AccelKey = KeyCode { Code = KEY_F9; };
+ };
+ MenuItem {
+ Identifier = RID_RUNBREAK;
+ TEXT[ en-US ] = "~Break";
+ AccelKey = KeyCode { Code = KEY_F5; Modifier1 = TRUE; };
+ };
+ MenuItem {
+ Identifier = RID_RUNSTOP;
+ TEXT[ en-US ] = "~Stop";
+ AccelKey = KeyCode { Code = KEY_F5; Shift = TRUE; };
+ };
+ MenuItem {
+ Identifier = RID_RUNNEXTERR;
+ TEXT[ en-US ] = "~Next Error";
+ AccelKey = KeyCode { Code = KEY_F8; Shift = TRUE; };
+ };
+ MenuItem {
+ Identifier = RID_RUNPREVERR;
+ TEXT[ en-US ] = "~Previous Error";
+ AccelKey = KeyCode { Code = KEY_F7; Shift = TRUE; };
+ };
+ MenuItem {
+ SEPARATOR = TRUE;
+ };
+ };
+};
+// Wird nur beim Test Tool eingef³gt
+
+// unter Folgendem Name
+String RID_TT_EXTRAS_NAME
+{
+ Text[ en-US ] = "E~xtra";
+};
+
+Menu RID_TT_EXTRAS {
+ ITEMLIST = {
+ MenuItem {
+ Identifier = RID_OPTIONS;
+ TEXT[ en-US ] = "~Settings";
+ };
+/* comment out till it gets functionality #i26908
+ MenuItem {
+ Identifier = RID_DECLARE_HELPER;
+ Text [ en-US ] = "~Record Dialogs";
+ };*/
+ };
+};
+Menu RID_WINDOW {
+ ITEMLIST = {
+/* MenuItem {
+ Identifier = RID_WINCASCADE;
+ TEXT[ en-US ] = "~Cascade";
+ };
+ MenuItem {
+ Identifier = RID_WINTILE;
+ TEXT[ en-US ] = "~Tile";
+ };
+ MenuItem {
+ Identifier = RID_WINTILEHORZ;
+ TEXT[ en-US ] = "~Arrange Horizontally";
+ };
+ MenuItem {
+ Identifier = RID_WINTILEVERT;
+ TEXT[ en-US ] = "~Arrange Vertically";
+ };*/
+ };
+};
+Menu RID_HELP {
+ ITEMLIST = {
+/* MenuItem {
+ Identifier = RID_HELPINDEX;
+ TEXT = "~Index";
+ };
+ MenuItem {
+ SEPARATOR = TRUE;
+ };
+ MenuItem {
+ Identifier = RID_HELPKEYS;
+ TEXT = "~Tastaturbelegung";
+ };
+ MenuItem {
+ Identifier = RID_HELPINTRO;
+ TEXT = "~Anleitung";
+ };
+ MenuItem {
+ SEPARATOR = TRUE;
+ };
+ MenuItem {
+ Identifier = RID_HELPTOPIC;
+ TEXT = "~Markierter Text";
+ };
+ MenuItem {
+ SEPARATOR = TRUE;
+ };
+*/ MenuItem {
+ ABOUT = TRUE;
+ Identifier = RID_HELPABOUT;
+ TEXT[ en-US ] = "~About...";
+ };
+ };
+};
+ModelessDialog IDD_PRINT_DIALOG {
+ Pos = MAP_APPFONT( 83, 42 );
+ Size = MAP_APPFONT( 171, 94 );
+ MOVEABLE = TRUE;
+ SVLook = TRUE;
+ FixedText RID_TEXT {
+ Pos = MAP_APPFONT( 11, 9 );
+ Size = MAP_APPFONT( 146, 28 );
+ CENTER = TRUE;
+ TEXT[ en-US ] = "Print ";
+ };
+ CancelButton RID_CANCEL {
+ Pos = MAP_APPFONT( 56, 46 );
+ Size = MAP_APPFONT( 47, 19 );
+ TEXT[ en-US ] = "Cancel";
+ };
+ TEXT[ en-US ] = "Testtool: Print File";
+};
+
+
+TabDialog IDD_OPTIONS_DLG
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT( 248, 140 );
+ Text[ en-US ] = "Settings";
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ TabControl RES_TC_OPTIONS
+ {
+ OutputSize = TRUE ;
+ Pos = MAP_APPFONT( 4, 4 );
+ Size = MAP_APPFONT( 240, 116 );
+ Hide = FALSE ;
+ PageList =
+ {
+ PageItem
+ {
+ Identifier = RID_TP_GEN ;
+ Text[ en-US ] = "Generic";
+ };
+ PageItem
+ {
+ Identifier = RID_TP_PRO ;
+ Text[ en-US ] = "Profile";
+ };
+ PageItem
+ {
+ Identifier = RID_TP_CRA ;
+ Text[ en-US ] = "Crashreport";
+ };
+ PageItem
+ {
+ Identifier = RID_TP_MIS ;
+ Text[ en-US ] = "Misc";
+ };
+ PageItem
+ {
+ Identifier = RID_TP_FON ;
+ Text[ en-US ] = "Font";
+ };
+ };
+ };
+};
+
+
+TabPage RID_TP_GENERIC {
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT( 244, 100 );
+ FixedLine RID_FL_AREA {
+ Pos = MAP_APPFONT( 4, 2 );
+ Size = MAP_APPFONT( 228, 8 );
+ Text[ en-US ] = "Area";
+ };
+ ComboBox RID_CB_AREA {
+ HScroll = TRUE;
+ VScroll = TRUE;
+ AutoHScroll = TRUE;
+ Border = TRUE;
+ Pos = MAP_APPFONT( 8, 12 );
+ Size = MAP_APPFONT( 132, 88 );
+ TabStop = TRUE;
+ DropDown = TRUE;
+ };
+ PushButton RID_PB_NEW_AREA {
+ Pos = MAP_APPFONT( 144, 12 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "New";
+ };
+ PushButton RID_PD_DEL_AREA {
+ Pos = MAP_APPFONT( 188, 12 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "Delete";
+ };
+ FixedLine RID_FL_VALUE {
+ Pos = MAP_APPFONT( 4, 32 );
+ Size = MAP_APPFONT( 228, 8 );
+ Text[ en-US ] = "Setting";
+ };
+ ComboBox RID_CB_VALUE {
+ HScroll = TRUE;
+ VScroll = TRUE;
+ AutoHScroll = TRUE;
+ Border = TRUE;
+ Pos = MAP_APPFONT( 8, 48 );
+ Size = MAP_APPFONT( 176, 44 );
+ TabStop = TRUE;
+ };
+ PushButton RID_PB_SELECT_FILE {
+ Pos = MAP_APPFONT( 188, 48 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "Path ...";
+ Disable = TRUE;
+ Hide = TRUE;
+ };
+ PushButton RID_PB_NEW_VALUE {
+ Pos = MAP_APPFONT( 188, 48 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "New";
+ };
+ PushButton RID_PB_DEL_VALUE {
+ Pos = MAP_APPFONT( 188, 64 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "Delete";
+ };
+};
+
+
+TabPage RID_TP_PROFILE {
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT( 244, 100 );
+ FixedLine RID_FL_PROFILE {
+ Pos = MAP_APPFONT( 4, 4 );
+ Size = MAP_APPFONT( 22, 8 );
+ Text[ en-US ] = "Profile";
+ };
+ ComboBox RID_CB_PROFILE {
+ HScroll = TRUE;
+ VScroll = TRUE;
+ AutoHScroll = TRUE;
+ Border = TRUE;
+ Pos = MAP_APPFONT( 30, 2 );
+ Size = MAP_APPFONT( 110, 88 );
+ TabStop = TRUE;
+ DropDown = TRUE;
+ };
+ PushButton RID_PB_NEW_PROFILE {
+ Pos = MAP_APPFONT( 144, 2 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "New";
+ };
+ PushButton RID_PD_DEL_PROFILE {
+ Pos = MAP_APPFONT( 188, 2 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "Delete";
+ };
+ FixedLine FL_DIRECTORIES {
+ Pos = MAP_APPFONT( 4, 16 );
+ Size = MAP_APPFONT( 230, 8 );
+ Text[ en-US ] = "Profile settings";
+ };
+ FixedText LOG_TEXT {
+ Pos = MAP_APPFONT( 7, 26 );
+ Size = MAP_APPFONT( 86, 12 );
+ Text[ en-US ] = "Log base directory";
+ };
+ FixedText BASIS_TEXT {
+ Pos = MAP_APPFONT( 7, 42 );
+ Size = MAP_APPFONT( 86, 12 );
+ Text[ en-US ] = "Base directory";
+ };
+ CheckBox HID_CHECK {
+ Pos = MAP_APPFONT( 7, 58 );
+ Size = MAP_APPFONT( 86, 12 );
+ Text[ en-US ] = "Default HID directory";
+ TabStop = TRUE;
+ Hide = FALSE;
+ };
+ Edit LOG_NAME {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 97, 26 );
+ Size = MAP_APPFONT( 116, 12 );
+ TabStop = TRUE;
+ };
+ Edit BASIS_NAME {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 97, 42 );
+ Size = MAP_APPFONT( 116, 12 );
+ TabStop = TRUE;
+ };
+ Edit HID_NAME {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 97, 58 );
+ Size = MAP_APPFONT( 116, 12 );
+ TabStop = TRUE;
+ };
+ PushButton LOG_SET {
+ Pos = MAP_APPFONT( 217, 26 );
+ Size = MAP_APPFONT( 12, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "...";
+ };
+ PushButton BASIS_SET {
+ Pos = MAP_APPFONT( 217, 42 );
+ Size = MAP_APPFONT( 12, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "...";
+ };
+ PushButton HID_SET {
+ Pos = MAP_APPFONT( 217, 58 );
+ Size = MAP_APPFONT( 12, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "...";
+ };
+ CheckBox CB_AUTORELOAD {
+ Pos = MAP_APPFONT( 7, 74 );
+ Size = MAP_APPFONT( 115, 12 );
+ Text[ en-US ] = "AutoReload";
+ };
+ CheckBox CB_AUTOSAVE {
+ Pos = MAP_APPFONT( 7, 87 );
+ Size = MAP_APPFONT( 115, 12 );
+ Text[ en-US ] = "Save before execute";
+ };
+ CheckBox CB_STOPONSYNTAXERRORS {
+ Pos = MAP_APPFONT( 132, 74 );
+ Size = MAP_APPFONT( 115, 12 );
+ Text[ en-US ] = "Stop on Syntax Errors";
+ };
+};
+
+TabPage RID_TP_CRASH {
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT( 244, 100 );
+ FixedLine FL_CRASHREPORT {
+ Pos = MAP_APPFONT( 4, 2 );
+ Size = MAP_APPFONT( 230, 8 );
+ Text[ en-US ] = "Crashreport";
+ };
+ CheckBox CB_USEPROXY {
+ Pos = MAP_APPFONT( 8, 12 );
+ Size = MAP_APPFONT( 120, 12 );
+ Text[ en-US ] = "Use Proxy";
+ };
+ FixedText FT_CRHOST {
+ Pos = MAP_APPFONT( 8+12, 12+13 );
+ Size = MAP_APPFONT( 30, 12 );
+ Text[ en-US ] = "Host";
+ };
+ Edit ED_CRHOST {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 43+12, 12+13 );
+ Size = MAP_APPFONT( 80, 12 );
+ TabStop = TRUE;
+ };
+ FixedText FT_CRPORT {
+ Pos = MAP_APPFONT( 8+12, 12+13+16 );
+ Size = MAP_APPFONT( 30, 12 );
+ Text[ en-US ] = "Port";
+ };
+ NumericField NF_CRPORT {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 43+12, 12+13+16 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Right = TRUE;
+ Repeat = TRUE;
+ Spin = TRUE;
+ Minimum = 1024;
+ Maximum = 0xffff;
+ First = 1024;
+ Last = 0xffff;
+ };
+ CheckBox CB_ALLOWCONTACT {
+ Pos = MAP_APPFONT( 8, 12+13+16+16 );
+ Size = MAP_APPFONT( 120, 12 );
+ Text[ en-US ] = "Allow Contact";
+ };
+ FixedText FT_EMAIL {
+ Pos = MAP_APPFONT( 8+12, 12+13+16+16+13 );
+ Size = MAP_APPFONT( 30, 12 );
+ Text[ en-US ] = "EMail";
+ };
+ Edit ED_EMAIL {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 43+12, 12+13+16+16+13 );
+ Size = MAP_APPFONT( 80, 12 );
+ TabStop = TRUE;
+ };
+};
+
+
+TabPage RID_TP_MISC {
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT( 244, 100 );
+ FixedLine FL_COMMUNICATION {
+ Pos = MAP_APPFONT( 4, 2 );
+ Size = MAP_APPFONT( 230, 8 );
+ Text[ en-US ] = "Communication";
+ };
+ FixedText FT_HOST {
+ Pos = MAP_APPFONT( 8, 12 );
+ Size = MAP_APPFONT( 30, 12 );
+ Text[ en-US ] = "Host";
+ };
+ Edit ED_HOST {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 43, 12);
+ Size = MAP_APPFONT( 80, 12 );
+ TabStop = TRUE;
+ };
+ FixedText FT_TTPORT {
+ Pos = MAP_APPFONT( 132, 12 );
+ Size = MAP_APPFONT( 70, 12 );
+ Text[ en-US ] = "Testtool Port";
+ };
+ NumericField NF_TTPORT {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 191, 12);
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Right = TRUE;
+ Repeat = TRUE;
+ Spin = TRUE;
+ Minimum = 1024;
+ Maximum = 0xffff;
+ First = 1024;
+ Last = 0xffff;
+ };
+ FixedText FT_UNOPORT {
+ Pos = MAP_APPFONT( 132, 12+15 );
+ Size = MAP_APPFONT( 70, 12 );
+ Text[ en-US ] = "Remote UNO Port";
+ };
+ NumericField NF_UNOPORT {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 191, 12+15);
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Right = TRUE;
+ Repeat = TRUE;
+ Spin = TRUE;
+ Minimum = 1024;
+ Maximum = 0xffff;
+ First = 1024;
+ Last = 0xffff;
+ };
+
+ FixedLine FL_OTHER {
+ Pos = MAP_APPFONT( 4, 27 +13 );
+ Size = MAP_APPFONT( 230, 8 );
+ Text[ en-US ] = "Other settings";
+ };
+ FixedText TIMEOUT_TEXT {
+ Pos = MAP_APPFONT( 8, 50 );
+ Size = MAP_APPFONT( 70, 12 );
+ Text[ en-US ] = "Server Timeout";
+ };
+ TimeField SERVER_TIMEOUT {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 83, 50 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Repeat = TRUE;
+ Spin = TRUE;
+ Format = TIMEF_SEC;
+ Duration = TRUE;
+ };
+ FixedText FT_LRU {
+ Pos = MAP_APPFONT( 132, 50 );
+ Size = MAP_APPFONT( 70, 12 );
+ Text[ en-US ] = "Max LRU Files";
+ };
+ NumericField TF_MAX_LRU {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 191, 50);
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Right = TRUE;
+ Repeat = TRUE;
+ Spin = TRUE;
+ Minimum = 0;
+ Maximum = IDM_FILE_LRUn - IDM_FILE_LRU1 +1;
+ };
+ FixedText FT_PROGDIR {
+ Pos = MAP_APPFONT( 8, 50+15 );
+ Size = MAP_APPFONT( 76, 12 );
+ Text[ en-US ] = "OOo Program Dir";
+ };
+ Edit ED_PROGDIR {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 83, 50+15 );
+ Size = MAP_APPFONT( 219-83-4, 12 );
+ TabStop = TRUE;
+ };
+ PushButton PB_PROGDIR {
+ Pos = MAP_APPFONT( 219, 50+15 );
+ Size = MAP_APPFONT( 12, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "...";
+ };
+};
+
+
+TabPage RID_TP_FONT {
+ Hide = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT( 244, 100 );
+ FixedText FT_FONTNAME {
+ Pos = MAP_APPFONT( 4, 2 );
+ Size = MAP_APPFONT( 123, 8 );
+ Text[ en-US ] = "Type";
+ };
+ ComboBox CB_FONTNAME {
+ Pos = MAP_APPFONT( 4, 12 );
+ Size = MAP_APPFONT( 123, 12*4 );
+ Sort = TRUE;
+ AutoHScroll = TRUE;
+ };
+ FixedText FT_FONTSTYLE {
+ Pos = MAP_APPFONT( 131, 2 );
+ Size = MAP_APPFONT( 65, 8 );
+ Text[ en-US ] = "Typeface";
+ };
+ ComboBox CB_FONTSTYLE {
+ Pos = MAP_APPFONT( 131, 12 );
+ Size = MAP_APPFONT( 65, 12*4 );
+ AutoHScroll = TRUE;
+ };
+ FixedText FT_FONTSIZE {
+ Pos = MAP_APPFONT( 200, 2 );
+ Size = MAP_APPFONT( 29, 8 );
+ Text[ en-US ] = "Size";
+ };
+ MetricBox MB_FONTSIZE {
+ Pos = MAP_APPFONT( 200, 12 );
+ Size = MAP_APPFONT( 29, 12*4 );
+ AutoHScroll = TRUE;
+ };
+ FixedText FT_PREVIEW {
+ Pos = MAP_APPFONT( 4, 12*5+5 );
+ Size = MAP_APPFONT( 229, 30 );
+ Center = TRUE;
+ Border = TRUE;
+ };
+ // 229 is max
+};
+
+
+FloatingWindow IDD_DISPLAY_HID {
+ OutputSize = TRUE;
+ SVLook = TRUE;
+ Size = MAP_APPFONT( 261, 160 );
+ Moveable = TRUE;
+ Closeable = TRUE;
+ Sizeable = TRUE;
+ Zoomable = TRUE;
+ Hide = TRUE;
+ ClipChildren = TRUE;
+ ToolBox RID_TB_CONF {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 0, 0 );
+ Size = MAP_APPFONT( 260, 14 );
+/* ItemList = {
+ ToolBoxItem {
+ Text = "erster der Toolbox";
+ };
+ };*/
+// Hide = TRUE;
+ };
+ FixedText RID_FT_CONTROLS {
+ Pos = MAP_APPFONT( 4, 16 );
+ Size = MAP_APPFONT( 128, 10 );
+ Text[ en-US ] = "Controls";
+ };
+ MultiListBox RID_MLB_CONTROLS {
+ Border = TRUE;
+ AutoHScroll = TRUE;
+ Pos = MAP_APPFONT( 4, 28 );
+ Size = MAP_APPFONT( 208, 88 );
+ TabStop = TRUE;
+ };
+ FixedText RID_FT_SLOTS {
+ Pos = MAP_APPFONT( 4, 120 );
+ Size = MAP_APPFONT( 128, 10 );
+ Text[ en-US ] = "Slots";
+ };
+ MultiListBox RID_MLB_SLOTS {
+ Border = TRUE;
+ AutoHScroll = TRUE;
+ Pos = MAP_APPFONT( 4, 132 );
+ Size = MAP_APPFONT( 208, 24 );
+ TabStop = TRUE;
+ };
+ PushButton RID_PB_KOPIEREN {
+ Pos = MAP_APPFONT( 216, 28 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "Copy";
+ };
+ PushButton RID_PB_BENENNEN {
+ Pos = MAP_APPFONT( 216, 44 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Hide = TRUE;
+ Text[ en-US ] = "Name";
+ };
+ PushButton RID_PB_SELECTALL {
+ Pos = MAP_APPFONT( 216, 44 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "Select all";
+ };
+ OKButton RID_OK_CLOSE {
+ Pos = MAP_APPFONT( 216, 144 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "Close";
+ };
+ Text[ en-US ] = "Display HId";
+};
+
+
+
+Accelerator MAIN_ACCEL {
+ ItemList = {
+ AcceleratorItem {
+ Identifier = RID_FILENEW;
+ Key = KeyCode { Function = KEYFUNC_NEW; };
+ };
+ AcceleratorItem {
+ Identifier = RID_FILEOPEN;
+ Key = KeyCode { Function = KEYFUNC_OPEN; };
+ };
+ AcceleratorItem {
+ Identifier = RID_FILECLOSE;
+ Key = KeyCode { Function = KEYFUNC_CLOSE; };
+ };
+ AcceleratorItem {
+ Identifier = RID_FILESAVE;
+ Key = KeyCode { Function = KEYFUNC_SAVE; };
+ };
+ AcceleratorItem {
+ Identifier = RID_FILESAVEAS;
+ Key = KeyCode { Function = KEYFUNC_SAVEAS; };
+ };
+ AcceleratorItem {
+ Identifier = RID_QUIT;
+ Key = KeyCode { Function = KEYFUNC_QUIT; };
+ };
+// AcceleratorItem {
+// Identifier = RID_EDITCUT;
+// Key = KeyCode { Function = KEYFUNC_CUT; };
+// };
+// AcceleratorItem {
+// Identifier = RID_EDITCOPY;
+// Key = KeyCode { Function = KEYFUNC_COPY; };
+// };
+// AcceleratorItem {
+// Identifier = RID_EDITPASTE;
+// Key = KeyCode { Function = KEYFUNC_PASTE; };
+// };
+// AcceleratorItem {
+// Identifier = RID_EDITDEL;
+// Key = KeyCode { Function = KEYFUNC_DELETE; };
+// };
+ AcceleratorItem {
+ Identifier = RID_EDITSEARCH;
+ Key = KeyCode { Function = KEYFUNC_FIND; };
+ };
+ AcceleratorItem {
+ Identifier = RID_EDITREPEAT;
+ Key = KeyCode { Code = KEY_F3; };
+// Key = KeyCode { Function = KEYFUNC_REPEAT; };
+ };
+ AcceleratorItem {
+ Identifier = RID_RUNSTART;
+ Key = KeyCode { Code = KEY_F5; };
+ };
+ AcceleratorItem {
+ Identifier = RID_RUNSTEPINTO;
+ Key = KeyCode { Code = KEY_F8; };
+ };
+ AcceleratorItem {
+ Identifier = RID_TOGLEBRKPNT;
+ Key = KeyCode { Code = KEY_F9; };
+ };
+ AcceleratorItem {
+ Identifier = RID_RUNSTEPOVER;
+ Key = KeyCode { Code = KEY_F10; };
+ };
+ AcceleratorItem {
+ Identifier = RID_RUNTOCURSOR;
+ Key = KeyCode { Code = KEY_F7; };
+ };
+ AcceleratorItem {
+ Identifier = RID_RUNBREAK;
+ Key = KeyCode { Code = KEY_F5; Modifier1 = TRUE; };
+ };
+ AcceleratorItem {
+ Identifier = RID_RUNSTOP;
+ Key = KeyCode { Code = KEY_F5; Shift = TRUE; };
+ };
+ AcceleratorItem {
+ Identifier = RID_RUNNEXTERR;
+ Key = KeyCode { Code = KEY_F8; Shift = TRUE; };
+ };
+ AcceleratorItem {
+ Identifier = RID_RUNPREVERR;
+ Key = KeyCode { Code = KEY_F7; Shift = TRUE; };
+ };
+ };
+};
+
+ImageList RID_IMGLST_LAYOUT
+{
+ Prefix = "im";
+ MaskColor = Color { Red = 0xFFFF ; Green = 0xFFFF ; Blue = 0xFFFF ; };
+ IdList =
+ {
+ IMGID_BRKENABLED ;
+ IMGID_BRKDISABLED ;
+ IMGID_STEPMARKER ;
+ IMGID_ERRORMARKER ;
+ };
+};
+
+ModelessDialog IDD_EDIT_VAR {
+ Pos = MAP_APPFONT( 0, 0 );
+ Size = MAP_APPFONT( 171, 87 );
+ Moveable = TRUE;
+ Closeable = TRUE;
+ FixedText RID_FT_NAME {
+ Pos = MAP_APPFONT( 8, 8 );
+ Size = MAP_APPFONT( 40, 10 );
+ Text[ en-US ] = "Name";
+ };
+ FixedText RID_FT_CONTENT {
+ Pos = MAP_APPFONT( 8, 21 );
+ Size = MAP_APPFONT( 40, 10 );
+ Text[ en-US ] = "Content";
+ };
+ FixedText RID_FT_NEW_CONTENT {
+ Pos = MAP_APPFONT( 8, 38 );
+ Size = MAP_APPFONT( 40, 10 );
+ Text[ en-US ] = "New content";
+ };
+ FixedText RID_FT_NAME_VALUE {
+ Pos = MAP_APPFONT( 53, 8 );
+ Size = MAP_APPFONT( 111, 10 );
+ Text[ en-US ] = "Name of variable";
+ };
+ FixedText RID_FT_CONTENT_VALUE {
+ Pos = MAP_APPFONT( 53, 21 );
+ Size = MAP_APPFONT( 111, 10 );
+ Text[ en-US ] = "Previous contents";
+ };
+ RadioButton RID_RB_NEW_BOOL_T {
+ Hide = TRUE;
+ Pos = MAP_APPFONT( 53, 37 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "True";
+ };
+ RadioButton RID_RB_NEW_BOOL_F {
+ Hide = TRUE;
+ Pos = MAP_APPFONT( 98, 37 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "False";
+ };
+ NumericField RID_NF_NEW_INTEGER {
+ Border = TRUE;
+ Hide = TRUE;
+ Pos = MAP_APPFONT( 53, 37 );
+ Size = MAP_APPFONT( 111, 12 );
+ TabStop = TRUE;
+ Repeat = TRUE;
+ Spin = TRUE;
+ Minimum = -32768;
+ Maximum = 32767;
+ First = -32768;
+ Last = 32767;
+ SpinSize = 10;
+ };
+ NumericField RID_NF_NEW_LONG {
+ Border = TRUE;
+ Hide = TRUE;
+ Pos = MAP_APPFONT( 53, 37 );
+ Size = MAP_APPFONT( 111, 12 );
+ TabStop = TRUE;
+ Repeat = TRUE;
+ Spin = TRUE;
+ Minimum = -2147483648;
+ Maximum = 2147483647;
+ First = -2147483648;
+ Last = 2147483647;
+ SpinSize = 10;
+ };
+ Edit RID_ED_NEW_STRING {
+ Hide = TRUE;
+ Border = TRUE;
+ Pos = MAP_APPFONT( 53, 37 );
+ Size = MAP_APPFONT( 111, 12 );
+ TabStop = TRUE;
+ Text[ en-US ] = "Edit";
+ };
+ OKButton RID_OK {
+ Pos = MAP_APPFONT( 33, 58 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ };
+ CancelButton RID_CANCEL {
+ Pos = MAP_APPFONT( 93, 58 );
+ Size = MAP_APPFONT( 40, 12 );
+ TabStop = TRUE;
+ };
+ Text[ en-US ] = "Edit variable";
+};
+
+FloatingWindow LOAD_CONF {
+ SVLook = TRUE;
+ Pos = MAP_APPFONT( 66, 23 );
+ Size = MAP_APPFONT( 156, 51 );
+ Moveable = TRUE;
+ FixedText WORK {
+ SVLook = TRUE;
+ Pos = MAP_APPFONT( 0, 8 );
+ Size = MAP_APPFONT( 155, 10 );
+ Center = TRUE;
+ Text[ en-US ] = "Slot IDs";
+ };
+ FixedText FILENAME {
+ SVLook = TRUE;
+ Pos = MAP_APPFONT( 0, 21 );
+ Size = MAP_APPFONT( 155, 10 );
+ Center = TRUE;
+ Text[ en-US ] = "File.win";
+ };
+ Text[ en-US ] = "Reading Configuration Files";
+};
+
diff --git a/basic/source/app/basicrt.cxx b/basic/source/app/basicrt.cxx
new file mode 100644
index 000000000000..e6c9f550ad5b
--- /dev/null
+++ b/basic/source/app/basicrt.cxx
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ * 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 "sbintern.hxx"
+#include "runtime.hxx"
+#include <basic/basicrt.hxx>
+
+const String BasicRuntime::GetSourceRevision()
+{
+ return pRun->GetModule()->GetComment();
+}
+
+const String BasicRuntime::GetModuleName( SbxNameType nType )
+{
+ return pRun->GetModule()->GetName( nType );
+}
+
+const String BasicRuntime::GetMethodName( SbxNameType nType )
+{
+ return pRun->GetMethod()->GetName( nType );
+}
+
+xub_StrLen BasicRuntime::GetLine()
+{
+ return pRun->nLine;
+}
+
+xub_StrLen BasicRuntime::GetCol1()
+{
+ return pRun->nCol1;
+}
+
+xub_StrLen BasicRuntime::GetCol2()
+{
+ return pRun->nCol2;
+}
+
+BOOL BasicRuntime::IsRun()
+{
+ return pRun->IsRun();
+}
+
+BasicRuntime BasicRuntime::GetNextRuntime()
+{
+ return BasicRuntime ( pRun->pNext );
+}
+
+
+
+const String BasicErrorStackEntry::GetSourceRevision()
+{
+ return pEntry->aMethod->GetModule()->GetComment();
+}
+
+const String BasicErrorStackEntry::GetModuleName( SbxNameType nType )
+{
+ return pEntry->aMethod->GetModule()->GetName( nType );
+}
+
+const String BasicErrorStackEntry::GetMethodName( SbxNameType nType )
+{
+ return pEntry->aMethod->GetName( nType );
+}
+
+xub_StrLen BasicErrorStackEntry::GetLine()
+{
+ return pEntry->nLine;
+}
+
+xub_StrLen BasicErrorStackEntry::GetCol1()
+{
+ return pEntry->nCol1;
+}
+
+xub_StrLen BasicErrorStackEntry::GetCol2()
+{
+ return pEntry->nCol2;
+}
+
+
+
+BasicRuntime BasicRuntimeAccess::GetRuntime()
+{
+ return BasicRuntime( pINST->pRun );
+}
+
+bool BasicRuntimeAccess::HasRuntime()
+{
+ return pINST && pINST->pRun != NULL;
+}
+
+USHORT BasicRuntimeAccess::GetStackEntryCount()
+{
+ return GetSbData()->pErrStack->Count();
+}
+
+BasicErrorStackEntry BasicRuntimeAccess::GetStackEntry( USHORT nIndex )
+{
+ return BasicErrorStackEntry( GetSbData()->pErrStack->GetObject( nIndex ) );
+}
+
+BOOL BasicRuntimeAccess::HasStack()
+{
+ return GetSbData()->pErrStack != NULL;
+}
+
+void BasicRuntimeAccess::DeleteStack()
+{
+ delete GetSbData()->pErrStack;
+ GetSbData()->pErrStack = NULL;
+}
+
+BOOL BasicRuntimeAccess::IsRunInit()
+{
+ return GetSbData()->bRunInit;
+}
diff --git a/basic/source/app/basmsg.hrc b/basic/source/app/basmsg.hrc
new file mode 100644
index 000000000000..5f66605dc725
--- /dev/null
+++ b/basic/source/app/basmsg.hrc
@@ -0,0 +1,45 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#include "basic/ttglobal.hrc"
+
+
+// Hier sind die Messages aus dem Verzeichnis /basic/source/app enhalten
+
+
+///////////////////////////////
+// Fehlermeldungen, die in das Resultfile gelangen.
+// *********************
+// *** !!ACHTUNG!! ***
+// *********************
+// Die Nummern dürfen sich NIE! ändern,
+// da sie in den Resultfiles gespeichert sind, und bei erneutem Anzeigen
+// statdessen die entsprechenden neuen oder garkeine Strings angzeigt werden.
+///////////////////////////////
+
+#define S_PROG_START ( BAS_START + 0 )
+#define S_ERROR_OUTSIDE_TESTCASE ( BAS_START + 1 )
+#define S_WARNING_PREFIX ( BAS_START + 2 )
diff --git a/basic/source/app/basmsg.src b/basic/source/app/basmsg.src
new file mode 100644
index 000000000000..6de25e82a170
--- /dev/null
+++ b/basic/source/app/basmsg.src
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#include "basmsg.hrc"
+
+
+// Hier sind die Messages aus dem Verzeichnis /basic/source/app enhalten
+
+
+///////////////////////////////
+// Fehlermeldungen, die in das Resultfile gelangen.
+// *********************
+// *** !!ACHTUNG!! ***
+// *********************
+// Die Nummern dürfen sich NIE! ändern,
+// da sie in den Resultfiles gespeichert sind, und bei erneutem Anzeigen
+// statdessen die entsprechenden neuen oder garkeine Strings angzeigt werden.
+///////////////////////////////
+String S_PROG_START
+{
+ Text[ en-US ] = "Program start: ($Arg1); ($Arg2)";
+};
+String S_ERROR_OUTSIDE_TESTCASE
+{
+ Text[ en-US ] = "Error outside of test case";
+};
+String S_WARNING_PREFIX
+{
+ Text[ en-US ] = "Warning: ";
+};
+
diff --git a/basic/source/app/brkpnts.cxx b/basic/source/app/brkpnts.cxx
new file mode 100644
index 000000000000..7bafc87e548a
--- /dev/null
+++ b/basic/source/app/brkpnts.cxx
@@ -0,0 +1,386 @@
+/*************************************************************************
+ *
+ * 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/list.hxx>
+#include <basic/sbx.hxx>
+#include <basic/sbmod.hxx>
+#include <basic/sbstar.hxx>
+#include <basic/sbmeth.hxx>
+#include <vcl/image.hxx>
+#include <svtools/textdata.hxx>
+#include <tools/config.hxx>
+#include <vcl/gradient.hxx>
+
+#ifndef _BASIC_TTRESHLP_HXX
+#include <basic/ttstrhlp.hxx>
+#endif
+
+#include "brkpnts.hxx"
+#include "basic.hrc"
+#include "resids.hrc"
+#include "basrid.hxx"
+
+struct Breakpoint
+{
+ USHORT nLine;
+
+ Breakpoint( USHORT nL ) { nLine = nL; }
+};
+
+
+ImageList* BreakpointWindow::pImages = NULL;
+
+
+BreakpointWindow::BreakpointWindow( Window *pParent )
+: Window( pParent )
+, nCurYOffset( 0 )
+, nMarkerPos( MARKER_NOMARKER )
+, pModule( NULL )
+, bErrorMarker( FALSE )
+{
+ if ( !pImages )
+ pImages = new ImageList( SttResId( RID_IMGLST_LAYOUT ) );
+
+ Gradient aGradient( GRADIENT_AXIAL, Color( 185, 182, 215 ), Color( 250, 245, 255 ) );
+ aGradient.SetAngle(900);
+ SetBackground( aGradient );
+ Show();
+}
+
+
+void BreakpointWindow::Reset()
+{
+ Breakpoint* pBrk = First();
+ while ( pBrk )
+ {
+ delete pBrk;
+ pBrk = Next();
+ }
+ Clear();
+
+ pModule->ClearAllBP();
+}
+
+void BreakpointWindow::SetModule( SbModule *pMod )
+{
+ pModule = pMod;
+ USHORT i;
+ for ( i=0 ; i < pModule->GetBPCount() ; i++ )
+ {
+ InsertBreakpoint( pModule->GetBP( i ) );
+ }
+ SetBPsInModule();
+}
+
+
+void BreakpointWindow::SetBPsInModule()
+{
+ pModule->ClearAllBP();
+
+ Breakpoint* pBrk = First();
+ while ( pBrk )
+ {
+ pModule->SetBP( (USHORT)pBrk->nLine );
+#if OSL_DEBUG_LEVEL > 1
+ DBG_ASSERT( !pModule->IsCompiled() || pModule->IsBP( (USHORT)pBrk->nLine ), "Brechpunkt wurde nicht gesetzt" );
+#endif
+ pBrk = Next();
+ }
+ for ( USHORT nMethod = 0; nMethod < pModule->GetMethods()->Count(); nMethod++ )
+ {
+ SbMethod* pMethod = (SbMethod*)pModule->GetMethods()->Get( nMethod );
+ DBG_ASSERT( pMethod, "Methode nicht gefunden! (NULL)" );
+ pMethod->SetDebugFlags( pMethod->GetDebugFlags() | SbDEBUG_BREAK );
+ }
+}
+
+
+void BreakpointWindow::InsertBreakpoint( USHORT nLine )
+{
+ Breakpoint* pNewBrk = new Breakpoint( nLine );
+ Breakpoint* pBrk = First();
+ while ( pBrk )
+ {
+ if ( nLine <= pBrk->nLine )
+ {
+ if ( pBrk->nLine != nLine )
+ Insert( pNewBrk );
+ else
+ delete pNewBrk;
+ pNewBrk = NULL;
+ pBrk = NULL;
+ }
+ else
+ pBrk = Next();
+ }
+ // No insert position found => LIST_APPEND
+ if ( pNewBrk )
+ Insert( pNewBrk, LIST_APPEND );
+
+ Invalidate();
+
+ if ( pModule->SetBP( nLine ) )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ DBG_ASSERT( !pModule->IsCompiled() || pModule->IsBP( nLine ), "Brechpunkt wurde nicht gesetzt" );
+#endif
+ if ( StarBASIC::IsRunning() )
+ {
+ for ( USHORT nMethod = 0; nMethod < pModule->GetMethods()->Count(); nMethod++ )
+ {
+ SbMethod* pMethod = (SbMethod*)pModule->GetMethods()->Get( nMethod );
+ DBG_ASSERT( pMethod, "Methode nicht gefunden! (NULL)" );
+ pMethod->SetDebugFlags( pMethod->GetDebugFlags() | SbDEBUG_BREAK );
+ }
+ }
+ }
+#if OSL_DEBUG_LEVEL > 1
+ DBG_ASSERT( !pModule->IsCompiled() || pModule->IsBP( nLine ), "Brechpunkt wurde nicht gesetzt" );
+#endif
+}
+
+
+Breakpoint* BreakpointWindow::FindBreakpoint( ULONG nLine )
+{
+ Breakpoint* pBrk = First();
+ while ( pBrk )
+ {
+ if ( pBrk->nLine == nLine )
+ return pBrk;
+
+ pBrk = Next();
+ }
+
+ return (Breakpoint*)0;
+}
+
+
+void BreakpointWindow::AdjustBreakpoints( ULONG nLine, BOOL bInserted )
+{
+ if ( nLine == 0 ) //TODO: nLine == TEXT_PARA_ALL+1
+ return;
+ Breakpoint* pBrk = First();
+ while ( pBrk )
+ {
+ BOOL bDelBrk = FALSE;
+ if ( pBrk->nLine == nLine )
+ {
+ if ( bInserted )
+ pBrk->nLine++;
+ else
+ bDelBrk = TRUE;
+ }
+ else if ( pBrk->nLine > nLine )
+ {
+ if ( bInserted )
+ pBrk->nLine++;
+ else
+ pBrk->nLine--;
+ }
+
+ if ( bDelBrk )
+ {
+ ULONG n = GetCurPos();
+ delete Remove( pBrk );
+ pBrk = Seek( n );
+ }
+ else
+ {
+ pBrk = Next();
+ }
+ }
+ Invalidate();
+}
+
+
+void BreakpointWindow::LoadBreakpoints( String aFilename )
+{
+ Config aConfig(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
+
+ aConfig.SetGroup("Breakpoints");
+
+ ByteString aBreakpoints;
+ aBreakpoints = aConfig.ReadKey( ByteString( aFilename, RTL_TEXTENCODING_UTF8 ) );
+
+ xub_StrLen i;
+
+ for ( i = 0 ; i < aBreakpoints.GetTokenCount( ';' ) ; i++ )
+ {
+ InsertBreakpoint( (USHORT)aBreakpoints.GetToken( i, ';' ).ToInt32() );
+ }
+}
+
+
+void BreakpointWindow::SaveBreakpoints( String aFilename )
+{
+ ByteString aBreakpoints;
+
+ Breakpoint* pBrk = First();
+ while ( pBrk )
+ {
+ if ( aBreakpoints.Len() )
+ aBreakpoints += ';';
+
+ aBreakpoints += ByteString::CreateFromInt32( pBrk->nLine );
+ pBrk = Next();
+ }
+
+ Config aConfig(Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ));
+
+ aConfig.SetGroup("Breakpoints");
+
+ if ( aBreakpoints.Len() )
+ aConfig.WriteKey( ByteString( aFilename, RTL_TEXTENCODING_UTF8 ), aBreakpoints );
+ else
+ aConfig.DeleteKey( ByteString( aFilename, RTL_TEXTENCODING_UTF8 ) );
+}
+
+
+void BreakpointWindow::Paint( const Rectangle& )
+{
+ Size aOutSz( GetOutputSize() );
+ long nLineHeight = GetTextHeight();
+
+ Image aBrk( pImages->GetImage( IMGID_BRKENABLED ) );
+ Size aBmpSz( aBrk.GetSizePixel() );
+ aBmpSz = PixelToLogic( aBmpSz );
+ Point aBmpOff( 0, 0 );
+ aBmpOff.X() = ( aOutSz.Width() - aBmpSz.Width() ) / 2;
+ aBmpOff.Y() = ( nLineHeight - aBmpSz.Height() ) / 2;
+
+ Breakpoint* pBrk = First();
+ while ( pBrk )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ DBG_ASSERT( !pModule->IsCompiled() || pModule->IsBP( pBrk->nLine ), "Brechpunkt wurde nicht gesetzt" );
+#endif
+ ULONG nLine = pBrk->nLine-1;
+ ULONG nY = nLine*nLineHeight - nCurYOffset;
+ DrawImage( Point( 0, nY ) + aBmpOff, aBrk );
+ pBrk = Next();
+ }
+ ShowMarker( TRUE );
+}
+
+
+Breakpoint* BreakpointWindow::FindBreakpoint( const Point& rMousePos )
+{
+ long nLineHeight = GetTextHeight();
+ long nYPos = rMousePos.Y() + nCurYOffset;
+
+ Breakpoint* pBrk = First();
+ while ( pBrk )
+ {
+ ULONG nLine = pBrk->nLine-1;
+ long nY = nLine*nLineHeight;
+ if ( ( nYPos > nY ) && ( nYPos < ( nY + nLineHeight ) ) )
+ return pBrk;
+ pBrk = Next();
+ }
+ return 0;
+}
+
+
+void BreakpointWindow::ToggleBreakpoint( USHORT nLine )
+{
+ Breakpoint* pBrk = FindBreakpoint( nLine );
+ if ( pBrk ) // remove
+ {
+ pModule->ClearBP( nLine );
+ delete Remove( pBrk );
+ }
+ else // create one
+ {
+ InsertBreakpoint( nLine );
+ }
+
+ Invalidate();
+}
+
+void BreakpointWindow::ShowMarker( BOOL bShow )
+{
+ if ( nMarkerPos == MARKER_NOMARKER )
+ return;
+
+ Size aOutSz( GetOutputSize() );
+ long nLineHeight = GetTextHeight();
+
+ Image aMarker;
+ if ( bErrorMarker )
+ aMarker = pImages->GetImage( IMGID_ERRORMARKER );
+ else
+ aMarker = pImages->GetImage( IMGID_STEPMARKER );
+
+ Size aMarkerSz( aMarker.GetSizePixel() );
+ aMarkerSz = PixelToLogic( aMarkerSz );
+ Point aMarkerOff( 0, 0 );
+ aMarkerOff.X() = ( aOutSz.Width() - aMarkerSz.Width() ) / 2;
+ aMarkerOff.Y() = ( nLineHeight - aMarkerSz.Height() ) / 2;
+
+ ULONG nY = nMarkerPos*nLineHeight - nCurYOffset;
+ Point aPos( 0, nY );
+ aPos += aMarkerOff;
+ if ( bShow )
+ DrawImage( aPos, aMarker );
+ else
+ Invalidate( Rectangle( aPos, aMarkerSz ) );
+}
+
+
+void BreakpointWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.GetClicks() == 2 )
+ {
+ Point aMousePos( PixelToLogic( rMEvt.GetPosPixel() ) );
+ long nLineHeight = GetTextHeight();
+ long nYPos = aMousePos.Y() + nCurYOffset;
+ long nLine = nYPos / nLineHeight + 1;
+ ToggleBreakpoint( sal::static_int_cast< USHORT >(nLine) );
+ Invalidate();
+ }
+}
+
+
+void BreakpointWindow::SetMarkerPos( USHORT nLine, BOOL bError )
+{
+ ShowMarker( FALSE ); // Remove old one
+ nMarkerPos = nLine;
+ bErrorMarker = bError;
+ ShowMarker( TRUE ); // Draw new one
+ Update();
+}
+
+
+void BreakpointWindow::Scroll( long nHorzScroll, long nVertScroll, USHORT nFlags )
+{
+ (void) nFlags; /* avoid warning about unused parameter */
+ nCurYOffset -= nVertScroll;
+ Window::Scroll( nHorzScroll, nVertScroll );
+}
+
diff --git a/basic/source/app/brkpnts.hxx b/basic/source/app/brkpnts.hxx
new file mode 100644
index 000000000000..05a03666a71b
--- /dev/null
+++ b/basic/source/app/brkpnts.hxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include <vcl/window.hxx>
+
+#define MARKER_NOMARKER 0xFFFF
+
+
+class SbModule;
+class BreakpointListe;
+struct Breakpoint;
+class ImageList;
+
+DECLARE_LIST( BreakpointList, Breakpoint* )
+
+class BreakpointWindow : public Window, public BreakpointList
+{
+using Window::Scroll;
+
+public:
+ BreakpointWindow( Window *pParent );
+// ~BreakpointWindow();
+
+ void Reset();
+
+ void SetModule( SbModule *pMod );
+ void SetBPsInModule();
+
+ void InsertBreakpoint( USHORT nLine );
+ void ToggleBreakpoint( USHORT nLine );
+ void AdjustBreakpoints( ULONG nLine, BOOL bInserted );
+
+ void LoadBreakpoints( String aFilename );
+ void SaveBreakpoints( String aFilename );
+
+protected:
+ Breakpoint* FindBreakpoint( ULONG nLine );
+
+private:
+ long nCurYOffset;
+ USHORT nMarkerPos;
+ SbModule* pModule;
+ BOOL bErrorMarker;
+ static ImageList *pImages;
+
+protected:
+ virtual void Paint( const Rectangle& );
+ Breakpoint* FindBreakpoint( const Point& rMousePos );
+ void ShowMarker( BOOL bShow );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+
+public:
+
+// void SetModulWindow( ModulWindow* pWin )
+// { pModulWindow = pWin; }
+
+ void SetMarkerPos( USHORT nLine, BOOL bErrorMarker = FALSE );
+
+ virtual void Scroll( long nHorzScroll, long nVertScroll,
+ USHORT nFlags = 0 );
+ long& GetCurYOffset() { return nCurYOffset; }
+};
+
+
+
+
+
+
+
+
diff --git a/basic/source/app/dataedit.hxx b/basic/source/app/dataedit.hxx
new file mode 100644
index 000000000000..cbb114108c56
--- /dev/null
+++ b/basic/source/app/dataedit.hxx
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef DATAEDIT_HXX
+#define DATAEDIT_HXX
+
+#include <vcl/menu.hxx>
+#include <tools/link.hxx>
+#include <tools/gen.hxx>
+#include <svtools/textdata.hxx>
+
+class String;
+class Font;
+
+// Find, Load and Save must be implemented,
+// the others must exist in MemberType
+#define DATA_FUNC_DEF( MemberName, MemberType ) \
+public: \
+ MemberType MemberName; \
+ BOOL Find( const String& rStr ); \
+ BOOL Load( const String& rStr ); \
+ BOOL Save( const String& rStr ); \
+ \
+ void GrabFocus(){ MemberName.GrabFocus(); } \
+ void Show(){ MemberName.Show(); } \
+ void SetPosPixel( const Point& rNewPos ){ MemberName.SetPosPixel(rNewPos); }\
+ void SetSizePixel( const Size& rNewSize ){ MemberName.SetSizePixel(rNewSize); } \
+ Size GetSizePixel(){ return MemberName.GetSizePixel(); } \
+ Point GetPosPixel(){ return MemberName.GetPosPixel(); } \
+ void Update(){ MemberName.Update(); } \
+ void SetFont( const Font& rNewFont ){ MemberName.SetFont(rNewFont); } \
+ \
+ void Delete(); \
+ void Cut(); \
+ void Copy(); \
+ void Paste(); \
+ void Undo(); \
+ void Redo(); \
+ String GetText() const; \
+ void SetText( const String& rStr ); \
+ BOOL HasText() const; \
+ String GetSelected(); \
+ TextSelection GetSelection() const; \
+ void SetSelection( const TextSelection& rSelection ); \
+ USHORT GetLineNr() const; \
+ void ReplaceSelected( const String& rStr ); \
+ BOOL IsModified(); \
+ void SetModifyHdl( Link l );
+
+
+class DataEdit
+{
+public:
+ virtual ~DataEdit(){}
+
+ virtual void Delete()=0;
+ virtual void Cut()=0;
+ virtual void Copy()=0;
+ virtual void Paste()=0;
+
+ virtual void Undo()=0;
+ virtual void Redo()=0;
+
+ virtual BOOL Find( const String& )=0; // Find and select text
+ virtual BOOL Load( const String& )=0; // Load text from file
+ virtual BOOL Save( const String& )=0; // Save text to file
+ virtual String GetSelected()=0;
+ virtual void GrabFocus()=0;
+ virtual TextSelection GetSelection() const=0;
+ virtual void SetSelection( const TextSelection& rSelection )=0;
+ virtual USHORT GetLineNr() const=0;
+ virtual String GetText() const=0;
+ virtual void SetText( const String& rStr )=0;
+ virtual BOOL HasText() const=0; // to avoid GetText.Len()
+ virtual void ReplaceSelected( const String& rStr )=0;
+ virtual BOOL IsModified()=0;
+ virtual void SetModifyHdl( Link )=0;
+ virtual void Show()=0;
+ virtual void SetPosPixel( const Point& rNewPos )=0;
+ virtual void SetSizePixel( const Size& rNewSize )=0;
+ virtual Size GetSizePixel()=0;
+ virtual Point GetPosPixel()=0;
+ virtual void Update()=0;
+ virtual void SetFont( const Font& rNewFont )=0;
+
+ virtual void BuildKontextMenu( PopupMenu *&pMenu )
+ {
+ (void) pMenu; /* avoid warning about unused parameter */
+ }
+};
+
+#endif
diff --git a/basic/source/app/dialogs.cxx b/basic/source/app/dialogs.cxx
new file mode 100644
index 000000000000..c5abb472a0e4
--- /dev/null
+++ b/basic/source/app/dialogs.cxx
@@ -0,0 +1,1507 @@
+/*************************************************************************
+ *
+ * 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/solar.h>
+
+#include <algorithm>
+#include <tools/rc.hxx>
+#include <vcl/metric.hxx>
+#ifndef _DIALOG_HXX //autogen
+#include <vcl/dialog.hxx>
+#endif
+#ifndef _BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+#ifndef _FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+#ifndef _EDIT_HXX //autogen
+#include <vcl/edit.hxx>
+#endif
+#include <tools/config.hxx>
+#ifndef _MSGBOX_HXX //autogen
+#include <vcl/msgbox.hxx>
+#endif
+#include <tools/debug.hxx>
+#ifndef _SV_FILEDLG_HXX //autogen
+#include <svtools/filedlg.hxx>
+#endif
+#include <tools/stream.hxx>
+#include <tools/fsys.hxx>
+#include <svtools/stringtransfer.hxx>
+#include <vcl/splitwin.hxx>
+#ifndef _ZFORLIST_HXX //autogen
+#include <svl/zformat.hxx>
+#endif
+#include <svtools/ctrltool.hxx>
+
+// Ohne Includeschutz
+#include <svtools/svtdata.hxx>
+#include <svl/solar.hrc>
+
+
+#include <basic/dispdefs.hxx>
+#include <basic/testtool.hxx>
+#include "dialogs.hxx"
+#include "resids.hrc"
+#include "basic.hrc"
+
+#include "app.hxx"
+#include "basrid.hxx"
+
+#include "_version.h"
+
+AboutDialog::AboutDialog( Window* pParent, const ResId& id )
+: ModalDialog( pParent, id )
+, a1( this, ResId( 1, *id.GetResMgr() ) )
+, a4( this, ResId( 4, *id.GetResMgr() ) )
+, aVersionString( this, ResId( RID_VERSIONSTRING, *id.GetResMgr() ) )
+, aOk ( this, ResId( RID_OK, *id.GetResMgr() ) )
+{
+ FreeResource();
+}
+
+////////////////////////////////////////////////////////////////////
+
+FindDialog::FindDialog( Window* pParent, const ResId& id, String& Text )
+: ModalDialog( pParent, id )
+, aFT1( this, ResId( RID_FIXEDTEXT1, *id.GetResMgr() ) )
+, aFind( this, ResId( RID_FIND, *id.GetResMgr() ) )
+, aOk( this, ResId( RID_OK, *id.GetResMgr() ) )
+, aCancel( this, ResId( RID_CANCEL, *id.GetResMgr() ) )
+{
+ FreeResource();
+ pFind = &Text;
+ // Button-Handler:
+ aOk.SetClickHdl( LINK( this, FindDialog, ButtonClick ) );
+ aCancel.SetClickHdl( LINK( this, FindDialog, ButtonClick ) );
+ aFind.SetText( Text );
+}
+
+IMPL_LINK_INLINE_START( FindDialog, ButtonClick, Button *, pB )
+{
+ if( pB == &aOk ) {
+ *pFind = aFind.GetText();
+ EndDialog( TRUE );
+ } else EndDialog( FALSE );
+ return TRUE;
+}
+IMPL_LINK_INLINE_END( FindDialog, ButtonClick, Button *, pB )
+
+ReplaceDialog::ReplaceDialog(Window* pParent, const ResId& id, String& Old, String& New )
+: ModalDialog( pParent, id )
+, aFT1( this, ResId( RID_FIXEDTEXT1, *id.GetResMgr() ) )
+, aFT2( this, ResId( RID_FIXEDTEXT2, *id.GetResMgr() ) )
+, aFind( this, ResId( RID_FIND, *id.GetResMgr() ) )
+, aReplace(this, ResId( RID_REPLACE, *id.GetResMgr() ) )
+, aOk( this, ResId( RID_OK, *id.GetResMgr() ) )
+, aCancel( this, ResId( RID_CANCEL, *id.GetResMgr() ) )
+{
+ FreeResource();
+ pFind = &Old;
+ pReplace = &New;
+ // Button-Handler:
+ aOk.SetClickHdl( LINK( this, ReplaceDialog, ButtonClick ) );
+ aCancel.SetClickHdl( LINK( this, ReplaceDialog, ButtonClick ) );
+ aFind.SetText( Old );
+ aReplace.SetText( New );
+}
+
+IMPL_LINK( ReplaceDialog, ButtonClick, Button *, pB )
+{
+ if( pB == &aOk ) {
+ *pFind = aFind.GetText();
+ *pReplace = aReplace.GetText();
+ EndDialog( TRUE );
+ } else EndDialog( FALSE );
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////
+
+
+void CheckButtons( ComboBox &aCB, Button &aNewB, Button &aDelB )
+{
+ aNewB.Enable( aCB.GetEntryPos( aCB.GetText() ) == COMBOBOX_ENTRY_NOTFOUND && aCB.GetText().Len() );
+ aDelB.Enable( aCB.GetEntryPos( aCB.GetText() ) != COMBOBOX_ENTRY_NOTFOUND );
+}
+
+
+void ConfEdit::Init( Config &aConf )
+{
+ aConf.SetGroup("Misc");
+ ByteString aCurrentProfile = aConf.ReadKey( "CurrentProfile", "Path" );
+ aConf.SetGroup( aCurrentProfile );
+
+ String aTemp = UniString( aConf.ReadKey( aKeyName ), RTL_TEXTENCODING_UTF8 );
+ aEdit.SetText( aTemp );
+}
+
+ConfEdit::ConfEdit( Window* pParent, USHORT nResText, USHORT nResEdit, USHORT nResButton, const ByteString& aKN, Config &aConf )
+: PushButton( pParent, SttResId(nResButton) )
+, aText( pParent, SttResId(nResText) )
+, aEdit( pParent, SttResId(nResEdit) )
+, aKeyName(aKN)
+{
+ Init( aConf );
+}
+
+ConfEdit::ConfEdit( Window* pParent, USHORT nResEdit, USHORT nResButton, const ByteString& aKN, Config &aConf )
+: PushButton( pParent, SttResId(nResButton) )
+, aText( pParent )
+, aEdit( pParent, SttResId(nResEdit) )
+, aKeyName(aKN)
+{
+ Init( aConf );
+ aText.Hide();
+}
+
+void ConfEdit::Save( Config &aConf )
+{
+ aConf.SetGroup("Misc");
+ ByteString aCurrentProfile = aConf.ReadKey( "CurrentProfile", "Path" );
+ aConf.SetGroup( aCurrentProfile );
+ aConf.WriteKey( aKeyName, ByteString( aEdit.GetText(), RTL_TEXTENCODING_UTF8 ) );
+}
+
+void ConfEdit::Reload( Config &aConf )
+{
+ aConf.SetGroup("Misc");
+ ByteString aCurrentProfile = aConf.ReadKey( "CurrentProfile", "Path" );
+ aConf.SetGroup( aCurrentProfile );
+ String aValue = String( aConf.ReadKey( aKeyName ), RTL_TEXTENCODING_UTF8 );
+ aEdit.SetText( aValue );
+}
+
+void ConfEdit::Click()
+{
+ PathDialog aPD( this );
+ aPD.SetPath( aEdit.GetText() );
+ if ( aPD.Execute() )
+ {
+ aEdit.SetText( aPD.GetPath() );
+ aEdit.Modify();
+ }
+}
+
+OptConfEdit::OptConfEdit( Window* pParent, USHORT nResCheck, USHORT nResEdit, USHORT nResButton, const ByteString& aKN, ConfEdit& rBaseEdit, Config& aConf )
+: ConfEdit( pParent, nResEdit, nResButton, aKN, aConf )
+, aCheck( pParent, SttResId( nResCheck ) )
+, rBase( rBaseEdit )
+{
+ aCheck.SetToggleHdl( LINK( this, OptConfEdit, ToggleHdl ) );
+ rBase.SetModifyHdl( LINK( this, OptConfEdit, BaseModifyHdl ) );
+}
+
+void OptConfEdit::Reload( Config &aConf )
+{
+ ConfEdit::Reload( aConf );
+
+ DirEntry aCalculatedHIDDir( rBase.GetValue() );
+ aCalculatedHIDDir += DirEntry( "global/hid", FSYS_STYLE_FAT );
+
+ DirEntry aCurrentHIDDir( aEdit.GetText() );
+
+ aCheck.Check( aCalculatedHIDDir == aCurrentHIDDir || aEdit.GetText().Len() == 0 );
+ aEdit.Enable( !aCheck.IsChecked() );
+ Enable( !aCheck.IsChecked() );
+}
+
+IMPL_LINK( OptConfEdit, ToggleHdl, CheckBox*, EMPTYARG )
+{
+ BaseModifyHdl( &aEdit );
+ aEdit.Enable( !aCheck.IsChecked() );
+ Enable( !aCheck.IsChecked() );
+ return 0;
+}
+
+IMPL_LINK( OptConfEdit, BaseModifyHdl, Edit*, EMPTYARG )
+{
+ if ( aCheck.IsChecked() )
+ {
+ DirEntry aCalculatedHIDDir( rBase.GetValue() );
+ aCalculatedHIDDir += DirEntry( "global/hid", FSYS_STYLE_FAT );
+ aEdit.SetText( aCalculatedHIDDir.GetFull() );
+ }
+ return 0;
+}
+
+
+OptionsDialog::OptionsDialog( Window* pParent, const ResId& aResId )
+: TabDialog( pParent, aResId )
+, aTabCtrl( this, ResId( RES_TC_OPTIONS, *aResId.GetResMgr() ) )
+, aOK( this )
+, aCancel( this )
+, aConfig( Config::GetConfigName( Config::GetDefDirectory(), CUniString("testtool") ) )
+{
+ aConfig.EnablePersistence( FALSE );
+ FreeResource();
+ aTabCtrl.SetActivatePageHdl( LINK( this, OptionsDialog, ActivatePageHdl ) );
+ aTabCtrl.SetCurPageId( RID_TP_PRO );
+ ActivatePageHdl( &aTabCtrl );
+
+ aOK.SetClickHdl( LINK( this, OptionsDialog, OKClick ) );
+
+ aOK.Show();
+ aCancel.Show();
+}
+
+OptionsDialog::~OptionsDialog()
+{
+ for ( USHORT i = 0; i < aTabCtrl.GetPageCount(); i++ )
+ delete aTabCtrl.GetTabPage( aTabCtrl.GetPageId( i ) );
+};
+
+BOOL OptionsDialog::Close()
+{
+ if ( TabDialog::Close() )
+ {
+ delete this;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+IMPL_LINK( OptionsDialog, ActivatePageHdl, TabControl *, pTabCtrl )
+{
+ USHORT nId = pTabCtrl->GetCurPageId();
+ // If TabPage was not yet created, do it
+ if ( !pTabCtrl->GetTabPage( nId ) )
+ {
+ TabPage *pNewTabPage = NULL;
+ switch ( nId )
+ {
+ case RID_TP_GEN:
+ pNewTabPage = new GenericOptions( pTabCtrl, aConfig );
+ break;
+ case RID_TP_PRO:
+ pNewTabPage = new ProfileOptions( pTabCtrl, aConfig );
+ break;
+ case RID_TP_CRA:
+ pNewTabPage = new CrashreportOptions( pTabCtrl, aConfig );
+ break;
+ case RID_TP_MIS:
+ pNewTabPage = new MiscOptions( pTabCtrl, aConfig );
+ break;
+ case RID_TP_FON:
+ pNewTabPage = new FontOptions( pTabCtrl, aConfig );
+ break;
+ default: DBG_ERROR( "PageHdl: Unbekannte ID!" );
+ }
+ DBG_ASSERT( pNewTabPage, "Keine Page!" );
+ pTabCtrl->SetTabPage( nId, pNewTabPage );
+ }
+ return 0;
+}
+
+
+
+
+IMPL_LINK( OptionsDialog, OKClick, Button *, pButton )
+{
+ (void) pButton; /* avoid warning about unused parameter */
+ aConfig.EnablePersistence();
+ GenericOptions *pGeneric;
+ pGeneric = (GenericOptions*)aTabCtrl.GetTabPage( RID_TP_GEN );
+ if ( pGeneric )
+ pGeneric->Save( aConfig );
+
+ ProfileOptions *pProfile;
+ pProfile = (ProfileOptions*)aTabCtrl.GetTabPage( RID_TP_PRO );
+ if ( pProfile )
+ pProfile->Save( aConfig );
+
+ CrashreportOptions *pCrash;
+ pCrash = (CrashreportOptions*)aTabCtrl.GetTabPage( RID_TP_CRA );
+ if ( pCrash )
+ pCrash->Save( aConfig );
+
+ MiscOptions *pMisc;
+ pMisc = (MiscOptions*)aTabCtrl.GetTabPage( RID_TP_MIS );
+ if ( pMisc )
+ pMisc->Save( aConfig );
+
+ FontOptions *pFonts;
+ pFonts = (FontOptions*)aTabCtrl.GetTabPage( RID_TP_FON );
+ if ( pFonts )
+ pFonts->Save( aConfig );
+
+ aConfig.Flush();
+
+ ((BasicApp*)GetpApp())->LoadIniFile();
+ Close();
+ return 0;
+}
+
+const ByteString ProfilePrefix("_profile_");
+const USHORT ProfilePrefixLen = ProfilePrefix.Len();
+
+ProfileOptions::ProfileOptions( Window* pParent, Config &rConfig )
+: TabPage( pParent, SttResId( RID_TP_PROFILE ) )
+, rConf( rConfig )
+
+, aFlProfile( this, SttResId( RID_FL_PROFILE ) )
+, aCbProfile( this, SttResId( RID_CB_PROFILE ) )
+, aPbNewProfile( this, SttResId( RID_PB_NEW_PROFILE ) )
+, aPbDelProfile( this, SttResId( RID_PD_DEL_PROFILE ) )
+
+, aDirs( this, SttResId(FL_DIRECTORIES) )
+, aLog( this, LOG_TEXT, LOG_NAME, LOG_SET, "LogBaseDir", rConfig )
+, aBasis( this, BASIS_TEXT, BASIS_NAME, BASIS_SET, "BaseDir", rConfig )
+, aHID( this, HID_CHECK, HID_NAME, HID_SET, "HIDDir", aBasis, rConfig )
+
+, aAutoReload( this, SttResId(CB_AUTORELOAD) )
+, aAutoSave( this, SttResId(CB_AUTOSAVE) )
+, aStopOnSyntaxError( this, SttResId(CB_STOPONSYNTAXERRORS) )
+{
+ FreeResource();
+
+ aCbProfile.EnableAutocomplete( TRUE );
+
+ aCbProfile.SetSelectHdl( LINK( this, ProfileOptions, Select ) );
+
+ aPbNewProfile.SetClickHdl( LINK( this, ProfileOptions, NewProfile ) );
+ aPbDelProfile.SetClickHdl( LINK( this, ProfileOptions, DelProfile ) );
+ aCbProfile.SetModifyHdl( LINK( this, ProfileOptions, CheckButtonsHdl ) );
+
+ LoadData();
+ ReloadProfile();
+}
+
+void ProfileOptions::LoadData()
+{
+ // collect all profiles (all groups starting with the ProfilePrefix)
+ for ( USHORT i = 0 ; i < rConf.GetGroupCount() ; i++ )
+ {
+ ByteString aProfile = rConf.GetGroupName( i );
+ if ( aProfile.Match( ProfilePrefix ) )
+ aCbProfile.InsertEntry( String( aProfile.Copy( ProfilePrefixLen ), RTL_TEXTENCODING_UTF8 ) );
+ }
+ // set the current profile
+ rConf.SetGroup( "Misc" );
+ ByteString aCurrentProfile = rConf.ReadKey( "CurrentProfile", "Path" );
+ aCbProfile.SetText( String( aCurrentProfile.Copy( ProfilePrefixLen ), RTL_TEXTENCODING_UTF8 ) );
+ CheckButtons( aCbProfile, aPbNewProfile, aPbDelProfile );
+}
+
+IMPL_LINK( ProfileOptions, Select, ComboBox*, EMPTYARG )
+{
+ if ( aCbProfile.GetEntryPos( aCbProfile.GetText() ) == LISTBOX_ENTRY_NOTFOUND )
+ return 1;
+ Save();
+ ByteString aProfileKey( ByteString( ProfilePrefix ).Append( ByteString( aCbProfile.GetText(), RTL_TEXTENCODING_UTF8 ) ) );
+ rConf.SetGroup( "Misc" );
+ rConf.WriteKey( "CurrentProfile", aProfileKey );
+ ReloadProfile();
+
+ return 0;
+}
+
+void ProfileOptions::ReloadProfile()
+{
+ aLog.Reload( rConf );
+ aBasis.Reload( rConf );
+ aHID.Reload( rConf );
+
+ ByteString aTemp;
+ rConf.SetGroup( "Misc" );
+ ByteString aCurrentProfile = rConf.ReadKey( "CurrentProfile", "Misc" );
+ rConf.SetGroup( aCurrentProfile );
+ aTemp = rConf.ReadKey( "AutoReload", "0" );
+ aAutoReload.Check( aTemp.Equals("1") );
+ aTemp = rConf.ReadKey( "AutoSave", "0" );
+ aAutoSave.Check( aTemp.Equals("1") );
+ aTemp = rConf.ReadKey( "StopOnSyntaxError", "0" );
+ aStopOnSyntaxError.Check( aTemp.Equals("1") );
+
+ CheckButtons( aCbProfile, aPbNewProfile, aPbDelProfile );
+}
+
+IMPL_LINK( ProfileOptions, DelProfile, Button*, EMPTYARG )
+{
+ String aProfile = aCbProfile.GetText();
+ ByteString aProfileKey( ByteString( ProfilePrefix ).Append( ByteString( aProfile, RTL_TEXTENCODING_UTF8 ) ) );
+ if ( aCbProfile.GetEntryPos( aProfile ) != COMBOBOX_ENTRY_NOTFOUND )
+ {
+ aCbProfile.RemoveEntry( aProfile );
+ rConf.DeleteGroup( aProfileKey );
+ }
+ // Set first remaining profile as current profile
+ aCbProfile.SetText( aCbProfile.GetEntry( 0 ) );
+ aProfile = aCbProfile.GetText();
+ aProfileKey = ByteString( ProfilePrefix ).Append( ByteString( aProfile, RTL_TEXTENCODING_UTF8 ) );
+ rConf.SetGroup( "Misc" );
+ rConf.WriteKey( "CurrentProfile", aProfileKey );
+ ReloadProfile();
+ CheckButtons( aCbProfile, aPbNewProfile, aPbDelProfile );
+
+ return 0;
+}
+
+IMPL_LINK( ProfileOptions, NewProfile, Button*, EMPTYARG )
+{
+ aCbProfile.InsertEntry( aCbProfile.GetText() );
+ ByteString aProfileKey( ByteString( ProfilePrefix ).Append( ByteString( aCbProfile.GetText(), RTL_TEXTENCODING_UTF8 ) ) );
+ rConf.SetGroup( "Misc" );
+ rConf.WriteKey( "CurrentProfile", aProfileKey );
+ // save last profile as new data for new profile
+ Save();
+ CheckButtons( aCbProfile, aPbNewProfile, aPbDelProfile );
+
+ return 0;
+}
+
+IMPL_LINK( ProfileOptions, CheckButtonsHdl, ComboBox*, pCB )
+{
+ (void) pCB; /* avoid warning about unused parameter */
+ CheckButtons( aCbProfile, aPbNewProfile, aPbDelProfile );
+ return 0;
+}
+
+void ProfileOptions::Save()
+{
+ Save(rConf);
+}
+
+void ProfileOptions::Save( Config &rConfig )
+{
+ // save data to current profile
+ aLog.Save( rConfig );
+ aBasis.Save( rConfig );
+ aHID.Save( rConfig );
+
+ rConfig.SetGroup( "Misc" );
+ ByteString aCurrentProfile = rConfig.ReadKey( "CurrentProfile", "Misc" );
+ rConfig.SetGroup( aCurrentProfile );
+ rConfig.WriteKey( "AutoReload", aAutoReload.IsChecked()?"1":"0" );
+ rConfig.WriteKey( "AutoSave", aAutoSave.IsChecked()?"1":"0" );
+ rConfig.WriteKey( "StopOnSyntaxError", aStopOnSyntaxError.IsChecked()?"1":"0" );
+}
+
+CrashreportOptions::CrashreportOptions( Window* pParent, Config &aConfig )
+: TabPage( pParent, SttResId( RID_TP_CRASH ) )
+, aFLCrashreport( this, SttResId( FL_CRASHREPORT ) )
+, aCBUseProxy( this, SttResId( CB_USEPROXY ) )
+, aFTCRHost( this, SttResId( FT_CRHOST ) )
+, aEDCRHost( this, SttResId( ED_CRHOST ) )
+, aFTCRPort( this, SttResId( FT_CRPORT ) )
+, aNFCRPort( this, SttResId( NF_CRPORT ) )
+, aCBAllowContact( this, SttResId( CB_ALLOWCONTACT ) )
+, aFTEMail( this, SttResId( FT_EMAIL ) )
+, aEDEMail( this, SttResId( ED_EMAIL ) )
+{
+ FreeResource();
+
+ aNFCRPort.SetUseThousandSep( FALSE );
+
+ ByteString aTemp;
+
+ aConfig.SetGroup("Crashreporter");
+
+ aTemp = aConfig.ReadKey( "UseProxy", "false" );
+ if ( aTemp.EqualsIgnoreCaseAscii( "true" ) || aTemp.Equals( "1" ) )
+ aCBUseProxy.Check();
+ else
+ aCBUseProxy.Check( FALSE );
+
+ aCBUseProxy.SetToggleHdl( LINK( this, CrashreportOptions, CheckProxy ) );
+ LINK( this, CrashreportOptions, CheckProxy ).Call( NULL ); // call once to initialize
+
+ aTemp = aConfig.ReadKey( "ProxyServer" );
+ aEDCRHost.SetText( String( aTemp, RTL_TEXTENCODING_UTF8 ) );
+ aTemp = aConfig.ReadKey( "ProxyPort", "8080" );
+ aNFCRPort.SetValue( aTemp.ToInt32() );
+
+
+ aTemp = aConfig.ReadKey( "AllowContact", "false" );
+ if ( aTemp.EqualsIgnoreCaseAscii( "true" ) || aTemp.Equals( "1" ) )
+ aCBAllowContact.Check();
+ else
+ aCBAllowContact.Check( FALSE );
+
+ aCBAllowContact.SetToggleHdl( LINK( this, CrashreportOptions, CheckResponse ) );
+ LINK( this, CrashreportOptions, CheckResponse ).Call( NULL ); // call once to initialize
+
+ aTemp = aConfig.ReadKey( "ReturnAddress" );
+ aEDEMail.SetText( String( aTemp, RTL_TEXTENCODING_UTF8 ) );
+}
+
+
+void CrashreportOptions::Save( Config &aConfig )
+{
+ aConfig.SetGroup("Crashreporter");
+
+ if ( aCBUseProxy.IsChecked() )
+ aConfig.WriteKey( "UseProxy", "true" );
+ else
+ aConfig.WriteKey( "UseProxy", "false" );
+
+ aConfig.WriteKey( "ProxyServer", ByteString( aEDCRHost.GetText(), RTL_TEXTENCODING_UTF8 ) );
+ aConfig.WriteKey( "ProxyPort", ByteString::CreateFromInt64( aNFCRPort.GetValue() ) );
+
+ if ( aCBAllowContact.IsChecked() )
+ aConfig.WriteKey( "AllowContact", "true" );
+ else
+ aConfig.WriteKey( "AllowContact", "false" );
+
+ aConfig.WriteKey( "ReturnAddress", ByteString( aEDEMail.GetText(), RTL_TEXTENCODING_UTF8 ) );
+}
+
+IMPL_LINK( CrashreportOptions, CheckProxy, void*, EMPTYARG )
+{
+ aFTCRHost.Enable( aCBUseProxy.IsChecked() );
+ aEDCRHost.Enable( aCBUseProxy.IsChecked() );
+ aFTCRPort.Enable( aCBUseProxy.IsChecked() );
+ aNFCRPort.Enable( aCBUseProxy.IsChecked() );
+
+ return 0;
+}
+IMPL_LINK( CrashreportOptions, CheckResponse, void*, EMPTYARG )
+{
+ aFTEMail.Enable( aCBAllowContact.IsChecked() );
+ aEDEMail.Enable( aCBAllowContact.IsChecked() );
+ return 0;
+}
+
+MiscOptions::MiscOptions( Window* pParent, Config &aConfig )
+: TabPage( pParent, SttResId( RID_TP_MISC ) )
+, aFLCommunication( this, SttResId(FL_COMMUNICATION) )
+, aFTHost( this, SttResId(FT_HOST) )
+, aEDHost( this, SttResId(ED_HOST) )
+, aFTTTPort( this, SttResId(FT_TTPORT) )
+, aNFTTPort( this, SttResId(NF_TTPORT) )
+, aFTUNOPort( this, SttResId(FT_UNOPORT) )
+, aNFUNOPort( this, SttResId(NF_UNOPORT) )
+, aOther( this, SttResId(FL_OTHER) )
+, aTimeoutText( this, SttResId(TIMEOUT_TEXT) )
+, aServerTimeout( this, SttResId(SERVER_TIMEOUT) )
+, aFTLRU( this, SttResId(FT_LRU) )
+, aTFMaxLRU( this, SttResId(TF_MAX_LRU) )
+, aFTProgDir( this, SttResId(FT_PROGDIR) )
+, aEDProgDir( this, SttResId(ED_PROGDIR) )
+, aPBProgDir( this, SttResId(PB_PROGDIR) )
+{
+ FreeResource();
+
+ aNFTTPort.SetUseThousandSep( FALSE );
+ aNFUNOPort.SetUseThousandSep( FALSE );
+ aTFMaxLRU.SetUseThousandSep( FALSE );
+
+ ByteString aTemp;
+
+ aConfig.SetGroup("Communication");
+ aTemp = aConfig.ReadKey( "Host", DEFAULT_HOST );
+ aEDHost.SetText( String( aTemp, RTL_TEXTENCODING_UTF8 ) );
+ aTemp = aConfig.ReadKey( "TTPort", ByteString::CreateFromInt32( TESTTOOL_DEFAULT_PORT ) );
+ aNFTTPort.SetValue( aTemp.ToInt32() );
+ aTemp = aConfig.ReadKey( "UnoPort", ByteString::CreateFromInt32( UNO_DEFAULT_PORT ) );
+ aNFUNOPort.SetValue( aTemp.ToInt32() );
+
+ aConfig.SetGroup("Misc");
+ aTemp = aConfig.ReadKey( "ServerTimeout", "10000" ); // Default 1 Minute
+ aServerTimeout.SetTime( Time(aTemp.ToInt32()) );
+
+ aConfig.SetGroup("LRU");
+ aTemp = aConfig.ReadKey( "MaxLRU", "4" );
+ aTFMaxLRU.SetValue( aTemp.ToInt32() );
+
+ aConfig.SetGroup("OOoProgramDir");
+ aTemp = aConfig.ReadKey( "Current" );
+ aEDProgDir.SetText( String( aTemp, RTL_TEXTENCODING_UTF8 ) );
+ aPBProgDir.SetClickHdl( LINK( this, MiscOptions, Click ) );
+}
+
+IMPL_LINK( MiscOptions, Click, void*, EMPTYARG )
+{
+ PathDialog aPD( this );
+ aPD.SetPath( aEDProgDir.GetText() );
+ if ( aPD.Execute() )
+ aEDProgDir.SetText( aPD.GetPath() );
+ return 0;
+}
+
+
+void MiscOptions::Save( Config &aConfig )
+{
+ aConfig.SetGroup("Communication");
+ aConfig.WriteKey( "Host", ByteString( aEDHost.GetText(), RTL_TEXTENCODING_UTF8 ) );
+ aConfig.WriteKey( "TTPort", ByteString::CreateFromInt64( aNFTTPort.GetValue() ) );
+ aConfig.WriteKey( "UnoPort", ByteString::CreateFromInt64( aNFUNOPort.GetValue() ) );
+
+ aConfig.SetGroup("Misc");
+ aConfig.WriteKey( "ServerTimeout", ByteString::CreateFromInt32( aServerTimeout.GetTime().GetTime() ) );
+
+ aConfig.SetGroup("LRU");
+ ByteString aTemp = aConfig.ReadKey( "MaxLRU", "4" );
+ USHORT nOldMaxLRU = (USHORT)aTemp.ToInt32();
+ USHORT n;
+ for ( n = nOldMaxLRU ; n > aTFMaxLRU.GetValue() ; n-- )
+ aConfig.DeleteKey( ByteString("LRU").Append( ByteString::CreateFromInt32( n ) ) );
+ aConfig.WriteKey( "MaxLRU", ByteString::CreateFromInt64( aTFMaxLRU.GetValue() ) );
+
+ aConfig.SetGroup("OOoProgramDir");
+ aConfig.WriteKey( C_KEY_AKTUELL, ByteString( aEDProgDir.GetText(), RTL_TEXTENCODING_UTF8 ) );
+ aConfig.WriteKey( C_KEY_TYPE, ByteString( "PATH" ) );
+}
+
+
+FontOptions::FontOptions( Window* pParent, Config &aConfig )
+: TabPage( pParent, SttResId( RID_TP_FONT ) )
+, aFTFontName( this, SttResId(FT_FONTNAME) )
+, aFontName( this, SttResId(CB_FONTNAME) )
+, aFTStyle( this, SttResId(FT_FONTSTYLE) )
+, aFontStyle( this, SttResId(CB_FONTSTYLE) )
+, aFTSize( this, SttResId(FT_FONTSIZE) )
+, aFontSize( this, SttResId(MB_FONTSIZE) )
+, aFTPreview( this, SttResId(FT_PREVIEW) )
+, aFontList( this )
+{
+ FreeResource();
+
+ aFontName.Fill( &aFontList );
+ aFontName.EnableWYSIWYG();
+ aFontName.EnableSymbols();
+
+// aFontSize.SetUnit( FUNIT_POINT );
+// MapMode aMode( MAP_POINT );
+// aFTPreview.SetMapMode( aMode );
+
+ aFontName.SetModifyHdl( LINK( this, FontOptions, FontNameChanged ) );
+ aFontStyle.SetModifyHdl( LINK( this, FontOptions, FontStyleChanged ) );
+ aFontSize.SetModifyHdl( LINK( this, FontOptions, FontSizeChanged ) );
+
+ ByteString aTemp;
+ aConfig.SetGroup("Misc");
+ aTemp = aConfig.ReadKey( "ScriptFontName", "Courier" );
+ aFontName.SetText( String( aTemp, RTL_TEXTENCODING_UTF8 ) );
+ aFontName.Modify();
+ aTemp = aConfig.ReadKey( "ScriptFontStyle", "normal" );
+ aFontStyle.SetText( String( aTemp, RTL_TEXTENCODING_UTF8 ) );
+ aFontStyle.Modify();
+ aTemp = aConfig.ReadKey( "ScriptFontSize", "12" );
+ aFontSize.SetText( String( aTemp, RTL_TEXTENCODING_UTF8 ) );
+ aFontSize.Modify();
+}
+
+IMPL_LINK( FontOptions, FontNameChanged, void*, EMPTYARG )
+{
+ aFontStyle.Fill( aFontName.GetText(), &aFontList );
+ FontStyleChanged( NULL );
+ return 0;
+}
+
+IMPL_LINK( FontOptions, FontStyleChanged, void*, EMPTYARG )
+{
+ FontInfo aFontInfo( aFontList.Get( aFontName.GetText(), aFontStyle.GetText() ) );
+ aFontSize.Fill( &aFontInfo, &aFontList );
+ FontSizeChanged( NULL );
+ return 0;
+}
+
+IMPL_LINK( FontOptions, FontSizeChanged, void*, EMPTYARG )
+{
+ UpdatePreview();
+ return 0;
+}
+
+void FontOptions::UpdatePreview()
+{
+ Font aFont = aFontList.Get( aFontName.GetText(), aFontStyle.GetText() );
+// ULONG nFontSize = aFontSize.GetValue( FUNIT_POINT );
+ ULONG nFontSize = static_cast<ULONG>((aFontSize.GetValue() + 5) / 10);
+ aFont.SetHeight( nFontSize );
+ aFTPreview.SetFont( aFont );
+ aFTPreview.SetText( aFontName.GetText() );
+ aFTPreview.Invalidate();
+}
+
+
+void FontOptions::Save( Config &aConfig )
+{
+ aConfig.SetGroup("Misc");
+ aConfig.WriteKey( "ScriptFontName", aFontName.GetText(), RTL_TEXTENCODING_UTF8 );
+ aConfig.WriteKey( "ScriptFontStyle", aFontStyle.GetText(), RTL_TEXTENCODING_UTF8 );
+ aConfig.WriteKey( "ScriptFontSize", aFontSize.GetText(), RTL_TEXTENCODING_UTF8 );
+}
+
+
+GenericOptions::GenericOptions( Window* pParent, Config &aConfig )
+: TabPage( pParent, SttResId( RID_TP_GENERIC ) )
+, aConf( aConfig )
+
+, aFlArea( this, SttResId( RID_FL_AREA ) )
+, aCbArea( this, SttResId( RID_CB_AREA ) )
+, aPbNewArea( this, SttResId( RID_PB_NEW_AREA ) )
+, aPbDelArea( this, SttResId( RID_PD_DEL_AREA ) )
+
+, aFlValue( this, SttResId( RID_FL_VALUE ) )
+, aCbValue( this, SttResId( RID_CB_VALUE ) )
+
+, aPbSelectPath( this, SttResId( RID_PB_SELECT_FILE ) )
+, aPbNewValue( this, SttResId( RID_PB_NEW_VALUE ) )
+, aPbDelValue( this, SttResId( RID_PB_DEL_VALUE ) )
+
+, nMoveButtons( 0 )
+, bShowSelectPath( FALSE )
+{
+ FreeResource();
+ LoadData();
+
+ aCbArea.EnableAutocomplete( TRUE );
+ aCbValue.EnableAutocomplete( TRUE );
+
+ aCbArea.SetSelectHdl( LINK( this, GenericOptions, LoadGroup ) );
+
+ aPbNewArea.SetClickHdl( LINK( this, GenericOptions, NewGroup ) );
+ aPbDelArea.SetClickHdl( LINK( this, GenericOptions, DelGroup ) );
+
+ aPbSelectPath.SetClickHdl( LINK( this, GenericOptions, SelectPath ) );
+ aPbNewValue.SetClickHdl( LINK( this, GenericOptions, NewValue ) );
+ aPbDelValue.SetClickHdl( LINK( this, GenericOptions, DelValue ) );
+
+ aCbArea.SetModifyHdl( LINK( this, GenericOptions, CheckButtonsHdl ) );
+ aCbValue.SetModifyHdl( LINK( this, GenericOptions, CheckButtonsHdl ) );
+ aCbValue.SetSelectHdl( LINK( this, GenericOptions, CheckButtonsHdl ) );
+
+ aMoveTimer.SetTimeout( 60 );
+ aMoveTimer.SetTimeoutHdl( LINK( this, GenericOptions, MoveButtons ) );
+}
+
+GenericOptions::~GenericOptions()
+{
+}
+
+StringList* GenericOptions::GetAllGroups()
+{
+ StringList* pGroups = new StringList();
+ for ( USHORT i = 0 ; i < aConf.GetGroupCount() ; i++ )
+ {
+ String *pGroup = new String( aConf.GetGroupName( i ), RTL_TEXTENCODING_UTF8 );
+ pGroups->Insert( pGroup );
+ }
+ return pGroups;
+}
+
+void GenericOptions::LoadData()
+{
+ StringList* pGroups = GetAllGroups();
+ String* pGroup;
+ while ( (pGroup = pGroups->First()) != NULL )
+ {
+ pGroups->Remove( pGroup );
+ aConf.SetGroup( ByteString( *pGroup, RTL_TEXTENCODING_UTF8 ) );
+ if ( aConf.ReadKey( C_KEY_AKTUELL ).Len() > 0 )
+ {
+ aCbArea.InsertEntry( *pGroup );
+ }
+ delete pGroup;
+ }
+ delete pGroups;
+ aCbArea.SetText( aCbArea.GetEntry( 0 ) );
+ CheckButtons( aCbArea, aPbNewArea, aPbDelArea );
+
+ // Add load the data
+ LINK( this, GenericOptions, LoadGroup ).Call( NULL );
+}
+
+void GenericOptions::ShowSelectPath( const String aType )
+{
+ Point aNPos = aPbNewValue.GetPosPixel();
+ Point aDPos = aPbDelValue.GetPosPixel();
+ long nDelta = aDPos.Y() - aNPos.Y();
+ if ( aType.EqualsIgnoreCaseAscii( "PATH" ) && !bShowSelectPath )
+ { // Show Path button
+ nMoveButtons += nDelta;
+ aMoveTimer.Start();
+ bShowSelectPath = TRUE;
+ aPbSelectPath.Show( TRUE );
+ aPbSelectPath.Enable( TRUE );
+ }
+ else if ( !aType.EqualsIgnoreCaseAscii( "PATH" ) && bShowSelectPath )
+ { // Hide Path button
+ nMoveButtons -= nDelta;
+ aMoveTimer.Start();
+ bShowSelectPath = FALSE;
+ aPbSelectPath.Enable( FALSE );
+ }
+}
+
+IMPL_LINK( GenericOptions, MoveButtons, AutoTimer*, aTimer )
+{
+ if ( nMoveButtons == 0 )
+ {
+ aTimer->Stop();
+ aPbSelectPath.Show( bShowSelectPath );
+ return 0;
+ }
+
+ int nStep = (nMoveButtons > 0) ? 2 : -2;
+ if ( nMoveButtons <= 1 && nMoveButtons >= -1 )
+ nStep = nMoveButtons;
+
+ nMoveButtons -= nStep ;
+
+ Point aPos;
+
+ aPos = aPbNewValue.GetPosPixel();
+ aPos.Y() += nStep;
+ aPbNewValue.SetPosPixel( aPos );
+
+ aPos = aPbDelValue.GetPosPixel();
+ aPos.Y() += nStep;
+ aPbDelValue.SetPosPixel( aPos );
+ return 0;
+}
+
+String GenericOptions::ReadKey( const ByteString &aGroup, const ByteString &aKey )
+{
+ aConf.SetGroup( aGroup );
+ return UniString( aConf.ReadKey( aKey ), RTL_TEXTENCODING_UTF8 );
+}
+
+IMPL_LINK( GenericOptions, LoadGroup, ComboBox*, EMPTYARG )
+{
+ String aCurrentValue;
+ String aAllValues;
+ String aType;
+
+ if ( aLastGroupName.Len() )
+ { // Cache values?
+ aCurrentValue = aCbValue.GetText();
+ if ( aCbValue.GetEntryPos( aCurrentValue ) == COMBOBOX_ENTRY_NOTFOUND )
+ { // Create a new value
+ LINK( this, GenericOptions, NewValue ).Call( NULL );
+ }
+
+ aConf.SetGroup( aLastGroupName );
+ aConf.WriteKey( C_KEY_AKTUELL, ByteString( aCurrentValue, RTL_TEXTENCODING_UTF8 ) );
+ USHORT i;
+ for ( i=0 ; i < aCbValue.GetEntryCount() ; i++ )
+ {
+ if ( i > 0 )
+ aAllValues += ';';
+ aAllValues += aCbValue.GetEntry( i );
+ }
+ aConf.WriteKey( C_KEY_ALLE, ByteString( aAllValues, RTL_TEXTENCODING_UTF8 ) );
+ }
+
+ aCbValue.Clear();
+
+ ByteString aGroupName = ByteString( aCbArea.GetText(), RTL_TEXTENCODING_UTF8 );
+ aCurrentValue = ReadKey( aGroupName, C_KEY_AKTUELL );
+ aAllValues = ReadKey( aGroupName, C_KEY_ALLE );
+ aType = ReadKey( aGroupName, C_KEY_TYPE );
+
+ xub_StrLen i;
+ for ( i=0 ; i < aAllValues.GetTokenCount() ; i++ )
+ {
+ aCbValue.InsertEntry( aAllValues.GetToken( i ) );
+ }
+ aCbValue.SetText( aCurrentValue );
+
+ aLastGroupName = aGroupName;
+ CheckButtons( aCbArea, aPbNewArea, aPbDelArea );
+ CheckButtons( aCbValue, aPbNewValue, aPbDelValue );
+ ShowSelectPath( aType );
+ return 0;
+}
+
+IMPL_LINK( GenericOptions, DelGroup, Button*, EMPTYARG )
+{
+ String aGroup = aCbArea.GetText();
+ if ( aCbArea.GetEntryPos( aGroup ) != COMBOBOX_ENTRY_NOTFOUND )
+ {
+ aCbArea.RemoveEntry( aGroup );
+ ByteString aByteGroup( aGroup, RTL_TEXTENCODING_UTF8 );
+ aConf.DeleteGroup( aByteGroup );
+ }
+
+ aCbArea.SetText( aCbArea.GetEntry( 0 ) );
+ LINK( this, GenericOptions, LoadGroup ).Call( NULL );
+
+ return 0;
+}
+
+IMPL_LINK( GenericOptions, NewGroup, Button*, EMPTYARG )
+{
+ aCbArea.InsertEntry( aCbArea.GetText() );
+
+ LINK( this, GenericOptions, LoadGroup ).Call( NULL );
+
+ return 0;
+}
+
+IMPL_LINK( GenericOptions, SelectPath, Button*, EMPTYARG )
+{
+ PathDialog aPD( this );
+ aPD.SetPath( aCbValue.GetText() );
+ if ( aPD.Execute() )
+ {
+ aCbValue.SetText( aPD.GetPath() );
+ CheckButtons( aCbValue, aPbNewValue, aPbDelValue );
+ if ( aPbNewValue.IsEnabled() )
+ {
+ LINK( this, GenericOptions, NewValue ).Call( NULL );
+ }
+ }
+ return 1;
+}
+
+IMPL_LINK( GenericOptions, DelValue, Button*, EMPTYARG )
+{
+ String aValue = aCbValue.GetText();
+ if ( aCbValue.GetEntryPos( aValue ) != COMBOBOX_ENTRY_NOTFOUND )
+ {
+ aCbValue.RemoveEntry( aValue );
+ }
+
+ aCbValue.SetText( aCbValue.GetEntry( 0 ) );
+ CheckButtons( aCbValue, aPbNewValue, aPbDelValue );
+ return 0;
+}
+
+IMPL_LINK( GenericOptions, NewValue, Button*, EMPTYARG )
+{
+ aCbValue.InsertEntry( aCbValue.GetText() );
+ CheckButtons( aCbValue, aPbNewValue, aPbDelValue );
+ return 0;
+}
+
+IMPL_LINK( GenericOptions, CheckButtonsHdl, ComboBox*, pCB )
+{
+ if ( pCB == &aCbArea )
+ CheckButtons( aCbArea, aPbNewArea, aPbDelArea );
+ if ( pCB == &aCbValue )
+ CheckButtons( aCbValue, aPbNewValue, aPbDelValue );
+ return 0;
+}
+
+void GenericOptions::Save( Config &aConfig )
+{
+ (void) aConfig; /* avoid warning about unused parameter */
+ DBG_ASSERT( &aConfig == &aConf, "Saving to different Configuration" );
+
+ // Save changes
+ LINK( this, GenericOptions, LoadGroup ).Call( NULL );
+}
+
+
+class TextAndWin : public DockingWindow
+{
+ FixedText *pFt;
+ Window *pWin;
+ Window* pFtOriginalParent;
+ Window* pWinOriginalParent;
+ long nSpace; // default space
+ BOOL bAlignTop;
+
+public:
+ TextAndWin( Window *pParent, FixedText *pFtP, Window *pWinP, long nSpaceP, BOOL bAlignTopP );
+ ~TextAndWin();
+
+ virtual void Resize();
+};
+
+TextAndWin::TextAndWin( Window *pParent, FixedText *pFtP, Window *pWinP, long nSpaceP, BOOL bAlignTopP )
+: DockingWindow( pParent )
+, pFt( pFtP )
+, pWin( pWinP )
+, nSpace( nSpaceP )
+, bAlignTop( bAlignTopP )
+{
+ pFtOriginalParent = pFt->GetParent();
+ pWinOriginalParent = pWin->GetParent();
+ pFt->SetParent( this );
+ pWin->SetParent( this );
+}
+
+TextAndWin::~TextAndWin()
+{
+ pFt->SetParent( pFtOriginalParent );
+ pWin->SetParent( pWinOriginalParent );
+}
+
+void TextAndWin::Resize()
+{
+ long nTopSpace = bAlignTop ? 0 : nSpace;
+ long nBottomSpace = bAlignTop ? nSpace : 0;
+
+ long nFixedTextOffset;
+ if ( GetOutputSizePixel().Height() < 3 * pFt->GetSizePixel().Height() )
+ {
+ pFt->Hide();
+ nFixedTextOffset = 0;
+ }
+ else
+ {
+ pFt->Show();
+ nFixedTextOffset = pFt->GetSizePixel().Height() + nSpace;
+
+ // FixedText positioning
+ pFt->SetPosPixel( Point( 0, nTopSpace ) );
+ }
+
+ // Window positioning
+ long nWinPosY = nFixedTextOffset;
+ nWinPosY += nTopSpace;
+ pWin->SetPosPixel( Point( 0, nWinPosY ) );
+
+ // Set size of window
+ long nWinHeight = GetOutputSizePixel().Height();
+ nWinHeight -= nWinPosY;
+ nWinHeight -= nBottomSpace;
+ pWin->SetSizePixel( Size( GetOutputSizePixel().Width(), nWinHeight ) );
+}
+
+DisplayHidDlg::DisplayHidDlg( Window * pParent )
+: FloatingWindow( pParent, SttResId( IDD_DISPLAY_HID ) )
+, aTbConf( this, SttResId( RID_TB_CONF ) )
+, aFtControls( this, SttResId( RID_FT_CONTROLS ) )
+, aMlbControls( this, SttResId( RID_MLB_CONTROLS ) )
+, aFtSlots( this, SttResId( RID_FT_SLOTS ) )
+, aMlbSlots( this, SttResId( RID_MLB_SLOTS ) )
+, aPbKopieren( this, SttResId( RID_PB_KOPIEREN ) )
+, aPbBenennen( this, SttResId( RID_PB_BENENNEN ) )
+, aPbSelectAll( this, SttResId( RID_PB_SELECTALL ) )
+, aOKClose( this, SttResId( RID_OK_CLOSE ) )
+, nDisplayMode( DH_MODE_KURZNAME | DH_MODE_LANGNAME ) // If we have an old office use this default
+{
+ FreeResource();
+
+/* ResMgr* pRM = CREATERESMGR( svt );
+ ToolBox aOrig( this, ResId( 12345, pRM ) );
+ delete pRM;
+
+ aTbConf.CopyItem( aOrig, 4 );
+ aTbConf.InsertSeparator();
+ aTbConf.CopyItem( aOrig, 5 );
+ aTbConf.CopyItem( aOrig, 6 );
+ aTbConf.CopyItem( aOrig, 7 ); */
+ aTbConf.SetOutStyle( TOOLBOX_STYLE_FLAT );
+
+#if OSL_DEBUG_LEVEL < 2
+ aTbConf.Hide();
+#endif
+
+ pSplit = new SplitWindow( this );
+ pControls = new TextAndWin( pSplit, &aFtControls, &aMlbControls, aMlbControls.GetPosPixel().X(), TRUE );
+ pSlots = new TextAndWin( pSplit, &aFtSlots, &aMlbSlots, aMlbControls.GetPosPixel().X(), FALSE );
+
+ pSplit->SetPosPixel( aFtControls.GetPosPixel() );
+ pSplit->InsertItem( 1, pControls, 70, SPLITWINDOW_APPEND, 0, SWIB_PERCENTSIZE );
+ pSplit->InsertItem( 2, pSlots, 30, SPLITWINDOW_APPEND, 0, SWIB_PERCENTSIZE );
+ pSplit->Show();
+
+ aTbConf.SetBorderStyle( WINDOW_BORDER_NORMAL );
+ aPbKopieren.SetClickHdl( LINK( this, DisplayHidDlg, CopyToClipboard ) );
+ aPbSelectAll.SetClickHdl( LINK( this, DisplayHidDlg, SelectAll ) );
+
+ aMlbControls.SetSelectHdl( LINK( this, DisplayHidDlg, Select ) );
+ aMlbSlots.SetSelectHdl( LINK( this, DisplayHidDlg, Select ) );
+ Select( NULL );
+}
+
+DisplayHidDlg::~DisplayHidDlg()
+{
+ delete pControls;
+ delete pSlots;
+ delete pSplit;
+}
+
+IMPL_LINK( DisplayHidDlg, CopyToClipboard, void*, EMPTYARG )
+{
+ String aSammel;
+ USHORT i;
+
+ for ( i=0 ; i < aMlbControls.GetSelectEntryCount() ; i++ )
+ {
+ if ( aSammel.Len() )
+ aSammel += '\n';
+ aSammel += aMlbControls.GetSelectEntry( i );
+ }
+ for ( i=0 ; i < aMlbSlots.GetSelectEntryCount() ; i++ )
+ {
+ if ( aSammel.Len() )
+ aSammel += '\n';
+ aSammel += aMlbSlots.GetSelectEntry( i );
+ }
+ ::svt::OStringTransfer::CopyString( aSammel, this );
+ return 0;
+}
+
+IMPL_LINK( DisplayHidDlg, SelectAll, PushButton*, pButton )
+{
+ if ( pButton->GetState() != STATE_CHECK )
+ {
+ USHORT i;
+ for ( i=0 ; i < aMlbControls.GetEntryCount() ; i++ )
+ aMlbControls.SelectEntryPos( i );
+ for ( i=0 ; i < aMlbSlots.GetEntryCount() ; i++ )
+ aMlbSlots.SelectEntryPos( i );
+ }
+ else
+ {
+ aMlbControls.SetNoSelection();
+ aMlbControls.Invalidate();
+ aMlbSlots.SetNoSelection();
+ aMlbSlots.Invalidate();
+ }
+ Select( NULL );
+ return 0;
+}
+
+IMPL_LINK( DisplayHidDlg, Select, void*, EMPTYARG )
+{
+ if ( !aMlbControls.GetSelectEntryCount() && !aMlbSlots.GetSelectEntryCount() )
+ aPbSelectAll.SetState( STATE_NOCHECK );
+ else if ( aMlbControls.GetSelectEntryCount() == aMlbControls.GetEntryCount()
+ && aMlbSlots.GetSelectEntryCount() == aMlbSlots.GetEntryCount() )
+ aPbSelectAll.SetState( STATE_CHECK );
+ else
+ aPbSelectAll.SetState( STATE_DONTKNOW );
+ return 0;
+}
+
+void DisplayHidDlg::AddData( WinInfoRec* pWinInfo )
+{
+ if ( pWinInfo->bIsReset )
+ {
+ aMlbControls.Clear();
+ aMlbSlots.Clear();
+
+ if ( pWinInfo->nRType & DH_MODE_DATA_VALID ) // no old office
+ nDisplayMode = pWinInfo->nRType; // Is used for mode transmission while reset
+// if ( pWinInfo->aUId.GetULONG() & DH_MODE_DATA_VALID ) // kein altes Office
+// nDisplayMode = pWinInfo->aUId.GetULONG(); // Wird im Reset zur �bermittlung des Modus verwendet
+
+ return;
+ }
+
+ String aMsg;
+ if ( ( nDisplayMode & DH_MODE_KURZNAME ) )
+ {
+ if ( pWinInfo->aKurzname.Len() > 0 )
+ aMsg += pWinInfo->aKurzname;
+ else
+ {
+ aMsg.AppendAscii( "--" );
+ aMsg += pWinInfo->aUId;
+ aMsg.AppendAscii( ": " );
+ aMsg += pWinInfo->aRName;
+ }
+ aMsg.Expand(20);
+ }
+ else
+ {
+ aMsg += pWinInfo->aUId;
+ aMsg.Expand(13);
+ }
+ aMsg.AppendAscii( " " ); // At least three blanks
+
+ if ( nDisplayMode & DH_MODE_LANGNAME )
+ {
+ if ( pWinInfo->aLangname.Len() > 0 )
+ aMsg += pWinInfo->aLangname;
+ else
+ aMsg += String( SttResId( IDS_NO_LONGNAME ) );
+ }
+
+ aMlbControls.InsertEntry( aMsg );
+
+
+ // Do we have a Slotname?
+ if ( ( nDisplayMode & DH_MODE_KURZNAME ) && pWinInfo->aSlotname.Len() > 0 )
+ {
+ aMsg = pWinInfo->aSlotname;
+ aMsg.Expand(20);
+ aMsg.AppendAscii( " " );
+
+ if ( nDisplayMode & DH_MODE_LANGNAME )
+ {
+ if ( pWinInfo->aLangname.Len() > 0 )
+ aMsg += pWinInfo->aLangname;
+ else
+ aMsg += String( SttResId( IDS_NO_LONGNAME ) );
+ }
+
+ aMlbSlots.InsertEntry( aMsg );
+ }
+}
+
+void DisplayHidDlg::Resize()
+{
+
+ if ( IsRollUp() )
+ {
+ // We want only the toolbox to be seend
+ SetOutputSizePixel( aTbConf.GetSizePixel() );
+ }
+ else
+ {
+// SetUpdateMode( FALSE );
+
+ // Minimum size
+ Size aSize( GetOutputSizePixel() );
+ aSize.Width() = std::max( aSize.Width(), (long)(aOKClose.GetSizePixel().Width() * 3 ));
+ aSize.Height() = std::max( aSize.Height(), (long)(aOKClose.GetSizePixel().Height() * 8 ));
+ SetOutputSizePixel( aSize );
+
+ // Default space
+ long nSpace = pSplit->GetPosPixel().X();
+
+ // Adapt ToolBox width
+ aTbConf.SetSizePixel( Size ( GetSizePixel().Width(), aTbConf.CalcWindowSizePixel().Height() ) );
+ aTbConf.SetSizePixel( Size() ); // Hide at first
+
+ // SplitWindow positioning
+ pSplit->SetPosPixel( Point( nSpace, nSpace + aTbConf.GetPosPixel().Y() + aTbConf.GetSizePixel().Height() ) );
+
+ // Calculate width of SplitWindows
+ long nSplitWidth = GetSizePixel().Width();
+ nSplitWidth -= aPbBenennen.GetSizePixel().Width();
+ nSplitWidth -= 3 * nSpace; // Spaces
+ nSplitWidth -= nSpace / 2; // Little more space at right margin
+
+ // Calculate hight of SplitWindows
+ long nSplitHeight = GetOutputSizePixel().Height();
+ nSplitHeight -= pSplit->GetPosPixel().Y();
+ nSplitHeight -= nSpace; // bottom margin
+
+ // Set size of SplitWindows
+ pSplit->SetSizePixel( Size( nSplitWidth, nSplitHeight ) );
+
+ Point aPos;
+
+ // Button "Copy" positioning
+ aPos = pSplit->GetPosPixel();
+ aPos.Move( nSplitWidth, 0 );
+ aPos.Move( nSpace, 0 );
+ aPbKopieren.SetPosPixel( aPos );
+
+ // Button "Get all"
+ aPos.Move( 0, aPbKopieren.GetSizePixel().Height() );
+ aPos.Move( 0, nSpace );
+ aPbSelectAll.SetPosPixel( aPos );
+
+ // Button "Name"
+ aPos.Move( 0, aPbSelectAll.GetSizePixel().Height() );
+ aPos.Move( 0, nSpace );
+ aPbBenennen.SetPosPixel( aPos );
+
+ // "Close" Button
+ aPos = pSplit->GetPosPixel();
+ aPos.Move( nSpace, -aOKClose.GetSizePixel().Height() );
+ aPos.Move( pSplit->GetSizePixel().Width(), pSplit->GetSizePixel().Height() );
+ aOKClose.SetPosPixel( aPos );
+
+// SetUpdateMode( TRUE );
+// Invalidate();
+ }
+ FloatingWindow::Resize();
+}
+
+
+VarEditDialog::VarEditDialog( Window * pParent, SbxVariable *pPVar )
+: ModelessDialog( pParent, SttResId( IDD_EDIT_VAR ) )
+, aFixedTextRID_FT_NAME( this, SttResId( RID_FT_NAME ) )
+, aFixedTextRID_FT_CONTENT( this, SttResId( RID_FT_CONTENT ) )
+, aFixedTextRID_FT_NEW_CONTENT( this, SttResId( RID_FT_NEW_CONTENT ) )
+, aFixedTextRID_FT_NAME_VALUE( this, SttResId( RID_FT_NAME_VALUE ) )
+, aFixedTextRID_FT_CONTENT_VALUE( this, SttResId( RID_FT_CONTENT_VALUE ) )
+
+, aRadioButtonRID_RB_NEW_BOOL_T( this, SttResId( RID_RB_NEW_BOOL_T ) )
+, aRadioButtonRID_RB_NEW_BOOL_F( this, SttResId( RID_RB_NEW_BOOL_F ) )
+, aNumericFieldRID_NF_NEW_INTEGER( this, SttResId( RID_NF_NEW_INTEGER ) )
+, aNumericFieldRID_NF_NEW_LONG( this, SttResId( RID_NF_NEW_LONG ) )
+, aEditRID_ED_NEW_STRING( this, SttResId( RID_ED_NEW_STRING ) )
+
+, aOKButtonRID_OK( this, SttResId( RID_OK ) )
+, aCancelButtonRID_CANCEL( this, SttResId( RID_CANCEL ) )
+, pVar( pPVar )
+{
+ aFixedTextRID_FT_NAME_VALUE.SetText( pVar->GetName() );
+ aFixedTextRID_FT_CONTENT_VALUE.SetText( pVar->GetString() );
+
+ SbxDataType eType = pVar->GetType();
+ if ( ( eType & ( SbxVECTOR | SbxARRAY | SbxBYREF )) == 0 )
+ {
+ switch ( eType )
+ {
+ case SbxBOOL:
+ aRadioButtonRID_RB_NEW_BOOL_T.Show();
+ aRadioButtonRID_RB_NEW_BOOL_F.Show();
+ if ( pVar->GetBool() )
+ aRadioButtonRID_RB_NEW_BOOL_T.Check();
+ else
+ aRadioButtonRID_RB_NEW_BOOL_F.Check();
+ break;
+// case SbxCURRENCY:
+// case SbxDATE:
+// break;
+ case SbxINTEGER:
+ aNumericFieldRID_NF_NEW_INTEGER.Show();
+ aNumericFieldRID_NF_NEW_INTEGER.SetText( pVar->GetString() );
+ aNumericFieldRID_NF_NEW_INTEGER.Reformat();
+ break;
+ case SbxLONG:
+ aNumericFieldRID_NF_NEW_LONG.Show();
+ aNumericFieldRID_NF_NEW_LONG.SetText( pVar->GetString() );
+ aNumericFieldRID_NF_NEW_LONG.Reformat();
+ // Must be hardcoded otherwise the Rsc Compiler will fail
+ aNumericFieldRID_NF_NEW_LONG.SetMin( -aNumericFieldRID_NF_NEW_LONG.GetMax()-1 );
+ aNumericFieldRID_NF_NEW_LONG.SetFirst( -aNumericFieldRID_NF_NEW_LONG.GetLast()-1 );
+ break;
+// case SbxOBJECT: // cannot be edited
+// break;
+ case SbxSINGLE:
+ case SbxDOUBLE:
+ case SbxSTRING:
+ case SbxVARIANT:
+ case SbxEMPTY:
+ aEditRID_ED_NEW_STRING.Show();
+ aEditRID_ED_NEW_STRING.SetText( pVar->GetString() );
+ break;
+ default: // don't know how to edit
+ ;
+ }
+ }
+
+
+ aOKButtonRID_OK.SetClickHdl( LINK( this, VarEditDialog, OKClick ) );
+}
+
+
+IMPL_LINK( VarEditDialog, OKClick, Button *, pButton )
+{
+ (void) pButton; /* avoid warning about unused parameter */
+ BOOL bWasError = SbxBase::IsError(); // Probably an error is thrown
+
+
+ SbxDataType eType = pVar->GetType();
+/*
+Boolean
+Currency
+Date
+Double
+Integer
+Long
+Object
+Single
+String
+Variant
+
+
+atof
+
+ ecvt
+ f
+ gcvt
+
+SvNumberformat::
+ static double StringToDouble( const xub_Unicode* pStr,
+ const International& rIntl,
+ int& nErrno,
+ const xub_Unicode** ppEnd = NULL );
+ // Converts just as strtod a decimal string to a double.
+ // Decimal and thousand separators come from International,
+ // leading spaces are omitted.
+ // If ppEnd!=NULL then *ppEnd is set after the parsed data.
+ // If pStr contains only the String to be parsed, then if success:
+ // **ppEnd=='\0' and *ppEnd-pStr==strlen(pStr).
+ // If overflow fVal=+/-HUGE_VAL, if underflow 0,
+ // nErrno is in this cases set to ERANGE otherwise 0.
+ // "+/-1.#INF" are recognized as +/-HUGE_VAL.
+
+ */
+
+
+
+ String aContent( aEditRID_ED_NEW_STRING.GetText() );
+ BOOL bError = FALSE;
+ switch ( eType )
+ {
+ case SbxBOOL:
+ pVar->PutBool( aRadioButtonRID_RB_NEW_BOOL_T.IsChecked() );
+ break;
+// case SbxCURRENCY:
+// pVar->PutCurrency( aContent );
+// break;
+// case SbxDATE:
+// pVar->PutDate( aContent );
+// break;
+ case SbxINTEGER:
+ pVar->PutInteger( (INT16)aNumericFieldRID_NF_NEW_INTEGER.GetValue() );
+ break;
+ case SbxLONG:
+ pVar->PutLong( static_cast<INT32>(aNumericFieldRID_NF_NEW_LONG.GetValue()) );
+ break;
+ case SbxDOUBLE:
+ case SbxSINGLE:
+ bError = !pVar->PutStringExt( aContent );
+ break;
+ case SbxSTRING:
+ pVar->PutString( aContent );
+ break;
+ case SbxVARIANT:
+ case SbxEMPTY:
+ bError = !pVar->PutStringExt( aContent );
+ break;
+ default: // don't know how to edit
+ ;
+ }
+
+
+// pVar->PutStringExt( aEditRID_ED_NEW_STRING.GetText() );
+ if ( !bWasError && SbxBase::IsError() )
+ {
+ bError = TRUE;
+ SbxBase::ResetError();
+ }
+
+ if ( bError )
+ {
+ ErrorBox( this, SttResId( IDS_INVALID_VALUE ) ).Execute();
+ return 1;
+ }
+
+// if ( aEditRID_ED_NEW_STRING.GetText().Compare( pVar->GetString() ) != COMPARE_EQUAL )
+// {
+// aFixedTextRID_FT_CONTENT_VALUE.SetText( pVar->GetString() );
+// aEditRID_ED_NEW_STRING.SetText( pVar->GetString() );
+// return 1;
+// }
+
+ Close();
+ return 0;
+}
+
+
+
diff --git a/basic/source/app/dialogs.hxx b/basic/source/app/dialogs.hxx
new file mode 100644
index 000000000000..fbd67aa85f1b
--- /dev/null
+++ b/basic/source/app/dialogs.hxx
@@ -0,0 +1,371 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _DIALOGS_HXX
+#define _DIALOGS_HXX
+
+#ifndef _DIALOG_HXX //autogen
+#include <vcl/dialog.hxx>
+#endif
+#ifndef _BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+#ifndef _EDIT_HXX //autogen
+#include <vcl/edit.hxx>
+#endif
+#ifndef _FIELD_HXX //autogen
+#include <vcl/field.hxx>
+#endif
+#include <vcl/fixed.hxx>
+#include <vcl/tabdlg.hxx>
+#include <vcl/tabctrl.hxx>
+#include <vcl/tabpage.hxx>
+#include <tools/config.hxx>
+#ifndef _TOOLS_LIST_HXX
+#include <tools/list.hxx>
+#endif
+#include <vcl/lstbox.hxx>
+#include <vcl/floatwin.hxx>
+#include <vcl/toolbox.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svtools/ctrlbox.hxx>
+
+class SbxVariable;
+
+#ifndef _BASIC_TTRESHLP_HXX
+#include <basic/ttstrhlp.hxx>
+#endif
+
+class AboutDialog : public ModalDialog {
+ FixedText a1,a4,aVersionString;
+ OKButton aOk;
+public:
+ AboutDialog (Window*, const ResId&);
+};
+
+class FindDialog : public ModalDialog {
+ FixedText aFT1;
+ Edit aFind;
+ OKButton aOk;
+ CancelButton aCancel;
+ String* pFind;
+ DECL_LINK( ButtonClick, Button * );
+public:
+ FindDialog (Window*, const ResId&, String&);
+};
+
+class ReplaceDialog : public ModalDialog {
+ FixedText aFT1;
+ FixedText aFT2;
+ Edit aFind;
+ Edit aReplace;
+ OKButton aOk;
+ CancelButton aCancel;
+ String* pFind;
+ String* pReplace;
+ DECL_LINK( ButtonClick, Button * );
+public:
+ ReplaceDialog (Window*, const ResId&, String&, String&);
+};
+
+////////////////////////////////////////////////////////////////////
+
+class ConfEdit : public PushButton
+{
+protected:
+ FixedText aText;
+ Edit aEdit;
+ ByteString aKeyName;
+
+ void Init( Config &aConf );
+
+public:
+ ConfEdit( Window* pParent, USHORT nResText, USHORT nResEdit, USHORT nResButton, const ByteString& aKN, Config &aConf );
+ ConfEdit( Window* pParent, USHORT nResEdit, USHORT nResButton, const ByteString& aKN, Config &aConf );
+ void Save( Config &aConf );
+ void Reload( Config &aConf );
+ void Click();
+ String GetValue() { return aEdit.GetText(); };
+ void SetModifyHdl( Link aLink ) { aEdit.SetModifyHdl( aLink ); };
+};
+
+
+class OptConfEdit : public ConfEdit
+{
+protected:
+ CheckBox aCheck;
+ ConfEdit& rBase;
+ DECL_LINK( ToggleHdl, CheckBox* );
+public:
+ OptConfEdit( Window* pParent, USHORT nResCheck, USHORT nResEdit, USHORT nResButton, const ByteString& aKN, ConfEdit& rBaseEdit, Config& aConf );
+ void Reload( Config &aConf );
+ DECL_LINK( BaseModifyHdl, Edit* );
+};
+
+
+class OptionsDialog : public TabDialog
+{
+private:
+ TabControl aTabCtrl;
+
+ OKButton aOK;
+ CancelButton aCancel;
+ DECL_LINK( OKClick, Button * );
+
+ Config aConfig;
+
+public:
+ OptionsDialog( Window* pParent, const ResId& );
+ ~OptionsDialog();
+ virtual BOOL Close();
+
+
+ DECL_LINK( ActivatePageHdl, TabControl * );
+};
+
+class ProfileOptions : public TabPage
+{
+ Config &rConf;
+
+ FixedLine aFlProfile;
+ ComboBox aCbProfile;
+ PushButton aPbNewProfile;
+ PushButton aPbDelProfile;
+
+ FixedLine aDirs;
+ ConfEdit aLog;
+ ConfEdit aBasis;
+ OptConfEdit aHID;
+
+ CheckBox aAutoReload;
+ CheckBox aAutoSave;
+ CheckBox aStopOnSyntaxError;
+
+ void LoadData();
+
+ DECL_LINK( Select, ComboBox* );
+ DECL_LINK( DelProfile, Button* );
+ DECL_LINK( NewProfile, Button* );
+ DECL_LINK( CheckButtonsHdl, ComboBox* );
+
+ void ReloadProfile();
+ void Save();
+
+public:
+ ProfileOptions( Window*, Config &rConfig );
+ void Save( Config &rConfig );
+};
+
+
+class CrashreportOptions : public TabPage
+{
+ FixedLine aFLCrashreport;
+ CheckBox aCBUseProxy;
+ FixedText aFTCRHost;
+ Edit aEDCRHost;
+ FixedText aFTCRPort;
+ NumericField aNFCRPort;
+
+ CheckBox aCBAllowContact;
+ FixedText aFTEMail;
+ Edit aEDEMail;
+
+ DECL_LINK( CheckProxy, void*);
+ DECL_LINK( CheckResponse, void*);
+
+public:
+ CrashreportOptions( Window*, Config &aConfig );
+ void Save( Config &aConfig );
+};
+
+class MiscOptions : public TabPage
+{
+ FixedLine aFLCommunication;
+ FixedText aFTHost;
+ Edit aEDHost;
+ FixedText aFTTTPort;
+ NumericField aNFTTPort;
+ FixedText aFTUNOPort;
+ NumericField aNFUNOPort;
+ FixedLine aOther;
+ FixedText aTimeoutText;
+ TimeField aServerTimeout;
+ FixedText aFTLRU;
+ NumericField aTFMaxLRU;
+ FixedText aFTProgDir;
+ Edit aEDProgDir;
+ PushButton aPBProgDir;
+
+ DECL_LINK( Click, void*);
+
+public:
+ MiscOptions( Window*, Config &aConfig );
+ void Save( Config &aConfig );
+};
+
+class FontOptions : public TabPage
+{
+ FixedText aFTFontName;
+ FontNameBox aFontName;
+ FixedText aFTStyle;
+ FontStyleBox aFontStyle;
+ FixedText aFTSize;
+ FontSizeBox aFontSize;
+ FixedText aFTPreview;
+
+ FontList aFontList;
+
+ DECL_LINK( FontNameChanged, void* );
+ DECL_LINK( FontStyleChanged, void* );
+ DECL_LINK( FontSizeChanged, void* );
+
+ void UpdatePreview();
+
+public:
+ FontOptions( Window*, Config &aConfig );
+ void Save( Config &aConfig );
+};
+
+
+DECLARE_LIST( StringList, String * )
+#define C_KEY_ALLE CByteString("All")
+#define C_KEY_AKTUELL CByteString("Current")
+#define C_KEY_TYPE CByteString("Type")
+#define C_KEY_DELETE CByteString("Deleted Groups")
+
+class GenericOptions : public TabPage
+{
+ Config &aConf;
+
+ FixedLine aFlArea;
+ ComboBox aCbArea;
+ PushButton aPbNewArea;
+ PushButton aPbDelArea;
+
+ FixedLine aFlValue;
+ ComboBox aCbValue;
+ PushButton aPbSelectPath;
+ PushButton aPbNewValue;
+ PushButton aPbDelValue;
+
+ int nMoveButtons;
+ BOOL bShowSelectPath;
+ AutoTimer aMoveTimer;
+ DECL_LINK( MoveButtons, AutoTimer* );
+
+ ByteString aLastGroupName;
+
+ String ReadKey( const ByteString &aGroup, const ByteString &aKey );
+
+ StringList* GetAllGroups();
+ void LoadData();
+
+ void ShowSelectPath( const String aType );
+
+ DECL_LINK( LoadGroup, ComboBox* );
+ DECL_LINK( DelGroup, Button* );
+ DECL_LINK( NewGroup, Button* );
+ DECL_LINK( SelectPath, Button* );
+ DECL_LINK( DelValue, Button* );
+ DECL_LINK( NewValue, Button* );
+ DECL_LINK( CheckButtonsHdl, ComboBox* );
+
+public:
+ GenericOptions( Window*, Config &aConfig );
+ ~GenericOptions();
+ void Save( Config &aConfig );
+};
+
+
+struct WinInfoRec;
+class SplitWindow;
+
+class DisplayHidDlg : public FloatingWindow
+{
+protected:
+ ToolBox aTbConf;
+ FixedText aFtControls;
+ MultiListBox aMlbControls;
+ FixedText aFtSlots;
+ MultiListBox aMlbSlots;
+ PushButton aPbKopieren;
+ PushButton aPbBenennen;
+ PushButton aPbSelectAll;
+ OKButton aOKClose;
+
+ DockingWindow* pControls;
+ DockingWindow* pSlots;
+ SplitWindow *pSplit;
+
+ ULONG nDisplayMode;
+
+ DECL_LINK( Select, void* );
+ DECL_LINK( SelectAll, PushButton* );
+ DECL_LINK( CopyToClipboard, void* );
+
+public:
+ DisplayHidDlg( Window * pParent );
+ virtual ~DisplayHidDlg();
+
+ virtual void Resize();
+
+ void AddData( WinInfoRec* pWinInfo );
+
+};
+
+
+class VarEditDialog : public ModelessDialog
+{
+protected:
+ FixedText aFixedTextRID_FT_NAME;
+ FixedText aFixedTextRID_FT_CONTENT;
+ FixedText aFixedTextRID_FT_NEW_CONTENT;
+ FixedText aFixedTextRID_FT_NAME_VALUE;
+ FixedText aFixedTextRID_FT_CONTENT_VALUE;
+
+ RadioButton aRadioButtonRID_RB_NEW_BOOL_T;
+ RadioButton aRadioButtonRID_RB_NEW_BOOL_F;
+ NumericField aNumericFieldRID_NF_NEW_INTEGER;
+ NumericField aNumericFieldRID_NF_NEW_LONG;
+ Edit aEditRID_ED_NEW_STRING;
+
+ OKButton aOKButtonRID_OK;
+ CancelButton aCancelButtonRID_CANCEL;
+
+ SbxVariable *pVar;
+
+ DECL_LINK( OKClick, Button * );
+
+// BOOL bCompare = FALSE;
+// String aCompareString;
+
+public:
+ VarEditDialog( Window * pParent, SbxVariable *pPVar );
+};
+
+
+#endif
diff --git a/basic/source/app/makefile.mk b/basic/source/app/makefile.mk
new file mode 100644
index 000000000000..07ceed6e5116
--- /dev/null
+++ b/basic/source/app/makefile.mk
@@ -0,0 +1,101 @@
+#*************************************************************************
+#
+# 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=app
+
+LIBTARGET = NO
+
+# --- Settings ------------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Common ------------------------------------------------------------
+
+OBJFILES = \
+ $(OBJ)$/ttbasic.obj \
+ $(OBJ)$/basicrt.obj \
+ $(OBJ)$/processw.obj \
+ $(OBJ)$/process.obj \
+ $(OBJ)$/brkpnts.obj \
+ $(OBJ)$/mybasic.obj \
+ $(OBJ)$/status.obj \
+ $(OBJ)$/printer.obj \
+ $(OBJ)$/appwin.obj \
+ $(OBJ)$/appedit.obj \
+ $(OBJ)$/appbased.obj \
+ $(OBJ)$/apperror.obj \
+ $(OBJ)$/textedit.obj \
+ $(OBJ)$/msgedit.obj \
+ $(OBJ)$/dialogs.obj \
+
+EXCEPTIONSFILES = \
+ $(OBJ)$/app.obj \
+ $(OBJ)$/printer.obj \
+ $(OBJ)$/process.obj
+
+.IF "$(GUI)" == "WNT"
+EXCEPTIONSFILES += \
+ $(OBJ)$/process.obj
+.ENDIF
+
+SRS1NAME=$(TARGET)
+SRC1FILES = \
+ basic.src \
+ ttmsg.src \
+ basmsg.src \
+ svtmsg.src \
+ testtool.src
+
+LIB1TARGET=$(LB)$/app.lib
+LIB1ARCHIV=$(LB)$/libapp.a
+LIB1OBJFILES = \
+ $(OBJ)$/basicrt.obj \
+ $(OBJ)$/processw.obj \
+ $(OBJ)$/process.obj \
+ $(OBJ)$/brkpnts.obj \
+ $(OBJ)$/app.obj \
+ $(OBJ)$/mybasic.obj \
+ $(OBJ)$/status.obj \
+ $(OBJ)$/printer.obj \
+ $(OBJ)$/appwin.obj \
+ $(OBJ)$/appedit.obj \
+ $(OBJ)$/appbased.obj \
+ $(OBJ)$/apperror.obj \
+ $(OBJ)$/textedit.obj \
+ $(OBJ)$/msgedit.obj \
+ $(OBJ)$/dialogs.obj \
+ $(OBJ)$/sbintern.obj
+
+# --- Targets ------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(OBJ)$/dialogs.obj : $(INCCOM)$/_version.h
+
diff --git a/basic/source/app/msgedit.cxx b/basic/source/app/msgedit.cxx
new file mode 100644
index 000000000000..51864a397435
--- /dev/null
+++ b/basic/source/app/msgedit.cxx
@@ -0,0 +1,999 @@
+/*************************************************************************
+ *
+ * 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"
+/*************************************************************************
+File Versions so far:
+No Version Initial Implementation without Version Information
+Version 2 changed order of entries(New Entries at the end)
+Version 3 Changed Charset from CHARSET_IBMPC to RTL_TEXTENCODING_UTF8
+
+*************************************************************************/
+#include <cstdio>
+#include <tools/time.hxx>
+#include <tools/stream.hxx>
+#ifndef _MSGBOX_HXX //autogen
+#include <vcl/msgbox.hxx>
+#endif
+#ifndef _SOUND_HXX //autogen
+#include <vcl/sound.hxx>
+#endif
+#include <tools/fsys.hxx>
+#include <svtools/stringtransfer.hxx>
+#include <unotools/syslocale.hxx>
+#ifndef _BASIC_TTRESHLP_HXX
+#include <basic/ttstrhlp.hxx>
+#endif
+#include "basic.hrc"
+#include "msgedit.hxx"
+#include "app.hxx"
+#include "apperror.hxx"
+#include "appbased.hxx"
+#include "basmsg.hrc"
+#include "basrid.hxx"
+
+USHORT MsgEdit::nMaxLogLen = 0;
+BOOL MsgEdit::bLimitLogLen = FALSE;
+BOOL MsgEdit::bPrintLogToStdout = FALSE;
+BOOL MsgEdit::bPrintLogToStdoutSet = FALSE;
+
+#define WARNING_PREFIX String( SttResId( S_WARNING_PREFIX ) )
+#define VERSION_STRING CUniString("File Format Version: ")
+#define THIS_VERSION 2
+
+#define LOGTYPE( pEntry ) ((pEntry && pEntry->GetUserData())?((TTDebugData*)pEntry->GetUserData())->aLogType:LOG_ERROR)
+
+MsgEdit::MsgEdit( AppError* pParent, BasicFrame *pBF, const WinBits& aBits )
+: pBasicFrame(pBF)
+, pCurrentRun(NULL)
+, pCurrentTestCase(NULL)
+, pCurrentAssertion( NULL )
+, pCurrentError(NULL)
+, bModified(FALSE)
+, bFileLoading(FALSE)
+, nVersion(0)
+, pAppError( pParent )
+, aEditTree( pParent, pBF, aBits | WB_HASBUTTONS | WB_HASLINES | WB_HASBUTTONSATROOT )
+{
+// SetFont( aEditTree.GetDefaultFont( DEFAULTFONT_FIXED, aEditTree.GetSettings().GetLanguage(), 0, &aEditTree ) );
+ aEditTree.SetNodeBitmaps( Bitmap( SttResId (MBP_PLUS) ), Bitmap( SttResId (MBP_MINUS) ) );
+ aEditTree.SetSelectionMode( MULTIPLE_SELECTION );
+ if ( aEditTree.GetModel()->GetSortMode() != SortNone )
+ aEditTree.GetModel()->SetSortMode( SortNone );
+
+ if ( !bPrintLogToStdoutSet )
+ {
+ bPrintLogToStdoutSet = TRUE;
+ for ( USHORT i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
+ {
+ if ( Application::GetCommandLineParam( i ).Copy(0,9).CompareIgnoreCaseToAscii("-printlog") == COMPARE_EQUAL
+ #ifndef UNX
+ || Application::GetCommandLineParam( i ).Copy(0,9).CompareIgnoreCaseToAscii("/printlog") == COMPARE_EQUAL
+ #endif
+ )
+ bPrintLogToStdout = TRUE;
+ }
+ }
+}
+
+MsgEdit::~MsgEdit()
+{}
+
+// set the LogType since calling the add method can be from other add methods
+#define COPY_TTDEBUGDATA( LOGTYPE ) \
+ TTDebugData *pTTDebugData = new TTDebugData; \
+ *pTTDebugData = aDebugData; \
+ pTTDebugData->aLogType = LOGTYPE; \
+
+
+void MsgEdit::AddAnyMsg( TTLogMsg *LogMsg )
+{
+ if ( LogMsg->aDebugData.aFilename.Copy(0,2).CompareToAscii( "--" ) == COMPARE_EQUAL )
+ LogMsg->aDebugData.aFilename.Erase(0,2);
+
+ if ( LogMsg->aDebugData.aFilename.Len() && LogMsg->aDebugData.aFilename.GetChar(0) != '~' ) // do we want to convert
+ {
+ DirEntry aConvert( LogMsg->aDebugData.aFilename );
+ if ( pAppError->aBaseDir.Contains( aConvert ) )
+ {
+ aConvert.ToRel( pAppError->aBaseDir );
+ LogMsg->aDebugData.aFilename = CUniString("~"); // mark as converted
+ LogMsg->aDebugData.aFilename += aConvert.GetFull( FSYS_STYLE_VFAT );
+ }
+ else if ( !bFileLoading )
+ {
+ LogMsg->aDebugData.aFilename.Insert( CUniString("~-"), 0); // mark as unconvertable
+ }
+ }
+ xub_StrLen nPos;
+ LogMsg->aDebugData.aMsg.ConvertLineEnd();
+ // does the message have several lines -> repeat the call for each line
+ if ( (nPos = LogMsg->aDebugData.aMsg.Search( CUniString("\n").ConvertLineEnd() )) != STRING_NOTFOUND )
+ {
+ String aOriginalMsg = LogMsg->aDebugData.aMsg;
+ xub_StrLen nSysLineEndLen = CUniString("\n").ConvertLineEnd().Len();
+ String aLastPart = LogMsg->aDebugData.aMsg.Copy( nPos+nSysLineEndLen );
+ LogMsg->aDebugData.aMsg.Erase( nPos );
+ AddAnyMsg( LogMsg );
+ if ( aLastPart.Len() )
+ {
+ LogMsg->aDebugData.aMsg = aLastPart;
+ AddAnyMsg( LogMsg );
+ }
+ LogMsg->aDebugData.aMsg = aOriginalMsg;
+ }
+ else
+ {
+ String aUILogMsg( pBasicFrame->GenRealString( LogMsg->aDebugData.aMsg ) );
+ switch ( LogMsg->aDebugData.aLogType )
+ {
+ case LOG_RUN:
+ {
+ if ( LogMsg->aDebugData.aMsg.Len() == 0 )
+ {
+ SvtSysLocale aLocale;
+ LogMsg->aDebugData.aMsg = GEN_RES_STR2( S_PROG_START,
+ aLocale.GetLocaleData().getDate(Date()),
+ aLocale.GetLocaleData().getTime(Time()) );
+ aUILogMsg = pBasicFrame->GenRealString( LogMsg->aDebugData.aMsg );
+ }
+ AddRun( aUILogMsg, LogMsg->aDebugData ); break;
+ }
+ case LOG_TEST_CASE: AddTestCase( aUILogMsg, LogMsg->aDebugData ); break;
+ case LOG_ERROR: AddError( aUILogMsg, LogMsg->aDebugData ); break;
+ case LOG_CALL_STACK:AddCallStack( aUILogMsg, LogMsg->aDebugData ); break;
+ case LOG_MESSAGE: AddMessage( aUILogMsg, LogMsg->aDebugData ); break;
+ case LOG_WARNING: AddWarning( aUILogMsg, LogMsg->aDebugData ); break;
+ case LOG_ASSERTION: AddAssertion( aUILogMsg, LogMsg->aDebugData ); break;
+ case LOG_ASSERTION_STACK: AddAssertionStack( aUILogMsg, LogMsg->aDebugData ); break;
+ case LOG_QA_ERROR: AddQAError( aUILogMsg, LogMsg->aDebugData ); break;
+ default:DBG_ERROR("Unbekannter Typ in ResultFile. Speichern des ResultFile resultiert in Informationsverlust");
+ }
+
+ if ( !bFileLoading )
+ { // Comes from Testtool and must be written immediately
+ BOOL bFileWasChanged = pAppError->DiskFileChanged( SINCE_LAST_LOAD );
+
+ DBG_ASSERT( aLogFileName == LogMsg->aLogFileName, "Logging to different logfile as before" );
+ DirEntry aEntry( LogMsg->aLogFileName );
+ BOOL bNewFile = !aEntry.Exists();
+ SvFileStream aStrm( LogMsg->aLogFileName, STREAM_STD_WRITE );
+ if ( bNewFile )
+ {
+ String aSave = VERSION_STRING.Append( UniString::CreateFromInt32( 3 ) ).AppendAscii("\n"); // Version 3
+ aSave.ConvertLineEnd(LINEEND_CRLF);
+ aStrm << ByteString( aSave, RTL_TEXTENCODING_IBM_850 ).GetBuffer();
+ }
+
+ String aLogMsg = Impl_MakeSaveText( LogMsg->aDebugData ).AppendAscii("\n");
+
+ if( aStrm.IsOpen() )
+ {
+ aLogMsg.ConvertLineEnd(LINEEND_CRLF);
+ aStrm.Seek(STREAM_SEEK_TO_END);
+ aStrm << ByteString( aLogMsg, RTL_TEXTENCODING_UTF8 ).GetBuffer();
+ aStrm.Close();
+ }
+ if ( !bFileWasChanged )
+ pAppError->UpdateFileInfo( HAS_BEEN_LOADED );
+
+
+ // now write to stdout
+ if ( bPrintLogToStdout )
+ {
+ String aPrintMsg, aOriginalMsg;
+
+ aOriginalMsg = LogMsg->aDebugData.aMsg;
+ // converting to human readable string for adding errors to list in testobject
+ LogMsg->aDebugData.aMsg = pBasicFrame->GenRealString( LogMsg->aDebugData.aMsg );
+
+ aPrintMsg = Impl_MakeSaveText( LogMsg->aDebugData ).AppendAscii("\n");
+
+ // restore Original Msg
+ LogMsg->aDebugData.aMsg = aOriginalMsg;
+
+ printf( ByteString( aPrintMsg, RTL_TEXTENCODING_UTF8 ).GetBuffer() );
+ }
+ }
+ }
+ // converting to human readable string for adding errors to list in testobject
+ LogMsg->aDebugData.aMsg = pBasicFrame->GenRealString( LogMsg->aDebugData.aMsg );
+}
+
+void MsgEdit::AddRun( String aMsg, TTDebugData aDebugData )
+{
+ if ( !bFileLoading && bLimitLogLen )
+ {
+ USHORT nSkip = nMaxLogLen;
+ SvLBoxEntry *pRun = aEditTree.First();
+ while ( nSkip-- && pRun )
+ pRun = aEditTree.NextSibling( pRun );
+ // Remove all Entries thereafter
+ if ( pRun )
+ {
+ while ( pRun && aEditTree.NextSibling( pRun ) )
+ aEditTree.GetModel()->Remove( aEditTree.NextSibling( pRun ) );
+
+ aEditTree.GetModel()->Remove( pRun );
+ bModified = TRUE;
+ lModify.Call( NULL );
+ Save( aLogFileName );
+ pAppError->UpdateFileInfo( HAS_BEEN_LOADED );
+ }
+ }
+
+ COPY_TTDEBUGDATA( LOG_RUN );
+ if ( !bFileLoading || ( bFileLoading && nVersion >= 2 ) )
+ pCurrentRun = aEditTree.InsertEntry( aMsg, NULL, FALSE, 0, pTTDebugData );
+ else // First file format
+ pCurrentRun = aEditTree.InsertEntry( aMsg, NULL, FALSE, LIST_APPEND, pTTDebugData ); // and therefor at the end
+
+ aEditTree.ShowEntry( pCurrentRun );
+ pCurrentTestCase = NULL;
+ pCurrentAssertion = NULL;
+ pCurrentError = NULL;
+}
+
+void MsgEdit::AddTestCase( String aMsg, TTDebugData aDebugData )
+{
+ if ( pCurrentRun )
+ {
+ if ( aMsg.Len() == 0 ) // End of Testcase
+ {
+ pCurrentTestCase = NULL;
+ }
+ else
+ {
+ COPY_TTDEBUGDATA( LOG_TEST_CASE );
+ pCurrentTestCase = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
+ aEditTree.ShowEntry( pCurrentTestCase );
+ }
+ }
+ pCurrentAssertion = NULL;
+ pCurrentError = NULL;
+}
+
+void MsgEdit::AddError( String aMsg, TTDebugData aDebugData )
+{
+ if ( !pCurrentTestCase )
+ {
+ TTLogMsg aLogMsg;
+ aLogMsg.aDebugData = aDebugData;
+ aLogMsg.aDebugData.aMsg = GEN_RES_STR0( S_ERROR_OUTSIDE_TESTCASE );
+ aLogMsg.aDebugData.aLogType = LOG_TEST_CASE;
+ aLogMsg.aLogFileName = aLogFileName;
+ AddAnyMsg( &aLogMsg );
+ }
+ if ( pCurrentTestCase )
+ {
+ COPY_TTDEBUGDATA( LOG_ERROR );
+ pCurrentError = aEditTree.InsertEntry( aMsg, pCurrentTestCase, FALSE, LIST_APPEND, pTTDebugData );
+ aEditTree.ShowEntry( pCurrentError );
+ }
+}
+
+void MsgEdit::AddCallStack( String aMsg, TTDebugData aDebugData )
+{
+ DBG_ASSERT( pCurrentError, "Callstack ohne CurrentError im Journal" );
+ if ( pCurrentError )
+ {
+ COPY_TTDEBUGDATA( LOG_CALL_STACK );
+ aEditTree.InsertEntry( aMsg, pCurrentError, FALSE, LIST_APPEND, pTTDebugData );
+ }
+}
+
+void MsgEdit::AddMessage( String aMsg, TTDebugData aDebugData )
+{
+ SvLBoxEntry *pThisEntry = NULL;
+ COPY_TTDEBUGDATA( LOG_MESSAGE );
+ if ( pCurrentTestCase )
+ pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentTestCase, FALSE, LIST_APPEND, pTTDebugData );
+ else if ( pCurrentRun )
+ {
+ pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
+ aEditTree.ShowEntry( pThisEntry );
+ }
+ else
+ {
+ AddRun( aMsg, aDebugData );
+ pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
+ aEditTree.ShowEntry( pThisEntry );
+ }
+}
+
+void MsgEdit::AddWarning( String aMsg, TTDebugData aDebugData )
+{
+ SvLBoxEntry *pThisEntry = NULL;
+ String aCompleteMsg;
+ aCompleteMsg = WARNING_PREFIX.Append( aMsg );
+ COPY_TTDEBUGDATA( LOG_WARNING );
+
+ if ( pCurrentTestCase )
+ pThisEntry = aEditTree.InsertEntry( aCompleteMsg, pCurrentTestCase, FALSE, LIST_APPEND, pTTDebugData );
+ else if ( pCurrentRun )
+ {
+ pThisEntry = aEditTree.InsertEntry( aCompleteMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
+ aEditTree.ShowEntry( pThisEntry );
+ }
+ else
+ {
+ AddRun( aMsg, aDebugData );
+ pThisEntry = aEditTree.InsertEntry( aCompleteMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
+ aEditTree.ShowEntry( pThisEntry );
+ }
+
+ while ( !aEditTree.IsEntryVisible( pThisEntry ) && ( pThisEntry = aEditTree.GetParent( pThisEntry ) ) != NULL )
+ aEditTree.InvalidateEntry( pThisEntry );
+}
+
+void MsgEdit::AddAssertion( String aMsg, TTDebugData aDebugData )
+{
+ const String aAssertionStackPrefix( CUniString(ASSERTION_STACK_PREFIX) );
+ if ( aMsg.Match( aAssertionStackPrefix ) == aAssertionStackPrefix.Len() )
+ {
+ AddAssertionStack( aMsg, aDebugData );
+ return;
+ }
+ SvLBoxEntry *pThisEntry = NULL;
+ COPY_TTDEBUGDATA( LOG_ASSERTION );
+ if ( pCurrentTestCase )
+ pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentTestCase, FALSE, LIST_APPEND, pTTDebugData );
+ else if ( pCurrentRun )
+ {
+ pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
+ aEditTree.ShowEntry( pThisEntry );
+ }
+ else
+ {
+ AddRun( aMsg, aDebugData );
+ pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
+ aEditTree.ShowEntry( pThisEntry );
+ }
+
+ pCurrentAssertion = pThisEntry;
+
+ while ( !aEditTree.IsEntryVisible( pThisEntry ) && ( pThisEntry = aEditTree.GetParent( pThisEntry ) ) != NULL )
+ aEditTree.InvalidateEntry( pThisEntry );
+}
+
+void MsgEdit::AddAssertionStack( String aMsg, TTDebugData aDebugData )
+{
+ SvLBoxEntry *pThisEntry = NULL;
+ COPY_TTDEBUGDATA( LOG_ASSERTION_STACK );
+ if ( pCurrentAssertion )
+ pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentAssertion, FALSE, LIST_APPEND, pTTDebugData );
+ else if ( pCurrentTestCase )
+ pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentTestCase, FALSE, LIST_APPEND, pTTDebugData );
+ else if ( pCurrentRun )
+ {
+ pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
+ aEditTree.ShowEntry( pThisEntry );
+ }
+ else
+ {
+ AddRun( aMsg, aDebugData );
+ pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
+ aEditTree.ShowEntry( pThisEntry );
+ }
+
+ while ( !aEditTree.IsEntryVisible( pThisEntry ) && ( pThisEntry = aEditTree.GetParent( pThisEntry ) ) != NULL )
+ aEditTree.InvalidateEntry( pThisEntry );
+}
+
+void MsgEdit::AddQAError( String aMsg, TTDebugData aDebugData )
+{
+ SvLBoxEntry *pThisEntry = NULL;
+ COPY_TTDEBUGDATA( LOG_QA_ERROR );
+ if ( pCurrentTestCase )
+ pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentTestCase, FALSE, LIST_APPEND, pTTDebugData );
+ else if ( pCurrentRun )
+ {
+ pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
+ aEditTree.ShowEntry( pThisEntry );
+ }
+ else
+ {
+ AddRun( aMsg, aDebugData );
+ pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
+ aEditTree.ShowEntry( pThisEntry );
+ }
+
+ while ( !aEditTree.IsEntryVisible( pThisEntry ) && ( pThisEntry = aEditTree.GetParent( pThisEntry ) ) != NULL )
+ aEditTree.InvalidateEntry( pThisEntry );
+}
+
+/*
+ SvLBoxEntry* GetEntry( SvLBoxEntry* pParent, ULONG nPos ) const { return SvLBox::GetEntry(pParent,nPos); }
+ SvLBoxEntry* GetEntry( ULONG nRootPos ) const { return SvLBox::GetEntry(nRootPos);}
+
+
+
+ SvLBoxEntry* FirstChild(SvLBoxEntry* pParent ) const { return (SvLBoxEntry*)(pModel->FirstChild(pParent)); }
+ SvLBoxEntry* NextSibling(SvLBoxEntry* pEntry ) const { return (SvLBoxEntry*)(pModel->NextSibling( pEntry )); }
+ SvLBoxEntry* PrevSibling(SvLBoxEntry* pEntry ) const { return (SvLBoxEntry*)(pModel->PrevSibling( pEntry )); }
+
+ SvLBoxEntry* FirstSelected() const { return (SvLBoxEntry*)SvListView::FirstSelected(); }
+ SvLBoxEntry* NextSelected( SvLBoxEntry* pEntry ) const { return (SvLBoxEntry*)(SvListView::NextSelected(pEntry)); }
+ SvLBoxEntry* PrevSelected( SvLBoxEntry* pEntry ) const { return (SvLBoxEntry*)(SvListView::PrevSelected(pEntry)); }
+ SvLBoxEntry* LastSelected() const { return (SvLBoxEntry*)(SvListView::LastSelected()); }
+
+ SvLBoxEntry* GetEntry( SvLBoxEntry* pParent, ULONG nPos ) const { return (SvLBoxEntry*)(pModel->GetEntry(pParent,nPos)); }
+ SvLBoxEntry* GetEntry( ULONG nRootPos ) const { return (SvLBoxEntry*)(pModel->GetEntry(nRootPos)); }
+
+ SvLBoxEntry* GetParent( SvLBoxEntry* pEntry ) const { return (SvLBoxEntry*)(pModel->GetParent(pEntry)); }
+ SvLBoxEntry* GetRootLevelParent(SvLBoxEntry* pEntry ) const { return (SvLBoxEntry*)(pModel->GetRootLevelParent( pEntry ));}
+
+ BOOL IsInChildList( SvListEntry* pParent, SvListEntry* pChild) const;
+ SvListEntry* GetEntry( SvListEntry* pParent, ULONG nPos ) const;
+ SvListEntry* GetEntry( ULONG nRootPos ) const;
+ SvListEntry* GetEntryAtAbsPos( ULONG nAbsPos ) const;
+ SvListEntry* GetParent( SvListEntry* pEntry ) const;
+ SvListEntry* GetRootLevelParent( SvListEntry* pEntry ) const;
+*/
+
+//#define CHECK( pMemo ) if ( pMemo && !aEditTree.GetViewData( pMemo ) ) pMemo = NULL
+#define CHECK( pMemo ) if ( pMemo && !aEditTree.GetModel()->IsInChildList( NULL, pMemo ) ) pMemo = NULL
+void MsgEdit::Delete()
+{
+ aEditTree.RemoveSelection();
+ CHECK( pCurrentRun );
+ CHECK( pCurrentTestCase );
+ CHECK( pCurrentAssertion );
+ CHECK( pCurrentError );
+ bModified = TRUE;
+ lModify.Call( NULL );
+}
+
+void MsgEdit::Cut(){ Copy(); Delete(); bModified = TRUE; lModify.Call( NULL ); }
+void MsgEdit::Copy(){ ::svt::OStringTransfer::CopyString( GetSelected(), &aEditTree ); }
+/**/void MsgEdit::Paste(){ Sound::Beep(); }
+void MsgEdit::Undo(){ Sound::Beep(); }
+void MsgEdit::Redo(){ Sound::Beep(); }
+
+
+String MsgEdit::Impl_MakeText( SvLBoxEntry *pEntry ) const
+{
+ String aRet;
+ TTDebugData *aData = (TTDebugData*)pEntry->GetUserData();
+ switch ( aData->aLogType )
+ {
+ case LOG_RUN: aRet.AppendAscii("\n"); break;
+ case LOG_TEST_CASE: break;
+ case LOG_ERROR: break;
+ case LOG_CALL_STACK:aRet.AppendAscii("--> "); break;
+ case LOG_MESSAGE: break;
+ case LOG_WARNING: break;
+ case LOG_ASSERTION: break;
+ case LOG_ASSERTION_STACK:aRet.AppendAscii("--> "); break;
+ case LOG_QA_ERROR: break;
+ default:DBG_ERROR("Unknown type in ResultWindow!");
+ }
+ aRet += aEditTree.GetEntryText( pEntry );
+ return aRet;
+}
+
+String MsgEdit::Impl_MakeSaveText( TTDebugData aData ) const
+{
+// LogType;Filename;Line;Col1;Col2;Message
+ String aRet;
+ aRet += String::CreateFromInt32( (int)aData.aLogType );
+ aRet += ';';
+ aRet += aData.aFilename;
+ aRet += ';';
+ aRet += String::CreateFromInt32( aData.nLine );
+ aRet += ';';
+ aRet += String::CreateFromInt32( aData.nCol1 );
+ aRet += ';';
+ aRet += String::CreateFromInt32( aData.nCol2 );
+ aRet += ';';
+ aRet += '"';
+ aRet += aData.aMsg;
+ aRet += '"';
+ return aRet;
+}
+
+String MsgEdit::Impl_MakeSaveText( SvLBoxEntry *pEntry ) const
+{
+// LogType;Filename;Line;Col1;Col2;Message
+ String aRet;
+ TTDebugData *aData = (TTDebugData*)pEntry->GetUserData();
+
+ if ( aEditTree.PrevSibling( pEntry ) && LOGTYPE( aEditTree.PrevSibling( pEntry ) ) == LOG_TEST_CASE )
+ { // To properly finish cases and warnings/msgs are in correct hierarchie
+ aRet += String::CreateFromInt32( (int)LOG_TEST_CASE );
+ aRet.AppendAscii(";;0;0;0;\"\"\n");
+ }
+ aRet += Impl_MakeSaveText( *aData );
+ return aRet;
+}
+
+String MsgEdit::GetSelected()
+{
+ String aRet;
+ SvLBoxEntry *pEntry = aEditTree.FirstSelected();
+ while ( pEntry )
+ {
+ aRet += Impl_MakeText( pEntry );
+ aRet += '\n';
+ pEntry = aEditTree.NextSelected( pEntry );
+ }
+ aRet.ConvertLineEnd();
+ return aRet;
+}
+
+TextSelection MsgEdit::GetSelection() const
+{
+ ULONG nStart=0,nEnd=0;
+
+ if ( aEditTree.FirstSelected() )
+ {
+ nStart = aEditTree.GetModel()->GetAbsPos(aEditTree.FirstSelected() );
+ if ( aEditTree.LastSelected() )
+ nEnd = aEditTree.GetModel()->GetAbsPos(aEditTree.LastSelected() );
+ return TextSelection( TextPaM( nStart, 0 ), TextPaM( nEnd, STRING_MAXLEN ) );
+ }
+ else
+ return TextSelection();
+}
+
+void MsgEdit::SetSelection( const TextSelection& rSelection )
+{
+ ULONG nStart,nEnd;
+
+ while ( aEditTree.GetSelectionCount() )
+ aEditTree.Select( aEditTree.FirstSelected(), FALSE );
+
+ if ( rSelection.HasRange() )
+ {
+ nStart = rSelection.GetStart().GetPara();
+ nEnd = rSelection.GetEnd().GetPara();
+
+ for ( ULONG i = nStart ; i <= nEnd ; i++ )
+ aEditTree.Select( aEditTree.GetModel()->GetEntryAtAbsPos( i ), TRUE );
+ }
+}
+
+USHORT MsgEdit::GetLineNr() const
+{
+ if ( aEditTree.GetCurEntry() )
+ return (USHORT)aEditTree.GetModel()->GetAbsPos(aEditTree.GetCurEntry() ) + 1;
+ else
+ return 0;
+}
+
+void MsgEdit::ReplaceSelected( const String& rStr )
+{
+ (void) rStr; /* avoid warning about unused parameter */
+ Sound::Beep();
+ DBG_ERROR("Not Implemented");
+}
+
+BOOL MsgEdit::IsModified(){ return bModified; }
+void MsgEdit::SetModifyHdl( Link l ){ lModify = l; }
+
+String MsgEdit::GetText() const
+{
+ String aRet;
+ SvLBoxEntry *pEntry = aEditTree.First();
+ while ( pEntry )
+ {
+ aRet += Impl_MakeText( pEntry );
+ aRet += '\n';
+ pEntry = aEditTree.Next( pEntry );
+ }
+ aRet.ConvertLineEnd();
+ return aRet;
+}
+
+void MsgEdit::SetText( const String& rStr )
+{
+ (void) rStr; /* avoid warning about unused parameter */
+ Sound::Beep();
+ DBG_ERROR("Not Implemented");
+}
+
+BOOL MsgEdit::HasText() const
+{
+ return aEditTree.First() != NULL;
+}
+
+// Search from the beginning or mark start + 1
+BOOL MsgEdit::Find( const String& s )
+{
+ TextSelection r = GetSelection();
+ USHORT bgn = (USHORT) r.GetStart().GetPara() + 1;
+ if ( r.GetStart().GetPara() == 0 )
+ bgn = 0; // Search from the beginning
+
+ SvLBoxEntry *pEntry = aEditTree.GetModel()->GetEntryAtAbsPos( bgn );
+ while ( pEntry )
+ {
+ if( aEditTree.GetEntryText( pEntry ).Search( s, 0 ) != STRING_NOTFOUND )
+ {
+ aEditTree.SetCurEntry( pEntry );
+ return TRUE;
+ }
+ pEntry = aEditTree.Next( pEntry );
+ }
+ return FALSE;
+}
+
+/******************************************************************
+
+ Fileformat of *.res file:
+ Information are stored as semicolon separated strings
+ Order:
+
+ LogType;Filename;Line;Col1;Col2;Message
+
+******************************************************************/
+
+BOOL MsgEdit::Load( const String& aName )
+{
+ aLogFileName = aName;
+ BOOL bOk = TRUE, bFirstLine = TRUE;
+ BOOL bLoadError = FALSE;
+ SvFileStream aStrm( aName, STREAM_STD_READ );
+ if( aStrm.IsOpen() )
+ {
+ aEditTree.Clear();
+ String aLine;
+ bFileLoading = TRUE; // To avoid logging to disk
+ TTLogMsg *pLogMsg = new TTLogMsg;
+ while( !aStrm.IsEof() && bOk )
+ {
+ if ( nVersion >= 3 ) // utf8
+ aStrm.ReadByteStringLine( aLine, RTL_TEXTENCODING_UTF8 );
+ else
+ aStrm.ReadByteStringLine( aLine, RTL_TEXTENCODING_IBM_850 );
+
+ if( aStrm.GetError() != SVSTREAM_OK )
+ bOk = FALSE;
+
+#define TOKEN( n ) aLine.GetToken( n )
+
+ if ( aLine.GetTokenCount() >= 6 )
+ {
+// LogType;Filename;Line;Col1;Col2;Message
+ TTDebugData aDebugData;
+ aDebugData.aLogType = TTLogType( TOKEN(0).ToInt32() );
+ aDebugData.aFilename = TOKEN(1);
+ aDebugData.nLine = USHORT( TOKEN(2).ToInt32() );
+ aDebugData.nCol1 = USHORT( TOKEN(3).ToInt32() );
+ aDebugData.nCol2 = USHORT( TOKEN(4).ToInt32() );
+ aDebugData.aMsg = aLine.GetQuotedToken( 5, CUniString("\"\"") );
+
+ // Remove leading and trailing quotes
+ aDebugData.aMsg.Erase(0,1);
+ aDebugData.aMsg.Erase(aDebugData.aMsg.Len()-1,1);
+
+ pLogMsg->aLogFileName.Erase();
+ pLogMsg->aDebugData = aDebugData;
+
+ AddAnyMsg( pLogMsg );
+ }
+ else if ( bFirstLine && (aLine.Search( VERSION_STRING ) == 0) )
+ nVersion = USHORT( aLine.Copy( VERSION_STRING.Len() ).ToInt32() );
+ else if ( aLine.Len() )
+ bLoadError = TRUE;
+
+ bFirstLine = FALSE;
+ }
+ bFileLoading = FALSE;
+ delete pLogMsg;
+ aStrm.Close();
+ if ( nVersion < 2 && !bLoadError )
+ Save( aName ); // Necessary to avoid mess
+
+ }
+ else
+ bOk = FALSE;
+ return bOk;
+}
+
+BOOL MsgEdit::Save( const String& aName )
+{
+ BOOL bOk = TRUE;
+ BOOL bIsText = DirEntry( aName ).GetExtension().CompareIgnoreCaseToAscii("TXT") == COMPARE_EQUAL;
+ if ( bIsText && !QueryBox( NULL, SttResId( IDS_LOSS_OF_INFORMATION ) ).Execute() )
+ return FALSE;
+ SvFileStream aStrm( aName, STREAM_STD_WRITE | STREAM_TRUNC );
+ if( aStrm.IsOpen() )
+ {
+ if ( bIsText )
+ {
+ String aSave = GetText();
+ aSave.ConvertLineEnd(LINEEND_CRLF);
+ aStrm << ByteString( aSave, RTL_TEXTENCODING_UTF8 ).GetBuffer();
+ }
+ else
+ {
+// LogType;Filename;Line;Col1;Col2;Message
+ String aSave = VERSION_STRING.Append( UniString::CreateFromInt32( 3 ) ).AppendAscii("\n"); // Version 3
+ SvLBoxEntry *pRun = aEditTree.First();
+ while ( pRun && aEditTree.NextSibling( pRun ) )
+ pRun = aEditTree.NextSibling( pRun );
+
+ aSave.ConvertLineEnd(LINEEND_CRLF);
+ aStrm << ByteString( aSave, RTL_TEXTENCODING_IBM_850 ).GetBuffer();
+
+ SvLBoxEntry *pEntry;
+ while ( pRun )
+ {
+ pEntry = pRun;
+ while ( pEntry && ( pEntry == pRun || LOGTYPE( pEntry ) != LOG_RUN ) )
+ {
+ aSave = Impl_MakeSaveText( pEntry );
+ aSave += '\n';
+ aSave.ConvertLineEnd(LINEEND_CRLF);
+ aStrm << ByteString( aSave, RTL_TEXTENCODING_UTF8 ).GetBuffer();
+ pEntry = aEditTree.Next( pEntry );
+ }
+ pRun = aEditTree.PrevSibling( pRun );
+
+ }
+ }
+ if( aStrm.GetError() != SVSTREAM_OK )
+ bOk = FALSE;
+ else
+ {
+ bModified = FALSE;
+ lModify.Call( NULL );
+ }
+
+ }
+ else
+ bOk = FALSE;
+ return bOk;
+}
+
+
+TTTreeListBox::TTTreeListBox( AppError* pParent, BasicFrame* pBF, WinBits nWinStyle )
+: SvTreeListBox( pParent, nWinStyle )
+, pBasicFrame(pBF)
+, pAppError( pParent )
+//, nDeselectParent(0)
+{}
+
+BOOL TTTreeListBox::JumpToSourcecode( SvLBoxEntry *pThisEntry )
+{
+ if ( pThisEntry && pThisEntry->GetUserData() && ((TTDebugData*)pThisEntry->GetUserData())->aFilename.Len() > 0 )
+ {
+ TTDebugData *aData = (TTDebugData*)pThisEntry->GetUserData();
+ String aFilename = aData->aFilename;
+ if ( aData->aFilename.GetChar(0) == '~' )
+ {
+ if ( aData->aFilename.GetChar(1) == '-' )
+ {
+ aFilename.Erase( 0,2 );
+ }
+ else
+ {
+ aFilename.Erase( 0,1 );
+ DirEntry aConvert( pAppError->aBaseDir );
+ aConvert += DirEntry( aFilename, FSYS_STYLE_VFAT );
+ aFilename = aConvert.GetFull();
+ }
+ }
+
+ if ( pBasicFrame->FindModuleWin( aFilename ) )
+ {
+ AppWin *pWin = pBasicFrame->FindModuleWin( aFilename );
+ pWin->ToTop();
+ }
+ else if ( pBasicFrame->Basic().FindModule( CUniString( "--" ).Append( aFilename ) ) )
+ {
+ SbModule* pMod = pBasicFrame->Basic().FindModule( CUniString( "--" ).Append( aFilename ) );
+ pBasicFrame->CreateModuleWin( pMod );
+ }
+ else
+ pBasicFrame->LoadFile( aFilename );
+
+ if ( pBasicFrame->pWork && pBasicFrame->pWork->ISA(AppEdit) )
+ ((AppEdit*)pBasicFrame->pWork)->Highlight( aData->nLine, aData->nCol1, aData->nCol2 );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL TTTreeListBox::DoubleClickHdl()
+{
+ return JumpToSourcecode( GetHdlEntry() );
+}
+
+/*ULONG TTTreeListBox::SelectChildren( SvLBoxEntry* pParent, BOOL bSelect )
+{
+ SvLBoxEntry *pEntry = FirstChild( pParent );
+ ULONG nRet = 0;
+ while ( pEntry )
+ {
+ nRet++;
+ Select( pEntry, bSelect );
+ pEntry = NextSibling( pEntry );
+ }
+ return nRet;
+}
+
+
+void TTTreeListBox::SelectHdl()
+{
+ SvLBoxEntry* pHdlEntry = GetHdlEntry();
+
+ SelectChildren( pHdlEntry, TRUE );
+ Select( pHdlEntry, TRUE );
+// InitMenu(pApp->GetAppMenu()->GetPopupMenu( RID_APPEDIT )); // So daß Delete richtig ist
+}
+
+void TTTreeListBox::DeselectHdl()
+{
+ SvLBoxEntry* pHdlEntry = GetHdlEntry();
+ if ( GetParent( pHdlEntry ) )
+ {
+ nDeselectParent++;
+ Select( GetParent( pHdlEntry ), FALSE );
+ nDeselectParent--;
+ }
+ if ( !nDeselectParent )
+ {
+ SelectChildren( pHdlEntry, FALSE );
+ Select( pHdlEntry, FALSE );
+ }
+ Invalidate();
+} */
+
+
+void TTTreeListBox::KeyInput( const KeyEvent& rKEvt )
+{
+ switch ( rKEvt.GetKeyCode().GetFunction() )
+ {
+ case KEYFUNC_CUT:
+ Control::GetParent()->Command( CommandEvent( Point(), RID_EDITCUT ) );
+ break;
+ case KEYFUNC_COPY:
+ Control::GetParent()->Command( CommandEvent( Point(), RID_EDITCOPY ) );
+ break;
+ case KEYFUNC_PASTE:
+ Control::GetParent()->Command( CommandEvent( Point(), RID_EDITPASTE ) );
+ break;
+ case KEYFUNC_DELETE:
+ Control::GetParent()->Command( CommandEvent( Point(), RID_EDITDEL ) );
+ break;
+ default:
+ if ( rKEvt.GetKeyCode().GetCode() == KEY_RETURN )
+ JumpToSourcecode( GetCurEntry() );
+ else
+ SvTreeListBox::KeyInput( rKEvt );
+ }
+}
+
+
+TTFeatures TTTreeListBox::GetFeatures( SvLBoxEntry* pEntry )
+{
+ switch ( LOGTYPE( pEntry ) )
+ {
+ case LOG_MESSAGE:
+ return HasNothing;
+ case LOG_WARNING :
+ return HasWarning;
+ case LOG_ERROR:
+ case LOG_CALL_STACK:
+ return HasError;
+ case LOG_RUN:
+ case LOG_TEST_CASE:
+ {
+ SvLBoxEntry* pThisEntry = FirstChild( pEntry );
+ TTFeatures aResult = HasNothing;
+ while ( pThisEntry && !( (aResult & HasError) == HasError ) )
+ {
+ if ( !IsEntryVisible( pThisEntry ) )
+ aResult |= GetFeatures( pThisEntry );
+ pThisEntry = NextSibling( pThisEntry );
+ }
+ return aResult;
+ }
+ case LOG_ASSERTION:
+ case LOG_ASSERTION_STACK:
+ return HasAssertion;
+ case LOG_QA_ERROR:
+ return HasQAError;
+ default:
+ DBG_ERROR("Unknown type in ResultWindow");
+ }
+ return HasNothing;
+}
+
+
+class TTLBoxString : public SvLBoxString
+{
+public:
+
+ TTLBoxString( SvLBoxEntry* pEntry, USHORT nFlags,
+ const String& rStr ) : SvLBoxString(pEntry,nFlags,rStr) {}
+
+ virtual void Paint( const Point& rPos, SvLBox& rDev, USHORT nFlags,
+ SvLBoxEntry* pEntry);
+};
+
+
+void TTLBoxString::Paint( const Point& rPos, SvLBox& rDev, USHORT nFlags,
+ SvLBoxEntry* pEntry )
+{
+ TTFeatures aFeatures = ((TTTreeListBox*)&rDev)->GetFeatures( pEntry );
+
+ Font aOldFont( rDev.GetFont());
+ Font aFont( aOldFont );
+ if ( aFeatures != HasNothing )
+ {
+ Color aCol;
+ if ( ( aFeatures & HasError ) == HasError )
+ aCol = Color( 255, 130, 130 ); // Red
+ else if ( ( aFeatures & HasWarning ) == HasWarning )
+ aCol = Color( 255, 200, 120 ); // Ocker oder so
+ else if ( ( aFeatures & HasAssertion ) == HasAssertion )
+ aCol = Color( 0xd0, 0xd0, 0xff ); // blueish
+ else
+ aCol = Color( 0xd0, 0xff, 0xd0 ); // greenish
+
+ if( rDev.IsSelected(pEntry) )
+ aFont.SetColor( aCol );
+ else
+ {
+ aFont.SetFillColor( aCol );
+ aFont.SetTransparent( FALSE );
+ Color aCol2( COL_BLACK );
+ aFont.SetColor( aCol2 );
+ }
+
+ rDev.SetFont( aFont );
+ rDev.DrawText( rPos, GetText() );
+ }
+ else
+ {
+ if( !rDev.IsSelected(pEntry) )
+ {
+ Color aCol( COL_BLACK );
+ aFont.SetColor( aCol );
+ }
+ rDev.SetFont( aFont );
+ SvLBoxString::Paint( rPos, rDev, nFlags, pEntry );
+ }
+ rDev.SetFont( aOldFont );
+}
+
+
+void TTTreeListBox::InitEntry(SvLBoxEntry* pEntry,
+ const String& rStr ,const Image& rImg1, const Image& rImg2,
+ SvLBoxButtonKind eButtonKind )
+{
+ USHORT nColToHilite = 1; //0==Bitmap;1=="Column1";2=="Column2"
+ SvTreeListBox::InitEntry( pEntry, rStr, rImg1, rImg2, eButtonKind );
+ SvLBoxString* pCol = (SvLBoxString*)pEntry->GetItem( nColToHilite );
+ TTLBoxString* pStr = new TTLBoxString( pEntry, 0, pCol->GetText() );
+ pEntry->ReplaceItem( pStr, nColToHilite );
+}
+
diff --git a/basic/source/app/msgedit.hxx b/basic/source/app/msgedit.hxx
new file mode 100644
index 000000000000..76b085668768
--- /dev/null
+++ b/basic/source/app/msgedit.hxx
@@ -0,0 +1,114 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _MSGEDIT_HXX
+#define _MSGEDIT_HXX
+
+#include <svtools/svtreebx.hxx>
+#include <basic/testtool.hxx>
+#include "dataedit.hxx"
+
+class BasicFrame;
+class AppError;
+
+#define SelectChildren SelectChilds // Sonst wird mir schlecht
+
+typedef USHORT TTFeatures; // Bitfield for features of the entries
+#define HasNothing TTFeatures(0x00)
+#define HasError TTFeatures(0x01)
+#define HasWarning TTFeatures(0x02)
+#define HasAssertion TTFeatures(0x04)
+#define HasQAError TTFeatures(0x08)
+
+
+class TTTreeListBox : public SvTreeListBox
+{
+protected:
+// virtual void Command( const CommandEvent& rCEvt );
+// USHORT nDeselectParent;
+ BasicFrame *pBasicFrame;
+ void InitEntry( SvLBoxEntry*, const String&, const Image&,
+ const Image&, SvLBoxButtonKind eButtonKind );
+ AppError *pAppError;
+
+ BOOL JumpToSourcecode( SvLBoxEntry *pThisEntry );
+
+public:
+ TTTreeListBox( AppError* pParent, BasicFrame* pBF, WinBits nWinStyle=0 );
+ ~TTTreeListBox(){}
+
+// virtual void SelectHdl();
+// virtual void DeselectHdl();
+ virtual BOOL DoubleClickHdl();
+
+ virtual void KeyInput( const KeyEvent& rKEvt );
+
+// ULONG SelectChildren( SvLBoxEntry* pParent, BOOL bSelect );
+ TTFeatures GetFeatures( SvLBoxEntry* );
+};
+
+class MsgEdit : public DataEdit
+{
+ BasicFrame *pBasicFrame;
+
+ SvLBoxEntry *pCurrentRun;
+ SvLBoxEntry *pCurrentTestCase;
+ SvLBoxEntry *pCurrentAssertion;
+ SvLBoxEntry *pCurrentError;
+ BOOL bModified;
+ Link lModify;
+ BOOL bFileLoading; // TRUE while loading a file
+ String Impl_MakeText( SvLBoxEntry *pEntry ) const;
+ String Impl_MakeSaveText( SvLBoxEntry *pEntry ) const;
+ String Impl_MakeSaveText( TTDebugData aData ) const;
+ USHORT nVersion; // Stores file version
+ AppError* pAppError;
+ String aLogFileName;
+
+ static USHORT nMaxLogLen;
+ static BOOL bLimitLogLen;
+ static BOOL bPrintLogToStdout;
+ static BOOL bPrintLogToStdoutSet; // has it been initialized yet
+public:
+ MsgEdit( AppError*, BasicFrame *pBF, const WinBits& );
+ ~MsgEdit();
+ void AddAnyMsg( TTLogMsg *LogMsg );
+ void AddRun( String aMsg, TTDebugData aDebugData );
+ void AddTestCase( String aMsg, TTDebugData aDebugData );
+ void AddError( String aMsg, TTDebugData aDebugData );
+ void AddCallStack( String aMsg, TTDebugData aDebugData );
+ void AddMessage( String aMsg, TTDebugData aDebugData );
+ void AddWarning( String aMsg, TTDebugData aDebugData );
+ void AddAssertion( String aMsg, TTDebugData aDebugData );
+ void AddAssertionStack( String aMsg, TTDebugData aDebugData );
+ void AddQAError( String aMsg, TTDebugData aDebugData );
+
+ static void SetMaxLogLen( USHORT nLen ) { nMaxLogLen = nLen; bLimitLogLen = TRUE; }
+DATA_FUNC_DEF( aEditTree, TTTreeListBox )
+};
+
+#endif
diff --git a/basic/source/app/mybasic.cxx b/basic/source/app/mybasic.cxx
new file mode 100644
index 000000000000..f69c4c468111
--- /dev/null
+++ b/basic/source/app/mybasic.cxx
@@ -0,0 +1,304 @@
+/*************************************************************************
+ *
+ * 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"
+
+#ifndef _MSGBOX_HXX //autogen
+#include <vcl/msgbox.hxx>
+#endif
+#include <basic/sbx.hxx>
+
+// AB-Uno-Test
+//#define unotest
+#ifdef unotest
+#ifndef _USR_UNO_HXX
+#include <usr/uno.hxx>
+#endif
+#include <basic/sbuno.hxx>
+#include <sbunoobj.hxx>
+#endif
+
+#include "sbintern.hxx"
+
+#ifndef _BASIC_TTRESHLP_HXX
+#include <basic/ttstrhlp.hxx>
+#endif
+#include <basic/mybasic.hxx>
+#include "basic.hrc"
+#include "appbased.hxx"
+
+#include "status.hxx"
+#include "basic.hrc"
+
+#include "object.hxx"
+
+#include "processw.hxx"
+#include "basrid.hxx"
+
+TYPEINIT1(MyBasic,StarBASIC)
+
+class MyFactory : public SbxFactory
+{
+public:
+ virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX );
+};
+
+static SampleObjectFac aFac1;
+static MyFactory aFac2;
+static ProcessFactory aProcessFac;
+static short nInst = 0;
+
+SbxBase* MyFactory::Create( UINT16 nSbxId, UINT32 nCr )
+{
+ if( nCr == SBXCR_TEST && nSbxId == SBXID_MYBASIC )
+ return new MyBasic;
+ else
+ return NULL;
+}
+
+MyBasic::MyBasic() : StarBASIC()
+{
+ nError = 0;
+ if( !nInst++ )
+ {
+ AddFactory( &aFac1 );
+ AddFactory( &aFac2 );
+ AddFactory( &aProcessFac );
+ }
+ SbxVariable* p = new SbxCollection( CUniString("MyColl") );
+ p->SetName( CUniString("Objects") );
+ Insert( p );
+
+ // AB-Uno-Test
+#ifdef unotest
+ // Get Uno-Service-Manager and Reflection Service
+ createAndSetDefaultServiceManager(); // done later
+
+ // Get Uno-Test-Object
+ UsrAny aObjAny = getIntrospectionTestObject();
+
+ // Box object into SbUnoObject
+ String aName( "UnoObject" );
+ SbxObjectRef xSbUnoObj = GetSbUnoObject( aName, aObjAny );
+ //SbxObjectRef xSbUnoObj = new SbUnoObject( aName, aObjAny );
+ Insert( (SbxObject*)xSbUnoObj );
+#endif
+
+ pTestObject = NULL;
+}
+
+Link MyBasic::GenLogHdl()
+{
+ return LINK( GetpApp()->GetAppWindow(), BasicFrame, Log );
+}
+
+Link MyBasic::GenWinInfoHdl()
+{
+ return LINK( GetpApp()->GetAppWindow(), BasicFrame, WinInfo );
+}
+
+Link MyBasic::GenModuleWinExistsHdl()
+{
+ return LINK( GetpApp()->GetAppWindow(), BasicFrame, ModuleWinExists );
+}
+
+Link MyBasic::GenWriteStringHdl()
+{
+ return LINK( GetpApp()->GetAppWindow(), BasicFrame, WriteString );
+}
+
+void MyBasic::StartListeningTT( SfxBroadcaster &rBroadcaster )
+{
+ ((BasicFrame*)GetpApp()->GetAppWindow())->StartListening( rBroadcaster );
+}
+
+void MyBasic::SetCompileModule( SbModule *pMod )
+{
+ GetSbData()->pCompMod = pMod;
+}
+
+SbModule *MyBasic::GetCompileModule()
+{
+ return GetSbData()->pCompMod;
+}
+
+String MyBasic::GenRealString( const String &aResString )
+{
+ return ((BasicFrame*)GetpApp()->GetAppWindow())->GenRealString( aResString );
+}
+
+void MyBasic::LoadIniFile()
+{
+}
+
+SbTextType MyBasic::GetSymbolType( const String &rSymbol, BOOL bWasTTControl )
+{
+ (void) rSymbol; /* avoid warning about unused parameter */
+ (void) bWasTTControl; /* avoid warning about unused parameter */
+ return SB_SYMBOL; // Everything here is of type SB_SYMBOL and continues to be so
+}
+
+
+MyBasic::~MyBasic()
+{
+ aErrors.Clear();
+ if( !--nInst )
+ {
+ RemoveFactory( &aFac1 );
+ RemoveFactory( &aFac2 );
+ RemoveFactory( &aProcessFac );
+ }
+}
+
+void MyBasic::Reset()
+{
+ aErrors.Clear();
+ nError = 0;
+}
+
+BOOL MyBasic::Compile( SbModule* p )
+{
+ Reset();
+ return StarBASIC::Compile( p );
+}
+
+BOOL MyBasic::ErrorHdl()
+{
+ AppBasEd* pWin = aBasicApp.pFrame->FindModuleWin( GetActiveModule()->GetName() );
+ if( !pWin )
+ { // open a window
+ pWin = aBasicApp.pFrame->CreateModuleWin( GetActiveModule() );
+ }
+ else
+ pWin->ToTop();
+ if( IsCompilerError() )
+ {
+ aErrors.Insert(
+ new BasicError
+ ( pWin,
+ 0, StarBASIC::GetErrorText(), GetLine(), GetCol1(), GetCol2() ),
+ LIST_APPEND );
+ nError++;
+ return BOOL( nError < 20 ); // Cancel after 20 errors
+ }
+ else
+ {
+ ReportRuntimeError( pWin );
+ return FALSE;
+ }
+}
+
+void MyBasic::ReportRuntimeError( AppBasEd *pEditWin )
+{
+ String nErrorText;
+ nErrorText = GetSpechialErrorText();
+
+ if ( pEditWin ) // just in case the focus is not right
+ pEditWin->ToTop();
+
+ BasicError( pEditWin,
+ GetVBErrorCode( GetErrorCode() ), nErrorText, GetLine(),
+ GetCol1(), GetCol2() ).Show();
+}
+
+void MyBasic::DebugFindNoErrors( BOOL bDebugFindNoErrors )
+{
+ (void) bDebugFindNoErrors; /* avoid warning about unused parameter */
+}
+
+const String MyBasic::GetSpechialErrorText()
+{
+ return GetErrorText();
+}
+
+USHORT MyBasic::BreakHdl()
+{
+ SbModule* pMod = GetActiveModule();
+ if( pMod )
+ {
+ AppBasEd* pWin = aBasicApp.pFrame->FindModuleWin( pMod->GetName() );
+ if( !pWin )
+ { // open a window
+ pWin = aBasicApp.pFrame->CreateModuleWin( pMod );
+ }
+ else
+ pWin->ToTop();
+ pWin->Highlight( GetLine(), GetCol1(), GetCol2() );
+ }
+
+ if( IsBreak() ) // If Breakpoint (or "Run to Cursor")
+ {
+// if ( GetActiveModule()->IsBP(GetLine()) )
+// GetActiveModule()->ClearBP(GetLine());
+ return aBasicApp.pFrame->BreakHandler();
+ }
+ else
+ {
+ return aBasicApp.pFrame->BreakHandler();
+ }
+}
+
+/***************************************************************************
+|*
+|* class BasicError
+|*
+***************************************************************************/
+
+BasicError::BasicError
+ ( AppBasEd* w, USHORT nE, const String& r, USHORT nL, USHORT nC1, USHORT nC2 )
+ : aText( SttResId( IDS_ERROR1 ) )
+{
+ pWin = w;
+ nLine = nL;
+ nCol1 = nC1;
+ nCol2 = nC2;
+ if( nE )
+ {
+ aText += String::CreateFromInt32( nE );
+ aText.AppendAscii(": ");
+ aText += r;
+ }
+ else
+ aText = r;
+}
+
+// This is a sample how to build the error information
+// to highlight a statement
+void BasicError::Show()
+{
+ if( pWin && aBasicApp.pFrame->IsWinValid( pWin ) )
+ {
+ pWin->Highlight( nLine, nCol1, nCol2 );
+ aBasicApp.pFrame->pStatus->Message( aText );
+ }
+ else
+ MessBox( aBasicApp.pFrame, WB_OK, aBasicApp.pFrame->GetText(),
+ aText ).Execute();
+}
+
+
diff --git a/basic/source/app/printer.cxx b/basic/source/app/printer.cxx
new file mode 100644
index 000000000000..0ad562970fe6
--- /dev/null
+++ b/basic/source/app/printer.cxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * 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"
+
+#ifndef _PRINT_HXX //autogen
+#include <vcl/print.hxx>
+#endif
+#ifndef _DIALOG_HXX //autogen
+#include <vcl/dialog.hxx>
+#endif
+#ifndef _FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+#ifndef _BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+#ifndef _BASIC_TTRESHLP_HXX
+#include <basic/ttstrhlp.hxx>
+#endif
+
+#include <algorithm>
+
+#include "app.hxx"
+#include "printer.hxx"
+#include "basic.hrc"
+#include "resids.hrc"
+#include "basrid.hxx"
+
+class PrintingDialog : public ModelessDialog {
+ String aName;
+ FixedText aText;
+ CancelButton aCancel;
+public:
+ PrintingDialog( Window*, BasicPrinter*, ResId&, String& );
+ void ChangeMessage( short );
+};
+
+BasicPrinter::BasicPrinter() : mpPrinter( new Printer() )
+{
+ nPage = 0; nLine = 9999;
+ mpPrinter->SetMapMode( MapMode( MAP_POINT ) );
+ Size s( mpPrinter->GetOutputSize() );
+ // Use 10 point font
+ Font aFont( FAMILY_MODERN, Size( 0, 10 ) );
+ aFont.SetPitch( PITCH_FIXED );
+ mpPrinter->SetFont( aFont );
+ // Output: 6 Lines/Inch = 12 Point
+ nLines = (short) s.Height() / 12;
+ nYoff = 12;
+}
+
+void BasicPrinter::Header()
+{
+ if( nPage ) mpListener->EndPage();
+ nPage++;
+ mpListener->StartPage();
+ String aHdr;
+ String aPage( SttResId( IDS_PAGE ) );
+ aPage.Append( String::CreateFromInt32(nPage) );
+ aHdr = aFile.Copy( 0, 80 - aPage.Len() );
+ aHdr.Expand( 80 - aPage.Len(), ' ' );
+ aHdr += aPage;
+ mpPrinter->DrawText( Point( 0, 0 ), aHdr );
+ nLine = 2;
+}
+
+void BasicPrinter::Print( const String& rFile, const String& rText, BasicFrame *pFrame )
+{
+ nPage = 0; nLine = 9999;
+ aFile = rFile;
+ // Disable PRINT-Menu
+ MenuBar* pBar = pFrame->GetMenuBar();
+ Menu* pFileMenu = pBar->GetPopupMenu( RID_APPFILE );
+ pFileMenu->EnableItem( RID_FILEPRINT, FALSE );
+
+ mpListener.reset( new vcl::OldStylePrintAdaptor( mpPrinter ) );
+ mpListener->StartPage();
+ xub_StrLen nDone=0;
+ while( nDone < rText.Len() )
+ {
+ if( nLine >= nLines ) Header();
+ xub_StrLen nLineEnd = std::min( rText.Search( '\n', nDone ), rText.Search( '\r', nDone ) );
+ mpPrinter->DrawText( Point( 0, nLine * nYoff ), rText, nDone, nLineEnd-nDone-1 );
+ nDone = nLineEnd;
+ if( nDone <= rText.Len() && rText.GetChar(nDone) == '\r' ) nDone++;
+ if( nDone <= rText.Len() && rText.GetChar(nDone) == '\n' ) nDone++;
+ nLine++;
+ }
+ mpListener->EndPage();
+
+ Printer::PrintJob( mpListener, mpPrinter->GetJobSetup() );
+ nPage = 1;
+ pFileMenu->EnableItem( RID_FILEPRINT, TRUE );
+}
+
+
diff --git a/basic/source/app/printer.hxx b/basic/source/app/printer.hxx
new file mode 100644
index 000000000000..505835278234
--- /dev/null
+++ b/basic/source/app/printer.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _BASICPRN_HXX
+#define _BASICPRN_HXX
+
+#include "vcl/print.hxx"
+#include "vcl/oldprintadaptor.hxx"
+
+class BasicPrinter
+{
+ boost::shared_ptr<Printer> mpPrinter;
+ boost::shared_ptr<vcl::OldStylePrintAdaptor> mpListener;
+
+ short nLine; // aktuelle Zeile
+ short nPage; // aktuelle Seite
+ short nLines; // Zeilen pro Seite
+ short nYoff; // Zeilenabstand in Points
+ String aFile; // Dateiname
+
+ void Header(); // Seitenkopf drucken
+ void StartPage();
+public:
+ BasicPrinter();
+ void Print( const String& rFile, const String& rText, BasicFrame *pFrame );
+};
+
+#endif
diff --git a/basic/source/app/process.cxx b/basic/source/app/process.cxx
new file mode 100644
index 000000000000..c37af05ac8da
--- /dev/null
+++ b/basic/source/app/process.cxx
@@ -0,0 +1,229 @@
+/*************************************************************************
+ *
+ * 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"
+
+
+#ifdef WNT
+#include <tools/prewin.h>
+#include "winbase.h"
+#include <tools/postwin.h>
+#endif
+#include <tools/errcode.hxx>
+#include <vos/process.hxx>
+#include <basic/sbxcore.hxx>
+#include <tools/string.hxx>
+#include <osl/file.hxx>
+
+#ifndef _BASIC_TTRESHLP_HXX
+#include <basic/ttstrhlp.hxx>
+#endif
+
+//#ifndef _BYTE_STRING_LIST
+//DECLARE_LIST( ByteStringList, ByteString * );
+//#define _BYTE_STRING_LIST
+//#endif
+
+#include <basic/process.hxx>
+
+Process::Process()
+: pArgumentList( NULL )
+, pEnvList( NULL )
+, pProcess( NULL )
+, bWasGPF( FALSE )
+, bHasBeenStarted( FALSE )
+{
+}
+
+Process::~Process()
+{
+// delete pArgumentList;
+// delete pEnvList;
+ delete pProcess;
+}
+
+
+BOOL Process::ImplIsRunning()
+{
+ if ( pProcess && bHasBeenStarted )
+ {
+ NAMESPACE_VOS(OProcess::TProcessInfo) aProcessInfo;
+ pProcess->getInfo( NAMESPACE_VOS(OProcess::TData_ExitCode), &aProcessInfo );
+ if ( !(aProcessInfo.Fields & NAMESPACE_VOS(OProcess::TData_ExitCode)) )
+ return TRUE;
+ else
+ return FALSE;
+ }
+ else
+ return FALSE;
+}
+
+long Process::ImplGetExitCode()
+{
+ if ( pProcess )
+ {
+ NAMESPACE_VOS(OProcess::TProcessInfo) aProcessInfo;
+ pProcess->getInfo( NAMESPACE_VOS(OProcess::TData_ExitCode), &aProcessInfo );
+ if ( !(aProcessInfo.Fields & NAMESPACE_VOS(OProcess::TData_ExitCode)) )
+ SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
+ return aProcessInfo.Code;
+ }
+ else
+ SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
+ return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+
+void Process::SetImage( const String &aAppPath, const String &aAppParams, const Environment *pEnv )
+{ // Set image file of executable
+ if ( pProcess && ImplIsRunning() )
+ SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
+ else
+ {
+ delete pArgumentList; pArgumentList = NULL;
+ delete pEnvList; pEnvList = NULL;
+ delete pProcess; pProcess = NULL;
+
+ xub_StrLen i, nCount = aAppParams.GetQuotedTokenCount( CUniString("\"\"" ), ' ' );
+ ::rtl::OUString *pParamList = new ::rtl::OUString[nCount];
+
+ xub_StrLen nParamCount = 0;
+ for ( i = 0 ; i < nCount ; i++ )
+ {
+ ::rtl::OUString aTemp = ::rtl::OUString(aAppParams.GetQuotedToken( i, CUniString("\"\"''" ), ' ' ));
+ if ( aTemp.getLength() )
+ {
+ pParamList[nParamCount] = aTemp;
+ nParamCount++;
+ }
+ }
+ pArgumentList = new NAMESPACE_VOS(OArgumentList)( pParamList, nCount );
+
+
+ ::rtl::OUString *pEnvArray = NULL;
+ if ( pEnv )
+ {
+ pEnvArray = new ::rtl::OUString[pEnv->size()];
+
+ xub_StrLen nEnvCount = 0;
+ Environment::const_iterator aIter = pEnv->begin();
+ while ( aIter != pEnv->end() )
+ {
+ ::rtl::OUString aTemp = ::rtl::OUString( (*aIter).first );
+ aTemp += ::rtl::OUString::createFromAscii( "=" );
+ aTemp += ::rtl::OUString( (*aIter).second );
+ pEnvArray[nEnvCount] = aTemp;
+ nEnvCount++;
+ aIter++;
+ }
+ pEnvList = new NAMESPACE_VOS(OEnvironment)( pEnvArray, nEnvCount );
+ }
+
+ ::rtl::OUString aNormalizedAppPath;
+ osl::FileBase::getFileURLFromSystemPath( ::rtl::OUString(aAppPath), aNormalizedAppPath );
+ pProcess = new NAMESPACE_VOS(OProcess)( aNormalizedAppPath );
+ bHasBeenStarted = FALSE;
+
+ delete [] pParamList;
+ delete [] pEnvArray;
+ }
+}
+
+BOOL Process::Start()
+{ // Start program
+ BOOL bSuccess=FALSE;
+ if ( pProcess && !ImplIsRunning() )
+ {
+ bWasGPF = FALSE;
+#ifdef WNT
+// sal_uInt32 nErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_NOALIGNMENTFAULTEXCEPT | SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
+ sal_uInt32 nErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX);
+ try
+ {
+#endif
+ if ( pEnvList )
+ {
+ bSuccess = pProcess->execute( (NAMESPACE_VOS(OProcess)::TProcessOption)
+ ( NAMESPACE_VOS(OProcess)::TOption_SearchPath
+ /*| NAMESPACE_VOS(OProcess)::TOption_Detached*/
+ /*| NAMESPACE_VOS(OProcess)::TOption_Wait*/ ),
+ *pArgumentList,
+ *pEnvList ) == NAMESPACE_VOS(OProcess)::E_None;
+ }
+ else
+ {
+ bSuccess = pProcess->execute( (NAMESPACE_VOS(OProcess)::TProcessOption)
+ ( NAMESPACE_VOS(OProcess)::TOption_SearchPath
+ /*| NAMESPACE_VOS(OProcess)::TOption_Detached*/
+ /*| NAMESPACE_VOS(OProcess)::TOption_Wait*/ ),
+ *pArgumentList ) == NAMESPACE_VOS(OProcess)::E_None;
+ }
+#ifdef WNT
+ }
+ catch( ... )
+ {
+ bWasGPF = TRUE;
+ // TODO: Output debug message !!
+ }
+ nErrorMode = SetErrorMode(nErrorMode);
+#endif
+ bHasBeenStarted = bSuccess;
+ }
+ else
+ SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
+ return bSuccess;
+}
+
+ULONG Process::GetExitCode()
+{ // ExitCode of program after execution
+ return ImplGetExitCode();
+}
+
+BOOL Process::IsRunning()
+{
+ return ImplIsRunning();
+}
+
+BOOL Process::WasGPF()
+{ // Did the process fail?
+#ifdef WNT
+ return ImplGetExitCode() == 3221225477;
+#else
+ return bWasGPF;
+#endif
+}
+
+BOOL Process::Terminate()
+{
+ if ( ImplIsRunning() )
+ return pProcess->terminate() == vos::OProcess::E_None;
+ return TRUE;
+}
+
diff --git a/basic/source/app/processw.cxx b/basic/source/app/processw.cxx
new file mode 100644
index 000000000000..291ea9db33b7
--- /dev/null
+++ b/basic/source/app/processw.cxx
@@ -0,0 +1,282 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#include <basic/sbxobj.hxx>
+#include <basic/sbx.hxx>
+#ifndef __SBX_SBXVARIABLE_HXX //autogen
+#include <basic/sbxvar.hxx>
+#endif
+
+//#include <osl/thread.h>
+#ifndef _BASIC_TTRESHLP_HXX
+#include <basic/ttstrhlp.hxx>
+#endif
+
+#include "processw.hxx"
+
+// Process has the following elements:
+// 1) Properties:
+// none
+// 2) Methods:
+// SetImage( Filename )
+// BOOL Start
+// USHORT GetExitCode
+// BOOL IsRunning
+// BOOL WasGPF
+
+
+// This implementation is a sample for a table driven version that
+// can contain lots of elements. The elements are taken into the object
+// when they are needed.
+
+// The nArgs field of a table entry is scrambled as follows:
+#define _ARGSMASK 0x00FF // Up to 255 arguments
+#define _RWMASK 0x0F00 // Mask for R/W-Bits
+#define _TYPEMASK 0xF000 // Mask for entry type
+
+#define _READ 0x0100 // can be read
+#define _BWRITE 0x0200 // can be used as Lvaluen
+#define _LVALUE _BWRITE
+#define _READWRITE 0x0300 // can read and written
+#define _OPT 0x0400 // TRUE: optional parameter
+#define _METHOD 0x1000 // Mask-Bit for a method
+#define _PROPERTY 0x2000 // Mask-Bit for a property
+#define _COLL 0x4000 // Mask-Bit for a collection
+
+// Combination of the bits above:
+#define _FUNCTION 0x1100 // Mask for a Function
+#define _LFUNCTION 0x1300 // Mask for a Function, that can be uses as Lvalue
+#define _ROPROP 0x2100 // Mask Read Only-Property
+#define _WOPROP 0x2200 // Mask Write Only-Property
+#define _RWPROP 0x2300 // Mask Read/Write-Property
+#define _COLLPROP 0x4100 // Mask Read-Collection-Element
+
+#define COLLNAME "Elements" // Name of the collection, hard coded
+
+
+ProcessWrapper::Methods ProcessWrapper::aProcessMethods[] = {
+// Imagefile of the Executable
+{ "SetImage", SbxEMPTY, &ProcessWrapper::PSetImage, 1 | _FUNCTION },
+ // Two Named Parameter
+ { "Filename", SbxSTRING, NULL, 0 },
+ { "Params", SbxSTRING, NULL, _OPT },
+// Program is started
+{ "Start", SbxBOOL, &ProcessWrapper::PStart, 0 | _FUNCTION },
+// ExitCode of the program
+{ "GetExitCode", SbxULONG, &ProcessWrapper::PGetExitCode, 0 | _FUNCTION },
+// Program is running
+{ "IsRunning", SbxBOOL, &ProcessWrapper::PIsRunning, 0 | _FUNCTION },
+// Program has faulted with GPF etc.
+{ "WasGPF", SbxBOOL, &ProcessWrapper::PWasGPF, 0 | _FUNCTION },
+
+{ NULL, SbxNULL, NULL, -1 }}; // End of table
+
+
+ProcessWrapper::ProcessWrapper() : SbxObject( CUniString("Process") )
+{
+ pProcess = new Process();
+ SetName( CUniString("Process") );
+ pMethods = &aProcessMethods[0];
+}
+
+ProcessWrapper::~ProcessWrapper()
+{
+ delete pProcess;
+}
+
+// Search for an element:
+// Linear search through the method table until an appropriate one
+// can be found.
+// If the the method/property cannot be found, NULL is return
+// without an error code, so that we can ask the whole
+// chain of objects for the method/property.
+SbxVariable* ProcessWrapper::Find( const String& rName, SbxClassType t )
+{
+ // Is the element already available?
+ SbxVariable* pRes = SbxObject::Find( rName, t );
+ if( !pRes && t != SbxCLASS_OBJECT )
+ {
+ // otherwise search
+ Methods* p = pMethods;
+ short nIndex = 0;
+ BOOL bFound = FALSE;
+ while( p->nArgs != -1 )
+ {
+ if( rName.EqualsIgnoreCaseAscii( p->pName ) )
+ {
+ bFound = TRUE; break;
+ }
+ nIndex += ( p->nArgs & _ARGSMASK ) + 1;
+ p = pMethods + nIndex;
+ }
+ if( bFound )
+ {
+ // isolate Args fields:
+ short nAccess = ( p->nArgs & _RWMASK ) >> 8;
+ short nType = ( p->nArgs & _TYPEMASK );
+ String aMethodName( p->pName, RTL_TEXTENCODING_ASCII_US );
+ SbxClassType eCT = SbxCLASS_OBJECT;
+ if( nType & _PROPERTY )
+ eCT = SbxCLASS_PROPERTY;
+ else if( nType & _METHOD )
+ eCT = SbxCLASS_METHOD;
+ pRes = Make( aMethodName, eCT, p->eType );
+ // We set array index + 1 because there are other
+ // default properties that must be activated
+ pRes->SetUserData( nIndex + 1 );
+ pRes->SetFlags( nAccess );
+ }
+ }
+ return pRes;
+}
+
+// Activation of an element or request for an info block
+void ProcessWrapper::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCT,
+ const SfxHint& rHint, const TypeId& rHT )
+{
+ const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
+ if( pHint )
+ {
+ SbxVariable* pVar = pHint->GetVar();
+ SbxArray* pNotifyPar = pVar->GetParameters();
+ USHORT nIndex = (USHORT) pVar->GetUserData();
+ // No index: put through
+ if( nIndex )
+ {
+ ULONG t = pHint->GetId();
+ if( t == SBX_HINT_INFOWANTED )
+ pVar->SetInfo( GetInfo( (short) pVar->GetUserData() ) );
+ else
+ {
+ BOOL bWrite = FALSE;
+ if( t == SBX_HINT_DATACHANGED )
+ bWrite = TRUE;
+ if( t == SBX_HINT_DATAWANTED || bWrite )
+ {
+ // Parameter-Test for methods:
+ USHORT nPar = pMethods[ --nIndex ].nArgs & 0x00FF;
+ // Element 0 is the return value
+ if( ( !pNotifyPar && nPar )
+ || ( pNotifyPar && pNotifyPar->Count() < nPar+1 ) )
+ SetError( SbxERR_WRONG_ARGS );
+ // ready for call
+ else
+ {
+ (this->*(pMethods[ nIndex ].pFunc))( pVar, pNotifyPar, bWrite );
+ }
+ }
+ }
+ }
+ SbxObject::SFX_NOTIFY( rBC, rBCT, rHint, rHT );
+ }
+}
+
+// Building the info struct for single elements
+SbxInfo* ProcessWrapper::GetInfo( short nIdx )
+{
+ Methods* p = &pMethods[ nIdx ];
+ // Wenn mal eine Hilfedatei zur Verfuegung steht:
+ // SbxInfo* pResultInfo = new SbxInfo( Hilfedateiname, p->nHelpId );
+ SbxInfo* pResultInfo = new SbxInfo;
+ short nPar = p->nArgs & _ARGSMASK;
+ for( short i = 0; i < nPar; i++ )
+ {
+ p++;
+ String aMethodName( p->pName, RTL_TEXTENCODING_ASCII_US );
+ USHORT nInfoFlags = ( p->nArgs >> 8 ) & 0x03;
+ if( p->nArgs & _OPT )
+ nInfoFlags |= SBX_OPTIONAL;
+ pResultInfo->AddParam( aMethodName, p->eType, nInfoFlags );
+ }
+ return pResultInfo;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////////
+
+// Properties and methods save the return value in argv[0] (Get, bPut = FALSE)
+// and store the value from argv[0] (Put, bPut = TRUE)
+
+void ProcessWrapper::PSetImage( SbxVariable* pVar, SbxArray* pMethodePar, BOOL bWriteIt )
+{ // Imagefile of the executable
+ (void) pVar; /* avoid warning about unused parameter */
+ (void) bWriteIt; /* avoid warning about unused parameter */
+ if ( pMethodePar->Count() >= 2 )
+ pProcess->SetImage(pMethodePar->Get( 1 )->GetString(), pMethodePar->Get( 2 )->GetString() );
+ else
+ pProcess->SetImage(pMethodePar->Get( 1 )->GetString(), String() );
+}
+
+void ProcessWrapper::PStart( SbxVariable* pVar, SbxArray* pMethodePar, BOOL bWriteIt )
+{ // Program is started
+ (void) pMethodePar; /* avoid warning about unused parameter */
+ (void) bWriteIt; /* avoid warning about unused parameter */
+ pVar->PutBool( pProcess->Start() );
+}
+
+void ProcessWrapper::PGetExitCode( SbxVariable* pVar, SbxArray* pMethodePar, BOOL bWriteIt )
+{ // ExitCode of the program after it was finished
+ (void) pMethodePar; /* avoid warning about unused parameter */
+ (void) bWriteIt; /* avoid warning about unused parameter */
+ pVar->PutULong( pProcess->GetExitCode() );
+}
+
+void ProcessWrapper::PIsRunning( SbxVariable* pVar, SbxArray* pMethodePar, BOOL bWriteIt )
+{ // Program is still running
+ (void) pMethodePar; /* avoid warning about unused parameter */
+ (void) bWriteIt; /* avoid warning about unused parameter */
+ pVar->PutBool( pProcess->IsRunning() );
+}
+
+void ProcessWrapper::PWasGPF( SbxVariable* pVar, SbxArray* pMethodePar, BOOL bWriteIt )
+{ // Program faulted with GPF etc.
+ (void) pMethodePar; /* avoid warning about unused parameter */
+ (void) bWriteIt; /* avoid warning about unused parameter */
+ pVar->PutBool( pProcess->WasGPF() );
+}
+
+
+
+
+
+
+// The factory creates our object
+SbxObject* ProcessFactory::CreateObject( const String& rClass )
+{
+ if( rClass.CompareIgnoreCaseToAscii( "Process" ) == COMPARE_EQUAL )
+ return new ProcessWrapper();
+ return NULL;
+}
+
diff --git a/basic/source/app/processw.hxx b/basic/source/app/processw.hxx
new file mode 100644
index 000000000000..e04396e20809
--- /dev/null
+++ b/basic/source/app/processw.hxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _PROCESSW_HXX
+#define _PROCESSW_HXX
+
+#include <basic/sbxfac.hxx>
+#ifndef __SBX_SBXVARIABLE_HXX //autogen
+#include <basic/sbxvar.hxx>
+#endif
+#include <basic/sbxobj.hxx>
+#include <basic/process.hxx>
+
+class ProcessWrapper : public SbxObject
+{
+using SbxVariable::GetInfo;
+// Definition of a table entry. This is done here because
+// through this methods and property can declared as private.
+#if defined ( ICC ) || defined ( HPUX ) || defined ( C50 ) || defined ( C52 )
+public:
+#endif
+ typedef void( ProcessWrapper::*pMeth )
+ ( SbxVariable* pThis, SbxArray* pArgs, BOOL bWrite );
+#if defined ( ICC ) || defined ( HPUX )
+private:
+#endif
+
+ struct Methods {
+ const char* pName; // Name of the entry
+ SbxDataType eType; // Data type
+ pMeth pFunc; // Function Pointer
+ short nArgs; // Arguments and flags
+ };
+ static Methods aProcessMethods[]; // Method table
+ Methods *pMethods; // Current method table
+
+ void PSetImage( SbxVariable* pVar, SbxArray* pPar, BOOL bWrite );
+ void PStart( SbxVariable* pVar, SbxArray* pPar, BOOL bWrite );
+ void PGetExitCode( SbxVariable* pVar, SbxArray* pPar, BOOL bWrite );
+ void PIsRunning( SbxVariable* pVar, SbxArray* pPar, BOOL bWrite );
+ void PWasGPF( SbxVariable* pVar, SbxArray* pPar, BOOL bWrite );
+
+ // Internal members and methods
+ Process *pProcess;
+
+ // Fill info block
+ SbxInfo* GetInfo( short nIdx );
+
+ // Broadcaster Notification
+ virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType );
+public:
+ ProcessWrapper();
+ ~ProcessWrapper();
+ // Search for an element
+ virtual SbxVariable* Find( const String&, SbxClassType );
+};
+
+// Factory
+class ProcessFactory : public SbxFactory
+{
+public:
+ virtual SbxObject* CreateObject( const String& );
+};
+
+#endif
diff --git a/basic/source/app/resids.hrc b/basic/source/app/resids.hrc
new file mode 100644
index 000000000000..5d3fbb098dde
--- /dev/null
+++ b/basic/source/app/resids.hrc
@@ -0,0 +1,158 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _RESIDS_HRC
+#define _RESIDS_HRC
+
+#define RID_OK 1
+#define RID_CANCEL 2
+#define RID_FILENAME 3
+#define RID_PATHNAME 4
+#define RID_FILELIST 5
+#define RID_DIRSLIST 6
+#define RID_FIND 7
+#define RID_REPLACE 8
+//#define RID_ICON 9
+//#define RID_EDITFIELD 10
+#define RID_TEXT 11
+//#define RID_FRAME1 12
+//#define RID_FRAME2 13
+#define RID_VERSIONSTRING 14
+#define RID_FIXEDTEXT1 15
+#define RID_FIXEDTEXT2 16
+
+
+// OptionsDialog
+#define RES_TC_OPTIONS 20
+
+// GenericOptions
+#define RID_TP_GEN 30
+#define RID_FL_AREA 31
+#define RID_CB_AREA 32
+#define RID_PB_NEW_AREA 33
+#define RID_PD_DEL_AREA 34
+#define RID_FL_VALUE 35
+#define RID_CB_VALUE 36
+#define RID_PB_SELECT_FILE 37
+#define RID_PB_NEW_VALUE 38
+#define RID_PB_DEL_VALUE 39
+
+// ProfileOptions
+#define RID_TP_PRO 40
+#define RID_FL_PROFILE 41
+#define RID_CB_PROFILE 42
+#define RID_PB_NEW_PROFILE 43
+#define RID_PD_DEL_PROFILE 44
+#define FL_DIRECTORIES 45
+#define LOG_TEXT 46
+#define BASIS_TEXT 47
+#define HID_CHECK 48
+#define LOG_NAME 49
+#define BASIS_NAME 50
+#define HID_NAME 51
+#define LOG_SET 52
+#define BASIS_SET 53
+#define HID_SET 54
+#define CB_AUTORELOAD 55
+#define CB_AUTOSAVE 56
+#define CB_STOPONSYNTAXERRORS 57
+
+// Crashreporter Options
+#define RID_TP_CRA 50
+#define FL_CRASHREPORT 51
+#define CB_USEPROXY 52
+#define FT_CRHOST 53
+#define ED_CRHOST 54
+#define FT_CRPORT 55
+#define NF_CRPORT 56
+#define CB_ALLOWCONTACT 57
+#define FT_EMAIL 58
+#define ED_EMAIL 59
+
+// MiscOptions
+#define RID_TP_MIS 60
+#define FL_COMMUNICATION 61
+#define FT_HOST 62
+#define ED_HOST 63
+#define FT_TTPORT 64
+#define NF_TTPORT 65
+#define FT_UNOPORT 66
+#define NF_UNOPORT 67
+#define FL_OTHER 68
+#define TIMEOUT_TEXT 69
+#define SERVER_TIMEOUT 70
+#define FT_LRU 71
+#define TF_MAX_LRU 72
+#define FT_PROGDIR 73
+#define ED_PROGDIR 74
+#define PB_PROGDIR 75
+
+
+// Font Settings
+#define RID_TP_FON 70
+#define FT_FONTNAME 71
+#define CB_FONTNAME 72
+#define FT_FONTSTYLE 73
+#define CB_FONTSTYLE 74
+#define FT_FONTSIZE 75
+#define MB_FONTSIZE 76
+#define FT_PREVIEW 77
+
+// DisplayHId
+#define RID_TB_CONF 80
+#define RID_FT_CONTROLS 81
+#define RID_MLB_CONTROLS 82
+#define RID_FT_SLOTS 83
+#define RID_MLB_SLOTS 84
+#define RID_PB_KOPIEREN 85
+#define RID_PB_BENENNEN 86
+#define RID_PB_SELECTALL 87
+#define RID_OK_CLOSE 88
+
+
+// BreakpointWindow
+#define IMGID_BRKENABLED 30838
+#define IMGID_BRKDISABLED 30839
+#define IMGID_STEPMARKER 30840
+#define IMGID_ERRORMARKER 30841
+
+
+// Edit Variables
+#define RID_FT_NAME 100
+#define RID_FT_CONTENT 101
+#define RID_FT_NEW_CONTENT 102
+#define RID_FT_NAME_VALUE 103
+#define RID_FT_CONTENT_VALUE 104
+
+#define RID_RB_NEW_BOOL_T 105
+#define RID_RB_NEW_BOOL_F 106
+#define RID_NF_NEW_INTEGER 107
+#define RID_NF_NEW_LONG 108
+#define RID_ED_NEW_STRING 109
+
+#endif
+
diff --git a/basic/source/app/status.cxx b/basic/source/app/status.cxx
new file mode 100644
index 000000000000..604fdedfc133
--- /dev/null
+++ b/basic/source/app/status.cxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * 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 "app.hxx"
+#include "basic.hrc"
+#include "appwin.hxx"
+#include "status.hxx"
+
+#include <vcl/decoview.hxx>
+
+StatusLine::StatusLine( BasicFrame* p )
+: TaskBar( p )
+, pFrame( p )
+{
+ // initialize TaskToolBox
+ TaskToolBox* pTempTaskToolBox = GetTaskToolBox();
+ pTempTaskToolBox->SetActivateTaskHdl( LINK( this, StatusLine, ActivateTask ) );
+
+ // initialize TaskStatusBar
+ TaskStatusBar* pTempStatusBar = GetStatusBar();
+ long nCharWidth = GetTextWidth( '0' ); // We state: All numbers has the same width
+ pTempStatusBar->InsertItem( ST_MESSAGE, GetTextWidth( 'X' ) * 20, SIB_LEFT | SIB_IN | SIB_AUTOSIZE );
+ pTempStatusBar->InsertItem( ST_LINE, 5*nCharWidth );
+ pTempStatusBar->InsertItem( ST_PROF, GetTextWidth( 'X' ) * 10 );
+ pTempStatusBar->InsertStatusField();
+
+ Show();
+}
+
+void StatusLine::Message( const String& s )
+{
+ GetStatusBar()->SetItemText( ST_MESSAGE, s );
+}
+
+void StatusLine::Pos( const String& s )
+{
+ GetStatusBar()->SetItemText( ST_LINE, s );
+}
+
+void StatusLine::SetProfileName( const String& s )
+{
+ GetStatusBar()->SetItemText( ST_PROF, s );
+}
+
+
+IMPL_LINK( StatusLine, ActivateTask, TaskToolBox*, pTTB )
+{
+ USHORT nFirstWinPos=0;
+ MenuBar* pMenu = pFrame->GetMenuBar();
+ PopupMenu* pWinMenu = pMenu->GetPopupMenu( RID_APPWINDOW );
+
+ while ( pWinMenu->GetItemId( nFirstWinPos ) < RID_WIN_FILE1 && nFirstWinPos < pWinMenu->GetItemCount() )
+ nFirstWinPos++;
+
+ nFirstWinPos += pTTB->GetItemPos( pTTB->GetCurItemId() ) / 2;
+
+ USHORT x;
+ x = pTTB->GetItemPos( pTTB->GetCurItemId() );
+ x = pWinMenu->GetItemId( nFirstWinPos );
+ x = pWinMenu->GetItemCount();
+ AppWin* pWin = pFrame->FindWin( pWinMenu->GetItemText( pWinMenu->GetItemId( nFirstWinPos ) ).EraseAllChars( L'~' ) );
+ if ( pWin )
+ {
+ pWin->Minimize( FALSE );
+ pWin->ToTop();
+ }
+ return 0;
+}
+
+void StatusLine::LoadTaskToolBox()
+{
+ USHORT nFirstWinPos=0;
+ MenuBar* pMenu = pFrame->GetMenuBar();
+ PopupMenu* pWinMenu = pMenu->GetPopupMenu( RID_APPWINDOW );
+
+ while ( pWinMenu->GetItemId( nFirstWinPos ) < RID_WIN_FILE1 && nFirstWinPos < pWinMenu->GetItemCount() )
+ nFirstWinPos++;
+
+ TaskToolBox* pTaskToolBox = GetTaskToolBox();
+
+ pTaskToolBox->StartUpdateTask();
+
+ while ( nFirstWinPos < pWinMenu->GetItemCount() )
+ { // There are windows
+ Window* pWin = pFrame->FindWin( pWinMenu->GetItemId( nFirstWinPos ) );
+
+ if ( pWin )
+ pTaskToolBox->UpdateTask( Image(), pWin->GetText(), pWin == pFrame->pList->Last() && !( pFrame->pList->Last()->GetWinState() & TT_WIN_STATE_HIDE ) );
+
+ nFirstWinPos++;
+ }
+
+ pTaskToolBox->EndUpdateTask();
+ Resize();
+ Invalidate();
+}
+
+
diff --git a/basic/source/app/status.hxx b/basic/source/app/status.hxx
new file mode 100644
index 000000000000..fd9ab033009e
--- /dev/null
+++ b/basic/source/app/status.hxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _BASICSTATUS_HXX
+#define _BASICSTATUS_HXX
+
+#include <svtools/taskbar.hxx>
+#include <vcl/status.hxx>
+
+#define ST_MESSAGE 1
+#define ST_LINE 2
+#define ST_PROF 3
+
+class BasicFrame;
+
+class StatusLine : public TaskBar
+{
+protected:
+ BasicFrame* pFrame;
+ DECL_LINK( ActivateTask, TaskToolBox* );
+
+public:
+ StatusLine( BasicFrame* );
+ void Message( const String& ); // Show text
+ void Pos( const String& s ); // Show text position
+ void SetProfileName( const String& s ); // Current Profile
+ void LoadTaskToolBox();
+};
+
+#endif
diff --git a/basic/source/app/svtmsg.src b/basic/source/app/svtmsg.src
new file mode 100644
index 000000000000..89686ebfc0ee
--- /dev/null
+++ b/basic/source/app/svtmsg.src
@@ -0,0 +1,339 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#include "svtmsg.hrc"
+
+
+// Hier sind die Messages aus dem Verzeichnis /basic/source/app enhalten
+
+
+///////////////////////////////
+// Fehlermeldungen, die in das Resultfile gelangen.
+// *********************
+// *** !!ACHTUNG!! ***
+// *********************
+// Die Nummern dürfen sich NIE! ändern,
+// da sie in den Resultfiles gespeichert sind, und bei erneutem Anzeigen
+// statdessen die entsprechenden neuen oder garkeine Strings angzeigt werden.
+///////////////////////////////
+String S_GPF_ABORT
+{
+ Text[ en-US ] = "Program aborted with GPF";
+};
+String S_APP_SHUTDOWN
+{
+ Text[ en-US ] = "Application has been shut down";
+};
+String S_SID_EXECUTE_FAILED_NO_DISPATCHER
+{
+ Text[ en-US ] = "Slot ID cannot be executed. No ActiveDispatcher";
+};
+String S_SID_EXECUTE_FAILED
+{
+ Text[ en-US ] = "Slot ID could not be executed";
+};
+String S_UNO_PROPERTY_NITIALIZE_FAILED
+{
+ Text[ en-US ] = "UnoSlot: Properties could not be initialized";
+};
+String S_RESETAPPLICATION_FAILED_COMPLEX
+{
+ Text[ en-US ] = "ResetApplication failed: too complex";
+};
+String S_RESETAPPLICATION_FAILED_UNKNOWN
+{
+ Text[ en-US ] = "ResetApplication failed: unknown window type";
+};
+String S_NO_ACTIVE_WINDOW
+{
+ Text[ en-US ] = "No active window found (GetNextCloseWindow)";
+};
+String S_NO_DIALOG_IN_GETACTIVE
+{
+ Text[ en-US ] = "GetActive does not return a dialog! Inform development";
+};
+String S_NO_POPUP
+{
+ Text[ en-US ] = "Pop-up menu not open";
+};
+String S_NO_SUBMENU
+{
+ Text[ en-US ] = "Submenu does not exist";
+};
+String S_CONTROLTYPE_NOT_SUPPORTED
+{
+ Text[ en-US ] = "ControlType ($Arg1) is not supported";
+};
+String S_SELECTION_BY_ATTRIBUTE_ONLY_DIRECTORIES
+{
+ Text[ en-US ] = "Selection by attributes only possible for directories";
+};
+String S_NO_MORE_FILES
+{
+ Text[ en-US ] = "No more files";
+};
+String S_UNKNOWN_METHOD
+{
+ Text[ en-US ] = "Unknown method '($Arg1)' on ($Arg2)";
+};
+String S_INVALID_PARAMETERS
+{
+ Text[ en-US ] = "Invalid Parameters";
+};
+String S_POINTER_OUTSIDE_APPWIN
+{
+ Text[ en-US ] = "Pointer not inside application window at '($Arg1)'";
+};
+String S_UNKNOWN_COMMAND
+{
+ Text[ en-US ] = "Unknown command '($Arg1)'";
+};
+String S_WIN_NOT_FOUND
+{
+ Text[ en-US ] = "($Arg1) could not be found";
+};
+String S_WIN_INVISIBLE
+{
+ Text[ en-US ] = "($Arg1) is not visible";
+};
+String S_WIN_DISABLED
+{
+ Text[ en-US ] = "($Arg1) could not be accessed. Disabled";
+};
+String S_NUMBER_TOO_BIG
+{
+ Text[ en-US ] = "Entry number ($Arg2) is too large in ($Arg1). Max. allowed is ($Arg3)";
+};
+String S_NUMBER_TOO_SMALL
+{
+ Text[ en-US ] = "The entry number ($Arg2) is too small in ($Arg1). Min allowed is ($Arg3)";
+};
+String S_WINDOW_DISAPPEARED
+{
+ Text[ en-US ] = "Window disappeared in the meantime at ($Arg1)";
+};
+String S_ERROR_SAVING_IMAGE
+{
+ Text[ en-US ] = "Error #($Arg1) when saving the image";
+};
+String S_INVALID_POSITION
+{
+ Text[ en-US ] = "Invalid position at ($Arg1)";
+};
+String S_SPLITWIN_NOT_FOUND
+{
+ Text[ en-US ] = "SplitWindow not found at ($Arg1)";
+};
+String S_INTERNAL_ERROR
+{
+ Text[ en-US ] = "Internal error at ($Arg1)";
+};
+String S_NO_STATUSBAR
+{
+ Text[ en-US ] = "No status bar at ($Arg1)";
+};
+String S_ITEMS_INVISIBLE
+{
+ Text[ en-US ] = "The items are hidden at ($Arg1)";
+};
+String S_TABPAGE_NOT_FOUND
+{
+ Text[ en-US ] = "Tab page not found at ($Arg1)";
+};
+String S_TRISTATE_NOT_ALLOWED
+{
+ Text[ en-US ] = "Tristate cannot be set at ($Arg1)";
+};
+String S_ERROR_IN_SET_TEXT
+{
+ Text[ en-US ] = "Set text did not function";
+};
+String S_ATTEMPT_TO_WRITE_READONLY
+{
+ Text[ en-US ] = "Attempt to write on read-only ($Arg1)";
+};
+String S_NO_SELECT_FALSE
+{
+ Text[ en-US ] = "Select FALSE not allowed. Use MultiSelect at ($Arg1)";
+};
+String S_ENTRY_NOT_FOUND
+{
+ Text[ en-US ] = "\"($Arg2)\" entry at ($Arg1) not found";
+};
+String S_METHOD_FAILED
+{
+ Text[ en-US ] = "($Arg1) of entry \"($Arg2)\" failed";
+};
+String S_HELPID_ON_TOOLBOX_NOT_FOUND
+{
+ Text[ en-US ] = "HelpID in ToolBox not found at ($Arg1)";
+};
+String S_BUTTON_DISABLED_ON_TOOLBOX
+{
+ Text[ en-US ] = "The button is disabled in ToolBox at ($Arg1)";
+};
+String S_BUTTON_HIDDEN_ON_TOOLBOX
+{
+ Text[ en-US ] = "The button is hidden in ToolBox at ($Arg1)";
+};
+String S_CANNOT_MAKE_BUTTON_VISIBLE_IN_TOOLBOX
+{
+ Text[ en-US ] = "Button cannot be made visible in ToolBox at ($Arg1)";
+};
+String S_TEAROFF_FAILED
+{
+ Text[ en-US ] = "TearOff failed in ToolBox at ($Arg1)";
+};
+
+// Has to stay in for old res files
+String S_NO_SELECTED_ENTRY_DEPRECATED
+{
+ Text[ en-US ] = "No entry is selected in TreeListBox at ($Arg1)";
+};
+String S_NO_SELECTED_ENTRY
+{
+ Text[ en-US ] = "No entry is selected in ($Arg2) at ($Arg1)";
+};
+String S_SELECT_DESELECT_VIA_STRING_NOT_IMPLEMENTED
+{
+ Text[ en-US ] = "Select/Deselect with string not implemented at ($Arg1)";
+};
+String S_ALLOWED_ONLY_IN_FLOATING_MODE
+{
+ Text[ en-US ] = "Method only allowed in floating mode at ($Arg1)";
+};
+String S_ALLOWED_ONLY_IN_DOCKING_MODE
+{
+ Text[ en-US ] = "Method only allowed in docking mode at ($Arg1)";
+};
+String S_SIZE_NOT_CHANGEABLE
+{
+ Text[ en-US ] = "Size cannot be altered at ($Arg1)";
+};
+String S_NO_OK_BUTTON
+{
+ Text[ en-US ] = "There is no OK button at ($Arg1)";
+};
+String S_NO_CANCEL_BUTTON
+{
+ Text[ en-US ] = "There is no Cancel button at ($Arg1)";
+};
+String S_NO_YES_BUTTON
+{
+ Text[ en-US ] = "There is no Yes button at ($Arg1)";
+};
+String S_NO_NO_BUTTON
+{
+ Text[ en-US ] = "There is no No button at ($Arg1)";
+};
+String S_NO_RETRY_BUTTON
+{
+ Text[ en-US ] = "There is no Repeat button at ($Arg1)";
+};
+String S_NO_HELP_BUTTON
+{
+ Text[ en-US ] = "There is no Help button at ($Arg1)";
+};
+String S_NO_DEFAULT_BUTTON
+{
+ Text[ en-US ] = "There is no Default button defined at ($Arg1)";
+};
+String S_BUTTON_ID_NOT_THERE
+{
+ Text[ en-US ] = "There is no button with ID ($Arg1) at ($Arg2)";
+};
+String S_BUTTONID_REQUIRED
+{
+ Text[ en-US ] = "A button ID needs to be given at ($Arg1)";
+};
+String S_UNKNOWN_TYPE
+{
+ Text[ en-US ] = "Unknown object type ($Arg1) from UId or method '($Arg2)' not supported";
+};
+String S_UNPACKING_STORAGE_FAILED
+{
+ Text[ en-US ] = "Unpacking storage \"($Arg1)\" to \"($Arg2)\" failed";
+};
+String S_NO_LIST_BOX_BUTTON
+{
+ Text[ en-US ] = "ListBoxButton does not exist in ($Arg1)";
+};
+String S_UNO_URL_EXECUTE_FAILED_NO_DISPATCHER
+{
+ Text[ en-US ] = "UNO URL \"($Arg1)\" could not be executed: No dispatcher was found.";
+};
+String S_UNO_URL_EXECUTE_FAILED_NO_FRAME
+{
+ Text[ en-US ] = "UNO URL \"($Arg1)\" could not be executed: No ActiveFrame on desktop.";
+};
+String S_NO_MENU
+{
+ Text[ en-US ] = "There is no menu at ($Arg1)";
+};
+String S_UNO_URL_EXECUTE_FAILED_DISABLED
+{
+ Text[ en-US ] = "UNO URL \"($Arg1)\" could not be run: Disabled";
+};
+String S_NO_SCROLLBAR
+{
+ Text[ en-US ] = "No scroll bar at ($Arg1)";
+};
+String S_NO_SAX_PARSER
+{
+ Text[ en-US ] = "No SAX Parser when using ($Arg1). Initialize with 'SAXReadFile' first.";
+};
+String S_CANNOT_CREATE_DIRECTORY
+{
+ Text[ en-US ] = "Cannot create Directory: \"($Arg1)\"";
+};
+String S_DIRECTORY_NOT_EMPTY
+{
+ Text[ en-US ] = "Directory has to be Empty to unpack to. Directory: \"($Arg1)\"";
+};
+String S_DEPRECATED
+{
+ Text[ en-US ] = "Deprecated! Please change the script.";
+};
+String S_SIZE_BELOW_MINIMUM
+{
+ Text[ en-US ] = "The Size is below the minimum. x=($Arg1) ,y=($Arg2)";
+};
+String S_CANNOT_FIND_FLOATING_WIN
+{
+ Text[ en-US ] = "Cannot find FloatingWindow for floating DockingWindow at ($Arg1).";
+};
+String S_NO_LIST_BOX_STRING
+{
+ Text[ en-US ] = "String does not exist in ($Arg1)";
+};
+String S_SLOT_IN_EXECUTE
+{
+ Text[ en-US ] = "Another Slot is being executed already.";
+};
+String S_MENU_NOT_CLOSING
+{
+ Text[ en-US ] = "Menu not closing.";
+};
diff --git a/basic/source/app/testbasi.cxx b/basic/source/app/testbasi.cxx
new file mode 100644
index 000000000000..b63986b63b2d
--- /dev/null
+++ b/basic/source/app/testbasi.cxx
@@ -0,0 +1,31 @@
+/*************************************************************************
+ *
+ * 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"
+#define testtool
+#include "mybasic.cxx"
diff --git a/basic/source/app/testtool.idl b/basic/source/app/testtool.idl
new file mode 100644
index 000000000000..acda657881c7
--- /dev/null
+++ b/basic/source/app/testtool.idl
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+module
+"484E40E0-1F23-101C-9961-04021C007002"
+"5A30E000-1F23-101C-9961-04021C007002"
+App
+[
+HelpText( "Test" ),
+TypeLibFile( "testtool.tlb" )
+]
+{
+ interface TestToolAutomation
+ [
+ uuid( "6706E171-FB05-101B-804c-04021c007002" )
+ ]
+ {
+ void Start( String aFilePath );
+ BOOL Call( String aProcName, UINT32 nUId );
+ void Close( );
+ }
+}
+
+
diff --git a/basic/source/app/testtool.src b/basic/source/app/testtool.src
new file mode 100644
index 000000000000..245cff6c7917
--- /dev/null
+++ b/basic/source/app/testtool.src
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#include "testtool.hrc"
+
+
+///////////////////////////////
+// Strings
+///////////////////////////////
+String S_INVALID_KEYCODE
+{
+ Text[ en-US ] = "Is an invalid KeyCode!";
+};
+String S_MANDATORY_FILE
+{
+ Text[ en-US ] = "\ncould not be found.\nThis file is indispensable.";
+};
+String S_READING_LONGNAMES
+{
+ Text[ en-US ] = "Reading long-names";
+};
+String S_READING_SLOT_IDS
+{
+ Text[ en-US ] = "Reading Slot IDs";
+};
+String S_READING_CONTROLS
+{
+ Text[ en-US ] = "Reading Controls";
+};
+String S_READING_BASIC_MODULE
+{
+ Text[ en-US ] = "Reading BASIC module";
+};
+String S_STARTING_APPLICATION
+{
+ Text[ en-US ] = "Starting application";
+};
+
diff --git a/basic/source/app/textedit.cxx b/basic/source/app/textedit.cxx
new file mode 100644
index 000000000000..bd18d4176803
--- /dev/null
+++ b/basic/source/app/textedit.cxx
@@ -0,0 +1,866 @@
+/*************************************************************************
+ *
+ * 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 <svtools/texteng.hxx>
+#include <svtools/textview.hxx>
+#include <svtools/txtattr.hxx>
+#include <basic/sbxmeth.hxx>
+#ifndef _BASIC_TTRESHLP_HXX
+#include <basic/ttstrhlp.hxx>
+#endif
+
+#include "basic.hrc"
+#include "textedit.hxx"
+#include "appedit.hxx"
+#include "brkpnts.hxx"
+#include <basic/testtool.hxx> // defines for syntax highlighting
+
+TextEditImp::TextEditImp( AppEdit* pParent, const WinBits& aBits )
+: Window( pParent, aBits )
+, pAppEdit( pParent )
+, bHighlightning( FALSE )
+, bDoSyntaxHighlight( FALSE )
+, bDelayHighlight( TRUE )
+, nTipId( 0 )
+, bViewMoved( FALSE )
+{
+ pTextEngine = new TextEngine();
+ pTextEngine->SetMaxTextLen( STRING_MAXLEN );
+ pTextEngine->EnableUndo( TRUE );
+
+ pTextView = new TextView( pTextEngine, this );
+ pTextEngine->InsertView( pTextView );
+ pTextEngine->SetModified( FALSE );
+
+ aSyntaxIdleTimer.SetTimeout( 200 );
+ aSyntaxIdleTimer.SetTimeoutHdl( LINK( this, TextEditImp, SyntaxTimerHdl ) );
+
+ aImplSyntaxIdleTimer.SetTimeout( 1 );
+ aImplSyntaxIdleTimer.SetTimeoutHdl( LINK( this, TextEditImp, SyntaxTimerHdl ) );
+
+ StartListening( *pTextEngine );
+
+ HideTipTimer.SetTimeout( 5000 ); // 5 seconds
+ ShowTipTimer.SetTimeout( 500 ); // 1/2 seconds
+ HideTipTimer.SetTimeoutHdl( LINK( this, TextEditImp, HideVarContents ) );
+ ShowTipTimer.SetTimeoutHdl( LINK( this, TextEditImp, ShowVarContents ) );
+}
+
+TextEditImp::~TextEditImp()
+{
+ pTextEngine->RemoveView( pTextView );
+ delete pTextView;
+ delete pTextEngine;
+}
+
+BOOL TextEditImp::ViewMoved()
+{
+ BOOL bOld = bViewMoved;
+ bViewMoved = FALSE;
+ return bOld;
+}
+
+void TextEditImp::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ (void) rBC; /* avoid warning about unused parameter */
+ if ( rHint.ISA( TextHint ) )
+ {
+ const TextHint& rTextHint = (const TextHint&)rHint;
+ if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED )
+ {
+ pAppEdit->pHScroll->SetThumbPos( pTextView->GetStartDocPos().X() );
+ pAppEdit->pVScroll->SetThumbPos( pTextView->GetStartDocPos().Y() );
+ if ( ((TextEdit*)(pAppEdit->pDataEdit))->GetBreakpointWindow() )
+ ((TextEdit*)(pAppEdit->pDataEdit))->GetBreakpointWindow()->Scroll( 0, ((TextEdit*)(pAppEdit->pDataEdit))->GetBreakpointWindow()->GetCurYOffset() - pTextView->GetStartDocPos().Y() );
+ bViewMoved = TRUE;
+ }
+ else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
+ {
+ if ( pTextView->GetStartDocPos().Y() )
+ {
+ long nOutHeight = GetOutputSizePixel().Height();
+ long nTextHeight = pTextEngine->GetTextHeight();
+ if ( nTextHeight < nOutHeight )
+ pTextView->Scroll( 0, pTextView->GetStartDocPos().Y() );
+ }
+
+ pAppEdit->SetScrollBarRanges();
+ }
+ else if( rTextHint.GetId() == TEXT_HINT_TEXTFORMATTED )
+ {
+ ULONG nWidth = pTextEngine->CalcTextWidth();
+ if ( (ULONG)nWidth != pAppEdit->nCurTextWidth )
+ {
+ pAppEdit->nCurTextWidth = nWidth;
+ if ( pAppEdit->pHScroll )
+ { // Initialization finished?
+ pAppEdit->pHScroll->SetRange( Range( 0, (long)nWidth) );
+ pAppEdit->pHScroll->SetThumbPos( pTextView->GetStartDocPos().X() );
+ }
+ }
+ }
+ else if( rTextHint.GetId() == TEXT_HINT_PARAINSERTED )
+ {
+ if ( ((TextEdit*)(pAppEdit->pDataEdit))->GetBreakpointWindow() )
+ ((TextEdit*)(pAppEdit->pDataEdit))->GetBreakpointWindow()->AdjustBreakpoints( rTextHint.GetValue()+1, TRUE );
+ }
+ else if( rTextHint.GetId() == TEXT_HINT_PARAREMOVED )
+ {
+ if ( ((TextEdit*)(pAppEdit->pDataEdit))->GetBreakpointWindow() )
+ ((TextEdit*)(pAppEdit->pDataEdit))->GetBreakpointWindow()->AdjustBreakpoints( rTextHint.GetValue()+1, FALSE );
+
+ // Itchy adaption for two signs at line ends instead of one (hard coded default)
+ pTextEngine->SetMaxTextLen( STRING_MAXLEN - pTextEngine->GetParagraphCount() );
+ }
+ else if( rTextHint.GetId() == TEXT_HINT_FORMATPARA )
+ {
+ DoDelayedSyntaxHighlight(
+ sal::static_int_cast< xub_StrLen >( rTextHint.GetValue() ) );
+ if ( pTextView->GetTextEngine()->IsModified() )
+ ModifyHdl.Call( NULL );
+ }
+ }
+}
+
+#define TEXTATTR_SPECHIAL 55
+class TextAttribSpechial : public TextAttrib
+{
+private:
+ FontWeight maFontWeight;
+
+public:
+ TextAttribSpechial( const FontWeight& rFontWeight );
+ TextAttribSpechial( const TextAttribSpechial& rAttr );
+ ~TextAttribSpechial() {;}
+
+ virtual void SetFont( Font& rFont ) const;
+ virtual TextAttrib* Clone() const;
+ virtual int operator==( const TextAttrib& rAttr ) const;
+};
+
+TextAttribSpechial::TextAttribSpechial( const FontWeight& rFontWeight )
+ : TextAttrib( TEXTATTR_SPECHIAL ), maFontWeight( rFontWeight )
+{}
+
+TextAttribSpechial::TextAttribSpechial( const TextAttribSpechial& rAttr )
+ : TextAttrib( rAttr ), maFontWeight( rAttr.maFontWeight )
+{}
+
+void TextAttribSpechial::SetFont( Font& rFont ) const
+{
+ rFont.SetWeight( maFontWeight );
+}
+
+TextAttrib* TextAttribSpechial::Clone() const
+{
+ return new TextAttribSpechial( *this );
+}
+
+int TextAttribSpechial::operator==( const TextAttrib& rAttr ) const
+{
+ return ( ( TextAttrib::operator==(rAttr ) ) &&
+ ( maFontWeight == ((const TextAttribSpechial&)rAttr).maFontWeight ) );
+}
+
+void TextEditImp::ImpDoHighlight( const String& rSource, ULONG nLineOff )
+{
+ SbTextPortions aPortionList;
+ pAppEdit->GetBasicFrame()->Basic().Highlight( rSource, aPortionList );
+
+ USHORT nCount = aPortionList.Count();
+ if ( !nCount )
+ return;
+
+ SbTextPortion& rLast = aPortionList[nCount-1];
+ if ( rLast.nStart > rLast.nEnd ) // Nur bis Bug von MD behoben
+ {
+#if OSL_DEBUG_LEVEL > 1
+ DBG_ERROR( "MD-Bug nicht beseitigt!" );
+#endif
+ nCount--;
+ aPortionList.Remove( nCount);
+ if ( !nCount )
+ return;
+ }
+
+ // here is the postprocessing for types for the TestTool
+ USHORT i;
+ BOOL bWasTTControl = FALSE;
+ for ( i = 0; i < aPortionList.Count(); i++ )
+ {
+ SbTextPortion& r = aPortionList[i];
+// DBG_ASSERT( r.nStart <= r.nEnd, "Highlight: Start > End?" );
+ if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoben
+ continue;
+
+ SbTextType eType = r.eType;
+ Color aColor;
+ switch ( eType )
+ {
+ case SB_SYMBOL:
+ {
+ String aSymbol = rSource.Copy( r.nStart, r.nEnd - r.nStart +1 );
+ r.eType = pAppEdit->GetBasicFrame()->Basic().GetSymbolType( aSymbol, bWasTTControl );
+
+ if ( r.eType == TT_CONTROL )
+ bWasTTControl = TRUE;
+ else
+ bWasTTControl = FALSE;
+ }
+ break;
+ case SB_PUNCTUATION:
+ {
+ String aPunctuation = rSource.Copy( r.nStart, r.nEnd - r.nStart +1 );
+ if ( aPunctuation.CompareToAscii( "." ) != COMPARE_EQUAL )
+ bWasTTControl = FALSE;
+ }
+ break;
+ default:
+ bWasTTControl = FALSE;
+ }
+ }
+
+ // Es muessen nur die Blanks und Tabs mit attributiert werden.
+ // If there are two equal attributes one after another,
+ // they are optimized by the EditEngine.
+ xub_StrLen nLastEnd = 0;
+#ifdef DBG_UTIL
+ xub_StrLen nLine1 = aPortionList[0].nLine;
+#endif
+ for ( i = 0; i < nCount; i++ )
+ {
+ SbTextPortion& r = aPortionList[i];
+ DBG_ASSERT( r.nLine == nLine1, "doch mehrere Zeilen ?" );
+ DBG_ASSERT( r.nStart <= r.nEnd, "Highlight: Start > End?" );
+ if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoben
+ continue;
+
+ if ( r.nStart > nLastEnd )
+ {
+ // Kann ich mich drauf verlassen, dass alle ausser
+ // Blank und Tab gehighlightet wird ?!
+ r.nStart = nLastEnd;
+ }
+ nLastEnd = r.nEnd+1;
+ if ( ( i == (nCount-1) ) && ( r.nEnd < rSource.Len() ) )
+ r.nEnd = rSource.Len()-1;
+ }
+
+ BOOL bWasModified = pTextEngine->IsModified();
+ for ( i = 0; i < aPortionList.Count(); i++ )
+ {
+ SbTextPortion& r = aPortionList[i];
+// DBG_ASSERT( r.nStart <= r.nEnd, "Highlight: Start > End?" );
+ if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoben
+ continue;
+
+ SbTextType eCol = r.eType;
+ Color aColor;
+ ULONG nLine = nLineOff+r.nLine-1; // -1, because BASIC starts with 1
+ switch ( +eCol )
+ {
+ case SB_KEYWORD:
+ aColor = Color( COL_BLUE );
+ break;
+ case SB_SYMBOL:
+ aColor = Color( RGB_COLORDATA( 0x00, 0x60, 0x00 ) );
+ break;
+ case SB_STRING:
+ aColor = Color( COL_RED );
+ break;
+ case SB_NUMBER:
+ aColor = Color( COL_MAGENTA );
+ break;
+ case SB_PUNCTUATION:
+ aColor = Color( COL_BLACK );
+ break;
+ case SB_COMMENT:
+ aColor = Color( COL_GRAY );
+ break;
+ case TT_KEYWORD:
+ case TT_LOCALCMD:
+ aColor = Color( COL_LIGHTBLUE );
+ break;
+ case TT_REMOTECMD:
+ aColor = Color( RGB_COLORDATA( 0x00, 0xB0, 0xB0 ) );
+ break;
+ case TT_CONTROL:
+ case TT_SLOT:
+ aColor = Color( RGB_COLORDATA( 0x00, 0xB0, 0x00 ) );
+ break;
+ case TT_METHOD:
+ aColor = Color( RGB_COLORDATA( 0x00, 0xB0, 0x00 ) );
+ break;
+ case TT_NOMETHOD:
+ {
+ aColor = Color( COL_RED );
+ pTextEngine->SetAttrib( TextAttribSpechial( WEIGHT_BOLD ), nLine, r.nStart, r.nEnd+1 );
+ }
+ break;
+ default:
+ {
+ aColor = Color( RGB_COLORDATA( 0xff, 0x80, 0x80 ) );
+ DBG_ERROR( "Unknown syntax color" );
+ }
+ }
+ pTextEngine->SetAttrib( TextAttribFontColor( aColor ), nLine, r.nStart, r.nEnd+1 );
+ }
+ // Highlighting should not modify the text
+ pTextEngine->SetModified( bWasModified );
+}
+
+void TextEditImp::DoSyntaxHighlight( ULONG nPara )
+{
+ // Due to delayed syntax highlight it can happend that the
+ // paragraph does no longer exist
+ if ( nPara < pTextEngine->GetParagraphCount() )
+ {
+ // leider weis ich nicht, ob genau diese Zeile Modified() ...
+// if ( pProgress )
+// pProgress->StepProgress();
+ pTextEngine->RemoveAttribs( nPara );
+ String aSource( pTextEngine->GetText( nPara ) );
+ ImpDoHighlight( aSource, nPara );
+ }
+}
+
+void TextEditImp::DoDelayedSyntaxHighlight( xub_StrLen nPara )
+{
+ // Paragraph is added to 'List', processed in TimerHdl.
+ // => Do not manipulate paragraphs while EditEngine is formatting
+// if ( pProgress )
+// pProgress->StepProgress();
+
+ if ( !bHighlightning && bDoSyntaxHighlight )
+ {
+ if ( bDelayHighlight )
+ {
+ aSyntaxLineTable.Insert( nPara, (void*)(ULONG)1 );
+ aSyntaxIdleTimer.Start();
+ }
+ else
+ DoSyntaxHighlight( nPara );
+ }
+}
+
+IMPL_LINK( TextEditImp, SyntaxTimerHdl, Timer *, EMPTYARG )
+{
+ DBG_ASSERT( pTextView, "Not yet a View but Syntax-Highlight ?!" );
+ pTextEngine->SetUpdateMode( FALSE );
+
+ bHighlightning = TRUE;
+ USHORT nLine;
+ while ( aSyntaxLineTable.First() && !Application::AnyInput( INPUT_MOUSEANDKEYBOARD ) )
+ {
+ nLine = (USHORT)aSyntaxLineTable.GetCurKey();
+ DoSyntaxHighlight( nLine );
+ aSyntaxLineTable.Remove( nLine );
+/* if ( Application::AnyInput() )
+ {
+ aSyntaxIdleTimer.Start(); // Starten, falls wir in einem Dialog landen
+ pTextView->ShowCursor( TRUE, TRUE );
+ pTextEngine->SetUpdateMode( TRUE );
+ bHighlightning = FALSE;
+ GetpApp()->Reschedule();
+ bHighlightning = TRUE;
+ pTextEngine->SetUpdateMode( FALSE );
+ }*/
+ }
+
+ BOOL bWasModified = pTextEngine->IsModified();
+ if ( aSyntaxLineTable.Count() > 3 ) // Without VDev
+ {
+ pTextEngine->SetUpdateMode( TRUE );
+ pTextView->ShowCursor( TRUE, TRUE );
+ }
+ else
+ pTextEngine->SetUpdateMode( TRUE ); // ! With VDev
+// pTextView->ForceUpdate();
+
+ // SetUpdateMode( TRUE ) soll kein Modify setzen
+ pTextEngine->SetModified( bWasModified );
+
+ // SyntaxTimerHdl wird gerufen, wenn Text-Aenderung
+ // => gute Gelegenheit, Textbreite zu ermitteln!
+// long nPrevTextWidth = nCurTextWidth;
+// nCurTextWidth = pTextEngine->CalcTextWidth();
+// if ( nCurTextWidth != nPrevTextWidth )
+// SetScrollBarRanges();
+ bHighlightning = FALSE;
+
+ if ( aSyntaxLineTable.First() )
+ aImplSyntaxIdleTimer.Start();
+
+// while ( Application::AnyInput() )
+// Application::Reschedule(); // Reschedule, da der UserEvent keine Paints etc. durchlässt
+
+ return 0;
+}
+
+void TextEditImp::InvalidateSyntaxHighlight()
+{
+ for ( xub_StrLen i = 0; i < pTextEngine->GetParagraphCount(); i++ )
+ DoDelayedSyntaxHighlight( i );
+}
+
+void TextEditImp::SyntaxHighlight( BOOL bNew )
+{
+ if ( ( bNew && bDoSyntaxHighlight ) || ( !bNew && !bDoSyntaxHighlight ) )
+ return;
+
+ bDoSyntaxHighlight = bNew;
+ if ( !pTextEngine )
+ return;
+
+
+ if ( bDoSyntaxHighlight )
+ {
+ InvalidateSyntaxHighlight();
+ }
+ else
+ {
+ aSyntaxIdleTimer.Stop();
+ pTextEngine->SetUpdateMode( FALSE );
+ for ( ULONG i = 0; i < pTextEngine->GetParagraphCount(); i++ )
+ pTextEngine->RemoveAttribs( i );
+
+// pTextEngine->QuickFormatDoc();
+ pTextEngine->SetUpdateMode( TRUE );
+ pTextView->ShowCursor(TRUE, TRUE );
+ }
+}
+
+
+void TextEditImp::SetFont( const Font& rNewFont )
+{
+ pTextEngine->SetFont(rNewFont);
+}
+
+BOOL TextEditImp::IsModified()
+{
+ return pTextEngine->IsModified();
+}
+
+void TextEditImp::KeyInput( const KeyEvent& rKeyEvent )
+{
+ BOOL bWasModified = pTextView->GetTextEngine()->IsModified();
+ pTextView->GetTextEngine()->SetModified( FALSE );
+
+ if ( !pTextView->KeyInput( rKeyEvent ) )
+ Window::KeyInput( rKeyEvent );
+
+ if ( pTextView->GetTextEngine()->IsModified() )
+ ModifyHdl.Call( NULL );
+ else
+ pTextView->GetTextEngine()->SetModified( bWasModified );
+}
+
+void TextEditImp::Paint( const Rectangle& rRect ){ pTextView->Paint( rRect );}
+void TextEditImp::MouseButtonUp( const MouseEvent& rMouseEvent ){ pTextView->MouseButtonUp( rMouseEvent );}
+//void TextEditImp::MouseButtonDown( const MouseEvent& rMouseEvent ){ pTextView->MouseButtonDown( rMouseEvent );}
+//void TextEditImp::MouseMove( const MouseEvent& rMouseEvent ){ pTextView->MouseMove( rMouseEvent );}
+//void TextEditImp::Command( const CommandEvent& rCEvt ){ pTextView->Command( rCEvt );}
+//BOOL TextEditImp::Drop( const DropEvent& rEvt ){ return FALSE /*pTextView->Drop( rEvt )*/;}
+//BOOL TextEditImp::QueryDrop( DropEvent& rEvt ){ return FALSE /*pTextView->QueryDrop( rEvt )*/;}
+
+
+void TextEditImp::Command( const CommandEvent& rCEvt )
+{
+ switch( rCEvt.GetCommand() ) {
+ case COMMAND_CONTEXTMENU:
+ case COMMAND_WHEEL:
+ GetParent()->Command( rCEvt );
+ break;
+ default:
+ pTextView->Command( rCEvt );
+ }
+}
+
+
+void TextEditImp::MouseButtonDown( const MouseEvent& rMouseEvent )
+{
+ pTextView->MouseButtonDown( rMouseEvent );
+ HideVarContents( NULL );
+ ShowTipTimer.Stop();
+}
+
+
+void TextEditImp::MouseMove( const MouseEvent& rMEvt )
+{
+ pTextView->MouseMove( rMEvt );
+ HideVarContents( NULL );
+ if ( rMEvt.GetButtons() == 0 )
+ ShowTipTimer.Start();
+ if ( rMEvt.IsLeaveWindow() )
+ ShowTipTimer.Stop();
+}
+
+
+IMPL_LINK( TextEditImp, HideVarContents, void*, EMPTYARG )
+{
+ if ( nTipId )
+ {
+ Help::HideTip( nTipId );
+ nTipId = 0;
+ aTipWord = String();
+ }
+ return 0;
+}
+
+static const char cSuffixes[] = "%&!#@$";
+
+
+SbxBase* TextEditImp::GetSbxAtMousePos( String &aWord )
+{
+ Point aPos = GetPointerPosPixel();
+ Point aDocPos = pTextView->GetDocPos( aPos );
+ aWord = pTextEngine->GetWord( pTextEngine->GetPaM( aDocPos ) );
+
+ if ( aWord.Len() /*&& !Application::GetAppInternational().IsNumeric( aWord )*/ )
+ {
+ xub_StrLen nLastChar = aWord.Len()-1;
+ String aSuffixes = CUniString( cSuffixes );
+ if ( aSuffixes.Search( aWord.GetChar(nLastChar) ) != STRING_NOTFOUND )
+ aWord.Erase( nLastChar, 1 );
+ // because perhaps TestTools throws an error
+ BOOL bWasError = SbxBase::IsError();
+ pAppEdit->GetBasicFrame()->Basic().DebugFindNoErrors( TRUE );
+ SbxBase* pSBX = StarBASIC::FindSBXInCurrentScope( aWord );
+ pAppEdit->GetBasicFrame()->Basic().DebugFindNoErrors( FALSE );
+ DBG_ASSERT( !( !bWasError && SbxBase::IsError()), "Error generated while retrieving Variable data for viewing" );
+ if ( !bWasError && SbxBase::IsError() )
+ SbxBase::ResetError();
+
+ return pSBX;
+ }
+ return NULL;
+}
+
+
+IMPL_LINK( TextEditImp, ShowVarContents, void*, EMPTYARG )
+{
+ String aWord;
+ SbxBase* pSBX = GetSbxAtMousePos( aWord );
+ String aHelpText;
+ Point aPos = GetPointerPosPixel();
+
+ if ( pSBX && pSBX->ISA( SbxVariable ) && !pSBX->ISA( SbxMethod ) )
+ {
+ SbxVariable* pVar = (SbxVariable*)pSBX;
+ SbxDataType eType = pVar->GetType();
+ if ( eType == SbxOBJECT )
+ {
+ // Can cause a crash: Type == Object does not mean pVar == Object
+ if ( pVar->GetObject() && pVar->GetObject()->ISA( SbxObject ) )
+ aHelpText = ((SbxObject*)(pVar->GetObject()))->GetClassName();
+ else
+ aHelpText = CUniString("Object");
+ }
+ else if ( eType & SbxARRAY )
+ aHelpText = CUniString("{...}");
+ else if ( eType != SbxEMPTY )
+ {
+ aHelpText = pVar->GetName();
+ if ( !aHelpText.Len() ) // Name is not copied in arguments
+ aHelpText = aWord;
+ aHelpText += '=';
+ aHelpText += pVar->GetString();
+ }
+ }
+
+
+ if ( aHelpText.Len() && aTipPos != aPos && aTipWord != aWord )
+ {
+ if ( nTipId )
+ Help::HideTip( nTipId );
+ nTipId = Help::ShowTip( this, Rectangle(), aHelpText );
+
+ HideTipTimer.Start();
+ aTipWord = aWord;
+ aTipPos = aPos;
+ }
+ if ( nTipId && aTipPos != aPos )
+ {
+ Help::HideTip( nTipId );
+ nTipId = 0;
+ aTipWord = String();
+ }
+
+ return 0;
+}
+
+
+void TextEditImp::BuildKontextMenu( PopupMenu *&pMenu )
+{
+ String aWord;
+ SbxBase* pSBX = GetSbxAtMousePos( aWord );
+ if ( pSBX && pSBX->ISA( SbxVariable ) && !pSBX->ISA( SbxMethod ) )
+ {
+ SbxVariable* pVar = (SbxVariable*)pSBX;
+ SbxDataType eType = pVar->GetType();
+
+ if ( ( eType & ( SbxVECTOR | SbxARRAY | SbxBYREF )) == 0 )
+ {
+
+/*
+Boolean
+Currency
+Date
+Double
+Integer
+Long
+Object
+Single
+String
+Variant(Empty)
+*/
+ switch ( eType )
+ {
+ case SbxBOOL:
+// case SbxCURRENCY:
+// case SbxDATE:
+ case SbxDOUBLE:
+ case SbxINTEGER:
+ case SbxLONG:
+// case SbxOBJECT: // cannot be edited
+ case SbxSINGLE:
+ case SbxSTRING:
+
+ case SbxVARIANT: // does not occure, instead SbxEMPTY
+ case SbxEMPTY:
+ {
+ pAppEdit->GetBasicFrame()->SetEditVar( pVar );
+ if ( !pMenu )
+ pMenu = new PopupMenu();
+ else
+ pMenu->InsertSeparator();
+
+ pMenu->InsertItem( RID_POPUPEDITVAR, ((BasicFrame*)GetpApp()->GetAppWindow())->GenRealString( GEN_RES_STR1( IDS_EDIT_VAR, aWord ) ) );
+ }
+ break;
+ default:
+ ;
+ }
+ }
+ }
+}
+
+
+
+
+DBG_NAME(TextEdit)
+
+TextEdit::TextEdit( AppEdit* pParent, const WinBits& aBits )
+: pBreakpointWindow( NULL )
+, bFileWasUTF8( FALSE )
+, bSaveAsUTF8( FALSE )
+, aEdit( pParent, aBits | WB_NOHIDESELECTION )
+{
+DBG_CTOR(TextEdit,0);
+}
+
+TextEdit::~TextEdit()
+{DBG_DTOR(TextEdit,0);}
+
+void TextEdit::Highlight( ULONG nLine, xub_StrLen nCol1, xub_StrLen nCol2 )
+{
+ if ( nLine ) // Should not occure but at 'Sub expected' in first line
+ nLine--;
+
+ String s = aEdit.pTextEngine->GetText( nLine );
+
+ if( nCol1 == STRING_NOTFOUND )
+ {
+ // No column given
+ nCol1 = 0;
+ nCol2 = STRING_NOTFOUND;
+ }
+ if( nCol2 == STRING_NOTFOUND )
+ {
+ nCol2 = s.Len();
+ }
+ // Adaption to the Precompiler | EditText != Compilied Text
+ if ( nCol2 > s.Len() )
+ nCol2 = s.Len();
+ if ( nCol1 >= nCol2 )
+ nCol1 = 0;
+
+ // Because nCol2 *may* point after the current statement
+ // (because the next one starts there) there are space
+ // that must be removed
+ BOOL bColon = FALSE;
+
+ while ( s.GetChar( nCol2 ) == ' ' && nCol2 > nCol1 && !bColon )
+ {
+ nCol2--;
+ if ( s.GetChar( nCol2 ) == ':' )
+ {
+ nCol2--;
+ bColon = TRUE;
+ }
+ }
+
+ aEdit.ViewMoved();
+ aEdit.pTextView->SetSelection( TextSelection(TextPaM(nLine,nCol2+1), TextPaM(nLine,nCol1)) );
+ if ( aEdit.ViewMoved() )
+ {
+ aEdit.pTextView->SetSelection( TextSelection(TextPaM(TEXT_PARA_ALL,1)) ); // fix #105169#
+ aEdit.pTextView->SetSelection( TextSelection(TextPaM((nLine>=2?nLine-2:0),nCol2+1)) );
+ aEdit.pTextView->SetSelection( TextSelection(TextPaM(nLine,nCol2+1), TextPaM(nLine,nCol1)) );
+ }
+}
+
+
+void TextEdit::Delete(){ aEdit.pTextView->KeyInput( KeyEvent( 0, KeyCode( KEYFUNC_DELETE ) )); }
+void TextEdit::Cut(){ aEdit.pTextView->Cut(); }
+void TextEdit::Copy(){ aEdit.pTextView->Copy(); }
+void TextEdit::Paste(){ aEdit.pTextView->Paste(); }
+void TextEdit::Undo(){ aEdit.pTextView->Undo(); }
+void TextEdit::Redo(){ aEdit.pTextView->Redo(); }
+String TextEdit::GetSelected(){ return aEdit.pTextView->GetSelected(); }
+TextSelection TextEdit::GetSelection() const{ return aEdit.pTextView->GetSelection(); }
+void TextEdit::SetSelection( const TextSelection& rSelection ){ aEdit.pTextView->SetSelection( rSelection ); }
+
+USHORT TextEdit::GetLineNr() const
+{
+ return sal::static_int_cast< USHORT >(
+ aEdit.pTextView->GetSelection().GetEnd().GetPara()+1);
+}
+
+void TextEdit::ReplaceSelected( const String& rStr ){ aEdit.pTextView->InsertText(rStr); }
+BOOL TextEdit::IsModified(){ return aEdit.IsModified(); }
+
+String TextEdit::GetText() const
+{
+ return aEdit.pTextEngine->GetText( GetSystemLineEnd() );
+}
+
+void TextEdit::SetText( const String& rStr ){ aEdit.pTextEngine->SetText(rStr); aEdit.pTextEngine->SetModified( FALSE ); }
+void TextEdit::SetModifyHdl( Link l ){ aEdit.SetModifyHdl(l); }
+BOOL TextEdit::HasText() const { return aEdit.pTextEngine->GetTextLen() > 0; }
+
+// Search from the beginning or at mark + 1
+BOOL TextEdit::Find( const String& s )
+{
+ DBG_CHKTHIS(TextEdit,0);
+
+ TextSelection aSelection = aEdit.pTextView->GetSelection();
+ ULONG nPara = aSelection.GetStart().GetPara();
+ xub_StrLen nIndex = aSelection.GetStart().GetIndex();
+
+ if ( aSelection.HasRange() )
+ nIndex ++;
+
+ while ( nPara <= aEdit.pTextEngine->GetParagraphCount() )
+ {
+ String aText = aEdit.pTextEngine->GetText( nPara );
+
+ nIndex = aText.Search( s, nIndex );
+ if( nIndex != STRING_NOTFOUND )
+ {
+ aEdit.pTextView->SetSelection( TextSelection( TextPaM( nPara, nIndex ), TextPaM( nPara, nIndex + s.Len() ) ) );
+ return TRUE;
+ }
+ nIndex = 0;
+ nPara++;
+ }
+ return FALSE;
+}
+
+BOOL TextEdit::Load( const String& aName )
+{
+DBG_CHKTHIS(TextEdit,0);
+ BOOL bOk = TRUE;
+ SvFileStream aStrm( aName, STREAM_STD_READ );
+ if( aStrm.IsOpen() )
+ {
+ String aText, aLine, aLineBreak;
+ BOOL bIsFirstLine = TRUE;
+ aLineBreak += '\n';
+ aLineBreak.ConvertLineEnd();
+ rtl_TextEncoding aFileEncoding = RTL_TEXTENCODING_IBM_850;
+ while( !aStrm.IsEof() && bOk )
+ {
+ aStrm.ReadByteStringLine( aLine, aFileEncoding );
+ if ( bIsFirstLine && IsTTSignatureForUnicodeTextfile( aLine ) )
+ {
+ aFileEncoding = RTL_TEXTENCODING_UTF8;
+ bFileWasUTF8 = TRUE;
+ }
+ else
+ {
+ if ( !bIsFirstLine )
+ aText += aLineBreak;
+ aText += aLine;
+ bIsFirstLine = FALSE;
+ }
+ if( aStrm.GetError() != SVSTREAM_OK )
+ bOk = FALSE;
+ }
+ SetText( aText );
+ }
+ else
+ bOk = FALSE;
+ return bOk;
+}
+
+BOOL TextEdit::Save( const String& aName )
+{
+DBG_CHKTHIS(TextEdit,0);
+ BOOL bOk = TRUE;
+ SvFileStream aStrm( aName, STREAM_STD_WRITE | STREAM_TRUNC );
+ rtl_TextEncoding aFileEncoding = RTL_TEXTENCODING_IBM_850;
+ if( aStrm.IsOpen() )
+ {
+ if ( bFileWasUTF8 || bSaveAsUTF8 )
+ {
+ aStrm << TT_SIGNATURE_FOR_UNICODE_TEXTFILES;
+ aStrm << sal_Char(_LF);
+ aFileEncoding = RTL_TEXTENCODING_UTF8;
+ }
+ String aSave = GetText();
+ aSave.ConvertLineEnd(LINEEND_LF);
+ aStrm << ByteString( aSave, aFileEncoding ).GetBuffer();
+ if( aStrm.GetError() != SVSTREAM_OK )
+ bOk = FALSE;
+ else
+ aEdit.pTextEngine->SetModified(FALSE);
+ } else bOk = FALSE;
+ return bOk;
+}
+
+
+void TextEdit::BuildKontextMenu( PopupMenu *&pMenu )
+{
+ DataEdit::BuildKontextMenu( pMenu );
+ aEdit.BuildKontextMenu( pMenu );
+}
+
+
diff --git a/basic/source/app/textedit.hxx b/basic/source/app/textedit.hxx
new file mode 100644
index 000000000000..354c94dc44ab
--- /dev/null
+++ b/basic/source/app/textedit.hxx
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _TEXTEDIT_HXX
+#define _TEXTEDIT_HXX
+
+class AppEdit;
+class TextEngine;
+class TextView;
+class TextEdit;
+class BreakpointWindow;
+
+#include <vcl/timer.hxx>
+#include <tools/table.hxx>
+#include <tools/debug.hxx>
+#include <svl/lstner.hxx>
+#include <svtools/svmedit.hxx>
+
+#include "dataedit.hxx"
+
+//#include <xtextedt.hxx>
+
+class TextEditImp : public Window, public SfxListener
+{
+using Window::Notify;
+
+protected:
+ void DoSyntaxHighlight( ULONG nPara );
+
+
+private:
+ AppEdit *pAppEdit;
+ Link ModifyHdl;
+
+ Timer aSyntaxIdleTimer;
+ Timer aImplSyntaxIdleTimer;
+ DECL_LINK( SyntaxTimerHdl, Timer * );
+ Table aSyntaxLineTable;
+
+ void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ void ImpDoHighlight( const String& rSource, ULONG nLineOff );
+ BOOL bHighlightning;
+ BOOL bDoSyntaxHighlight;
+ BOOL bDelayHighlight;
+
+
+ SbxBase* GetSbxAtMousePos( String &aWord );
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ DECL_LINK( HideVarContents, void* );
+ DECL_LINK( ShowVarContents, void* );
+ Point aTipPos;
+ String aTipWord;
+ ULONG nTipId;
+
+ Timer HideTipTimer;
+ Timer ShowTipTimer;
+
+ BOOL bViewMoved;
+
+public:
+ TextEditImp( AppEdit *pParent, const WinBits& aBits );
+ ~TextEditImp();
+
+ TextEngine *pTextEngine;
+ TextView *pTextView;
+
+ void SetFont( const Font& rNewFont );
+ BOOL IsModified();
+ void SetModifyHdl( Link l ){ ModifyHdl = l; }
+
+ void KeyInput( const KeyEvent& rKeyEvent );
+ void Paint( const Rectangle& rRect );
+ void MouseButtonUp( const MouseEvent& rMouseEvent );
+ void MouseButtonDown( const MouseEvent& rMouseEvent );
+// void MouseMove( const MouseEvent& rMouseEvent );
+ void Command( const CommandEvent& rCEvt );
+ //BOOL Drop( const DropEvent& rEvt );
+ //BOOL QueryDrop( DropEvent& rEvt );
+
+ BOOL ViewMoved();
+
+ void DoDelayedSyntaxHighlight( xub_StrLen nPara );
+ void InvalidateSyntaxHighlight();
+ void SyntaxHighlight( BOOL bNew );
+ void BuildKontextMenu( PopupMenu *&pMenu );
+};
+
+
+
+DBG_NAMEEX(TextEdit)
+class TextEdit : public DataEdit {
+
+ BreakpointWindow *pBreakpointWindow;
+ BOOL bFileWasUTF8;
+ BOOL bSaveAsUTF8;
+
+public:
+ TextEdit( AppEdit*, const WinBits& );
+ ~TextEdit();
+ void Highlight( ULONG nLine, xub_StrLen nCol1, xub_StrLen nCol2 );
+ TextEditImp& GetTextEditImp() { return aEdit; }
+
+ void SetBreakpointWindow( BreakpointWindow *pBPWindow ){ pBreakpointWindow = pBPWindow; }
+ BreakpointWindow *GetBreakpointWindow(){ return pBreakpointWindow; }
+
+ DATA_FUNC_DEF( aEdit, TextEditImp )
+
+ virtual void BuildKontextMenu( PopupMenu *&pMenu );
+
+ void SaveAsUTF8( BOOL bUTF8 ) { bSaveAsUTF8 = bUTF8; }
+};
+
+#endif
diff --git a/basic/source/app/ttbasic.cxx b/basic/source/app/ttbasic.cxx
new file mode 100644
index 000000000000..98ffc1e4c08d
--- /dev/null
+++ b/basic/source/app/ttbasic.cxx
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * 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 <basic/mybasic.hxx>
+#include "ttbasic.hxx"
+
+MyBasic* TTBasic::CreateMyBasic()
+{
+ return new MyBasic;
+}
diff --git a/basic/source/app/ttbasic.hxx b/basic/source/app/ttbasic.hxx
new file mode 100644
index 000000000000..04d74daa1bb7
--- /dev/null
+++ b/basic/source/app/ttbasic.hxx
@@ -0,0 +1,32 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+class TTBasic
+{
+public:
+ static MyBasic* CreateMyBasic();
+};
+
diff --git a/basic/source/app/ttmsg.src b/basic/source/app/ttmsg.src
new file mode 100644
index 000000000000..63a6643f3cf1
--- /dev/null
+++ b/basic/source/app/ttmsg.src
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#include "ttmsg.hrc"
+
+
+// Hier sind die Messages aus dem Verzeichnis /basic/source/testtool enhalten
+
+
+///////////////////////////////
+// Fehlermeldungen, die in das Resultfile gelangen.
+// *********************
+// *** !!ACHTUNG!! ***
+// *********************
+// Die Nummern dürfen sich NIE! ändern,
+// da sie in den Resultfiles gespeichert sind, und bei erneutem Anzeigen
+// statdessen die entsprechenden neuen oder garkeine Strings angzeigt werden.
+///////////////////////////////
+String S_NAME_NOT_THERE
+{
+ Text[ en-US ] = "Name doesn't exist: #($Arg1)";
+};
+String S_DOUBLE_NAME
+{
+ Text[ en-US ] = "Name double: ($Arg1)";
+};
+String S_READING_FILE
+{
+ Text[ en-US ] = "Reading the files";
+};
+String S_CANNOT_OPEN_FILE
+{
+ Text[ en-US ] = "File cannot be opened: ($Arg1)";
+};
+String S_INVALID_LINE
+{
+ Text[ en-US ] = "Line \"($Arg1)\" is invalid.";
+};
+String S_SHORTNAME_UNKNOWN
+{
+ Text[ en-US ] = "Short-name unknown during copying: ($Arg1)";
+};
+String S_LONGNAME_UNKNOWN
+{
+ Text[ en-US ] = "Long-name unknown: ($Arg1)";
+};
+String S_FIRST_SHORTNAME_REQ_ASTRX
+{
+ Text[ en-US ] = "First short-name must start with * . Ignoring.";
+};
+String S_TIMOUT_WAITING
+{
+ Text[ en-US ] = "Server Timeout while waiting for answer. Sequence No: ($Arg1)";
+};
+String S_APPLICATION_RESTARTED
+{
+ Text[ en-US ] = "Application has been restarted.";
+};
+String S_APPLICATION_START_FAILED
+{
+ Text[ en-US ] = "Application \"($Arg1)\" cannot be started. ";
+};
+String S_TIMOUT_SENDING
+{
+ Text[ en-US ] = "Server Timeout while sending. Sequence No: ($Arg1)";
+};
+String S_NO_CONNECTION
+{
+ Text[ en-US ] = "No connection. Sequence No: ($Arg1)";
+};
+String S_NO_FILES_FOUND // Not used anymore. needed only for old *.res files
+{
+ Text[ en-US ] = "No ($Arg1) files found";
+};
+String S_ERRORS_DETECTED
+{
+ Text[ en-US ] = "** ($Arg1) errors occurred";
+};
+String S_NO_ERRORS_DETECTED
+{
+ Text[ en-US ] = "** No errors have occurred";
+};
+String S_WARNINGS_DETECTED
+{
+ Text[ en-US ] = "** ($Arg1) warnings occurred";
+};
+String S_NO_WARNINGS_DETECTED
+{
+ Text[ en-US ] = "** No warnings have occurred";
+};
+String S_INCLUDE_FILE_WARNINGS_DETECTED
+{
+ Text[ en-US ] = "** ($Arg1) warnings occurred during initialization";
+};
+String S_NO_INCLUDE_FILE_WARNINGS_DETECTED
+{
+ Text[ en-US ] = "** No warnings occurred during initialization";
+};
+String S_UNKNOWN_SLOT_CONTROL
+{
+ Text[ en-US ] = "Slot/Control unknown :\"($Arg1)\"";
+};
+String S_RETURN_SEQUENCE_MISSMATCH
+{
+ Text[ en-US ] = "Return Stream has wrong sequence: ($Arg1) instead of ($Arg2)";
+};
+String S_RETURNED_VALUE_ID_MISSMATCH
+{
+ Text[ en-US ] = "Return value received but different Id expected";
+};
+String S_RETURNED_VALUE_NO_RECEIVER
+{
+ Text[ en-US ] = "Return value received but no receiver defined";
+};
+String S_UNKNOWN_METHOD
+{
+ Text[ en-US ] = "Unknown method on object :($Arg1).($Arg2)";
+};
+/*
+String
+{
+ Text[ en-US ] = ;
+};
+String
+{
+ Text[ en-US ] = ;
+};
+String
+{
+ Text[ en-US ] = ;
+};
+String
+{
+ Text[ en-US ] = ;
+};
+*/
+
diff --git a/basic/source/basmgr/basicmanagerrepository.cxx b/basic/source/basmgr/basicmanagerrepository.cxx
new file mode 100644
index 000000000000..f6a16ffa80c0
--- /dev/null
+++ b/basic/source/basmgr/basicmanagerrepository.cxx
@@ -0,0 +1,641 @@
+/*************************************************************************
+ *
+ * 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 <basic/basicmanagerrepository.hxx>
+#include <basic/basmgr.hxx>
+#include "scriptcont.hxx"
+#include "dlgcont.hxx"
+#include <basic/sbuno.hxx>
+#include "sbintern.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
+#include <com/sun/star/document/XEmbeddedScripts.hpp>
+/** === end UNO includes === **/
+#include <svtools/ehdl.hxx>
+#include <svtools/sfxecode.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svl/smplhint.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/urlobj.hxx>
+#include <comphelper/stl_types.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/documentinfo.hxx>
+#include <unotools/eventlisteneradapter.hxx>
+
+#ifndef INCLUDED_OSL_DOUBLECHECKEDLOCKING_H
+#include <rtl/instance.hxx>
+#endif
+
+#include <map>
+
+//........................................................................
+namespace basic
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::frame::XModel;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::embed::XStorage;
+ using ::com::sun::star::script::XPersistentLibraryContainer;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::lang::XMultiServiceFactory;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::beans::XPropertySet;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::document::XStorageBasedDocument;
+ using ::com::sun::star::lang::XComponent;
+ using ::com::sun::star::document::XEmbeddedScripts;
+ /** === end UNO using === **/
+
+ typedef BasicManager* BasicManagerPointer;
+ typedef ::std::map< Reference< XInterface >, BasicManagerPointer, ::comphelper::OInterfaceCompare< XInterface > > BasicManagerStore;
+
+ typedef ::std::vector< BasicManagerCreationListener* > CreationListeners;
+
+ //====================================================================
+ //= BasicManagerCleaner
+ //====================================================================
+ /// is the only instance which is allowed to delete a BasicManager instance
+ class BasicManagerCleaner
+ {
+ public:
+ static void deleteBasicManager( BasicManager*& _rpManager )
+ {
+ delete _rpManager;
+ _rpManager = NULL;
+ }
+ };
+
+ //====================================================================
+ //= ImplRepository
+ //====================================================================
+ class ImplRepository : public ::utl::OEventListenerAdapter, public SfxListener
+ {
+ private:
+ friend struct CreateImplRepository;
+ ImplRepository();
+
+ private:
+ ::osl::Mutex m_aMutex;
+ BasicManagerStore m_aStore;
+ CreationListeners m_aCreationListeners;
+
+ public:
+ static ImplRepository& Instance();
+
+ BasicManager* getDocumentBasicManager( const Reference< XModel >& _rxDocumentModel );
+ BasicManager* getApplicationBasicManager( bool _bCreate );
+ void setApplicationBasicManager( BasicManager* _pBasicManager );
+ void registerCreationListener( BasicManagerCreationListener& _rListener );
+ void revokeCreationListener( BasicManagerCreationListener& _rListener );
+
+ private:
+ /** retrieves the location at which the BasicManager for the given model
+ is stored.
+
+ If previously, the BasicManager for this model has never been requested,
+ then the model is added to the map, with an initial NULL BasicManager.
+
+ @param _rxDocumentModel
+ the model whose BasicManager's location is to be retrieved. Must not be <NULL/>.
+
+ @precond
+ our mutex is locked
+ */
+ BasicManagerPointer&
+ impl_getLocationForModel( const Reference< XModel >& _rxDocumentModel );
+
+ /** creates a new BasicManager instance for the given model
+ */
+ BasicManagerPointer
+ impl_createManagerForModel( const Reference< XModel >& _rxDocumentModel );
+
+ /** creates the application-wide BasicManager
+ */
+ BasicManagerPointer impl_createApplicationBasicManager();
+
+ /** notifies all listeners which expressed interest in the creation of BasicManager instances.
+ */
+ void impl_notifyCreationListeners(
+ const Reference< XModel >& _rxDocumentModel,
+ BasicManager& _rManager
+ );
+
+ /** retrieves the current storage of a given document
+
+ @param _rxDocument
+ the document whose storage is to be retrieved.
+
+ @param _out_rStorage
+ takes the storage upon successful return. Note that this might be <NULL/> even
+ if <TRUE/> is returned. In this case, the document has not yet been saved.
+
+ @return
+ <TRUE/> if the storage could be successfully retrieved (in which case
+ <arg>_out_rStorage</arg> might or might not be <NULL/>), <FALSE/> otherwise.
+ In the latter case, processing this document should stop.
+ */
+ bool impl_getDocumentStorage_nothrow( const Reference< XModel >& _rxDocument, Reference< XStorage >& _out_rStorage );
+
+ /** retrieves the containers for Basic and Dialog libraries for a given document
+
+ @param _rxDocument
+ the document whose containers are to be retrieved.
+
+ @param _out_rxBasicLibraries
+ takes the basic library container upon successful return
+
+ @param _out_rxDialogLibraries
+ takes the dialog library container upon successful return
+
+ @return
+ <TRUE/> if and only if both containers exist, and could successfully be retrieved
+ */
+ bool impl_getDocumentLibraryContainers_nothrow(
+ const Reference< XModel >& _rxDocument,
+ Reference< XPersistentLibraryContainer >& _out_rxBasicLibraries,
+ Reference< XPersistentLibraryContainer >& _out_rxDialogLibraries
+ );
+
+ /** initializes the given library containers, which belong to a document
+ */
+ void impl_initDocLibraryContainers_nothrow(
+ const Reference< XPersistentLibraryContainer >& _rxBasicLibraries,
+ const Reference< XPersistentLibraryContainer >& _rxDialogLibraries
+ );
+
+ // OEventListenerAdapter overridables
+ virtual void _disposing( const ::com::sun::star::lang::EventObject& _rSource );
+
+ // SfxListener overridables
+ virtual void Notify( SfxBroadcaster& _rBC, const SfxHint& _rHint );
+
+ /** removes the Model/BasicManager pair given by iterator from our store
+ */
+ void impl_removeFromRepository( BasicManagerStore::iterator _pos );
+
+ private:
+ StarBASIC* impl_getDefaultAppBasicLibrary();
+ };
+
+ //====================================================================
+ //= CreateImplRepository
+ //====================================================================
+ struct CreateImplRepository
+ {
+ ImplRepository* operator()()
+ {
+ static ImplRepository* pRepository = new ImplRepository;
+ return pRepository;
+ }
+ };
+
+
+ //====================================================================
+ //= ImplRepository
+ //====================================================================
+ //--------------------------------------------------------------------
+ ImplRepository::ImplRepository()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ ImplRepository& ImplRepository::Instance()
+ {
+ return *rtl_Instance< ImplRepository, CreateImplRepository, ::osl::MutexGuard, ::osl::GetGlobalMutex >::
+ create( CreateImplRepository(), ::osl::GetGlobalMutex() );
+ }
+
+ //--------------------------------------------------------------------
+ BasicManager* ImplRepository::getDocumentBasicManager( const Reference< XModel >& _rxDocumentModel )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ BasicManagerPointer& pBasicManager = impl_getLocationForModel( _rxDocumentModel );
+ if ( pBasicManager == NULL )
+ pBasicManager = impl_createManagerForModel( _rxDocumentModel );
+
+ return pBasicManager;
+ }
+
+ //--------------------------------------------------------------------
+ BasicManager* ImplRepository::getApplicationBasicManager( bool _bCreate )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ BasicManager* pAppManager = GetSbData()->pAppBasMgr;
+ if ( ( pAppManager == NULL ) && _bCreate )
+ pAppManager = impl_createApplicationBasicManager();
+
+ return pAppManager;
+ }
+
+ //--------------------------------------------------------------------
+ void ImplRepository::setApplicationBasicManager( BasicManager* _pBasicManager )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ BasicManager* pPreviousManager = getApplicationBasicManager( false );
+ BasicManagerCleaner::deleteBasicManager( pPreviousManager );
+
+ GetSbData()->pAppBasMgr = _pBasicManager;
+ }
+
+ //--------------------------------------------------------------------
+ BasicManager* ImplRepository::impl_createApplicationBasicManager()
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ OSL_PRECOND( getApplicationBasicManager( false ) == NULL, "ImplRepository::impl_createApplicationBasicManager: there already is one!" );
+
+ // Determine Directory
+ SvtPathOptions aPathCFG;
+ String aAppBasicDir( aPathCFG.GetBasicPath() );
+ if ( !aAppBasicDir.Len() )
+ aPathCFG.SetBasicPath( String::CreateFromAscii("$(prog)") );
+
+ // #58293# soffice.new search only in user dir => first dir
+ String aAppFirstBasicDir = aAppBasicDir.GetToken(1);
+
+ // Create basic and load it
+ // MT: #47347# AppBasicDir is now a PATH
+ INetURLObject aAppBasic( SvtPathOptions().SubstituteVariable( String::CreateFromAscii("$(progurl)") ) );
+ aAppBasic.insertName( Application::GetAppName() );
+
+ BasicManager* pBasicManager = new BasicManager( new StarBASIC, &aAppBasicDir );
+ setApplicationBasicManager( pBasicManager );
+
+ // Als Destination das erste Dir im Pfad:
+ String aFileName( aAppBasic.getName() );
+ aAppBasic = INetURLObject( aAppBasicDir.GetToken(1) );
+ DBG_ASSERT( aAppBasic.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+ aAppBasic.insertName( aFileName );
+ pBasicManager->SetStorageName( aAppBasic.PathToFileName() );
+
+ // Basic container
+ SfxScriptLibraryContainer* pBasicCont = new SfxScriptLibraryContainer( Reference< XStorage >() );
+ Reference< XPersistentLibraryContainer > xBasicCont( pBasicCont );
+ pBasicCont->setBasicManager( pBasicManager );
+
+ // Dialog container
+ SfxDialogLibraryContainer* pDialogCont = new SfxDialogLibraryContainer( Reference< XStorage >() );
+ Reference< XPersistentLibraryContainer > xDialogCont( pDialogCont );
+
+ LibraryContainerInfo aInfo( xBasicCont, xDialogCont, static_cast< OldBasicPassword* >( pBasicCont ) );
+ pBasicManager->SetLibraryContainerInfo( aInfo );
+
+ // global constants
+
+ // StarDesktop
+ Reference< XMultiServiceFactory > xSMgr = ::comphelper::getProcessServiceFactory();
+ pBasicManager->SetGlobalUNOConstant(
+ "StarDesktop",
+ makeAny( xSMgr->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ) ) )
+ );
+
+ // (BasicLibraries and DialogLibraries have automatically been added in SetLibraryContainerInfo)
+
+ // notify
+ impl_notifyCreationListeners( NULL, *pBasicManager );
+
+ // outta here
+ return pBasicManager;
+ }
+
+ //--------------------------------------------------------------------
+ void ImplRepository::registerCreationListener( BasicManagerCreationListener& _rListener )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_aCreationListeners.push_back( &_rListener );
+ }
+
+ //--------------------------------------------------------------------
+ void ImplRepository::revokeCreationListener( BasicManagerCreationListener& _rListener )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ CreationListeners::iterator pos = ::std::find( m_aCreationListeners.begin(), m_aCreationListeners.end(), &_rListener );
+ if ( pos != m_aCreationListeners.end() )
+ m_aCreationListeners.erase( pos );
+ else {
+ DBG_ERROR( "ImplRepository::revokeCreationListener: listener is not registered!" );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void ImplRepository::impl_notifyCreationListeners( const Reference< XModel >& _rxDocumentModel, BasicManager& _rManager )
+ {
+ for ( CreationListeners::const_iterator loop = m_aCreationListeners.begin();
+ loop != m_aCreationListeners.end();
+ ++loop
+ )
+ {
+ (*loop)->onBasicManagerCreated( _rxDocumentModel, _rManager );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ StarBASIC* ImplRepository::impl_getDefaultAppBasicLibrary()
+ {
+ BasicManager* pAppManager = getApplicationBasicManager( true );
+
+ StarBASIC* pAppBasic = pAppManager ? pAppManager->GetLib(0) : NULL;
+ DBG_ASSERT( pAppBasic != NULL, "impl_getApplicationBasic: unable to determine the default application's Basic library!" );
+ return pAppBasic;
+ }
+
+ //--------------------------------------------------------------------
+ BasicManagerPointer& ImplRepository::impl_getLocationForModel( const Reference< XModel >& _rxDocumentModel )
+ {
+ Reference< XInterface > xNormalized( _rxDocumentModel, UNO_QUERY );
+ DBG_ASSERT( xNormalized.is(), "ImplRepository::impl_getLocationForModel: invalid model!" );
+
+ BasicManagerPointer& location = m_aStore[ xNormalized ];
+ return location;
+ }
+
+ //--------------------------------------------------------------------
+ void ImplRepository::impl_initDocLibraryContainers_nothrow( const Reference< XPersistentLibraryContainer >& _rxBasicLibraries, const Reference< XPersistentLibraryContainer >& _rxDialogLibraries )
+ {
+ OSL_PRECOND( _rxBasicLibraries.is() && _rxDialogLibraries.is(),
+ "ImplRepository::impl_initDocLibraryContainers_nothrow: illegal library containers, this will crash!" );
+
+ try
+ {
+ // ensure there's a standard library in the basic container
+ ::rtl::OUString aStdLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
+ if ( !_rxBasicLibraries->hasByName( aStdLibName ) )
+ _rxBasicLibraries->createLibrary( aStdLibName );
+ // as well as in the dialog container
+ if ( !_rxDialogLibraries->hasByName( aStdLibName ) )
+ _rxDialogLibraries->createLibrary( aStdLibName );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ BasicManagerPointer ImplRepository::impl_createManagerForModel( const Reference< XModel >& _rxDocumentModel )
+ {
+ StarBASIC* pAppBasic = impl_getDefaultAppBasicLibrary();
+
+ BasicManager* pBasicManager( NULL );
+ Reference< XStorage > xStorage;
+ if ( !impl_getDocumentStorage_nothrow( _rxDocumentModel, xStorage ) )
+ // the document is not able to provide the storage it is based on.
+ return pBasicManager;
+
+ Reference< XPersistentLibraryContainer > xBasicLibs;
+ Reference< XPersistentLibraryContainer > xDialogLibs;
+ if ( !impl_getDocumentLibraryContainers_nothrow( _rxDocumentModel, xBasicLibs, xDialogLibs ) )
+ // the document does not have BasicLibraries and DialogLibraries
+ return pBasicManager;
+
+ if ( xStorage.is() )
+ {
+ // load BASIC-manager
+ SfxErrorContext aErrContext( ERRCTX_SFX_LOADBASIC,
+ ::comphelper::DocumentInfo::getDocumentTitle( _rxDocumentModel ) );
+ String aAppBasicDir = SvtPathOptions().GetBasicPath();
+
+ // Storage and BaseURL are only needed by binary documents!
+ SotStorageRef xDummyStor = new SotStorage( ::rtl::OUString() );
+ pBasicManager = new BasicManager( *xDummyStor, String() /* TODO/LATER: xStorage */,
+ pAppBasic,
+ &aAppBasicDir, TRUE );
+ if ( pBasicManager->HasErrors() )
+ {
+ // handle errors
+ BasicError* pErr = pBasicManager->GetFirstError();
+ while ( pErr )
+ {
+ // show message to user
+ if ( ERRCODE_BUTTON_CANCEL == ErrorHandler::HandleError( pErr->GetErrorId() ) )
+ {
+ // user wants to break loading of BASIC-manager
+ BasicManagerCleaner::deleteBasicManager( pBasicManager );
+ xStorage.clear();
+ break;
+ }
+ pErr = pBasicManager->GetNextError();
+ }
+ }
+ }
+
+ // not loaded?
+ if ( !xStorage.is() )
+ {
+ // create new BASIC-manager
+ StarBASIC* pBasic = new StarBASIC( pAppBasic );
+ pBasic->SetFlag( SBX_EXTSEARCH );
+ pBasicManager = new BasicManager( pBasic, NULL, TRUE );
+ }
+
+ // knit the containers with the BasicManager
+ LibraryContainerInfo aInfo( xBasicLibs, xDialogLibs, dynamic_cast< OldBasicPassword* >( xBasicLibs.get() ) );
+ OSL_ENSURE( aInfo.mpOldBasicPassword, "ImplRepository::impl_createManagerForModel: wrong BasicLibraries implementation!" );
+ pBasicManager->SetLibraryContainerInfo( aInfo );
+ //pBasicCont->setBasicManager( pBasicManager );
+ // that's not needed anymore today. The containers will retrieve their associated
+ // BasicManager from the BasicManagerRepository, when needed.
+
+ // initialize the containers
+ impl_initDocLibraryContainers_nothrow( xBasicLibs, xDialogLibs );
+
+ // damit auch Dialoge etc. 'qualifiziert' angesprochen werden k"onnen
+ pBasicManager->GetLib(0)->SetParent( pAppBasic );
+
+ // global properties in the document's Basic
+ pBasicManager->SetGlobalUNOConstant( "ThisComponent", makeAny( _rxDocumentModel ) );
+
+ // notify
+ impl_notifyCreationListeners( _rxDocumentModel, *pBasicManager );
+
+ // register as listener for this model being disposed/closed
+ Reference< XComponent > xDocumentComponent( _rxDocumentModel, UNO_QUERY );
+ OSL_ENSURE( xDocumentComponent.is(), "ImplRepository::impl_createManagerForModel: the document must be an XComponent!" );
+ startComponentListening( xDocumentComponent );
+
+ // register as listener for the BasicManager being destroyed
+ StartListening( *pBasicManager );
+
+ return pBasicManager;
+ }
+
+ //--------------------------------------------------------------------
+ bool ImplRepository::impl_getDocumentStorage_nothrow( const Reference< XModel >& _rxDocument, Reference< XStorage >& _out_rStorage )
+ {
+ _out_rStorage.clear();
+ try
+ {
+ Reference< XStorageBasedDocument > xStorDoc( _rxDocument, UNO_QUERY_THROW );
+ _out_rStorage.set( xStorDoc->getDocumentStorage() );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ return false;
+ }
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ bool ImplRepository::impl_getDocumentLibraryContainers_nothrow( const Reference< XModel >& _rxDocument,
+ Reference< XPersistentLibraryContainer >& _out_rxBasicLibraries, Reference< XPersistentLibraryContainer >& _out_rxDialogLibraries )
+ {
+ _out_rxBasicLibraries.clear();
+ _out_rxDialogLibraries.clear();
+ try
+ {
+ Reference< XEmbeddedScripts > xScripts( _rxDocument, UNO_QUERY_THROW );
+ _out_rxBasicLibraries.set( xScripts->getBasicLibraries(), UNO_QUERY_THROW );
+ _out_rxDialogLibraries.set( xScripts->getDialogLibraries(), UNO_QUERY_THROW );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return _out_rxBasicLibraries.is() && _out_rxDialogLibraries.is();
+ }
+
+ //--------------------------------------------------------------------
+ void ImplRepository::impl_removeFromRepository( BasicManagerStore::iterator _pos )
+ {
+ OSL_PRECOND( _pos != m_aStore.end(), "ImplRepository::impl_removeFromRepository: invalid position!" );
+
+ BasicManager* pManager = _pos->second;
+
+ // *first* remove from map (else Notify won't work properly)
+ m_aStore.erase( _pos );
+
+ // *then* delete the BasicManager
+ EndListening( *pManager );
+ BasicManagerCleaner::deleteBasicManager( pManager );
+ }
+
+ //--------------------------------------------------------------------
+ void ImplRepository::_disposing( const ::com::sun::star::lang::EventObject& _rSource )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ Reference< XInterface > xNormalizedSource( _rSource.Source, UNO_QUERY );
+ #if OSL_DEBUG_LEVEL > 0
+ bool bFound = false;
+ #endif
+
+ for ( BasicManagerStore::iterator loop = m_aStore.begin();
+ loop != m_aStore.end();
+ ++loop
+ )
+ {
+ if ( loop->first.get() == xNormalizedSource.get() )
+ {
+ impl_removeFromRepository( loop );
+ #if OSL_DEBUG_LEVEL > 0
+ bFound = true;
+ #endif
+ break;
+ }
+ }
+
+ OSL_ENSURE( bFound, "ImplRepository::_disposing: where does this come from?" );
+ }
+
+ //--------------------------------------------------------------------
+ void ImplRepository::Notify( SfxBroadcaster& _rBC, const SfxHint& _rHint )
+ {
+ const SfxSimpleHint* pSimpleHint = dynamic_cast< const SfxSimpleHint* >( &_rHint );
+ if ( !pSimpleHint || ( pSimpleHint->GetId() != SFX_HINT_DYING ) )
+ // not interested in
+ return;
+
+ BasicManager* pManager = dynamic_cast< BasicManager* >( &_rBC );
+ OSL_ENSURE( pManager, "ImplRepository::Notify: where does this come from?" );
+
+ for ( BasicManagerStore::iterator loop = m_aStore.begin();
+ loop != m_aStore.end();
+ ++loop
+ )
+ {
+ if ( loop->second == pManager )
+ {
+ // a BasicManager which is still in our repository is being deleted.
+ // That's bad, since by definition, we *own* all instances in our
+ // repository.
+ OSL_ENSURE( false, "ImplRepository::Notify: nobody should tamper with the managers, except ourself!" );
+ m_aStore.erase( loop );
+ break;
+ }
+ }
+ }
+
+ //====================================================================
+ //= BasicManagerRepository
+ //====================================================================
+ //--------------------------------------------------------------------
+ BasicManager* BasicManagerRepository::getDocumentBasicManager( const Reference< XModel >& _rxDocumentModel )
+ {
+ return ImplRepository::Instance().getDocumentBasicManager( _rxDocumentModel );
+ }
+
+ //--------------------------------------------------------------------
+ BasicManager* BasicManagerRepository::getApplicationBasicManager( bool _bCreate )
+ {
+ return ImplRepository::Instance().getApplicationBasicManager( _bCreate );
+ }
+
+ //--------------------------------------------------------------------
+ void BasicManagerRepository::resetApplicationBasicManager()
+ {
+ return ImplRepository::Instance().setApplicationBasicManager( NULL );
+ }
+
+ //--------------------------------------------------------------------
+ void BasicManagerRepository::registerCreationListener( BasicManagerCreationListener& _rListener )
+ {
+ ImplRepository::Instance().registerCreationListener( _rListener );
+ }
+
+ //--------------------------------------------------------------------
+ void BasicManagerRepository::revokeCreationListener( BasicManagerCreationListener& _rListener )
+ {
+ ImplRepository::Instance().revokeCreationListener( _rListener );
+ }
+
+//........................................................................
+} // namespace basic
+//........................................................................
+
diff --git a/basic/source/basmgr/basmgr.cxx b/basic/source/basmgr/basmgr.cxx
new file mode 100644
index 000000000000..84763468e64c
--- /dev/null
+++ b/basic/source/basmgr/basmgr.cxx
@@ -0,0 +1,2490 @@
+/*************************************************************************
+ *
+ * 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 <sot/storage.hxx>
+#include <tools/urlobj.hxx>
+#include <svl/smplhint.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/msgbox.hxx>
+#include <basic/sbx.hxx>
+#include <sot/storinfo.hxx>
+#include <unotools/pathoptions.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <basic/sbmod.hxx>
+#include <basic/sbobjmod.hxx>
+
+#include <basic/sbuno.hxx>
+#include <basic/basmgr.hxx>
+#include <sbunoobj.hxx>
+#include "basrid.hxx"
+#include "sbintern.hxx"
+#include <sb.hrc>
+
+
+#define LIB_SEP 0x01
+#define LIBINFO_SEP 0x02
+#define LIBINFO_ID 0x1491
+#define PASSWORD_MARKER 0x31452134
+
+
+// Library API, implemented for XML import/export
+
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/script/XStarBasicAccess.hpp>
+#include <com/sun/star/script/XStarBasicModuleInfo.hpp>
+#include <com/sun/star/script/XStarBasicDialogInfo.hpp>
+#include <com/sun/star/script/XStarBasicLibraryInfo.hpp>
+#include <com/sun/star/script/XLibraryContainerPassword.hpp>
+#include <com/sun/star/script/ModuleInfo.hpp>
+#include <com/sun/star/script/vba/XVBACompatibility.hpp>
+#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
+
+#include <cppuhelper/implbase1.hxx>
+
+using com::sun::star::uno::Reference;
+using namespace com::sun::star::container;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::script;
+using namespace cppu;
+
+typedef WeakImplHelper1< XNameContainer > NameContainerHelper;
+typedef WeakImplHelper1< XStarBasicModuleInfo > ModuleInfoHelper;
+typedef WeakImplHelper1< XStarBasicDialogInfo > DialogInfoHelper;
+typedef WeakImplHelper1< XStarBasicLibraryInfo > LibraryInfoHelper;
+typedef WeakImplHelper1< XStarBasicAccess > StarBasicAccessHelper;
+
+
+
+#define CURR_VER 2
+
+// Version 1
+// ULONG nEndPos
+// USHORT nId
+// USHORT nVer
+// BOOL bDoLoad
+// String LibName
+// String AbsStorageName
+// String RelStorageName
+// Version 2
+// + BOOL bReference
+
+static const char* szStdLibName = "Standard";
+static const char szBasicStorage[] = "StarBASIC";
+static const char* szOldManagerStream = "BasicManager";
+static const char szManagerStream[] = "BasicManager2";
+static const char* szImbedded = "LIBIMBEDDED";
+static const char* szCryptingKey = "CryptedBasic";
+static const char* szScriptLanguage = "StarBasic";
+
+TYPEINIT1( BasicManager, SfxBroadcaster );
+DBG_NAME( BasicManager );
+
+StreamMode eStreamReadMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYALL;
+StreamMode eStorageReadMode = STREAM_READ | STREAM_SHARE_DENYWRITE;
+
+DECLARE_LIST( BasErrorLst, BasicError* )
+
+//----------------------------------------------------------------------------
+// BasicManager impl data
+struct BasicManagerImpl
+{
+ LibraryContainerInfo maContainerInfo;
+
+ // Save stream data
+ SvMemoryStream* mpManagerStream;
+ SvMemoryStream** mppLibStreams;
+ sal_Int32 mnLibStreamCount;
+ sal_Bool mbModifiedByLibraryContainer;
+ sal_Bool mbError;
+
+ BasicManagerImpl( void )
+ : mpManagerStream( NULL )
+ , mppLibStreams( NULL )
+ , mnLibStreamCount( 0 )
+ , mbModifiedByLibraryContainer( sal_False )
+ , mbError( sal_False )
+ {}
+ ~BasicManagerImpl();
+};
+
+BasicManagerImpl::~BasicManagerImpl()
+{
+ delete mpManagerStream;
+ if( mppLibStreams )
+ {
+ for( sal_Int32 i = 0 ; i < mnLibStreamCount ; i++ )
+ delete mppLibStreams[i];
+ delete[] mppLibStreams;
+ }
+}
+
+//============================================================================
+// BasMgrContainerListenerImpl
+//============================================================================
+
+typedef ::cppu::WeakImplHelper1< ::com::sun::star::container::XContainerListener > ContainerListenerHelper;
+
+class BasMgrContainerListenerImpl: public ContainerListenerHelper
+{
+ BasicManager* mpMgr;
+ ::rtl::OUString maLibName; // empty -> no lib, but lib container
+
+public:
+ BasMgrContainerListenerImpl( BasicManager* pMgr, ::rtl::OUString aLibName )
+ : mpMgr( pMgr )
+ , maLibName( aLibName ) {}
+
+ static void insertLibraryImpl( const Reference< XLibraryContainer >& xScriptCont, BasicManager* pMgr,
+ Any aLibAny, ::rtl::OUString aLibName );
+ static void addLibraryModulesImpl( BasicManager* pMgr, Reference< XNameAccess > xLibNameAccess,
+ ::rtl::OUString aLibName );
+
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XContainerListener
+ virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& Event )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event )
+ throw(::com::sun::star::uno::RuntimeException);
+};
+
+
+//============================================================================
+// BasMgrContainerListenerImpl
+//============================================================================
+
+void BasMgrContainerListenerImpl::insertLibraryImpl( const Reference< XLibraryContainer >& xScriptCont,
+ BasicManager* pMgr, Any aLibAny, ::rtl::OUString aLibName )
+{
+ Reference< XNameAccess > xLibNameAccess;
+ aLibAny >>= xLibNameAccess;
+
+ if( !pMgr->GetLib( aLibName ) )
+ {
+ BasicManager* pBasMgr = static_cast< BasicManager* >( pMgr );
+#ifdef DBG_UTIL
+ StarBASIC* pLib =
+#endif
+ pBasMgr->CreateLibForLibContainer( aLibName, xScriptCont );
+ DBG_ASSERT( pLib, "XML Import: Basic library could not be created");
+ }
+
+ Reference< XContainer> xLibContainer( xLibNameAccess, UNO_QUERY );
+ if( xLibContainer.is() )
+ {
+ // Register listener for library
+ Reference< XContainerListener > xLibraryListener
+ = static_cast< XContainerListener* >
+ ( new BasMgrContainerListenerImpl( pMgr, aLibName ) );
+ xLibContainer->addContainerListener( xLibraryListener );
+ }
+
+ if( xScriptCont->isLibraryLoaded( aLibName ) )
+ {
+ addLibraryModulesImpl( pMgr, xLibNameAccess, aLibName );
+ }
+}
+
+
+void BasMgrContainerListenerImpl::addLibraryModulesImpl( BasicManager* pMgr,
+ Reference< XNameAccess > xLibNameAccess, ::rtl::OUString aLibName )
+{
+ Sequence< ::rtl::OUString > aModuleNames = xLibNameAccess->getElementNames();
+ sal_Int32 nModuleCount = aModuleNames.getLength();
+
+ StarBASIC* pLib = pMgr->GetLib( aLibName );
+ DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::addLibraryModulesImpl: Unknown lib!");
+ if( pLib )
+ {
+ const ::rtl::OUString* pNames = aModuleNames.getConstArray();
+ for( sal_Int32 j = 0 ; j < nModuleCount ; j++ )
+ {
+ ::rtl::OUString aModuleName = pNames[ j ];
+ Any aElement = xLibNameAccess->getByName( aModuleName );
+ ::rtl::OUString aMod;
+ aElement >>= aMod;
+ Reference< vba::XVBAModuleInfo > xVBAModuleInfo( xLibNameAccess, UNO_QUERY );
+ if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aModuleName ) )
+ {
+ ModuleInfo mInfo = xVBAModuleInfo->getModuleInfo( aModuleName );
+ OSL_TRACE("#addLibraryModulesImpl - aMod");
+ pLib->MakeModule32( aModuleName, mInfo, aMod );
+ }
+ else
+ pLib->MakeModule32( aModuleName, aMod );
+ }
+ }
+
+ pLib->SetModified( FALSE );
+}
+
+
+
+// XEventListener
+//----------------------------------------------------------------------------
+
+void SAL_CALL BasMgrContainerListenerImpl::disposing( const EventObject& Source )
+ throw( RuntimeException )
+{
+ (void)Source;
+}
+
+// XContainerListener
+//----------------------------------------------------------------------------
+
+void SAL_CALL BasMgrContainerListenerImpl::elementInserted( const ContainerEvent& Event )
+ throw( RuntimeException )
+{
+ sal_Bool bLibContainer = ( maLibName.getLength() == 0 );
+ ::rtl::OUString aName;
+ Event.Accessor >>= aName;
+
+ mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True;
+
+ if( bLibContainer )
+ {
+ Reference< XLibraryContainer > xScriptCont( Event.Source, UNO_QUERY );
+ insertLibraryImpl( xScriptCont, mpMgr, Event.Element, aName );
+ StarBASIC* pLib = mpMgr->GetLib( aName );
+ if ( pLib )
+ {
+ Reference< vba::XVBACompatibility > xVBACompat( xScriptCont, UNO_QUERY );
+ if ( xVBACompat.is() )
+ pLib->SetVBAEnabled( xVBACompat->getVBACompatibilityMode() );
+ }
+ }
+ else
+ {
+
+ StarBASIC* pLib = mpMgr->GetLib( maLibName );
+ DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::elementInserted: Unknown lib!");
+ if( pLib )
+ {
+ SbModule* pMod = pLib->FindModule( aName );
+ if( !pMod )
+ {
+ ::rtl::OUString aMod;
+ Event.Element >>= aMod;
+ Reference< vba::XVBAModuleInfo > xVBAModuleInfo( Event.Source, UNO_QUERY );
+ if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aName ) )
+ {
+ ModuleInfo mInfo = xVBAModuleInfo->getModuleInfo( aName );
+ pLib->MakeModule32( aName, mInfo, aMod );
+ }
+ else
+ pLib->MakeModule32( aName, aMod );
+ pLib->SetModified( FALSE );
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void SAL_CALL BasMgrContainerListenerImpl::elementReplaced( const ContainerEvent& Event )
+ throw( RuntimeException )
+{
+ ::rtl::OUString aName;
+ Event.Accessor >>= aName;
+
+ mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True;
+
+ // Replace not possible for library container
+#ifdef DBG_UTIL
+ sal_Bool bLibContainer = ( maLibName.getLength() == 0 );
+#endif
+ DBG_ASSERT( !bLibContainer, "library container fired elementReplaced()");
+
+ StarBASIC* pLib = mpMgr->GetLib( maLibName );
+ if( pLib )
+ {
+ SbModule* pMod = pLib->FindModule( aName );
+ ::rtl::OUString aMod;
+ Event.Element >>= aMod;
+
+ if( pMod )
+ pMod->SetSource32( aMod );
+ else
+ pLib->MakeModule32( aName, aMod );
+
+ pLib->SetModified( FALSE );
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void SAL_CALL BasMgrContainerListenerImpl::elementRemoved( const ContainerEvent& Event )
+ throw( RuntimeException )
+{
+ ::rtl::OUString aName;
+ Event.Accessor >>= aName;
+
+ mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True;
+
+ sal_Bool bLibContainer = ( maLibName.getLength() == 0 );
+ if( bLibContainer )
+ {
+ StarBASIC* pLib = mpMgr->GetLib( aName );
+ if( pLib )
+ {
+ USHORT nLibId = mpMgr->GetLibId( aName );
+ mpMgr->RemoveLib( nLibId, FALSE );
+ }
+ }
+ else
+ {
+ StarBASIC* pLib = mpMgr->GetLib( maLibName );
+ SbModule* pMod = pLib ? pLib->FindModule( aName ) : NULL;
+ if( pMod )
+ {
+ pLib->Remove( pMod );
+ pLib->SetModified( FALSE );
+ }
+ }
+}
+
+
+//=====================================================================
+
+class BasicErrorManager
+{
+private:
+ BasErrorLst aErrorList;
+
+public:
+ ~BasicErrorManager();
+
+ void Reset();
+ void InsertError( const BasicError& rError );
+
+ BOOL HasErrors() { return (BOOL)aErrorList.Count(); }
+ BasicError* GetFirstError() { return aErrorList.First(); }
+ BasicError* GetNextError() { return aErrorList.Next(); }
+};
+
+
+BasicErrorManager::~BasicErrorManager()
+{
+ Reset();
+}
+
+void BasicErrorManager::Reset()
+{
+ BasicError* pError = (BasicError*)aErrorList.First();
+ while ( pError )
+ {
+ delete pError;
+ pError = (BasicError*)aErrorList.Next();
+ }
+ aErrorList.Clear();
+}
+
+void BasicErrorManager::InsertError( const BasicError& rError )
+{
+ aErrorList.Insert( new BasicError( rError ), LIST_APPEND );
+}
+
+
+BasicError::BasicError()
+{
+ nErrorId = 0;
+ nReason = 0;
+}
+
+BasicError::BasicError( ULONG nId, USHORT nR, const String& rErrStr ) :
+ aErrStr( rErrStr )
+{
+ nErrorId = nId;
+ nReason = nR;
+}
+
+BasicError::BasicError( const BasicError& rErr ) :
+ aErrStr( rErr.aErrStr )
+{
+ nErrorId = rErr.nErrorId;
+ nReason = rErr.nReason;
+}
+
+
+class BasicLibInfo
+{
+private:
+ StarBASICRef xLib;
+ String aLibName;
+ String aStorageName; // String is sufficient, unique at runtime
+ String aRelStorageName;
+ String aPassword;
+
+ BOOL bDoLoad;
+ BOOL bReference;
+ BOOL bPasswordVerified;
+ BOOL bFoundInPath; // Must not relativated again!
+
+ // Lib represents library in new UNO library container
+ Reference< XLibraryContainer > mxScriptCont;
+
+public:
+ BasicLibInfo();
+ BasicLibInfo( const String& rStorageName );
+
+ BOOL IsReference() const { return bReference; }
+ BOOL& IsReference() { return bReference; }
+
+ BOOL IsExtern() const { return ! aStorageName.EqualsAscii(szImbedded); }
+
+ void SetStorageName( const String& rName ) { aStorageName = rName; }
+ const String& GetStorageName() const { return aStorageName; }
+
+ void SetRelStorageName( const String& rN ) { aRelStorageName = rN; }
+ const String& GetRelStorageName() const { return aRelStorageName; }
+ void CalcRelStorageName( const String& rMgrStorageName );
+
+ StarBASICRef GetLib() const
+ {
+ if( mxScriptCont.is() && mxScriptCont->hasByName( aLibName ) &&
+ !mxScriptCont->isLibraryLoaded( aLibName ) )
+ return StarBASICRef();
+ return xLib;
+ }
+ StarBASICRef& GetLibRef() { return xLib; }
+ void SetLib( StarBASIC* pBasic ) { xLib = pBasic; }
+
+ const String& GetLibName() const { return aLibName; }
+ void SetLibName( const String& rName ) { aLibName = rName; }
+
+ // Only temporary for Load/Save
+ BOOL DoLoad() { return bDoLoad; }
+
+ BOOL HasPassword() const { return aPassword.Len() != 0; }
+ const String& GetPassword() const { return aPassword; }
+ void SetPassword( const String& rNewPassword )
+ { aPassword = rNewPassword; }
+ BOOL IsPasswordVerified() const { return bPasswordVerified; }
+ void SetPasswordVerified() { bPasswordVerified = TRUE; }
+
+ BOOL IsFoundInPath() const { return bFoundInPath; }
+ void SetFoundInPath( BOOL bInPath ) { bFoundInPath = bInPath; }
+
+ void Store( SotStorageStream& rSStream, const String& rBasMgrStorageName, BOOL bUseOldReloadInfo );
+ static BasicLibInfo* Create( SotStorageStream& rSStream );
+
+ Reference< XLibraryContainer > GetLibraryContainer( void )
+ { return mxScriptCont; }
+ void SetLibraryContainer( const Reference< XLibraryContainer >& xScriptCont )
+ { mxScriptCont = xScriptCont; }
+};
+
+DECLARE_LIST( BasicLibsBase, BasicLibInfo* )
+
+class BasicLibs : public BasicLibsBase
+{
+public:
+ String aBasicLibPath; // TODO: Should be member of manager, but currently not incompatible
+};
+
+BasicLibInfo::BasicLibInfo()
+{
+ bReference = FALSE;
+ bPasswordVerified = FALSE;
+ bDoLoad = FALSE;
+ bFoundInPath = FALSE;
+ mxScriptCont = NULL;
+ aStorageName = String::CreateFromAscii(szImbedded);
+ aRelStorageName = String::CreateFromAscii(szImbedded);
+}
+
+BasicLibInfo::BasicLibInfo( const String& rStorageName )
+{
+ bReference = TRUE;
+ bPasswordVerified = FALSE;
+ bDoLoad = FALSE;
+ mxScriptCont = NULL;
+ aStorageName = rStorageName;
+}
+
+void BasicLibInfo::Store( SotStorageStream& rSStream, const String& rBasMgrStorageName, BOOL bUseOldReloadInfo )
+{
+ ULONG nStartPos = rSStream.Tell();
+ sal_uInt32 nEndPos = 0;
+
+ USHORT nId = LIBINFO_ID;
+ USHORT nVer = CURR_VER;
+
+ rSStream << nEndPos;
+ rSStream << nId;
+ rSStream << nVer;
+
+ String aCurStorageName = INetURLObject(rBasMgrStorageName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
+ DBG_ASSERT(aCurStorageName.Len() != 0, "Bad storage name");
+
+ // If not set initialize StorageName
+ if ( aStorageName.Len() == 0 )
+ aStorageName = aCurStorageName;
+
+ // Load again?
+ BOOL bDoLoad_ = xLib.Is();
+ if ( bUseOldReloadInfo )
+ bDoLoad_ = DoLoad();
+ rSStream << bDoLoad_;
+
+ // The name of the lib...
+ rSStream.WriteByteString(GetLibName());
+
+ // Absolute path...
+ if ( ! GetStorageName().EqualsAscii(szImbedded) )
+ {
+ String aSName = INetURLObject( GetStorageName(), INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
+ DBG_ASSERT(aSName.Len() != 0, "Bad storage name");
+ rSStream.WriteByteString( aSName );
+ }
+ else
+ rSStream.WriteByteString( szImbedded );
+
+ // Relative path...
+ if ( ( aStorageName == aCurStorageName ) || ( aStorageName.EqualsAscii(szImbedded) ) )
+ rSStream.WriteByteString( szImbedded );
+ else
+ {
+ // Do not determine the relative path if the file was only found in path:
+ // because the relative path would change and after moving the lib the
+ // the file cannot be found.
+ if ( !IsFoundInPath() )
+ CalcRelStorageName( aCurStorageName );
+ rSStream.WriteByteString(aRelStorageName);
+ }
+
+ // ------------------------------
+ // Version 2
+ // ------------------------------
+
+ // reference...
+ rSStream << bReference;
+
+ // ------------------------------
+ // End
+ // ------------------------------
+
+ nEndPos = rSStream.Tell();
+ rSStream.Seek( nStartPos );
+ rSStream << nEndPos;
+ rSStream.Seek( nEndPos );
+}
+
+BasicLibInfo* BasicLibInfo::Create( SotStorageStream& rSStream )
+{
+ BasicLibInfo* pInfo = new BasicLibInfo;
+
+ sal_uInt32 nEndPos;
+ USHORT nId;
+ USHORT nVer;
+
+ rSStream >> nEndPos;
+ rSStream >> nId;
+ rSStream >> nVer;
+
+ DBG_ASSERT( nId == LIBINFO_ID, "Keine BasicLibInfo !?" );
+ if( nId == LIBINFO_ID )
+ {
+ // Reload?
+ BOOL bDoLoad;
+ rSStream >> bDoLoad;
+ pInfo->bDoLoad = bDoLoad;
+
+ // The name of the lib...
+ String aName;
+ rSStream.ReadByteString(aName);
+ pInfo->SetLibName( aName );
+
+ // Absolute path...
+ String aStorageName;
+ rSStream.ReadByteString(aStorageName);
+ pInfo->SetStorageName( aStorageName );
+
+ // Relative path...
+ String aRelStorageName;
+ rSStream.ReadByteString(aRelStorageName);
+ pInfo->SetRelStorageName( aRelStorageName );
+
+ if ( nVer >= 2 )
+ {
+ BOOL bReferenz;
+ rSStream >> bReferenz;
+ pInfo->IsReference() = bReferenz;
+ }
+
+ rSStream.Seek( nEndPos );
+ }
+ return pInfo;
+}
+
+void BasicLibInfo::CalcRelStorageName( const String& rMgrStorageName )
+{
+ if ( rMgrStorageName.Len() )
+ {
+ INetURLObject aAbsURLObj( rMgrStorageName );
+ aAbsURLObj.removeSegment();
+ String aPath = aAbsURLObj.GetMainURL( INetURLObject::NO_DECODE );
+ UniString aRelURL = INetURLObject::GetRelURL( aPath, GetStorageName() );
+ SetRelStorageName( aRelURL );
+ }
+ else
+ SetRelStorageName( String() );
+}
+BasicManager::BasicManager( SotStorage& rStorage, const String& rBaseURL, StarBASIC* pParentFromStdLib, String* pLibPath, BOOL bDocMgr ) : mbDocMgr( bDocMgr )
+{
+ DBG_CTOR( BasicManager, 0 );
+
+ Init();
+
+ if( pLibPath )
+ pLibs->aBasicLibPath = *pLibPath;
+
+ String aStorName( rStorage.GetName() );
+ maStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
+
+ // #91251: Storage name not longer available for documents < 5.0
+ // Should be no real problem, because only relative storage names
+ // (links) can be affected.
+ // DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
+ // DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
+
+ // If there is no Manager Stream, no further actions are necessary
+ if ( rStorage.IsStream( String(RTL_CONSTASCII_USTRINGPARAM(szManagerStream)) ) )
+ {
+ LoadBasicManager( rStorage, rBaseURL );
+ // StdLib contains Parent:
+ StarBASIC* pStdLib = GetStdLib();
+ DBG_ASSERT( pStdLib, "Standard-Lib not loaded?" );
+ if ( !pStdLib )
+ {
+ // Should never happen, but if it happens we wont crash...
+ pStdLib = new StarBASIC( NULL, mbDocMgr );
+ BasicLibInfo* pStdLibInfo = pLibs->GetObject( 0 );
+ if ( !pStdLibInfo )
+ pStdLibInfo = CreateLibInfo();
+ pStdLibInfo->SetLib( pStdLib );
+ StarBASICRef xStdLib = pStdLibInfo->GetLib();
+ xStdLib->SetName( String::CreateFromAscii(szStdLibName) );
+ pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
+ xStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
+ xStdLib->SetModified( FALSE );
+ }
+ else
+ {
+ pStdLib->SetParent( pParentFromStdLib );
+ // The other get StdLib as parent:
+ for ( USHORT nBasic = 1; nBasic < GetLibCount(); nBasic++ )
+ {
+ StarBASIC* pBasic = GetLib( nBasic );
+ if ( pBasic )
+ {
+// pBasic->SetParent( pStdLib );
+ pStdLib->Insert( pBasic );
+ pBasic->SetFlag( SBX_EXTSEARCH );
+ }
+ }
+ // Modified through insert
+ pStdLib->SetModified( FALSE );
+ }
+
+ // #91626 Save all stream data to save it unmodified if basic isn't modified
+ // in an 6.0+ office. So also the old basic dialogs can be saved.
+ SotStorageStreamRef xManagerStream = rStorage.OpenSotStream
+ ( String(RTL_CONSTASCII_USTRINGPARAM(szManagerStream)), eStreamReadMode );
+ mpImpl->mpManagerStream = new SvMemoryStream();
+ *static_cast<SvStream*>(&xManagerStream) >> *mpImpl->mpManagerStream;
+
+ SotStorageRef xBasicStorage = rStorage.OpenSotStorage
+ ( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)), eStorageReadMode, FALSE );
+ if( xBasicStorage.Is() && !xBasicStorage->GetError() )
+ {
+ USHORT nLibs = GetLibCount();
+ mpImpl->mppLibStreams = new SvMemoryStream*[ nLibs ];
+ for( USHORT nL = 0; nL < nLibs; nL++ )
+ {
+ BasicLibInfo* pInfo = pLibs->GetObject( nL );
+ DBG_ASSERT( pInfo, "pInfo?!" );
+ SotStorageStreamRef xBasicStream = xBasicStorage->OpenSotStream( pInfo->GetLibName(), eStreamReadMode );
+ mpImpl->mppLibStreams[nL] = new SvMemoryStream();
+ *static_cast<SvStream*>(&xBasicStream) >> *( mpImpl->mppLibStreams[nL] );
+ }
+ }
+ else
+ mpImpl->mbError = sal_True;
+ }
+ else
+ {
+ ImpCreateStdLib( pParentFromStdLib );
+ if ( rStorage.IsStream( String::CreateFromAscii(szOldManagerStream) ) )
+ LoadOldBasicManager( rStorage );
+ }
+
+ bBasMgrModified = FALSE;
+}
+
+void copyToLibraryContainer( StarBASIC* pBasic, const LibraryContainerInfo& rInfo )
+{
+ Reference< XLibraryContainer > xScriptCont( rInfo.mxScriptCont.get() );
+ if ( !xScriptCont.is() )
+ return;
+
+ String aLibName = pBasic->GetName();
+ if( !xScriptCont->hasByName( aLibName ) )
+ xScriptCont->createLibrary( aLibName );
+
+ Any aLibAny = xScriptCont->getByName( aLibName );
+ Reference< XNameContainer > xLib;
+ aLibAny >>= xLib;
+ if ( !xLib.is() )
+ return;
+
+ USHORT nModCount = pBasic->GetModules()->Count();
+ for ( USHORT nMod = 0 ; nMod < nModCount ; nMod++ )
+ {
+ SbModule* pModule = (SbModule*)pBasic->GetModules()->Get( nMod );
+ DBG_ASSERT( pModule, "Modul nicht erhalten!" );
+
+ String aModName = pModule->GetName();
+ if( !xLib->hasByName( aModName ) )
+ {
+ ::rtl::OUString aSource = pModule->GetSource32();
+ Any aSourceAny;
+ aSourceAny <<= aSource;
+ xLib->insertByName( aModName, aSourceAny );
+ }
+ }
+}
+
+const Reference< XPersistentLibraryContainer >& BasicManager::GetDialogLibraryContainer() const
+{
+ return mpImpl->maContainerInfo.mxDialogCont;
+}
+
+const Reference< XPersistentLibraryContainer >& BasicManager::GetScriptLibraryContainer() const
+{
+ return mpImpl->maContainerInfo.mxScriptCont;
+}
+
+void BasicManager::SetLibraryContainerInfo( const LibraryContainerInfo& rInfo )
+{
+ mpImpl->maContainerInfo = rInfo;
+
+ Reference< XLibraryContainer > xScriptCont( mpImpl->maContainerInfo.mxScriptCont.get() );
+ StarBASIC* pStdLib = GetStdLib();
+ String aLibName = pStdLib->GetName();
+ if( xScriptCont.is() )
+ {
+ // Register listener for lib container
+ ::rtl::OUString aEmptyLibName;
+ Reference< XContainerListener > xLibContainerListener
+ = static_cast< XContainerListener* >
+ ( new BasMgrContainerListenerImpl( this, aEmptyLibName ) );
+
+ Reference< XContainer> xLibContainer( xScriptCont, UNO_QUERY );
+ xLibContainer->addContainerListener( xLibContainerListener );
+
+ Sequence< ::rtl::OUString > aScriptLibNames = xScriptCont->getElementNames();
+ const ::rtl::OUString* pScriptLibName = aScriptLibNames.getConstArray();
+ sal_Int32 i, nNameCount = aScriptLibNames.getLength();
+
+ if( nNameCount )
+ {
+ for( i = 0 ; i < nNameCount ; ++i, ++pScriptLibName )
+ {
+ Any aLibAny = xScriptCont->getByName( *pScriptLibName );
+
+ if ( pScriptLibName->equalsAscii( "Standard" ) )
+ xScriptCont->loadLibrary( *pScriptLibName );
+
+ BasMgrContainerListenerImpl::insertLibraryImpl
+ ( xScriptCont, this, aLibAny, *pScriptLibName );
+ }
+ }
+ else
+ {
+ // No libs? Maybe an 5.2 document already loaded
+ USHORT nLibs = GetLibCount();
+ for( USHORT nL = 0; nL < nLibs; nL++ )
+ {
+ BasicLibInfo* pBasLibInfo = pLibs->GetObject( nL );
+ StarBASIC* pLib = pBasLibInfo->GetLib();
+ if( !pLib )
+ {
+ BOOL bLoaded = ImpLoadLibary( pBasLibInfo, NULL, FALSE );
+ if( bLoaded )
+ pLib = pBasLibInfo->GetLib();
+ }
+ if( pLib )
+ {
+ copyToLibraryContainer( pLib, mpImpl->maContainerInfo );
+ if( pBasLibInfo->HasPassword() )
+ {
+ OldBasicPassword* pOldBasicPassword =
+ mpImpl->maContainerInfo.mpOldBasicPassword;
+ if( pOldBasicPassword )
+ {
+ pOldBasicPassword->setLibraryPassword
+ ( pLib->GetName(), pBasLibInfo->GetPassword() );
+ pBasLibInfo->SetPasswordVerified();
+ }
+ }
+ }
+ }
+
+ mpImpl->mbModifiedByLibraryContainer = sal_False;
+ }
+ }
+
+ SetGlobalUNOConstant( "BasicLibraries", makeAny( mpImpl->maContainerInfo.mxScriptCont ) );
+ SetGlobalUNOConstant( "DialogLibraries", makeAny( mpImpl->maContainerInfo.mxDialogCont ) );
+}
+
+BasicManager::BasicManager( StarBASIC* pSLib, String* pLibPath, BOOL bDocMgr ) : mbDocMgr( bDocMgr )
+{
+ DBG_CTOR( BasicManager, 0 );
+ Init();
+ DBG_ASSERT( pSLib, "BasicManager cannot be created with a NULL-Pointer!" );
+
+ if( pLibPath )
+ pLibs->aBasicLibPath = *pLibPath;
+
+ BasicLibInfo* pStdLibInfo = CreateLibInfo();
+ pStdLibInfo->SetLib( pSLib );
+ StarBASICRef xStdLib = pStdLibInfo->GetLib();
+ xStdLib->SetName( String::CreateFromAscii(szStdLibName));
+ pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
+ pSLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
+
+ // Save is only necessary if basic has changed
+ xStdLib->SetModified( FALSE );
+ bBasMgrModified = FALSE;
+}
+
+BasicManager::BasicManager()
+{
+ DBG_CTOR( BasicManager, 0 );
+ // This ctor may only be used to adapt relative paths for 'Save As'.
+ // There is no AppBasic so libs must not be loaded...
+ Init();
+}
+
+void BasicManager::ImpMgrNotLoaded( const String& rStorageName )
+{
+ // pErrInf is only destroyed if the error os processed by an
+ // ErrorHandler
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, rStorageName, ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENMGRSTREAM, rStorageName ) );
+
+ // Create a stdlib otherwise we crash!
+ BasicLibInfo* pStdLibInfo = CreateLibInfo();
+ pStdLibInfo->SetLib( new StarBASIC( NULL, mbDocMgr ) );
+ StarBASICRef xStdLib = pStdLibInfo->GetLib();
+ xStdLib->SetName( String::CreateFromAscii(szStdLibName) );
+ pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
+ xStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
+ xStdLib->SetModified( FALSE );
+}
+
+
+void BasicManager::ImpCreateStdLib( StarBASIC* pParentFromStdLib )
+{
+ BasicLibInfo* pStdLibInfo = CreateLibInfo();
+ StarBASIC* pStdLib = new StarBASIC( pParentFromStdLib, mbDocMgr );
+ pStdLibInfo->SetLib( pStdLib );
+ pStdLib->SetName( String::CreateFromAscii(szStdLibName) );
+ pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
+ pStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
+}
+
+
+void BasicManager::LoadBasicManager( SotStorage& rStorage, const String& rBaseURL, BOOL bLoadLibs )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+// StreamMode eStreamMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE;
+
+ SotStorageStreamRef xManagerStream = rStorage.OpenSotStream
+ ( String(RTL_CONSTASCII_USTRINGPARAM(szManagerStream)), eStreamReadMode );
+
+ String aStorName( rStorage.GetName() );
+ // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
+
+ if ( !xManagerStream.Is() || xManagerStream->GetError() || ( xManagerStream->Seek( STREAM_SEEK_TO_END ) == 0 ) )
+ {
+ ImpMgrNotLoaded( aStorName );
+ return;
+ }
+
+ maStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
+ // #i13114 removed, DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
+
+ String aRealStorageName = maStorageName; // for relative paths, can be modified through BaseURL
+
+ // If loaded from template, only BaseURL is used:
+ //String aBaseURL = INetURLObject::GetBaseURL();
+ if ( rBaseURL.Len() )
+ {
+ INetURLObject aObj( rBaseURL );
+ if ( aObj.GetProtocol() == INET_PROT_FILE )
+ aRealStorageName = aObj.PathToFileName();
+ }
+
+ xManagerStream->SetBufferSize( 1024 );
+ xManagerStream->Seek( STREAM_SEEK_TO_BEGIN );
+
+ sal_uInt32 nEndPos;
+ *xManagerStream >> nEndPos;
+
+ USHORT nLibs;
+ *xManagerStream >> nLibs;
+ // Plausi!
+ if( nLibs & 0xF000 )
+ {
+ DBG_ASSERT( !this, "BasicManager-Stream defect!" );
+ return;
+ }
+ for ( USHORT nL = 0; nL < nLibs; nL++ )
+ {
+ BasicLibInfo* pInfo = BasicLibInfo::Create( *xManagerStream );
+
+ // Correct absolute pathname if relative is existing.
+ // Always try relative first if there are two stands on disk
+ if ( pInfo->GetRelStorageName().Len() && ( ! pInfo->GetRelStorageName().EqualsAscii(szImbedded) ) )
+ {
+ INetURLObject aObj( aRealStorageName, INET_PROT_FILE );
+ aObj.removeSegment();
+ bool bWasAbsolute = FALSE;
+ aObj = aObj.smartRel2Abs( pInfo->GetRelStorageName(), bWasAbsolute );
+
+ //*** TODO: Replace if still necessary
+ /* if ( SfxContentHelper::Exists( aObj.GetMainURL() ) )
+ pInfo->SetStorageName( aObj.GetMainURL() );
+ else */
+ //*** TODO-End
+ if ( pLibs->aBasicLibPath.Len() )
+ {
+ // Search lib in path
+ String aSearchFile = pInfo->GetRelStorageName();
+ SvtPathOptions aPathCFG;
+ if( aPathCFG.SearchFile( aSearchFile, SvtPathOptions::PATH_BASIC ) )
+ {
+ pInfo->SetStorageName( aSearchFile );
+ pInfo->SetFoundInPath( TRUE );
+ }
+ }
+ }
+
+ pLibs->Insert( pInfo, LIST_APPEND );
+ // Libs from external files should be loaded only when necessary.
+ // But references are loaded at once, otherwise some big customers get into trouble
+ if ( bLoadLibs && pInfo->DoLoad() &&
+ ( ( !pInfo->IsExtern() ) || ( pInfo->IsReference() ) ) )
+ {
+ ImpLoadLibary( pInfo, &rStorage );
+ }
+ }
+
+ xManagerStream->Seek( nEndPos );
+ xManagerStream->SetBufferSize( 0 );
+ xManagerStream.Clear();
+}
+
+void BasicManager::LoadOldBasicManager( SotStorage& rStorage )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+// StreamMode eStreamMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE;
+
+ SotStorageStreamRef xManagerStream = rStorage.OpenSotStream
+ ( String::CreateFromAscii(szOldManagerStream), eStreamReadMode );
+
+ String aStorName( rStorage.GetName() );
+ DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
+
+ if ( !xManagerStream.Is() || xManagerStream->GetError() || ( xManagerStream->Seek( STREAM_SEEK_TO_END ) == 0 ) )
+ {
+ ImpMgrNotLoaded( aStorName );
+ return;
+ }
+
+ xManagerStream->SetBufferSize( 1024 );
+ xManagerStream->Seek( STREAM_SEEK_TO_BEGIN );
+ sal_uInt32 nBasicStartOff, nBasicEndOff;
+ *xManagerStream >> nBasicStartOff;
+ *xManagerStream >> nBasicEndOff;
+
+ DBG_ASSERT( !xManagerStream->GetError(), "Ungueltiger Manager-Stream!" );
+
+ xManagerStream->Seek( nBasicStartOff );
+ if( !ImplLoadBasic( *xManagerStream, pLibs->GetObject(0)->GetLibRef() ) )
+ {
+// String aErrorText( BasicResId( IDS_SBERR_MGROPEN ) );
+// aErrorText.SearchAndReplace( "XX", aStorName );
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, aStorName, ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENMGRSTREAM, aStorName ) );
+ // und es geht weiter...
+ }
+ xManagerStream->Seek( nBasicEndOff+1 ); // +1: 0x00 as separator
+ String aLibs;
+ xManagerStream->ReadByteString(aLibs);
+ xManagerStream->SetBufferSize( 0 );
+ xManagerStream.Clear(); // Close stream
+
+ if ( aLibs.Len() )
+ {
+ String aCurStorageName( aStorName );
+ INetURLObject aCurStorage( aCurStorageName, INET_PROT_FILE );
+ USHORT nLibs = aLibs.GetTokenCount( LIB_SEP );
+ for ( USHORT nLib = 0; nLib < nLibs; nLib++ )
+ {
+ String aLibInfo( aLibs.GetToken( nLib, LIB_SEP ) );
+ // TODO: Remove == 2
+ DBG_ASSERT( ( aLibInfo.GetTokenCount( LIBINFO_SEP ) == 2 ) || ( aLibInfo.GetTokenCount( LIBINFO_SEP ) == 3 ), "Ungueltige Lib-Info!" );
+ String aLibName( aLibInfo.GetToken( 0, LIBINFO_SEP ) );
+ String aLibAbsStorageName( aLibInfo.GetToken( 1, LIBINFO_SEP ) );
+ String aLibRelStorageName( aLibInfo.GetToken( 2, LIBINFO_SEP ) );
+ INetURLObject aLibAbsStorage( aLibAbsStorageName, INET_PROT_FILE );
+
+ INetURLObject aLibRelStorage( aStorName );
+ aLibRelStorage.removeSegment();
+ bool bWasAbsolute = FALSE;
+ aLibRelStorage = aLibRelStorage.smartRel2Abs( aLibRelStorageName, bWasAbsolute);
+ DBG_ASSERT(!bWasAbsolute, "RelStorageName was absolute!" );
+
+ SotStorageRef xStorageRef;
+ if ( ( aLibAbsStorage == aCurStorage ) || ( aLibRelStorageName.EqualsAscii(szImbedded) ) )
+ xStorageRef = &rStorage;
+ else
+ {
+ xStorageRef = new SotStorage( FALSE, aLibAbsStorage.GetMainURL
+ ( INetURLObject::NO_DECODE ), eStorageReadMode, TRUE );
+ if ( xStorageRef->GetError() != ERRCODE_NONE )
+ xStorageRef = new SotStorage( FALSE, aLibRelStorage.
+ GetMainURL( INetURLObject::NO_DECODE ), eStorageReadMode, TRUE );
+ }
+ if ( xStorageRef.Is() )
+ AddLib( *xStorageRef, aLibName, FALSE );
+ else
+ {
+// String aErrorText( BasicResId( IDS_SBERR_LIBLOAD ) );
+// aErrorText.SearchAndReplace( "XX", aLibName );
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, aStorName, ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_STORAGENOTFOUND, aStorName ) );
+ }
+ }
+ }
+}
+
+BasicManager::~BasicManager()
+{
+ DBG_DTOR( BasicManager, 0 );
+
+ // Notify listener if something needs to be saved
+ Broadcast( SfxSimpleHint( SFX_HINT_DYING) );
+
+ // Destroy Basic-Infos...
+ // In reverse order
+ BasicLibInfo* pInf = pLibs->Last();
+ while ( pInf )
+ {
+ delete pInf;
+ pInf = pLibs->Prev();
+ }
+ pLibs->Clear();
+ delete pLibs;
+ delete pErrorMgr;
+ delete mpImpl;
+}
+
+void BasicManager::LegacyDeleteBasicManager( BasicManager*& _rpManager )
+{
+ delete _rpManager;
+ _rpManager = NULL;
+}
+
+void BasicManager::Init()
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ bBasMgrModified = FALSE;
+ pErrorMgr = new BasicErrorManager;
+ pLibs = new BasicLibs;
+ mpImpl = new BasicManagerImpl();
+}
+
+BasicLibInfo* BasicManager::CreateLibInfo()
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pInf = new BasicLibInfo;
+ pLibs->Insert( pInf, LIST_APPEND );
+ return pInf;
+}
+
+BOOL BasicManager::ImpLoadLibary( BasicLibInfo* pLibInfo, SotStorage* pCurStorage, BOOL bInfosOnly ) const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ DBG_ASSERT( pLibInfo, "LibInfo!?" );
+
+ String aStorageName( pLibInfo->GetStorageName() );
+ if ( !aStorageName.Len() || ( aStorageName.EqualsAscii(szImbedded) ) )
+ aStorageName = GetStorageName();
+
+ SotStorageRef xStorage;
+ // The current must not be opened again...
+ if ( pCurStorage )
+ {
+ String aStorName( pCurStorage->GetName() );
+ // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
+
+ INetURLObject aCurStorageEntry(aStorName, INET_PROT_FILE);
+ // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::NO_DECODE ).Len() != 0, "Bad storage name");
+
+ INetURLObject aStorageEntry(aStorageName, INET_PROT_FILE);
+ // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::NO_DECODE ).Len() != 0, "Bad storage name");
+
+ if ( aCurStorageEntry == aStorageEntry )
+ xStorage = pCurStorage;
+ }
+
+ if ( !xStorage.Is() )
+ xStorage = new SotStorage( FALSE, aStorageName, eStorageReadMode );
+
+ SotStorageRef xBasicStorage = xStorage->OpenSotStorage
+ ( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)), eStorageReadMode, FALSE );
+
+ if ( !xBasicStorage.Is() || xBasicStorage->GetError() )
+ {
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, xStorage->GetName(), ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTORAGE, pLibInfo->GetLibName() ) );
+ }
+ else
+ {
+ // In the Basic-Storage every lib is in a Stream...
+ SotStorageStreamRef xBasicStream = xBasicStorage->OpenSotStream( pLibInfo->GetLibName(), eStreamReadMode );
+ if ( !xBasicStream.Is() || xBasicStream->GetError() )
+ {
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD , pLibInfo->GetLibName(), ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTREAM, pLibInfo->GetLibName() ) );
+ }
+ else
+ {
+ BOOL bLoaded = FALSE;
+ if ( xBasicStream->Seek( STREAM_SEEK_TO_END ) != 0 )
+ {
+ if ( !bInfosOnly )
+ {
+ if ( !pLibInfo->GetLib().Is() )
+ pLibInfo->SetLib( new StarBASIC( GetStdLib(), mbDocMgr ) );
+ xBasicStream->SetBufferSize( 1024 );
+ xBasicStream->Seek( STREAM_SEEK_TO_BEGIN );
+ bLoaded = ImplLoadBasic( *xBasicStream, pLibInfo->GetLibRef() );
+ xBasicStream->SetBufferSize( 0 );
+ StarBASICRef xStdLib = pLibInfo->GetLib();
+ xStdLib->SetName( pLibInfo->GetLibName() );
+ xStdLib->SetModified( FALSE );
+ xStdLib->SetFlag( SBX_DONTSTORE );
+ }
+ else
+ {
+ // Skip Basic...
+ xBasicStream->Seek( STREAM_SEEK_TO_BEGIN );
+ ImplEncryptStream( *xBasicStream );
+ SbxBase::Skip( *xBasicStream );
+ bLoaded = TRUE;
+ }
+ }
+ if ( !bLoaded )
+ {
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, pLibInfo->GetLibName(), ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_BASICLOADERROR, pLibInfo->GetLibName() ) );
+ }
+ else
+ {
+ // Perhaps there are additional information in the stream...
+ xBasicStream->SetKey( szCryptingKey );
+ xBasicStream->RefreshBuffer();
+ sal_uInt32 nPasswordMarker = 0;
+ *xBasicStream >> nPasswordMarker;
+ if ( ( nPasswordMarker == PASSWORD_MARKER ) && !xBasicStream->IsEof() )
+ {
+ String aPassword;
+ xBasicStream->ReadByteString(aPassword);
+ pLibInfo->SetPassword( aPassword );
+ }
+ xBasicStream->SetKey( ByteString() );
+ CheckModules( pLibInfo->GetLib(), pLibInfo->IsReference() );
+ }
+ return bLoaded;
+ }
+ }
+ return FALSE;
+}
+
+BOOL BasicManager::ImplEncryptStream( SvStream& rStrm ) const
+{
+ ULONG nPos = rStrm.Tell();
+ UINT32 nCreator;
+ rStrm >> nCreator;
+ rStrm.Seek( nPos );
+ BOOL bProtected = FALSE;
+ if ( nCreator != SBXCR_SBX )
+ {
+ // Should only be the case for encrypted Streams
+ bProtected = TRUE;
+ rStrm.SetKey( szCryptingKey );
+ rStrm.RefreshBuffer();
+ }
+ return bProtected;
+}
+
+// This code is necessary to load the BASIC of Beta 1
+// TODO: Which Beta 1?
+BOOL BasicManager::ImplLoadBasic( SvStream& rStrm, StarBASICRef& rOldBasic ) const
+{
+ BOOL bProtected = ImplEncryptStream( rStrm );
+ SbxBaseRef xNew = SbxBase::Load( rStrm );
+ BOOL bLoaded = FALSE;
+ if( xNew.Is() )
+ {
+ if( xNew->IsA( TYPE(StarBASIC) ) )
+ {
+ StarBASIC* pNew = (StarBASIC*)(SbxBase*) xNew;
+ // Use the Parent of the old BASICs
+ if( rOldBasic.Is() )
+ {
+ pNew->SetParent( rOldBasic->GetParent() );
+ if( pNew->GetParent() )
+ pNew->GetParent()->Insert( pNew );
+ pNew->SetFlag( SBX_EXTSEARCH );
+ }
+ rOldBasic = pNew;
+
+ // Fill new libray container (5.2 -> 6.0)
+ copyToLibraryContainer( pNew, mpImpl->maContainerInfo );
+
+/*
+ if( rOldBasic->GetParent() )
+ {
+ rOldBasic->GetParent()->Insert( rOldBasic );
+ rOldBasic->SetFlag( SBX_EXTSEARCH );
+ }
+*/
+ pNew->SetModified( FALSE );
+ bLoaded = TRUE;
+ }
+ }
+ if ( bProtected )
+ rStrm.SetKey( ByteString() );
+ return bLoaded;
+}
+
+void BasicManager::CheckModules( StarBASIC* pLib, BOOL bReference ) const
+{
+ if ( !pLib )
+ return;
+
+ BOOL bModified = pLib->IsModified();
+
+ for ( USHORT nMod = 0; nMod < pLib->GetModules()->Count(); nMod++ )
+ {
+ SbModule* pModule = (SbModule*)pLib->GetModules()->Get( nMod );
+ DBG_ASSERT( pModule, "Modul nicht erhalten!" );
+ if ( !pModule->IsCompiled() && !StarBASIC::GetErrorCode() )
+ pLib->Compile( pModule );
+ }
+
+ // #67477, AB 8.12.99 On demand compile in referenced libs should not
+ // cause modified
+ if( !bModified && bReference )
+ {
+ DBG_ERROR( "Per Reference eingebundene Basic-Library ist nicht compiliert!" );
+ pLib->SetModified( FALSE );
+ }
+}
+
+StarBASIC* BasicManager::AddLib( SotStorage& rStorage, const String& rLibName, BOOL bReference )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ String aStorName( rStorage.GetName() );
+ DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
+
+ String aStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
+ DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
+
+ String aNewLibName( rLibName );
+ while ( HasLib( aNewLibName ) )
+ aNewLibName += '_';
+
+ BasicLibInfo* pLibInfo = CreateLibInfo();
+ // Use original name otherwise ImpLoadLibary failes...
+ pLibInfo->SetLibName( rLibName );
+ // Funktioniert so aber nicht, wenn Name doppelt
+// USHORT nLibId = GetLibId( rLibName );
+ USHORT nLibId = (USHORT) pLibs->GetPos( pLibInfo );
+
+ // Set StorageName before load because it is compared with pCurStorage
+ pLibInfo->SetStorageName( aStorageName );
+ BOOL bLoaded = ImpLoadLibary( pLibInfo, &rStorage );
+
+ if ( bLoaded )
+ {
+ if ( aNewLibName != rLibName )
+ SetLibName( nLibId, aNewLibName );
+
+ if ( bReference )
+ {
+ pLibInfo->GetLib()->SetModified( FALSE ); // Don't save in this case
+ pLibInfo->SetRelStorageName( String() );
+// pLibInfo->CalcRelStorageName( GetStorageName() );
+ pLibInfo->IsReference() = TRUE;
+ }
+ else
+ {
+ pLibInfo->GetLib()->SetModified( TRUE ); // Must be saved after Add!
+ pLibInfo->SetStorageName( String::CreateFromAscii(szImbedded) ); // Save in BasicManager-Storage
+ }
+ bBasMgrModified = TRUE;
+ }
+ else
+ {
+ RemoveLib( nLibId, FALSE );
+ pLibInfo = 0;
+ }
+
+ if( pLibInfo )
+ return &*pLibInfo->GetLib() ;
+ else
+ return 0;
+}
+
+BOOL BasicManager::IsReference( USHORT nLib )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
+ DBG_ASSERT( pLibInfo, "Lib?!" );
+ if ( pLibInfo )
+ return pLibInfo->IsReference();
+
+ return FALSE;
+}
+
+BOOL BasicManager::RemoveLib( USHORT nLib )
+{
+ // Only pyhsical deletion if no reference
+ return RemoveLib( nLib, !IsReference( nLib ) );
+}
+
+BOOL BasicManager::RemoveLib( USHORT nLib, BOOL bDelBasicFromStorage )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ DBG_ASSERT( nLib, "Standard-Lib cannot be removed!" );
+
+ BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
+ DBG_ASSERT( pLibInfo, "Lib not found!" );
+
+ if ( !pLibInfo || !nLib )
+ {
+// String aErrorText( BasicResId( IDS_SBERR_REMOVELIB ) );
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, String(), ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_STDLIB, pLibInfo->GetLibName() ) );
+ return FALSE;
+ }
+
+ // If one of the streams cannot be opened, this is not an error,
+ // because BASIC was never written before...
+ if ( bDelBasicFromStorage && !pLibInfo->IsReference() &&
+ ( !pLibInfo->IsExtern() || SotStorage::IsStorageFile( pLibInfo->GetStorageName() ) ) )
+ {
+ SotStorageRef xStorage;
+ if ( !pLibInfo->IsExtern() )
+ xStorage = new SotStorage( FALSE, GetStorageName() );
+ else
+ xStorage = new SotStorage( FALSE, pLibInfo->GetStorageName() );
+
+ if ( xStorage->IsStorage( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)) ) )
+ {
+ SotStorageRef xBasicStorage = xStorage->OpenSotStorage
+ ( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)), STREAM_STD_READWRITE, FALSE );
+
+ if ( !xBasicStorage.Is() || xBasicStorage->GetError() )
+ {
+// String aErrorText( BasicResId( IDS_SBERR_REMOVELIB ) );
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, String(), ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTORAGE, pLibInfo->GetLibName() ) );
+ }
+ else if ( xBasicStorage->IsStream( pLibInfo->GetLibName() ) )
+ {
+ xBasicStorage->Remove( pLibInfo->GetLibName() );
+ xBasicStorage->Commit();
+
+ // If no further stream available,
+ // delete the SubStorage.
+ SvStorageInfoList aInfoList( 0, 4 );
+ xBasicStorage->FillInfoList( &aInfoList );
+ if ( !aInfoList.Count() )
+ {
+ xBasicStorage.Clear();
+ xStorage->Remove( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)) );
+ xStorage->Commit();
+ // If no further Streams or SubStorages available,
+ // delete the Storage, too.
+ aInfoList.Clear();
+ xStorage->FillInfoList( &aInfoList );
+ if ( !aInfoList.Count() )
+ {
+ String aName_( xStorage->GetName() );
+ xStorage.Clear();
+ //*** TODO: Replace if still necessary
+ //SfxContentHelper::Kill( aName );
+ //*** TODO-End
+ }
+ }
+ }
+ }
+ }
+ bBasMgrModified = TRUE;
+ if ( pLibInfo->GetLib().Is() )
+ GetStdLib()->Remove( pLibInfo->GetLib() );
+ delete pLibs->Remove( pLibInfo );
+ return TRUE; // Remove was successful, del unimportant
+}
+
+USHORT BasicManager::GetLibCount() const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ return (USHORT)pLibs->Count();
+}
+
+StarBASIC* BasicManager::GetLib( USHORT nLib ) const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ BasicLibInfo* pInf = pLibs->GetObject( nLib );
+ DBG_ASSERT( pInf, "Lib existiert nicht!" );
+ if ( pInf )
+ return pInf->GetLib();
+ return 0;
+}
+
+StarBASIC* BasicManager::GetStdLib() const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ StarBASIC* pLib = GetLib( 0 );
+ return pLib;
+}
+
+StarBASIC* BasicManager::GetLib( const String& rName ) const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pInf = pLibs->First();
+ while ( pInf )
+ {
+ if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL )// Check if available...
+ return pInf->GetLib();
+
+ pInf = pLibs->Next();
+ }
+ return 0;
+}
+
+USHORT BasicManager::GetLibId( const String& rName ) const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pInf = pLibs->First();
+ while ( pInf )
+ {
+ if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL )
+ return (USHORT)pLibs->GetCurPos();
+
+ pInf = pLibs->Next();
+ }
+ return LIB_NOTFOUND;
+}
+
+BOOL BasicManager::HasLib( const String& rName ) const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pInf = pLibs->First();
+ while ( pInf )
+ {
+ if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL )
+ return TRUE;
+
+ pInf = pLibs->Next();
+ }
+ return FALSE;
+}
+
+BOOL BasicManager::SetLibName( USHORT nLib, const String& rName )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
+ DBG_ASSERT( pLibInfo, "Lib?!" );
+ if ( pLibInfo )
+ {
+ pLibInfo->SetLibName( rName );
+ if ( pLibInfo->GetLib().Is() )
+ {
+ StarBASICRef xStdLib = pLibInfo->GetLib();
+ xStdLib->SetName( rName );
+ xStdLib->SetModified( TRUE );
+ }
+ bBasMgrModified = TRUE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+String BasicManager::GetLibName( USHORT nLib )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
+ DBG_ASSERT( pLibInfo, "Lib?!" );
+ if ( pLibInfo )
+ return pLibInfo->GetLibName();
+ return String();
+}
+
+BOOL BasicManager::LoadLib( USHORT nLib )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BOOL bDone = FALSE;
+ BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
+ DBG_ASSERT( pLibInfo, "Lib?!" );
+ if ( pLibInfo )
+ {
+ Reference< XLibraryContainer > xLibContainer = pLibInfo->GetLibraryContainer();
+ if( xLibContainer.is() )
+ {
+ String aLibName = pLibInfo->GetLibName();
+ xLibContainer->loadLibrary( aLibName );
+ bDone = xLibContainer->isLibraryLoaded( aLibName );;
+ }
+ else
+ {
+ bDone = ImpLoadLibary( pLibInfo, NULL, FALSE );
+ StarBASIC* pLib = GetLib( nLib );
+ if ( pLib )
+ {
+ // pLib->SetParent( GetStdLib() );
+ GetStdLib()->Insert( pLib );
+ pLib->SetFlag( SBX_EXTSEARCH );
+ }
+ }
+ }
+ else
+ {
+// String aErrorText( BasicResId( IDS_SBERR_LIBLOAD ) );
+// aErrorText.SearchAndReplace( "XX", "" );
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, String(), ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_LIBNOTFOUND, String::CreateFromInt32(nLib) ) );
+ }
+ return bDone;
+}
+
+StarBASIC* BasicManager::CreateLib( const String& rLibName )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ if ( GetLib( rLibName ) )
+ return 0;
+
+ BasicLibInfo* pLibInfo = CreateLibInfo();
+ StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr );
+ GetStdLib()->Insert( pNew );
+ pNew->SetFlag( SBX_EXTSEARCH | SBX_DONTSTORE );
+ pLibInfo->SetLib( pNew );
+ pLibInfo->SetLibName( rLibName );
+ pLibInfo->GetLib()->SetName( rLibName );
+ return pLibInfo->GetLib();
+}
+
+// For XML import/export:
+StarBASIC* BasicManager::CreateLib
+ ( const String& rLibName, const String& Password, const String& LinkTargetURL )
+{
+ // Ask if lib exists because standard lib is always there
+ StarBASIC* pLib = GetLib( rLibName );
+ if( !pLib )
+ {
+ if( LinkTargetURL.Len() != 0 )
+ {
+ SotStorageRef xStorage = new SotStorage( FALSE, LinkTargetURL, STREAM_READ | STREAM_SHARE_DENYWRITE );
+ if( !xStorage->GetError() )
+ {
+ pLib = AddLib( *xStorage, rLibName, TRUE );
+
+ //if( !pLibInfo )
+ //pLibInfo = FindLibInfo( pLib );
+ //pLibInfo->SetStorageName( LinkTargetURL );
+ //pLibInfo->GetLib()->SetModified( FALSE ); // Dann nicht speichern
+ //pLibInfo->SetRelStorageName( String() );
+ //pLibInfo->IsReference() = TRUE;
+ }
+ //else
+ //Message?
+
+ DBG_ASSERT( pLib, "XML Import: Linked basic library could not be loaded");
+ }
+ else
+ {
+ pLib = CreateLib( rLibName );
+ if( Password.Len() != 0 )
+ {
+ BasicLibInfo* pLibInfo = FindLibInfo( pLib );
+ pLibInfo ->SetPassword( Password );
+ }
+ }
+ //ExternalSourceURL ?
+ }
+ return pLib;
+}
+
+StarBASIC* BasicManager::CreateLibForLibContainer( const String& rLibName,
+ const Reference< XLibraryContainer >& xScriptCont )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ if ( GetLib( rLibName ) )
+ return 0;
+
+ BasicLibInfo* pLibInfo = CreateLibInfo();
+ StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr );
+ GetStdLib()->Insert( pNew );
+ pNew->SetFlag( SBX_EXTSEARCH | SBX_DONTSTORE );
+ pLibInfo->SetLib( pNew );
+ pLibInfo->SetLibName( rLibName );
+ pLibInfo->GetLib()->SetName( rLibName );
+ pLibInfo->SetLibraryContainer( xScriptCont );
+ return pNew;
+}
+
+
+BasicLibInfo* BasicManager::FindLibInfo( StarBASIC* pBasic ) const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pInf = ((BasicManager*)this)->pLibs->First();
+ while ( pInf )
+ {
+ if ( pInf->GetLib() == pBasic )
+ return pInf;
+
+ pInf = ((BasicManager*)this)->pLibs->Next();
+ }
+ return 0;
+}
+
+
+BOOL BasicManager::IsModified() const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ if ( bBasMgrModified )
+ return TRUE;
+ return IsBasicModified();
+}
+
+BOOL BasicManager::IsBasicModified() const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pInf = pLibs->First();
+ while ( pInf )
+ {
+ if ( pInf->GetLib().Is() && pInf->GetLib()->IsModified() )
+ return TRUE;
+
+ pInf = pLibs->Next();
+ }
+ return FALSE;
+}
+
+void BasicManager::SetFlagToAllLibs( short nFlag, BOOL bSet ) const
+{
+ USHORT nLibs = GetLibCount();
+ for ( USHORT nL = 0; nL < nLibs; nL++ )
+ {
+ BasicLibInfo* pInfo = pLibs->GetObject( nL );
+ DBG_ASSERT( pInfo, "Info?!" );
+ StarBASIC* pLib = pInfo->GetLib();
+ if ( pLib )
+ {
+ if ( bSet )
+ pLib->SetFlag( nFlag );
+ else
+ pLib->ResetFlag( nFlag );
+ }
+ }
+}
+
+BOOL BasicManager::HasErrors()
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ return pErrorMgr->HasErrors();
+}
+
+void BasicManager::ClearErrors()
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ pErrorMgr->Reset();
+}
+
+BasicError* BasicManager::GetFirstError()
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ return pErrorMgr->GetFirstError();
+}
+
+BasicError* BasicManager::GetNextError()
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ return pErrorMgr->GetNextError();
+}
+bool BasicManager::GetGlobalUNOConstant( const sal_Char* _pAsciiName, ::com::sun::star::uno::Any& aOut )
+{
+ bool bRes = false;
+ StarBASIC* pStandardLib = GetStdLib();
+ OSL_PRECOND( pStandardLib, "BasicManager::GetGlobalUNOConstant: no lib to read from!" );
+ if ( pStandardLib )
+ bRes = pStandardLib->GetUNOConstant( _pAsciiName, aOut );
+ return bRes;
+}
+
+Any BasicManager::SetGlobalUNOConstant( const sal_Char* _pAsciiName, const Any& _rValue )
+{
+ Any aOldValue;
+
+ StarBASIC* pStandardLib = GetStdLib();
+ OSL_PRECOND( pStandardLib, "BasicManager::SetGlobalUNOConstant: no lib to insert into!" );
+ if ( !pStandardLib )
+ return aOldValue;
+
+ ::rtl::OUString sVarName( ::rtl::OUString::createFromAscii( _pAsciiName ) );
+
+ // obtain the old value
+ SbxVariable* pVariable = pStandardLib->Find( sVarName, SbxCLASS_OBJECT );
+ if ( pVariable )
+ aOldValue = sbxToUnoValue( pVariable );
+
+ SbxObjectRef xUnoObj = GetSbUnoObject( sVarName, _rValue );
+ xUnoObj->SetFlag( SBX_DONTSTORE );
+ pStandardLib->Insert( xUnoObj );
+
+ return aOldValue;
+}
+
+bool BasicManager::LegacyPsswdBinaryLimitExceeded( ::com::sun::star::uno::Sequence< rtl::OUString >& _out_rModuleNames )
+{
+ try
+ {
+ Reference< XNameAccess > xScripts( GetScriptLibraryContainer(), UNO_QUERY_THROW );
+ Reference< XLibraryContainerPassword > xPassword( GetScriptLibraryContainer(), UNO_QUERY_THROW );
+
+ Sequence< ::rtl::OUString > aNames( xScripts->getElementNames() );
+ const ::rtl::OUString* pNames = aNames.getConstArray();
+ const ::rtl::OUString* pNamesEnd = aNames.getConstArray() + aNames.getLength();
+ for ( ; pNames != pNamesEnd; ++pNames )
+ {
+ if( /*pLib->mbSharedIndexFile ||*/ !xPassword->isLibraryPasswordProtected( *pNames ) )
+ continue;
+
+ StarBASIC* pBasicLib = GetLib( *pNames );
+ if ( !pBasicLib )
+ continue;
+
+ Reference< XNameAccess > xScriptLibrary( xScripts->getByName( *pNames ), UNO_QUERY_THROW );
+ Sequence< ::rtl::OUString > aElementNames( xScriptLibrary->getElementNames() );
+ sal_Int32 nLen = aElementNames.getLength();
+
+ Sequence< ::rtl::OUString > aBigModules( nLen );
+ sal_Int32 nBigModules = 0;
+
+ const ::rtl::OUString* pElementNames = aElementNames.getConstArray();
+ const ::rtl::OUString* pElementNamesEnd = aElementNames.getConstArray() + aElementNames.getLength();
+ for ( ; pElementNames != pElementNamesEnd; ++pElementNames )
+ {
+ SbModule* pMod = pBasicLib->FindModule( *pElementNames );
+ if ( pMod && pMod->ExceedsLegacyModuleSize() )
+ aBigModules[ nBigModules++ ] = *pElementNames;
+ }
+
+ if ( nBigModules )
+ {
+ aBigModules.realloc( nBigModules );
+ _out_rModuleNames = aBigModules;
+ return true;
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return false;
+}
+
+//=====================================================================
+
+class ModuleInfo_Impl : public ModuleInfoHelper
+{
+ ::rtl::OUString maName;
+ ::rtl::OUString maLanguage;
+ ::rtl::OUString maSource;
+
+public:
+ ModuleInfo_Impl( const ::rtl::OUString& aName, const ::rtl::OUString& aLanguage, const ::rtl::OUString& aSource )
+ : maName( aName ), maLanguage( aLanguage), maSource( aSource ) {}
+
+ // Methods XStarBasicModuleInfo
+ virtual ::rtl::OUString SAL_CALL getName() throw(RuntimeException)
+ { return maName; }
+ virtual ::rtl::OUString SAL_CALL getLanguage() throw(RuntimeException)
+ { return maLanguage; }
+ virtual ::rtl::OUString SAL_CALL getSource() throw(RuntimeException)
+ { return maSource; }
+};
+
+
+//=====================================================================
+
+class DialogInfo_Impl : public DialogInfoHelper
+{
+ ::rtl::OUString maName;
+ Sequence< sal_Int8 > mData;
+
+public:
+ DialogInfo_Impl( const ::rtl::OUString& aName, Sequence< sal_Int8 > Data )
+ : maName( aName ), mData( Data ) {}
+
+ // Methods XStarBasicDialogInfo
+ virtual ::rtl::OUString SAL_CALL getName() throw(RuntimeException)
+ { return maName; }
+ virtual Sequence< sal_Int8 > SAL_CALL getData() throw(RuntimeException)
+ { return mData; }
+};
+
+
+//=====================================================================
+
+class LibraryInfo_Impl : public LibraryInfoHelper
+{
+ ::rtl::OUString maName;
+ Reference< XNameContainer > mxModuleContainer;
+ Reference< XNameContainer > mxDialogContainer;
+ ::rtl::OUString maPassword;
+ ::rtl::OUString maExternaleSourceURL;
+ ::rtl::OUString maLinkTargetURL;
+
+public:
+ LibraryInfo_Impl
+ (
+ const ::rtl::OUString& aName,
+ Reference< XNameContainer > xModuleContainer,
+ Reference< XNameContainer > xDialogContainer,
+ const ::rtl::OUString& aPassword,
+ const ::rtl::OUString& aExternaleSourceURL,
+ const ::rtl::OUString& aLinkTargetURL
+ )
+ : maName( aName )
+ , mxModuleContainer( xModuleContainer )
+ , mxDialogContainer( xDialogContainer )
+ , maPassword( aPassword )
+ , maExternaleSourceURL( aExternaleSourceURL )
+ , maLinkTargetURL( aLinkTargetURL )
+ {}
+
+ // Methods XStarBasicLibraryInfo
+ virtual ::rtl::OUString SAL_CALL getName() throw(RuntimeException)
+ { return maName; }
+ virtual Reference< XNameContainer > SAL_CALL getModuleContainer() throw(RuntimeException)
+ { return mxModuleContainer; }
+ virtual Reference< XNameContainer > SAL_CALL getDialogContainer() throw(RuntimeException)
+ { return mxDialogContainer; }
+ virtual ::rtl::OUString SAL_CALL getPassword() throw(RuntimeException)
+ { return maPassword; }
+ virtual ::rtl::OUString SAL_CALL getExternalSourceURL() throw(RuntimeException)
+ { return maExternaleSourceURL; }
+ virtual ::rtl::OUString SAL_CALL getLinkTargetURL() throw(RuntimeException)
+ { return maLinkTargetURL; }
+};
+
+//=====================================================================
+
+class ModuleContainer_Impl : public NameContainerHelper
+{
+ StarBASIC* mpLib;
+
+public:
+ ModuleContainer_Impl( StarBASIC* pLib )
+ :mpLib( pLib ) {}
+
+ // Methods XElementAccess
+ virtual Type SAL_CALL getElementType()
+ throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements()
+ throw(RuntimeException);
+
+ // Methods XNameAccess
+ virtual Any SAL_CALL getByName( const ::rtl::OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException);
+ virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames()
+ throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
+ throw(RuntimeException);
+
+ // Methods XNameReplace
+ virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException);
+
+ // Methods XNameContainer
+ virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException);
+ virtual void SAL_CALL removeByName( const ::rtl::OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException);
+};
+
+// Methods XElementAccess
+Type ModuleContainer_Impl::getElementType()
+ throw(RuntimeException)
+{
+ Type aModuleType = ::getCppuType( (const Reference< XStarBasicModuleInfo > *)0 );
+ return aModuleType;
+}
+
+sal_Bool ModuleContainer_Impl::hasElements()
+ throw(RuntimeException)
+{
+ SbxArray* pMods = mpLib ? mpLib->GetModules() : NULL;
+ return pMods && pMods->Count() > 0;
+}
+
+// Methods XNameAccess
+Any ModuleContainer_Impl::getByName( const ::rtl::OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : NULL;
+ if( !pMod )
+ throw NoSuchElementException();
+ Reference< XStarBasicModuleInfo > xMod = (XStarBasicModuleInfo*)new ModuleInfo_Impl
+ ( aName, ::rtl::OUString::createFromAscii( szScriptLanguage ), pMod->GetSource32() );
+ Any aRetAny;
+ aRetAny <<= xMod;
+ return aRetAny;
+}
+
+Sequence< ::rtl::OUString > ModuleContainer_Impl::getElementNames()
+ throw(RuntimeException)
+{
+ SbxArray* pMods = mpLib ? mpLib->GetModules() : NULL;
+ USHORT nMods = pMods ? pMods->Count() : 0;
+ Sequence< ::rtl::OUString > aRetSeq( nMods );
+ ::rtl::OUString* pRetSeq = aRetSeq.getArray();
+ for( USHORT i = 0 ; i < nMods ; i++ )
+ {
+ SbxVariable* pMod = pMods->Get( i );
+ pRetSeq[i] = ::rtl::OUString( pMod->GetName() );
+ }
+ return aRetSeq;
+}
+
+sal_Bool ModuleContainer_Impl::hasByName( const ::rtl::OUString& aName )
+ throw(RuntimeException)
+{
+ SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : NULL;
+ sal_Bool bRet = (pMod != NULL);
+ return bRet;
+}
+
+
+// Methods XNameReplace
+void ModuleContainer_Impl::replaceByName( const ::rtl::OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ removeByName( aName );
+ insertByName( aName, aElement );
+}
+
+
+// Methods XNameContainer
+void ModuleContainer_Impl::insertByName( const ::rtl::OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ Type aModuleType = ::getCppuType( (const Reference< XStarBasicModuleInfo > *)0 );
+ Type aAnyType = aElement.getValueType();
+ if( aModuleType != aAnyType )
+ throw IllegalArgumentException();
+ Reference< XStarBasicModuleInfo > xMod;
+ aElement >>= xMod;
+ mpLib->MakeModule32( aName, xMod->getSource() );
+}
+
+void ModuleContainer_Impl::removeByName( const ::rtl::OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ SbModule* pMod = mpLib ? mpLib->FindModule( Name ) : NULL;
+ if( !pMod )
+ throw NoSuchElementException();
+ mpLib->Remove( pMod );
+}
+
+
+//=====================================================================
+
+Sequence< sal_Int8 > implGetDialogData( SbxObject* pDialog )
+{
+ SvMemoryStream aMemStream;
+ pDialog->Store( aMemStream );
+ sal_Int32 nLen = aMemStream.Tell();
+ Sequence< sal_Int8 > aData( nLen );
+ sal_Int8* pDestData = aData.getArray();
+ const sal_Int8* pSrcData = (const sal_Int8*)aMemStream.GetData();
+ rtl_copyMemory( pDestData, pSrcData, nLen );
+ return aData;
+}
+
+SbxObject* implCreateDialog( Sequence< sal_Int8 > aData )
+{
+ sal_Int8* pData = aData.getArray();
+ SvMemoryStream aMemStream( pData, aData.getLength(), STREAM_READ );
+ SbxObject* pDialog = (SbxObject*)SbxBase::Load( aMemStream );
+ return pDialog;
+}
+
+// HACK! Because this value is defined in basctl/inc/vcsbxdef.hxx
+// which we can't include here, we have to use the value directly
+#define SBXID_DIALOG 101
+
+
+class DialogContainer_Impl : public NameContainerHelper
+{
+ StarBASIC* mpLib;
+
+public:
+ DialogContainer_Impl( StarBASIC* pLib )
+ :mpLib( pLib ) {}
+
+ // Methods XElementAccess
+ virtual Type SAL_CALL getElementType()
+ throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements()
+ throw(RuntimeException);
+
+ // Methods XNameAccess
+ virtual Any SAL_CALL getByName( const ::rtl::OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException);
+ virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames()
+ throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
+ throw(RuntimeException);
+
+ // Methods XNameReplace
+ virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException);
+
+ // Methods XNameContainer
+ virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException);
+ virtual void SAL_CALL removeByName( const ::rtl::OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException);
+};
+
+// Methods XElementAccess
+Type DialogContainer_Impl::getElementType()
+ throw(RuntimeException)
+{
+ Type aModuleType = ::getCppuType( (const Reference< XStarBasicDialogInfo > *)0 );
+ return aModuleType;
+}
+
+sal_Bool DialogContainer_Impl::hasElements()
+ throw(RuntimeException)
+{
+ sal_Bool bRet = sal_False;
+
+ mpLib->GetAll( SbxCLASS_OBJECT );
+ sal_Int16 nCount = mpLib->GetObjects()->Count();
+ for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ )
+ {
+ SbxVariable* pVar = mpLib->GetObjects()->Get( nObj );
+ if ( pVar->ISA( SbxObject ) && ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) )
+ {
+ bRet = sal_True;
+ break;
+ }
+ }
+ return bRet;
+}
+
+// Methods XNameAccess
+Any DialogContainer_Impl::getByName( const ::rtl::OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxCLASS_DONTCARE );
+ if( !( pVar && pVar->ISA( SbxObject ) &&
+ ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) ) )
+ {
+ throw NoSuchElementException();
+ }
+
+ Reference< XStarBasicDialogInfo > xDialog =
+ (XStarBasicDialogInfo*)new DialogInfo_Impl
+ ( aName, implGetDialogData( (SbxObject*)pVar ) );
+
+ Any aRetAny;
+ aRetAny <<= xDialog;
+ return aRetAny;
+}
+
+Sequence< ::rtl::OUString > DialogContainer_Impl::getElementNames()
+ throw(RuntimeException)
+{
+ mpLib->GetAll( SbxCLASS_OBJECT );
+ sal_Int16 nCount = mpLib->GetObjects()->Count();
+ Sequence< ::rtl::OUString > aRetSeq( nCount );
+ ::rtl::OUString* pRetSeq = aRetSeq.getArray();
+ sal_Int32 nDialogCounter = 0;
+
+ for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ )
+ {
+ SbxVariable* pVar = mpLib->GetObjects()->Get( nObj );
+ if ( pVar->ISA( SbxObject ) && ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) )
+ {
+ pRetSeq[ nDialogCounter ] = ::rtl::OUString( pVar->GetName() );
+ nDialogCounter++;
+ }
+ }
+ aRetSeq.realloc( nDialogCounter );
+ return aRetSeq;
+}
+
+sal_Bool DialogContainer_Impl::hasByName( const ::rtl::OUString& aName )
+ throw(RuntimeException)
+{
+ sal_Bool bRet = sal_False;
+ SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxCLASS_DONTCARE );
+ if( pVar && pVar->ISA( SbxObject ) &&
+ ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) )
+ {
+ bRet = sal_True;
+ }
+ return bRet;
+}
+
+
+// Methods XNameReplace
+void DialogContainer_Impl::replaceByName( const ::rtl::OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ removeByName( aName );
+ insertByName( aName, aElement );
+}
+
+
+// Methods XNameContainer
+void DialogContainer_Impl::insertByName( const ::rtl::OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ (void)aName;
+ Type aModuleType = ::getCppuType( (const Reference< XStarBasicDialogInfo > *)0 );
+ Type aAnyType = aElement.getValueType();
+ if( aModuleType != aAnyType )
+ throw IllegalArgumentException();
+ Reference< XStarBasicDialogInfo > xMod;
+ aElement >>= xMod;
+ SbxObjectRef xDialog = implCreateDialog( xMod->getData() );
+ mpLib->Insert( xDialog );
+}
+
+void DialogContainer_Impl::removeByName( const ::rtl::OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ (void)Name;
+ SbxVariable* pVar = mpLib->GetObjects()->Find( Name, SbxCLASS_DONTCARE );
+ if( !( pVar && pVar->ISA( SbxObject ) &&
+ ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) ) )
+ {
+ throw NoSuchElementException();
+ }
+ mpLib->Remove( pVar );
+}
+
+
+//=====================================================================
+
+
+class LibraryContainer_Impl : public NameContainerHelper
+{
+ BasicManager* mpMgr;
+
+public:
+ LibraryContainer_Impl( BasicManager* pMgr )
+ :mpMgr( pMgr ) {}
+
+ // Methods XElementAccess
+ virtual Type SAL_CALL getElementType()
+ throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements()
+ throw(RuntimeException);
+
+ // Methods XNameAccess
+ virtual Any SAL_CALL getByName( const ::rtl::OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException);
+ virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames()
+ throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
+ throw(RuntimeException);
+
+ // Methods XNameReplace
+ virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException);
+
+ // Methods XNameContainer
+ virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException);
+ virtual void SAL_CALL removeByName( const ::rtl::OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException);
+};
+
+
+// Methods XElementAccess
+Type LibraryContainer_Impl::getElementType()
+ throw(RuntimeException)
+{
+ Type aType = ::getCppuType( (const Reference< XStarBasicLibraryInfo > *)0 );
+ return aType;
+}
+
+sal_Bool LibraryContainer_Impl::hasElements()
+ throw(RuntimeException)
+{
+ sal_Int32 nLibs = mpMgr->GetLibCount();
+ sal_Bool bRet = (nLibs > 0);
+ return bRet;
+}
+
+// Methods XNameAccess
+Any LibraryContainer_Impl::getByName( const ::rtl::OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ Any aRetAny;
+ if( !mpMgr->HasLib( aName ) )
+ throw NoSuchElementException();
+ StarBASIC* pLib = mpMgr->GetLib( aName );
+
+ Reference< XNameContainer > xModuleContainer =
+ (XNameContainer*)new ModuleContainer_Impl( pLib );
+
+ Reference< XNameContainer > xDialogContainer;
+ (XNameContainer*)new DialogContainer_Impl( pLib );
+
+ BasicLibInfo* pLibInfo = mpMgr->FindLibInfo( pLib );
+
+ ::rtl::OUString aPassword = pLibInfo->GetPassword();
+
+ // TODO Only provide extern info!
+ ::rtl::OUString aExternaleSourceURL;
+ ::rtl::OUString aLinkTargetURL;
+ if( pLibInfo->IsReference() )
+ aLinkTargetURL = pLibInfo->GetStorageName();
+ else if( pLibInfo->IsExtern() )
+ aExternaleSourceURL = pLibInfo->GetStorageName();
+
+ Reference< XStarBasicLibraryInfo > xLibInfo = new LibraryInfo_Impl
+ (
+ aName,
+ xModuleContainer,
+ xDialogContainer,
+ aPassword,
+ aExternaleSourceURL,
+ aLinkTargetURL
+ );
+
+ aRetAny <<= xLibInfo;
+ return aRetAny;
+}
+
+Sequence< ::rtl::OUString > LibraryContainer_Impl::getElementNames()
+ throw(RuntimeException)
+{
+ USHORT nLibs = mpMgr->GetLibCount();
+ Sequence< ::rtl::OUString > aRetSeq( nLibs );
+ ::rtl::OUString* pRetSeq = aRetSeq.getArray();
+ for( USHORT i = 0 ; i < nLibs ; i++ )
+ {
+ pRetSeq[i] = ::rtl::OUString( mpMgr->GetLibName( i ) );
+ }
+ return aRetSeq;
+}
+
+sal_Bool LibraryContainer_Impl::hasByName( const ::rtl::OUString& aName )
+ throw(RuntimeException)
+{
+ sal_Bool bRet = mpMgr->HasLib( aName );
+ return bRet;
+}
+
+// Methods XNameReplace
+void LibraryContainer_Impl::replaceByName( const ::rtl::OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ removeByName( aName );
+ insertByName( aName, aElement );
+}
+
+// Methods XNameContainer
+void LibraryContainer_Impl::insertByName( const ::rtl::OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ (void)aName;
+ (void)aElement;
+ // TODO: Insert a complete Library?!
+}
+
+void LibraryContainer_Impl::removeByName( const ::rtl::OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ StarBASIC* pLib = mpMgr->GetLib( Name );
+ if( !pLib )
+ throw NoSuchElementException();
+ USHORT nLibId = mpMgr->GetLibId( Name );
+ mpMgr->RemoveLib( nLibId );
+}
+
+//=====================================================================
+
+typedef WeakImplHelper1< XStarBasicAccess > StarBasicAccessHelper;
+
+
+class StarBasicAccess_Impl : public StarBasicAccessHelper
+{
+ BasicManager* mpMgr;
+ Reference< XNameContainer > mxLibContainer;
+
+public:
+ StarBasicAccess_Impl( BasicManager* pMgr )
+ :mpMgr( pMgr ) {}
+
+public:
+
+ // Methods
+ virtual Reference< XNameContainer > SAL_CALL getLibraryContainer()
+ throw(RuntimeException);
+ virtual void SAL_CALL createLibrary( const ::rtl::OUString& LibName, const ::rtl::OUString& Password,
+ const ::rtl::OUString& ExternalSourceURL, const ::rtl::OUString& LinkTargetURL )
+ throw(ElementExistException, RuntimeException);
+ virtual void SAL_CALL addModule( const ::rtl::OUString& LibraryName, const ::rtl::OUString& ModuleName,
+ const ::rtl::OUString& Language, const ::rtl::OUString& Source )
+ throw(NoSuchElementException, RuntimeException);
+ virtual void SAL_CALL addDialog( const ::rtl::OUString& LibraryName, const ::rtl::OUString& DialogName,
+ const Sequence< sal_Int8 >& Data )
+ throw(NoSuchElementException, RuntimeException);
+
+};
+
+Reference< XNameContainer > SAL_CALL StarBasicAccess_Impl::getLibraryContainer()
+ throw(RuntimeException)
+{
+ if( !mxLibContainer.is() )
+ mxLibContainer = (XNameContainer*)new LibraryContainer_Impl( mpMgr );
+ return mxLibContainer;
+}
+
+void SAL_CALL StarBasicAccess_Impl::createLibrary
+(
+ const ::rtl::OUString& LibName,
+ const ::rtl::OUString& Password,
+ const ::rtl::OUString& ExternalSourceURL,
+ const ::rtl::OUString& LinkTargetURL
+)
+ throw(ElementExistException, RuntimeException)
+{
+ (void)ExternalSourceURL;
+#ifdef DBG_UTIL
+ StarBASIC* pLib =
+#endif
+ mpMgr->CreateLib( LibName, Password, LinkTargetURL );
+ DBG_ASSERT( pLib, "XML Import: Basic library could not be created");
+}
+
+void SAL_CALL StarBasicAccess_Impl::addModule
+(
+ const ::rtl::OUString& LibraryName,
+ const ::rtl::OUString& ModuleName,
+ const ::rtl::OUString& Language,
+ const ::rtl::OUString& Source
+)
+ throw(NoSuchElementException, RuntimeException)
+{
+ (void)Language;
+ StarBASIC* pLib = mpMgr->GetLib( LibraryName );
+ DBG_ASSERT( pLib, "XML Import: Lib for module unknown");
+ if( pLib )
+ pLib->MakeModule32( ModuleName, Source );
+}
+
+void SAL_CALL StarBasicAccess_Impl::addDialog
+(
+ const ::rtl::OUString& LibraryName,
+ const ::rtl::OUString& DialogName,
+ const Sequence< sal_Int8 >& Data
+)
+ throw(NoSuchElementException, RuntimeException)
+{
+ (void)LibraryName;
+ (void)DialogName;
+ (void)Data;
+}
+
+// Basic XML Import/Export
+Reference< XStarBasicAccess > getStarBasicAccess( BasicManager* pMgr )
+{
+ Reference< XStarBasicAccess > xRet =
+ new StarBasicAccess_Impl( (BasicManager*)pMgr );
+ return xRet;
+}
+
diff --git a/basic/source/basmgr/makefile.mk b/basic/source/basmgr/makefile.mk
new file mode 100644
index 000000000000..e08e9cc753bd
--- /dev/null
+++ b/basic/source/basmgr/makefile.mk
@@ -0,0 +1,46 @@
+#*************************************************************************
+#
+# 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=basicmgr
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+
+# --- Allgemein -----------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/basmgr.obj \
+ $(SLO)$/basicmanagerrepository.obj
+
+# --- Targets -------------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/basic/source/classes/disas.cxx b/basic/source/classes/disas.cxx
new file mode 100644
index 000000000000..a837a3dc4f24
--- /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
+BOOL SbModule::Disassemble( String& rText )
+{
+ rText.Erase();
+ if( pImage )
+ {
+ SbiDisas aDisas( this, pImage );
+ aDisas.Disas( rText );
+ }
+ return 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( USHORT i = 0; i < pMod->GetMethods()->Count(); i++ )
+ {
+ SbMethod* pMeth = PTR_CAST(SbMethod,pMod->GetMethods()->Get( i ));
+ if( pMeth )
+ {
+ USHORT nPos = (USHORT) (pMeth->GetId());
+ cLabels[ nPos >> 3 ] |= ( 1 << ( nPos & 7 ) );
+ }
+ }
+}
+
+// Read current opcode
+BOOL SbiDisas::Fetch()
+{
+ nPC = nOff;
+ if( nOff >= rImg.GetCodeSize() )
+ return 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 TRUE;
+ }
+ else if( eOp <= SbOP1_END )
+ {
+ nOff += 5;
+ if( nOff > rImg.GetCodeSize() )
+ return FALSE;
+ nOp1 = *p++; nOp1 |= *p++ << 8; nOp1 |= *p++ << 16; nOp1 |= *p++ << 24;
+ nParts = 2;
+ return TRUE;
+ }
+ else if( eOp <= SbOP2_END )
+ {
+ nOff += 9;
+ if( nOff > rImg.GetCodeSize() )
+ return 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 TRUE;
+ }
+ else
+ return 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();
+}
+
+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 FALSE;
+
+#ifdef DBG_TRACE_BASIC
+ String aTraceStr_STMNT;
+#endif
+
+ // New line?
+ if( eOp == _STMNT && nOp1 != nLine )
+ {
+ // Find line
+ String aSource = rImg.aOUSource;
+ nLine = nOp1;
+ USHORT n = 0;
+ USHORT l = (USHORT)nLine;
+ while( --l ) {
+ n = aSource.SearchAscii( "\n", n );
+ if( n == STRING_NOTFOUND ) break;
+ else n++;
+ }
+ // Show position
+ if( n != STRING_NOTFOUND )
+ {
+ USHORT n2 = aSource.SearchAscii( "\n", n );
+ if( n2 == STRING_NOTFOUND ) n2 = aSource.Len() - n;
+ String s( aSource.Copy( n, n2 - n + 1 ) );
+ BOOL bDone;
+ do {
+ bDone = TRUE;
+ n = s.Search( '\r' );
+ if( n != STRING_NOTFOUND ) bDone = FALSE, s.Erase( n, 1 );
+ n = s.Search( '\n' );
+ if( n != STRING_NOTFOUND ) bDone = 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( USHORT 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, (USHORT) 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 TRUE;
+}
+
+// Read from StringPool
+void SbiDisas::StrOp( String& rText )
+{
+ String aStr = rImg.GetString( (USHORT)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 += (USHORT)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
+// 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 += (USHORT)nOp1;
+}
+
+// Print var: String-ID and type
+void SbiDisas::VarOp( String& rText )
+{
+ rText += rImg.GetString( (USHORT)(nOp1 & 0x7FFF) );
+ rText.AppendAscii( "\t; " );
+ // The type
+ 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( (USHORT)(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
+ 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 += (USHORT)nOp1;
+ }
+}
+#ifdef HP9000
+#undef pTypes
+#endif
+
+// 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 += ',';
+ UINT32 nCol = nOp2 & 0xFF;
+ 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..791e9fe5a8c1
--- /dev/null
+++ b/basic/source/classes/eventatt.cxx
@@ -0,0 +1,647 @@
+/*************************************************************************
+ *
+ * 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;
+
+
+
+Reference< frame::XModel > 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 aThisComponent( sbxToUnoValue( pThisComponent ) );
+ Reference< frame::XModel > xModel( aThisComponent, UNO_QUERY );
+ if ( !xModel.is() )
+ {
+ // it's no XModel. Okay, ThisComponent nowadays is allowed to be a controller.
+ Reference< frame::XController > xController( aThisComponent, 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;
+}
+
+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: ???
+ //NAMESPACE_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
+ USHORT 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< USHORT >(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, 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 = 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..79f49eb8724a
--- /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 = FALSE;
+ bFirstInit = 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 = FALSE;
+}
+
+/**************************************************************************
+*
+* Service-Routines for Load/Store
+*
+**************************************************************************/
+
+BOOL SbiGood( SvStream& r )
+{
+ return BOOL( !r.IsEof() && r.GetError() == SVSTREAM_OK );
+}
+
+// Open Record
+ULONG SbiOpenRecord( SvStream& r, UINT16 nSignature, UINT16 nElem )
+{
+ ULONG nPos = r.Tell();
+ r << nSignature << (INT32) 0 << nElem;
+ return nPos;
+}
+
+// Close Record
+void SbiCloseRecord( SvStream& r, ULONG nOff )
+{
+ ULONG nPos = r.Tell();
+ r.Seek( nOff + 2 );
+ r << (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
+BOOL SbiImage::Load( SvStream& r )
+{
+ UINT32 nVersion = 0; // Versionsnumber
+ return Load( r, nVersion );
+}
+BOOL SbiImage::Load( SvStream& r, UINT32& nVersion )
+{
+
+ UINT16 nSign, nCount;
+ UINT32 nLen, nOff;
+
+ Clear();
+ // Read Master-Record
+ r >> nSign >> nLen >> nCount;
+ ULONG nLast = r.Tell() + nLen;
+ UINT32 nCharSet; // System charset
+ UINT32 lDimBase;
+ UINT16 nReserved1;
+ UINT32 nReserved2;
+ UINT32 nReserved3;
+ BOOL bBadVer = FALSE;
+ if( nSign == B_MODULE )
+ {
+ r >> nVersion >> nCharSet >> lDimBase
+ >> nFlags >> nReserved1 >> nReserved2 >> nReserved3;
+ eCharSet = (CharSet) nCharSet;
+ eCharSet = GetSOLoadTextEncoding( eCharSet );
+ bBadVer = BOOL( nVersion > B_CURVERSION );
+ nDimBase = (USHORT) lDimBase;
+ }
+
+ bool bLegacy = ( nVersion < B_EXT_IMG_VERSION );
+
+ ULONG 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( 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 = (UINT16) nCodeSize;
+ pLegacyPCode = pCode;
+
+ PCodeBuffConvertor< UINT16, UINT32 > aLegacyToNew( (BYTE*)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 ] = (USHORT) nOff;
+ }
+ r >> nLen;
+ if( SbiGood( r ) )
+ {
+ delete [] pStrings;
+ pStrings = new sal_Unicode[ nLen ];
+ nStringSize = (USHORT) nLen;
+
+ char* pByteStrings = new char[ nLen ];
+ r.Read( pByteStrings, nStringSize );
+ for( short j = 0; j < nStrings; j++ )
+ {
+ USHORT nOff2 = (USHORT) 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 = TRUE;
+ return BOOL( !bError );
+}
+
+BOOL SbiImage::Save( SvStream& r, 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 TRUE;
+ }
+ // First of all the header
+ ULONG nStart = SbiOpenRecord( r, B_MODULE, 1 );
+ ULONG nPos;
+
+ eCharSet = GetSOStoreTextEncoding( eCharSet );
+ if ( bLegacy )
+ r << (INT32) B_LEGACYVERSION;
+ else
+ r << (INT32) B_CURVERSION;
+ r << (INT32) eCharSet
+ << (INT32) nDimBase
+ << (INT16) nFlags
+ << (INT16) 0
+ << (INT32) 0
+ << (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;
+ UINT16 nUnitCount = UINT16( (nRemainingLen + nMaxUnitSize - 1) / nMaxUnitSize );
+ nPos = SbiOpenRecord( r, B_EXTSOURCE, nUnitCount );
+ for( 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< UINT32, UINT16 > aNewToLegacy( (BYTE*)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:
+ // UINT32 Offset of the Strings in the Stringblock
+ short i;
+
+ for( i = 0; i < nStrings && SbiGood( r ); i++ )
+ r << (UINT32) pStringOff[ i ];
+
+ // Then the String-Block
+ char* pByteStrings = new char[ nStringSize ];
+ for( i = 0; i < nStrings; i++ )
+ {
+ USHORT nOff = (USHORT) pStringOff[ i ];
+ ByteString aStr( pStrings + nOff, eCharSet );
+ memcpy( pByteStrings + nOff, aStr.GetBuffer(), (aStr.Len() + 1) * sizeof( char ) );
+ }
+ r << (UINT32) nStringSize;
+ r.Write( pByteStrings, nStringSize );
+
+ delete[] pByteStrings;
+ SbiCloseRecord( r, nPos );
+ }
+ // Set overall length
+ SbiCloseRecord( r, nStart );
+ if( !SbiGood( r ) )
+ bError = TRUE;
+ return 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 UINT32[ nSize ];
+ if( pStrings && pStringOff )
+ {
+ nStrings = nSize;
+ memset( pStringOff, 0, nSize * sizeof( UINT32 ) );
+ memset( pStrings, 0, nStringSize * sizeof( sal_Unicode ) );
+ }
+ else
+ bError = 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 = TRUE;
+ if( !bError )
+ {
+ xub_StrLen len = r.Len() + 1;
+ UINT32 needed = nStringOff + len;
+ if( needed > 0xFFFFFF00L )
+ bError = TRUE; // out of mem!
+ else if( needed > nStringSize )
+ {
+ 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< UINT16 >(nNewLen);
+ }
+ else
+ bError = 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, 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 )
+ {
+ UINT32 nOff = pStringOff[ nId - 1 ];
+ sal_Unicode* pStr = pStrings + nOff;
+
+ // #i42467: Special treatment for vbNullChar
+ if( *pStr == 0 )
+ {
+ UINT32 nNextOff = (nId < nStrings) ? pStringOff[ nId ] : nStringOff;
+ 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;
+}
+
+UINT16 SbiImage::CalcLegacyOffset( INT32 nOffset )
+{
+ return SbiCodeGen::calcLegacyOffSet( (BYTE*)pCode, nOffset ) ;
+}
+
+UINT32 SbiImage::CalcNewOffset( INT16 nOffset )
+{
+ return SbiCodeGen::calcNewOffSet( (BYTE*)pLegacyPCode, nOffset ) ;
+}
+
+void SbiImage::ReleaseLegacyBuffer()
+{
+ delete[] pLegacyPCode;
+ pLegacyPCode = NULL;
+ nLegacyCodeSize = 0;
+}
+
+BOOL SbiImage::ExceedsLegacyLimits()
+{
+ if ( ( nStringSize > 0xFF00L ) || ( CalcLegacyOffset( nCodeSize ) > 0xFF00L ) )
+ return TRUE;
+ return 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..8c7fa0b273b2
--- /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 ( USHORT 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;
+}
+
+//-------------------------------------------------------------------------
+
+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)
+{
+ INT32 nIndex = GetIndex_Impl( aPropertyName );
+ PropertyValue *pPropVal = _aPropVals.GetObject(
+ sal::static_int_cast< USHORT >(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)
+{
+ INT32 nIndex = GetIndex_Impl( aPropertyName );
+ if ( nIndex != USHRT_MAX )
+ return _aPropVals.GetObject(
+ sal::static_int_cast< USHORT >(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 ( USHORT 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()
+{
+}
+
+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<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 ( USHORT 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 );
+}
+
+BOOL SbPropertySetInfo::hasPropertyByName(const ::rtl::OUString& Name)
+ throw( RuntimeException )
+{
+ return aImpl.hasPropertyByName( Name );
+}
+
+
+//----------------------------------------------------------------------------
+
+SbPropertyContainer::SbPropertyContainer()
+{
+}
+
+//----------------------------------------------------------------------------
+
+SbPropertyContainer::~SbPropertyContainer()
+{
+}
+
+//----------------------------------------------------------------------------
+void SbPropertyContainer::addProperty(const ::rtl::OUString& Name,
+ 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 );
+}
+
+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, 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 100755
index 000000000000..056c2ea38c4c
--- /dev/null
+++ b/basic/source/classes/sb.cxx
@@ -0,0 +1,2109 @@
+/*************************************************************************
+ *
+ * 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 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
+{
+ USHORT 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( UINT16 nSbxId, 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( UINT16 nSbxId, UINT32 = SBXCR_SBX );
+ virtual SbxObject* CreateObject( const String& );
+};
+
+SbxBase* SbOLEFactory::Create( UINT16, 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( UINT16 nSbxId, UINT32 = SBXCR_SBX );
+ virtual SbxObject* CreateObject( const String& );
+};
+
+SbxBase* SbFormFactory::Create( UINT16, 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() ) )
+ {
+ 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();
+ UINT32 nCount = pProps->Count32();
+ for( 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() );
+ INT32 lb = 0;
+ INT32 ub = 0;
+
+ pDest->setHasFixedSize( pSource->hasFixedSize() );
+ if ( pSource->GetDims() && pSource->hasFixedSize() )
+ {
+ for ( INT32 j = 1 ; j <= pSource->GetDims(); ++j )
+ {
+ pSource->GetDim32( (INT32)j, lb, ub );
+ pDest->AddDim32( lb, ub );
+ }
+ }
+ else
+ pDest->unoAddDim( 0, -1 ); // variant array
+
+ USHORT 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( UINT16 nSbxId, UINT32 = SBXCR_SBX );
+ virtual SbxObject* CreateObject( const String& );
+};
+
+SbxBase* SbTypeFactory::Create( UINT16, 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();
+ UINT32 nMethodCount = pClassMethods->Count32();
+ 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 )
+ {
+ USHORT 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(), 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();
+ UINT32 nPropertyCount = pClassProps->Count32();
+ for( i = 0 ; i < nPropertyCount ; i++ )
+ {
+ SbxVariable* pVar = pClassProps->Get32( i );
+ SbProcedureProperty* pProcedureProp = PTR_CAST( SbProcedureProperty, pVar );
+ if( pProcedureProp )
+ {
+ USHORT 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(), TRUE );
+ }
+ else
+ {
+ SbxProperty* pProp = PTR_CAST( SbxProperty, pVar );
+ if( pProp )
+ {
+ USHORT 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();
+ (void)aObjClass;
+
+ 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 )
+{
+ 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();
+ USHORT nVarParCount = (pArg != NULL) ? pArg->Count() : 0;
+ if( nVarParCount > 1 )
+ {
+ SbxArrayRef xMethParameters = new SbxArray;
+ xMethParameters->Put( pMeth, 0 ); // Method as parameter 0
+ for( USHORT 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::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+}
+
+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( UINT16, 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;
+}
+
+StarBASIC::StarBASIC( StarBASIC* p, BOOL bIsDocBasic )
+ : SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("StarBASIC") ) ), bDocBasic( bIsDocBasic )
+{
+ SetParent( p );
+ pLibInfo = NULL;
+ bNoRtl = bBreak = FALSE;
+ bVBAEnabled = FALSE;
+ pModules = new SbxArray;
+
+ if( !GetSbData()->nInst++ )
+ {
+ pSBFAC = new SbiFactory;
+ AddFactory( pSBFAC );
+ pUNOFAC = new SbUnoFactory;
+ AddFactory( pUNOFAC );
+ pTYPEFAC = new SbTypeFactory;
+ AddFactory( pTYPEFAC );
+ pCLASSFAC = new SbClassFactory;
+ AddFactory( pCLASSFAC );
+ pOLEFAC = new SbOLEFactory;
+ AddFactory( pOLEFAC );
+ pFORMFAC = new SbFormFactory;
+ AddFactory( pFORMFAC );
+ }
+ pRtl = new SbiStdObject( String( RTL_CONSTASCII_USTRINGPARAM(RTLNAME) ), this );
+ // Search via StarBasic is always global
+ SetFlag( SBX_GBLSEARCH );
+ pVBAGlobals = NULL;
+ bQuit = FALSE;
+}
+
+// #51727 Override SetModified so that the modified state
+// is not given to the parent
+void StarBASIC::SetModified( 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
+ }
+
+ // #100326 Set Parent NULL in registered listeners
+ if( xUnoListeners.Is() )
+ {
+ USHORT uCount = xUnoListeners->Count();
+ for( USHORT i = 0 ; i < uCount ; i++ )
+ {
+ SbxVariable* pListenerObj = xUnoListeners->Get( i );
+ pListenerObj->SetParent( NULL );
+ }
+ xUnoListeners = NULL;
+ }
+}
+
+// Override new() operator, so that everyone can create a new instance
+void* StarBASIC::operator new( size_t n )
+{
+ if( n < sizeof( StarBASIC ) )
+ {
+// DBG_ASSERT( FALSE, "Warnung: inkompatibler BASIC-Stand!" );
+ n = sizeof( StarBASIC );
+ }
+ return ::operator new( n );
+}
+
+void StarBASIC::operator delete( void* p )
+{
+ ::operator delete( p );
+}
+
+/**************************************************************************
+*
+* 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( TRUE );
+ return p;
+}
+
+void StarBASIC::Insert( SbxVariable* pVar )
+{
+ if( pVar->IsA( TYPE(SbModule) ) )
+ {
+ pModules->Insert( pVar, pModules->Count() );
+ pVar->SetParent( this );
+ StartListening( pVar->GetBroadcaster(), TRUE );
+ }
+ else
+ {
+ BOOL bWasModified = IsModified();
+ SbxObject::Insert( pVar );
+ if( !bWasModified && pVar->IsSet( SBX_DONTSTORE ) )
+ SetModified( 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 );
+}
+
+BOOL StarBASIC::Compile( SbModule* pMod )
+{
+ return pMod ? pMod->Compile() : FALSE;
+}
+
+BOOL StarBASIC::Disassemble( SbModule* pMod, String& rText )
+{
+ rText.Erase();
+ if( pMod )
+ pMod->Disassemble( rText );
+ return BOOL( rText.Len() != 0 );
+}
+
+void StarBASIC::Clear()
+{
+ while( pModules->Count() )
+ pModules->Remove( pModules->Count() - 1 );
+}
+
+SbModule* StarBASIC::FindModule( const String& rName )
+{
+ for( USHORT 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 )
+ {}
+};
+
+typedef std::hash_map< ::rtl::OUString, ClassModuleRunInitItem,
+ ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > ModuleInitDependencyMap;
+
+static ModuleInitDependencyMap* GpMIDMap = NULL;
+
+void SbModule::implProcessModuleRunInit( ClassModuleRunInitItem& rItem )
+{
+ ModuleInitDependencyMap& rMIDMap = *GpMIDMap;
+
+ 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 = rMIDMap.find( rStr );
+ if( itFind != rMIDMap.end() )
+ {
+ ClassModuleRunInitItem& rParentItem = itFind->second;
+ if( rParentItem.m_bProcessing )
+ {
+ // TODO: raise error?
+ DBG_ERROR( "Cyclic module dependency detected" );
+ continue;
+ }
+
+ if( !rParentItem.m_bRunInitDone )
+ implProcessModuleRunInit( 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 )
+{
+ // Init own modules
+ for ( USHORT 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;
+ GpMIDMap = &aMIDMap;
+ for ( USHORT 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( rItem );
+ }
+ GpMIDMap = NULL;
+
+ // Call RunInit on standard modules
+ for ( USHORT 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 ( USHORT 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 ( USHORT nMod = 0; nMod < pModules->Count(); nMod++ )
+ {
+ SbModule* pModule = (SbModule*)pModules->Get( nMod );
+ if( pModule->pImage )
+ pModule->pImage->bInit = false;
+ }
+
+ for ( USHORT 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() );
+ USHORT nPropCount = xProps->Count();
+ for ( USHORT nProp = 0 ; nProp < nPropCount ; ++nProp )
+ {
+ SbxBase* pVar = xProps->Get( nProp );
+ pVar->Clear();
+ }
+ SetModified( 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( USHORT 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
+ 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)
+ USHORT 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;
+}
+
+BOOL StarBASIC::Call( const String& rName, SbxArray* pParam )
+{
+ 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, USHORT& 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 = TRUE;
+}
+
+void StarBASIC::Stop()
+{
+ SbiInstance* p = pINST;
+ while( p )
+ {
+ p->Stop();
+ p = p->pNext;
+ }
+}
+
+BOOL StarBASIC::IsRunning()
+{
+ return 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, 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( USHORT 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( USHORT nLevel )
+{
+ if( pINST )
+ return pINST->GetCaller( nLevel );
+ else
+ return NULL;
+}
+
+SbModule* StarBASIC::GetActiveModule()
+{
+ if( pINST && !IsCompilerError() )
+ return pINST->GetActiveModule();
+ else
+ return pCMOD;
+}
+
+USHORT StarBASIC::BreakPoint( USHORT l, USHORT c1, USHORT c2 )
+{
+ SetErrorData( 0, l, c1, c2 );
+ bBreak = TRUE;
+ if( GetSbData()->aBreakHdl.IsSet() )
+ return (USHORT) GetSbData()->aBreakHdl.Call( this );
+ else
+ return BreakHdl();
+}
+
+USHORT StarBASIC::StepPoint( USHORT l, USHORT c1, USHORT c2 )
+{
+ SetErrorData( 0, l, c1, c2 );
+ bBreak = FALSE;
+ if( GetSbData()->aBreakHdl.IsSet() )
+ return (USHORT) GetSbData()->aBreakHdl.Call( this );
+ else
+ return BreakHdl();
+}
+
+USHORT __EXPORT StarBASIC::BreakHdl()
+{
+ return (USHORT) ( aBreakHdl.IsSet()
+ ? aBreakHdl.Call( this ) : SbDEBUG_CONTINUE );
+}
+
+// Calls for error handler and break handler
+USHORT StarBASIC::GetLine() { return GetSbData()->nLine; }
+USHORT StarBASIC::GetCol1() { return GetSbData()->nCol1; }
+USHORT StarBASIC::GetCol2() { return GetSbData()->nCol2; }
+
+// Specific to error handler
+SbError StarBASIC::GetErrorCode() { return GetSbData()->nCode; }
+const String& StarBASIC::GetErrorText() { return GetSbData()->aErrMsg; }
+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
+USHORT StarBASIC::GetVBErrorCode( SbError nError )
+{
+ USHORT 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;
+ USHORT 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( USHORT 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;
+ USHORT 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, USHORT nLine, USHORT nCol1, USHORT 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, USHORT nId)
+ : Resource( rErrIdP ),aResId(nId, *rErrIdP.GetResMgr() ){}
+ ~BasicStringList_Impl() { FreeResource(); }
+
+ String GetString(){ return String( aResId ); }
+ BOOL IsErrorTextAvailable( void )
+ { return IsAvailableRes(aResId.SetRT(RSC_STRING)); }
+};
+//----------------------------------------------------------------
+
+// #60175 Flag, das bei Basic-Fehlern das Anziehen der SFX-Resourcen verhindert
+static BOOL bStaticSuppressSfxResource = FALSE;
+
+void StarBASIC::StaticSuppressSfxResource( BOOL bSuppress )
+{
+ bStaticSuppressSfxResource = bSuppress;
+}
+
+// Hack for #83750, use bStaticSuppressSfxResource as setup flag
+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;
+ }
+
+ USHORT nOldID = GetVBErrorCode( nId );
+
+ // Hilfsklasse instanzieren
+ BasResId aId( RID_BASIC_START );
+ BasicStringList_Impl aMyStringList( aId, USHORT(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)") );
+ USHORT 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();
+
+}
+
+BOOL StarBASIC::CError
+ ( SbError code, const String& rMsg, USHORT l, USHORT c1, USHORT 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 FALSE;
+
+ Stop();
+ }
+
+ // Flag setzen, damit GlobalRunInit den Fehler mitbekommt
+ GetSbData()->bGlobalInitErr = TRUE;
+
+ // Fehlertext basteln
+ MakeErrorText( code, rMsg );
+
+ // Umsetzung des Codes fuer String-Transport in SFX-Error
+ if( rMsg.Len() )
+ code = (ULONG)*new StringErrorInfo( code, String(rMsg) );
+
+ SetErrorData( code, l, c1, c2 );
+ GetSbData()->bCompiler = TRUE;
+ BOOL bRet;
+ if( GetSbData()->aErrHdl.IsSet() )
+ bRet = (BOOL) GetSbData()->aErrHdl.Call( this );
+ else
+ bRet = ErrorHdl();
+ GetSbData()->bCompiler = FALSE; // nur TRUE fuer Error-Handler
+ return bRet;
+}
+
+BOOL StarBASIC::RTError
+ ( SbError code, USHORT l, USHORT c1, USHORT c2 )
+{
+ return RTError( code, String(), l, c1, c2 );
+}
+
+BOOL StarBASIC::RTError( SbError code, const String& rMsg, USHORT l, USHORT c1, USHORT 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 = (ULONG)*new StringErrorInfo( code, aTmp );
+ }
+ else
+ code = (ULONG)*new StringErrorInfo( code, String(rMsg) );
+ }
+
+ SetErrorData( code, l, c1, c2 );
+ if( GetSbData()->aErrHdl.IsSet() )
+ return (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();
+}
+
+USHORT StarBASIC::GetErl()
+{
+ if( pINST )
+ return pINST->GetErl();
+ else
+ return 0;
+}
+
+BOOL __EXPORT StarBASIC::ErrorHdl()
+{
+ return (BOOL) ( aErrorHdl.IsSet()
+ ? aErrorHdl.Call( this ) : 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
+*
+**************************************************************************/
+
+BOOL StarBASIC::LoadData( SvStream& r, USHORT nVer )
+{
+ if( !SbxObject::LoadData( r, nVer ) )
+ return FALSE;
+
+ // #95459 Delete dialogs, otherwise endless recursion
+ // in SbxVarable::GetType() if dialogs are accessed
+ USHORT nObjCount = pObjs->Count();
+ SbxVariable** ppDeleteTab = new SbxVariable*[ nObjCount ];
+ USHORT 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;
+
+ UINT16 nMod;
+ pModules->Clear();
+ r >> nMod;
+ for( USHORT i = 0; i < nMod; i++ )
+ {
+ SbModule* pMod = (SbModule*) SbxBase::Load( r );
+ if( !pMod )
+ return 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 TRUE;
+}
+
+BOOL StarBASIC::StoreData( SvStream& r ) const
+{
+ if( !SbxObject::StoreData( r ) )
+ return FALSE;
+ r << (UINT16) pModules->Count();
+ for( USHORT i = 0; i < pModules->Count(); i++ )
+ {
+ SbModule* p = (SbModule*) pModules->Get( i );
+ if( !p->Store( r ) )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL StarBASIC::LoadOldModules( SvStream& )
+{
+ return 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;
+}
+
+//========================================================================
+// #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 USHORT 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 )
+ {
+ ULONG nId = p->GetId();
+ BOOL bRead = BOOL( nId == SBX_HINT_DATAWANTED );
+ BOOL bWrite = BOOL( nId == SBX_HINT_DATACHANGED );
+ BOOL bRequestInfo = 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 );
+}
+
+INT32 BasicCollection::implGetIndex( SbxVariable* pIndexVar )
+{
+ INT32 nIndex = -1;
+ if( pIndexVar->GetType() == SbxSTRING )
+ nIndex = implGetIndexForName( pIndexVar->GetString() );
+ else
+ nIndex = pIndexVar->GetLong() - 1;
+ return nIndex;
+}
+
+INT32 BasicCollection::implGetIndexForName( const String& rName )
+{
+ INT32 nIndex = -1;
+ INT32 nCount = xItemArray->Count32();
+ INT32 nNameHash = MakeHashCode( rName );
+ for( 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_ )
+{
+ USHORT 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);
+ INT32 nAfterIndex = implGetIndex( pAfter );
+ if( nAfterIndex == -1 )
+ {
+ SetError( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ nNextIndex = nAfterIndex + 1;
+ }
+ else // if( nCount == 4 )
+ {
+ 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 );
+ INT32 nIndex = implGetIndex( p );
+ if( nIndex >= 0 && nIndex < (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 );
+ INT32 nIndex = implGetIndex( p );
+ if( nIndex >= 0 && nIndex < (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..55b5f7f371ce
--- /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 = FALSE;
+ bGlobalInitErr = FALSE;
+ bRunInit = FALSE;
+ eLanguageMode = SB_LANG_BASIC;
+ pErrStack = NULL;
+ pTransliterationWrapper = NULL;
+ bBlockCompilerError = 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..c9123b06341b
--- /dev/null
+++ b/basic/source/classes/sbunoobj.cxx
@@ -0,0 +1,4434 @@
+/*************************************************************************
+ *
+ * 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/exc_hlp.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/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/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/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( (USHORT)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( (USHORT)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 ) );
+ }
+}
+
+// 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, (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;
+ 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;
+ USHORT nFlags = pVar->GetFlags();
+ pVar->ResetFlag( SBX_FIXED );
+ pVar->PutObject( (SbxDimArray*)xArray );
+ pVar->SetFlags( nFlags );
+ }
+ 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< INT32 >(
+ nValue64 >> 32);
+ aInt64.nLow = (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, (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
+ USHORT 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;
+
+ INT32 nSize = nUpper - nLower + 1;
+ INT32 nIdx = nLower;
+ for( 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
+ UINT32 nFlatArraySize = pArray->Count32();
+
+ sal_Bool bNeedsInit = sal_True;
+ for( 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;
+ }
+ }
+ }
+
+ 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 );
+}
+
+// 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;
+
+ /* 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, USHORT nRekLevel )
+{
+ Type aIfaceType = ::getCppuType( (const Reference< XInterface > *)0 );
+ static Reference< XIdlClass > xIfaceClass = TypeToIdlClass( aIfaceType );
+
+ String aRetStr;
+ for( USHORT 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();
+ UINT32 nSuperIfaceCount = aSuperClassSeq.getLength();
+ for( 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();
+ UINT32 nIfaceCount = aTypeSeq.getLength();
+ for( 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();
+ UINT32 nIfaceCount = aTypeSeq.getLength();
+ for( 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 );
+ UINT32 nUnoPropCount = props.getLength();
+ const Property* pUnoProps = props.getConstArray();
+
+ SbxArray* pProps = pUnoObj->GetProperties();
+ USHORT nPropCount = pProps->Count();
+ USHORT nPropsPerLine = 1 + nPropCount / 30;
+ for( USHORT 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();
+
+ BOOL bMaybeVoid = 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 = 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();
+ USHORT nMethodCount = pMethods->Count();
+ if( !nMethodCount )
+ {
+ aRet.AppendAscii( "\nNo methods found\n" );
+ return aRet;
+ }
+ USHORT nPropsPerLine = 1 + nMethodCount / 30;
+ for( USHORT 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();
+ UINT32 nParamCount = aParamsSeq.getLength();
+ const Reference< XIdlClass >* pParams = aParamsSeq.getConstArray();
+
+ if( nParamCount > 0 )
+ {
+ for( USHORT 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
+ 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
+ UINT32 nParamCount = pParams ? ((UINT32)pParams->Count() - 1) : 0;
+ Sequence<Any> args;
+ BOOL bOutParams = FALSE;
+ UINT32 i;
+
+ if( !bInvocation && mxUnoAccess.is() )
+ {
+ // Infos holen
+ const Sequence<ParamInfo>& rInfoSeq = pMeth->getParamInfos();
+ const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
+ UINT32 nUnoParamCount = rInfoSeq.getLength();
+ 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( (USHORT)(i+1) ), aType );
+
+ // Wenn es nicht schon feststeht pruefen, ob Out-Parameter vorliegen
+ if( !bOutParams )
+ {
+ ParamMode aParamMode = rInfo.aMode;
+ if( aParamMode != ParamMode_IN )
+ bOutParams = 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++ )
+ {
+ USHORT iSbx = (USHORT)(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( (USHORT)(i+1) ),
+ bBlockConversionToSmallestType );
+ }
+ }
+ }
+
+ // Methode callen
+ GetSbData()->bBlockCompilerError = 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();
+
+ 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( (USHORT)(j+1) ), pAnyArgs[ j ] );
+ }
+ }
+ }
+ else if( bInvocation && mxInvocation.is() )
+ {
+ Sequence< INT16 > OutParamIndex;
+ Sequence< Any > OutParam;
+ Any aRetAny = mxInvocation->invoke( pMeth->GetName(), args, OutParamIndex, OutParam );
+
+ // Wert von Uno nach Sbx uebernehmen
+ unoToSbxValue( pVar, aRetAny );
+
+ const INT16* pIndices = OutParamIndex.getConstArray();
+ UINT32 nLen = OutParamIndex.getLength();
+ if( nLen )
+ {
+ const Any* pNewValues = OutParam.getConstArray();
+ for( UINT32 j = 0 ; j < nLen ; j++ )
+ {
+ INT16 iTarget = pIndices[ j ];
+ if( iTarget >= (INT16)nParamCount )
+ break;
+ unoToSbxValue( (SbxVariable*)pParams->Get( (USHORT)(j+1) ), pNewValues[ j ] );
+ }
+ }
+ }
+
+ // #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 = 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( TRUE )
+ , bIgnoreNativeCOMObjectMembers( 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 = 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() )
+ bIgnoreNativeCOMObjectMembers = TRUE;
+ }
+
+ maTmpUnoObj = aUnoObj_;
+
+
+ //*** Namen bestimmen ***
+ BOOL bFatalError = TRUE;
+
+ // Ist es ein Interface oder eine struct?
+ BOOL bSetClassName = FALSE;
+ String aClassName_;
+ if( eType == TypeClass_STRUCT || eType == TypeClass_EXCEPTION )
+ {
+ // Struct ist Ok
+ bFatalError = FALSE;
+
+ // #67173 Echten Klassen-Namen eintragen
+ if( aName_.Len() == 0 )
+ {
+ aClassName_ = String( aUnoObj_.getValueType().getTypeName() );
+ bSetClassName = TRUE;
+ }
+ }
+ else if( eType == TypeClass_INTERFACE )
+ {
+ // #70197 Interface geht immer durch Typ im Any
+ bFatalError = 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();
+ UINT32 nLen = szClasses.getLength();
+ if( nLen )
+ {
+ const Reference< XIdlClass > xImplClass = szClasses.getConstArray()[ 0 ];
+ if( xImplClass.is() )
+ {
+ aClassName_ = String( xImplClass->getName() );
+ bSetClassName = 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 = 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 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
+)
+ : SbxMethod( aName_, eSbxType )
+ , mbInvocation( bInvocation )
+{
+ 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();
+ UINT32 nParamCount = rInfoSeq.getLength();
+
+ for( 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;
+ USHORT 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_,
+ 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() && !bIgnoreNativeCOMObjectMembers )
+ {
+ 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;
+ }
+ }
+ 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() || bIgnoreNativeCOMObjectMembers )
+ {
+ if( mxInvocation.is() )
+ xAccess = mxInvocation->getIntrospection();
+ else if( bIgnoreNativeCOMObjectMembers )
+ return;
+ }
+ if( !xAccess.is() )
+ return;
+
+ // Properties anlegen
+ Sequence<Property> props = xAccess->getProperties( PropertyConcept::ALL - PropertyConcept::DANGEROUS );
+ UINT32 nPropCount = props.getLength();
+ const Property* pProps_ = props.getConstArray();
+
+ 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 );
+ 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( UINT16, 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, 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, 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, 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, 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, BOOL bWrite )
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // Wir brauchen mindestens 2 Parameter
+ USHORT nParCount = rPar.Count();
+ if( nParCount < 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Variable fuer Rueckgabewert
+ SbxVariableRef refVar = rPar.Get(0);
+ refVar->PutBool( 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( USHORT 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 TRUE liefern
+ refVar->PutBool( TRUE );
+}
+
+void RTL_Impl_IsUnoStruct( StarBASIC* pBasic, SbxArray& rPar, 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( 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( TRUE );
+}
+
+
+void RTL_Impl_EqualUnoObjects( StarBASIC* pBasic, SbxArray& rPar, 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( 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( 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(), 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
+ UINT32 nParamCount = pParams ? ((UINT32)pParams->Count() - 1) : 0;
+ Sequence<Any> args;
+ BOOL bOutParams = FALSE;
+
+ Reference< XServiceConstructorDescription > xCtor = pUnoCtor->getServiceCtorDesc();
+ Sequence< Reference< XParameter > > aParameterSeq = xCtor->getParameters();
+ const Reference< XParameter >* pParameterSeq = aParameterSeq.getConstArray();
+ 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?
+ USHORT nSbxParameterOffset = 1;
+ USHORT 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;
+ }
+
+ UINT32 nEffectiveParamCount = nParamCount - nParameterOffsetByContext;
+ 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( UINT32 i = 0 ; i < nEffectiveParamCount ; i++ )
+ {
+ USHORT iSbx = (USHORT)(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 = 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( UINT32 j = 0 ; j < nUnoParamCount ; j++ )
+ {
+ Reference< XParameter > xParam = pParameterSeq[j];
+ if( !xParam.is() )
+ continue;
+
+ if( xParam->isOut() )
+ unoToSbxValue( (SbxVariable*)pParams->Get( (USHORT)(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();
+ UINT32 nParamCount = pParams ? ((UINT32)pParams->Count() - 1) : 0;
+ 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 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 )
+{
+ NAMESPACE_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();
+ INT32 nCount = Event.Arguments.getLength();
+ for( 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< USHORT >(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
+ USHORT 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 )
+{
+ NAMESPACE_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, 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, 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, BOOL bWrite )
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // 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);
+
+ // 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 );
+}
+
+//==========================================================================
+
+typedef WeakImplHelper1< XInvocation > ModuleInvocationProxyHelper;
+
+class ModuleInvocationProxy : public ModuleInvocationProxyHelper
+{
+ ::rtl::OUString m_aPrefix;
+ SbxObjectRef m_xScopeObj;
+ bool m_bProxyIsClassModuleObject;
+
+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 );
+};
+
+ModuleInvocationProxy::ModuleInvocationProxy( const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj )
+ : m_aPrefix( aPrefix + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_") ) )
+ , m_xScopeObj( xScopeObj )
+{
+ 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();
+
+ NAMESPACE_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();
+
+ NAMESPACE_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 )
+{
+ NAMESPACE_VOS(OGuard) guard( Application::GetSolarMutex() );
+
+ Any aRet;
+ if( !m_xScopeObj.Is() )
+ return aRet;
+
+ ::rtl::OUString aFunctionName = m_aPrefix;
+ aFunctionName += rFunction;
+
+ SbxVariable* p = m_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< USHORT >(i+1) );
+ }
+ }
+
+ // Call method
+ SbxVariableRef xValue = new SbxVariable;
+ if( xArray.Is() )
+ pMeth->SetParameters( xArray );
+ pMeth->Call( xValue );
+ aRet = sbxToUnoValue( xValue );
+ pMeth->SetParameters( NULL );
+
+ // TODO: OutParameter?
+
+ return aRet;
+}
+
+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;
+}
+
+// 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;
+ USHORT nCount = pModIfaces->Count();
+ for( USHORT 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 )
+ {
+ o_rRetAny <<= xRet;
+ break;
+ }
+ }
+ }
+
+ return bSuccess;
+}
+
diff --git a/basic/source/classes/sbxmod.cxx b/basic/source/classes/sbxmod.cxx
new file mode 100644
index 000000000000..8b1069bbeab3
--- /dev/null
+++ b/basic/source/classes/sbxmod.cxx
@@ -0,0 +1,2456 @@
+/*************************************************************************
+ *
+ * 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;
+ USHORT 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< USHORT >( 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 ( USHORT 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 )
+ {
+ USHORT 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 )
+ {
+ USHORT 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)
+
+SV_DECL_VARARR(SbiBreakpoints,USHORT,4,4)
+SV_IMPL_VARARR(SbiBreakpoints,USHORT)
+
+
+SV_IMPL_VARARR(HighlightPortions, HighlightPortion)
+
+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;
+}
+
+#if 0
+bool UnlockControllerHack( StarBASIC* pBasic )
+{
+ bool bRes = false;
+ if ( pBasic && pBasic->IsDocBasic() )
+ {
+ uno::Any aUnoVar;
+ ::rtl::OUString sVarName( ::rtl::OUString::createFromAscii( "ThisComponent" ) );
+ SbUnoObject* pGlobs = dynamic_cast<SbUnoObject*>( pBasic->Find( sVarName, SbxCLASS_DONTCARE ) );
+ if ( pGlobs )
+ aUnoVar = pGlobs->getUnoAny();
+ uno::Reference< frame::XModel > xModel( aUnoVar, uno::UNO_QUERY);
+ if ( xModel.is() )
+ {
+ try
+ {
+ xModel->unlockControllers();
+ bRes = true;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ }
+ return bRes;
+}
+#endif
+/////////////////////////////////////////////////////////////////////////////
+
+// Ein BASIC-Modul hat EXTSEARCH gesetzt, damit die im Modul enthaltenen
+// Elemente von anderen Modulen aus gefunden werden koennen.
+
+SbModule::SbModule( const String& rName, 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;
+}
+
+BOOL SbModule::IsCompiled() const
+{
+ return 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
+ USHORT i;
+ for( i = 0; i < pMethods->Count(); i++ )
+ {
+ SbMethod* p = PTR_CAST(SbMethod,pMethods->Get( i ) );
+ if( p )
+ p->bInvalid = 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(), TRUE );
+ }
+ // Per Default ist die Methode GUELTIG, da sie auch vom Compiler
+ // (Codegenerator) erzeugt werden kann
+ pMeth->bInvalid = 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(), 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(), 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 = FALSE;
+ return pMapperMethod;
+}
+
+SbIfaceMapperMethod::~SbIfaceMapperMethod()
+{
+}
+
+TYPEINIT1(SbIfaceMapperMethod,SbMethod)
+
+
+// Aus dem Codegenerator: Ungueltige Eintraege entfernen
+
+void SbModule::EndDefinitions( BOOL bNewState )
+{
+ for( USHORT 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( 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;
+
+ ULONG 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 ) )
+ {
+ BOOL bIsVBA = ( aTok.GetDbl()== 1 );
+ SetVBACompat( bIsVBA );
+ aTok.SetCompatible( bIsVBA );
+ }
+ }
+ }
+ eLastTok = eCurTok;
+ }
+ // Definition der Methode
+ SbMethod* pMeth = NULL;
+ if( eEndTok != NIL )
+ {
+ USHORT 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 = 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( TRUE );
+}
+
+void SbModule::SetComment( const String& r )
+{
+ aComment = r;
+ SetModified( TRUE );
+}
+
+SbMethod* SbModule::GetFunctionForLine( USHORT nLine )
+{
+ for( USHORT 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, ULONG 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( USHORT 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, ULONG 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();
+ USHORT nCount = pObjs->Count();
+ for( USHORT 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 );
+}
+BOOL SbModule::IsVBACompat() const
+{
+ return mbVBACompat;
+}
+
+void SbModule::SetVBACompat( BOOL bCompat )
+{
+ mbVBACompat = bCompat;
+}
+// Ausfuehren eines BASIC-Unterprogramms
+USHORT SbModule::Run( SbMethod* pMeth )
+{
+ static USHORT nMaxCallLevel = 0;
+ static String aMSOMacroRuntimeLibName = String::CreateFromAscii( "Launcher" );
+ static String aMSOMacroRuntimeAppSymbol = String::CreateFromAscii( "Application" );
+
+ USHORT nRes = 0;
+ BOOL bDelInst = 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
+ 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 )
+ {
+ USHORT 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 == 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( 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 = 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 );
+
+ DBG_ASSERT(pINST->nCallLvl==0,"BASIC-Call-Level > 0");
+ delete pINST, pINST = NULL, bDelInst = FALSE;
+
+ // #i30690
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ SendHint( GetParent(), SBX_HINT_BASICSTOP, pMeth );
+
+ GlobalRunDeInit();
+ }
+ }
+ else
+ pINST->nCallLvl--; // Call-Level wieder runter
+ }
+ else
+ {
+ pINST->nCallLvl--; // Call-Level wieder runter
+ StarBASIC::FatalError( SbERR_STACK_OVERFLOW );
+ }
+
+ // VBA always ensure screenupdating is enabled after completing
+ StarBASIC* pBasic = PTR_CAST(StarBASIC,GetParent());
+#if 0
+ if ( pBasic && pBasic->IsDocBasic() && !pINST )
+ UnlockControllerHack( pBasic );
+#endif
+ 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 = TRUE;
+
+ // BOOL bDelInst = 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 = TRUE;
+ pImage->bFirstInit = FALSE;
+
+ // RunInit ist nicht mehr aktiv
+ GetSbData()->bRunInit = 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( USHORT 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( USHORT j = 0 ; j < pArray->Count() ; j++ )
+ {
+ SbxVariable* pj = PTR_CAST(SbxVariable,pArray->Get( j ));
+ pj->SbxValue::Clear();
+ /*
+ USHORT nFlags = pj->GetFlags();
+ pj->SetFlags( (nFlags | SBX_WRITE) & (~SBX_FIXED) );
+ pj->PutEmpty();
+ pj->SetFlags( nFlags );
+ */
+ }
+ }
+ }
+ else
+ {
+ p->SbxValue::Clear();
+ /*
+ USHORT nFlags = p->GetFlags();
+ p->SetFlags( (nFlags | SBX_WRITE) & (~SBX_FIXED) );
+ p->PutEmpty();
+ p->SetFlags( nFlags );
+ */
+ }
+ }
+ }
+}
+
+// Zunaechst in dieses Modul, um 358-faehig zu bleiben
+// (Branch in sb.cxx vermeiden)
+void StarBASIC::ClearAllModuleVars( void )
+{
+ // Eigene Module initialisieren
+ for ( USHORT 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->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 ( USHORT 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( 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 = 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 BYTE* SbModule::FindNextStmnt( const BYTE* p, USHORT& nLine, USHORT& nCol ) const
+{
+ return FindNextStmnt( p, nLine, nCol, FALSE );
+}
+
+const BYTE* SbModule::FindNextStmnt( const BYTE* p, USHORT& nLine, USHORT& nCol,
+ BOOL bFollowJumps, const SbiImage* pImg ) const
+{
+ UINT32 nPC = (UINT32) ( p - (const BYTE*) 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" );
+ UINT32 nOp1 = *p++; nOp1 |= *p++ << 8;
+ nOp1 |= *p++ << 16; nOp1 |= *p++ << 24;
+ p = (const BYTE*) pImg->GetCode() + nOp1;
+ }
+ else if( eOp >= SbOP1_START && eOp <= SbOP1_END )
+ p += 4, nPC += 4;
+ else if( eOp == _STMNT )
+ {
+ 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 = (USHORT)nl; nCol = (USHORT)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
+
+BOOL SbModule::IsBreakable( USHORT nLine ) const
+{
+ if( !pImage )
+ return FALSE;
+ const BYTE* p = (const BYTE* ) pImage->GetCode();
+ USHORT nl, nc;
+ while( ( p = FindNextStmnt( p, nl, nc ) ) != NULL )
+ if( nl == nLine )
+ return TRUE;
+ return FALSE;
+}
+
+USHORT SbModule::GetBPCount() const
+{
+ return pBreaks ? pBreaks->Count() : 0;
+}
+
+USHORT SbModule::GetBP( USHORT n ) const
+{
+ if( pBreaks && n < pBreaks->Count() )
+ return pBreaks->GetObject( n );
+ else
+ return 0;
+}
+
+BOOL SbModule::IsBP( USHORT nLine ) const
+{
+ if( pBreaks )
+ {
+ const USHORT* p = pBreaks->GetData();
+ USHORT n = pBreaks->Count();
+ for( USHORT i = 0; i < n; i++, p++ )
+ {
+ USHORT b = *p;
+ if( b == nLine )
+ return TRUE;
+ if( b < nLine )
+ break;
+ }
+ }
+ return FALSE;
+}
+
+BOOL SbModule::SetBP( USHORT nLine )
+{
+ if( !IsBreakable( nLine ) )
+ return FALSE;
+ if( !pBreaks )
+ pBreaks = new SbiBreakpoints;
+ const USHORT* p = pBreaks->GetData();
+ USHORT n = pBreaks->Count();
+ USHORT i;
+ for( i = 0; i < n; i++, p++ )
+ {
+ USHORT b = *p;
+ if( b == nLine )
+ return TRUE;
+ if( b < nLine )
+ break;
+ }
+ pBreaks->Insert( &nLine, 1, i );
+
+ // #38568: Zur Laufzeit auch hier SbDEBUG_BREAK setzen
+ if( pINST && pINST->pRun )
+ pINST->pRun->SetDebugFlags( SbDEBUG_BREAK );
+
+ return IsBreakable( nLine );
+}
+
+BOOL SbModule::ClearBP( USHORT nLine )
+{
+ BOOL bRes = FALSE;
+ if( pBreaks )
+ {
+ const USHORT* p = pBreaks->GetData();
+ USHORT n = pBreaks->Count();
+ for( USHORT i = 0; i < n; i++, p++ )
+ {
+ USHORT b = *p;
+ if( b == nLine )
+ {
+ pBreaks->Remove( i, 1 ); bRes = TRUE; break;
+ }
+ if( b < nLine )
+ break;
+ }
+ if( !pBreaks->Count() )
+ 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( UINT32 i = 0; i < pMethods->Count(); i++ )
+ {
+ SbMethod* pMeth = PTR_CAST(SbMethod,pMethods->Get( (USHORT)i ) );
+ if( pMeth )
+ {
+ //fixup method start positions
+ if ( bCvtToLegacy )
+ pMeth->nStart = pImg->CalcLegacyOffset( pMeth->nStart );
+ else
+ pMeth->nStart = pImg->CalcNewOffset( (USHORT)pMeth->nStart );
+ }
+ }
+
+}
+
+BOOL SbModule::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ Clear();
+ if( !SbxObject::LoadData( rStrm, 1 ) )
+ return FALSE;
+ // Sicherheitshalber...
+ SetFlag( SBX_EXTSEARCH | SBX_GBLSEARCH );
+ BYTE bImage;
+ rStrm >> bImage;
+ if( bImage )
+ {
+ SbiImage* p = new SbiImage;
+ UINT32 nImgVer = 0;
+
+ if( !p->Load( rStrm, nImgVer ) )
+ {
+ delete p;
+ return 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 TRUE;
+}
+
+BOOL SbModule::StoreData( SvStream& rStrm ) const
+{
+ BOOL bFixup = ( pImage && !pImage->ExceedsLegacyLimits() );
+ if ( bFixup )
+ fixUpMethodStart( true );
+ BOOL bRet = SbxObject::StoreData( rStrm );
+ if ( !bRet )
+ return FALSE;
+
+ if( pImage )
+ {
+ pImage->aOUSource = aOUSource;
+ pImage->aComment = aComment;
+ pImage->aName = GetName();
+ rStrm << (BYTE) 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 << (BYTE) 1;
+ return aImg.Save( rStrm );
+ }
+}
+
+BOOL SbModule::ExceedsLegacyModuleSize()
+{
+ if ( !IsCompiled() )
+ Compile();
+ if ( pImage && pImage->ExceedsLegacyLimits() )
+ return true;
+ return false;
+}
+
+
+// Store only image, no source
+BOOL SbModule::StoreBinaryData( SvStream& rStrm )
+{
+ return StoreBinaryData( rStrm, 0 );
+}
+
+BOOL SbModule::StoreBinaryData( SvStream& rStrm, USHORT nVer )
+{
+ BOOL bRet = Compile();
+ if( bRet )
+ {
+ 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 << (BYTE) 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
+//
+
+BOOL SbModule::LoadBinaryData( SvStream& rStrm )
+{
+ ::rtl::OUString aKeepSource = aOUSource;
+ bool bRet = LoadData( rStrm, 2 );
+ LoadCompleted();
+ aOUSource = aKeepSource;
+ return bRet;
+}
+
+
+BOOL SbModule::LoadCompleted()
+{
+ SbxArray* p = GetMethods();
+ USHORT 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 TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////
+// Implementation SbJScriptModule (Basic-Modul fuer JavaScript-Sourcen)
+SbJScriptModule::SbJScriptModule( const String& rName )
+ :SbModule( rName )
+{
+}
+
+BOOL SbJScriptModule::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ (void)nVer;
+
+ Clear();
+ if( !SbxObject::LoadData( rStrm, 1 ) )
+ return FALSE;
+
+ // Source-String holen
+ String aTmp;
+ rStrm.ReadByteString( aTmp, gsl_getSystemTextEncoding() );
+ aOUSource = aTmp;
+ //rStrm >> aSource;
+ return TRUE;
+}
+
+BOOL SbJScriptModule::StoreData( SvStream& rStrm ) const
+{
+ if( !SbxObject::StoreData( rStrm ) )
+ return FALSE;
+
+ // Source-String schreiben
+ String aTmp = aOUSource;
+ rStrm.WriteByteString( aTmp, gsl_getSystemTextEncoding() );
+ //rStrm << aSource;
+ return TRUE;
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+
+SbMethod::SbMethod( const String& r, SbxDataType t, SbModule* p )
+ : SbxMethod( r, t ), pMod( p )
+{
+ bInvalid = 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;
+}
+
+BOOL SbMethod::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ if( !SbxMethod::LoadData( rStrm, 1 ) )
+ return FALSE;
+ INT16 n;
+ rStrm >> n;
+ INT16 nTempStart = (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 TRUE;
+}
+
+BOOL SbMethod::StoreData( SvStream& rStrm ) const
+{
+ if( !SbxMethod::StoreData( rStrm ) )
+ return FALSE;
+ rStrm << (INT16) nDebugFlags
+ << (INT16) nLine1
+ << (INT16) nLine2
+ << (INT16) nStart
+ << (BYTE) bInvalid;
+ return TRUE;
+}
+
+void SbMethod::GetLineRange( USHORT& l1, USHORT& 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( ULONG 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 ) );
+
+ USHORT 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 ) );
+}
+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;
+}
+
+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()
+{
+ if ( 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< USHORT >( 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< USHORT >(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 )
+{
+}
+
+BOOL SbUserFormModuleInstance::IsClass( const XubString& rName ) const
+{
+ BOOL bParentNameMatches = m_pParentModule->GetName().EqualsIgnoreCaseAscii( rName );
+ 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 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 );
+ // 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 = FALSE;
+}
+
+SbProperty::~SbProperty()
+{}
+
+/////////////////////////////////////////////////////////////////////////
+
+SbProcedureProperty::~SbProcedureProperty()
+{}
+
diff --git a/basic/source/comp/buffer.cxx b/basic/source/comp/buffer.cxx
new file mode 100644
index 000000000000..74559bf0e6c4
--- /dev/null
+++ b/basic/source/comp/buffer.cxx
@@ -0,0 +1,250 @@
+/*************************************************************************
+ *
+ * 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 "sbcomp.hxx"
+#include "buffer.hxx"
+#include <string.h>
+
+const static UINT32 UP_LIMIT=0xFFFFFF00L;
+
+// Der SbiBuffer wird in Inkrements von mindestens 16 Bytes erweitert.
+// Dies ist notwendig, da viele Klassen von einer Pufferlaenge
+// von x*16 Bytes ausgehen.
+
+SbiBuffer::SbiBuffer( SbiParser* p, short n )
+{
+ pParser = p;
+ n = ( (n + 15 ) / 16 ) * 16;
+ if( !n ) n = 16;
+ pBuf = NULL;
+ pCur = NULL;
+ nInc = n;
+ nSize =
+ nOff = 0;
+}
+
+SbiBuffer::~SbiBuffer()
+{
+ delete[] pBuf;
+}
+
+// Rausreichen des Puffers
+// Dies fuehrt zur Loeschung des Puffers!
+
+char* SbiBuffer::GetBuffer()
+{
+ char* p = pBuf;
+ pBuf = NULL;
+ pCur = NULL;
+ return p;
+}
+
+// Test, ob der Puffer n Bytes aufnehmen kann.
+// Im Zweifelsfall wird er vergroessert
+
+BOOL SbiBuffer::Check( USHORT n )
+{
+ if( !n ) return TRUE;
+ if( ( static_cast<UINT32>( nOff )+ n ) > static_cast<UINT32>( nSize ) )
+ {
+ if( nInc == 0 )
+ return FALSE;
+ USHORT nn = 0;
+ while( nn < n ) nn = nn + nInc;
+ char* p;
+ if( ( static_cast<UINT32>( nSize ) + nn ) > UP_LIMIT ) p = NULL;
+ else p = new char [nSize + nn];
+ if( !p )
+ {
+ pParser->Error( SbERR_PROG_TOO_LARGE );
+ nInc = 0;
+ delete[] pBuf; pBuf = NULL;
+ return FALSE;
+ }
+ else
+ {
+ if( nSize ) memcpy( p, pBuf, nSize );
+ delete[] pBuf;
+ pBuf = p;
+ pCur = pBuf + nOff;
+ nSize = nSize + nn;
+ }
+ }
+ return TRUE;
+}
+
+// Angleich des Puffers auf die uebergebene Byte-Grenze
+
+void SbiBuffer::Align( INT32 n )
+{
+ if( nOff % n ) {
+ UINT32 nn =( ( nOff + n ) / n ) * n;
+ if( nn <= UP_LIMIT )
+ {
+ nn = nn - nOff;
+ if( Check( static_cast<USHORT>(nn) ) )
+ {
+ memset( pCur, 0, nn );
+ pCur += nn;
+ nOff = nOff + nn;
+ }
+ }
+ }
+}
+
+// Patch einer Location
+
+void SbiBuffer::Patch( UINT32 off, UINT32 val )
+{
+ if( ( off + sizeof( UINT32 ) ) < nOff )
+ {
+ UINT16 val1 = static_cast<UINT16>( val & 0xFFFF );
+ UINT16 val2 = static_cast<UINT16>( val >> 16 );
+ BYTE* p = (BYTE*) pBuf + off;
+ *p++ = (char) ( val1 & 0xFF );
+ *p++ = (char) ( val1 >> 8 );
+ *p++ = (char) ( val2 & 0xFF );
+ *p = (char) ( val2 >> 8 );
+ }
+}
+
+// Forward References auf Labels und Prozeduren
+// bauen eine Kette auf. Der Anfang der Kette ist beim uebergebenen
+// Parameter, das Ende der Kette ist 0.
+
+void SbiBuffer::Chain( UINT32 off )
+{
+ if( off && pBuf )
+ {
+ BYTE *ip;
+ UINT32 i = off;
+ UINT32 val1 = (nOff & 0xFFFF);
+ UINT32 val2 = (nOff >> 16);
+ do
+ {
+ ip = (BYTE*) pBuf + i;
+ BYTE* pTmp = ip;
+ i = *pTmp++; i |= *pTmp++ << 8; i |= *pTmp++ << 16; i |= *pTmp++ << 24;
+
+ if( i >= nOff )
+ {
+ pParser->Error( SbERR_INTERNAL_ERROR, "BACKCHAIN" );
+ break;
+ }
+ *ip++ = (char) ( val1 & 0xFF );
+ *ip++ = (char) ( val1 >> 8 );
+ *ip++ = (char) ( val2 & 0xFF );
+ *ip = (char) ( val2 >> 8 );
+ } while( i );
+ }
+}
+
+BOOL SbiBuffer::operator +=( INT8 n )
+{
+ if( Check( 1 ) )
+ {
+ *pCur++ = (char) n; nOff++; return TRUE;
+ } else return FALSE;
+}
+
+BOOL SbiBuffer::operator +=( UINT8 n )
+{
+ if( Check( 1 ) )
+ {
+ *pCur++ = (char) n; nOff++; return TRUE;
+ } else return FALSE;
+}
+
+BOOL SbiBuffer::operator +=( INT16 n )
+{
+ if( Check( 2 ) )
+ {
+ *pCur++ = (char) ( n & 0xFF );
+ *pCur++ = (char) ( n >> 8 );
+ nOff += 2; return TRUE;
+ } else return FALSE;
+}
+
+BOOL SbiBuffer::operator +=( UINT16 n )
+{
+ if( Check( 2 ) )
+ {
+ *pCur++ = (char) ( n & 0xFF );
+ *pCur++ = (char) ( n >> 8 );
+ nOff += 2; return TRUE;
+ } else return FALSE;
+}
+
+BOOL SbiBuffer::operator +=( UINT32 n )
+{
+ if( Check( 4 ) )
+ {
+ UINT16 n1 = static_cast<UINT16>( n & 0xFFFF );
+ UINT16 n2 = static_cast<UINT16>( n >> 16 );
+ if ( operator +=( n1 ) && operator +=( n2 ) )
+ return TRUE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL SbiBuffer::operator +=( INT32 n )
+{
+ return operator +=( (UINT32) n );
+}
+
+
+BOOL SbiBuffer::operator +=( const String& n )
+{
+ USHORT l = n.Len() + 1;
+ if( Check( l ) )
+ {
+ ByteString aByteStr( n, gsl_getSystemTextEncoding() );
+ memcpy( pCur, aByteStr.GetBuffer(), l );
+ pCur += l;
+ nOff = nOff + l;
+ return TRUE;
+ }
+ else return FALSE;
+}
+
+BOOL SbiBuffer::Add( const void* p, USHORT len )
+{
+ if( Check( len ) )
+ {
+ memcpy( pCur, p, len );
+ pCur += len;
+ nOff = nOff + len;
+ return TRUE;
+ } else return FALSE;
+}
+
+
+
diff --git a/basic/source/comp/codegen.cxx b/basic/source/comp/codegen.cxx
new file mode 100644
index 000000000000..93fb18baf86e
--- /dev/null
+++ b/basic/source/comp/codegen.cxx
@@ -0,0 +1,539 @@
+/*************************************************************************
+ *
+ * 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 <basic/sbx.hxx>
+#include "sbcomp.hxx"
+#include "image.hxx"
+#include <limits>
+#include <com/sun/star/script/ModuleType.hpp>
+
+// nInc ist die Inkrementgroesse der Puffer
+
+SbiCodeGen::SbiCodeGen( SbModule& r, SbiParser* p, short nInc )
+ : rMod( r ), aCode( p, nInc )
+{
+ pParser = p;
+ bStmnt = FALSE;
+ nLine = 0;
+ nCol = 0;
+ nForLevel = 0;
+}
+
+UINT32 SbiCodeGen::GetPC()
+{
+ return aCode.GetSize();
+}
+
+// Statement merken
+
+void SbiCodeGen::Statement()
+{
+ bStmnt = TRUE;
+
+ nLine = pParser->GetLine();
+ nCol = pParser->GetCol1();
+
+ // #29955 Information der for-Schleifen-Ebene
+ // in oberen Byte der Spalte speichern
+ nCol = (nCol & 0xff) + 0x100 * nForLevel;
+}
+
+// Anfang eines Statements markieren
+
+void SbiCodeGen::GenStmnt()
+{
+ if( bStmnt )
+ {
+ bStmnt = FALSE;
+ Gen( _STMNT, nLine, nCol );
+ }
+}
+
+// Die Gen-Routinen returnen den Offset des 1. Operanden,
+// damit Jumps dort ihr Backchain versenken koennen
+
+UINT32 SbiCodeGen::Gen( SbiOpcode eOpcode )
+{
+#ifdef DBG_UTIL
+ if( eOpcode < SbOP0_START || eOpcode > SbOP0_END )
+ pParser->Error( SbERR_INTERNAL_ERROR, "OPCODE1" );
+#endif
+ GenStmnt();
+ aCode += (UINT8) eOpcode;
+ return GetPC();
+}
+
+UINT32 SbiCodeGen::Gen( SbiOpcode eOpcode, UINT32 nOpnd )
+{
+#ifdef DBG_UTIL
+ if( eOpcode < SbOP1_START || eOpcode > SbOP1_END )
+ pParser->Error( SbERR_INTERNAL_ERROR, "OPCODE2" );
+#endif
+ GenStmnt();
+ aCode += (UINT8) eOpcode;
+ UINT32 n = GetPC();
+ aCode += nOpnd;
+ return n;
+}
+
+UINT32 SbiCodeGen::Gen( SbiOpcode eOpcode, UINT32 nOpnd1, UINT32 nOpnd2 )
+{
+#ifdef DBG_UTIL
+ if( eOpcode < SbOP2_START || eOpcode > SbOP2_END )
+ pParser->Error( SbERR_INTERNAL_ERROR, "OPCODE3" );
+#endif
+ GenStmnt();
+ aCode += (UINT8) eOpcode;
+ UINT32 n = GetPC();
+ aCode += nOpnd1;
+ aCode += nOpnd2;
+ return n;
+}
+
+// Abspeichern des erzeugten Images im Modul
+
+void SbiCodeGen::Save()
+{
+ SbiImage* p = new SbiImage;
+ rMod.StartDefinitions();
+ // OPTION BASE-Wert:
+ p->nDimBase = pParser->nBase;
+ // OPTION EXPLICIT-Flag uebernehmen
+ if( pParser->bExplicit )
+ p->SetFlag( SBIMG_EXPLICIT );
+
+ int nIfaceCount = 0;
+ if( rMod.mnType == com::sun::star::script::ModuleType::CLASS )
+ {
+ OSL_TRACE("COdeGen::save() classmodule processing");
+ rMod.bIsProxyModule = true;
+ p->SetFlag( SBIMG_CLASSMODULE );
+ pCLASSFAC->AddClassModule( &rMod );
+
+ nIfaceCount = pParser->aIfaceVector.size();
+ if( !rMod.pClassData )
+ rMod.pClassData = new SbClassData;
+ if( nIfaceCount )
+ {
+ for( int i = 0 ; i < nIfaceCount ; i++ )
+ {
+ const String& rIfaceName = pParser->aIfaceVector[i];
+ SbxVariable* pIfaceVar = new SbxVariable( SbxVARIANT );
+ pIfaceVar->SetName( rIfaceName );
+ SbxArray* pIfaces = rMod.pClassData->mxIfaces;
+ pIfaces->Insert( pIfaceVar, pIfaces->Count() );
+ }
+ }
+
+ rMod.pClassData->maRequiredTypes = pParser->aRequiredTypes;
+ }
+ else
+ {
+ pCLASSFAC->RemoveClassModule( &rMod );
+ // Only a ClassModule can revert to Normal
+ if ( rMod.mnType == com::sun::star::script::ModuleType::CLASS )
+ rMod.mnType = com::sun::star::script::ModuleType::NORMAL;
+ rMod.bIsProxyModule = false;
+ }
+
+ if( pParser->bText )
+ p->SetFlag( SBIMG_COMPARETEXT );
+ // GlobalCode-Flag
+ if( pParser->HasGlobalCode() )
+ p->SetFlag( SBIMG_INITCODE );
+ // Die Entrypoints:
+ for( SbiSymDef* pDef = pParser->aPublics.First(); pDef;
+ pDef = pParser->aPublics.Next() )
+ {
+ SbiProcDef* pProc = pDef->GetProcDef();
+ if( pProc && pProc->IsDefined() )
+ {
+ String aProcName = pProc->GetName();
+ String aIfaceProcName;
+ String aIfaceName;
+ USHORT nPassCount = 1;
+ if( nIfaceCount )
+ {
+ int nPropPrefixFound =
+ aProcName.Search( String( RTL_CONSTASCII_USTRINGPARAM("Property ") ) );
+ String aPureProcName = aProcName;
+ String aPropPrefix;
+ if( nPropPrefixFound == 0 )
+ {
+ aPropPrefix = aProcName.Copy( 0, 13 ); // 13 == Len( "Property ?et " )
+ aPureProcName = aProcName.Copy( 13 );
+ }
+ for( int i = 0 ; i < nIfaceCount ; i++ )
+ {
+ const String& rIfaceName = pParser->aIfaceVector[i];
+ int nFound = aPureProcName.Search( rIfaceName );
+ if( nFound == 0 && '_' == aPureProcName.GetChar( rIfaceName.Len() ) )
+ {
+ if( nPropPrefixFound == 0 )
+ aIfaceProcName += aPropPrefix;
+ aIfaceProcName += aPureProcName.Copy( rIfaceName.Len() + 1 );
+ aIfaceName = rIfaceName;
+ nPassCount = 2;
+ break;
+ }
+ }
+ }
+ SbMethod* pMeth = NULL;
+ for( USHORT nPass = 0 ; nPass < nPassCount ; nPass++ )
+ {
+ if( nPass == 1 )
+ aProcName = aIfaceProcName;
+
+ PropertyMode ePropMode = pProc->getPropertyMode();
+ if( ePropMode != PROPERTY_MODE_NONE )
+ {
+ SbxDataType ePropType = SbxEMPTY;
+ switch( ePropMode )
+ {
+ case PROPERTY_MODE_GET:
+ ePropType = pProc->GetType();
+ break;
+ case PROPERTY_MODE_LET:
+ {
+ // type == type of first parameter
+ ePropType = SbxVARIANT; // Default
+ SbiSymPool* pPool = &pProc->GetParams();
+ if( pPool->GetSize() > 1 )
+ {
+ SbiSymDef* pPar = pPool->Get( 1 );
+ if( pPar )
+ ePropType = pPar->GetType();
+ }
+ break;
+ }
+ case PROPERTY_MODE_SET:
+ ePropType = SbxOBJECT;
+ break;
+ case PROPERTY_MODE_NONE:
+ DBG_ERROR( "Illegal PropertyMode PROPERTY_MODE_NONE" );
+ break;
+ }
+ String aPropName = pProc->GetPropName();
+ if( nPass == 1 )
+ aPropName = aPropName.Copy( aIfaceName.Len() + 1 );
+ SbProcedureProperty* pProcedureProperty = NULL;
+ pProcedureProperty = rMod.GetProcedureProperty( aPropName, ePropType );
+ }
+ if( nPass == 1 )
+ {
+ SbIfaceMapperMethod* pMapperMeth = NULL;
+ pMapperMeth = rMod.GetIfaceMapperMethod( aProcName, pMeth );
+ }
+ else
+ {
+ pMeth = rMod.GetMethod( aProcName, pProc->GetType() );
+
+ // #110004
+ if( !pProc->IsPublic() )
+ pMeth->SetFlag( SBX_PRIVATE );
+
+ // Declare? -> Hidden
+ if( pProc->GetLib().Len() > 0 )
+ pMeth->SetFlag( SBX_HIDDEN );
+
+ pMeth->nStart = pProc->GetAddr();
+ pMeth->nLine1 = pProc->GetLine1();
+ pMeth->nLine2 = pProc->GetLine2();
+ // Die Parameter:
+ SbxInfo* pInfo = pMeth->GetInfo();
+ String aHelpFile, aComment;
+ ULONG nHelpId = 0;
+ if( pInfo )
+ {
+ // Die Zusatzdaten retten
+ aHelpFile = pInfo->GetHelpFile();
+ aComment = pInfo->GetComment();
+ nHelpId = pInfo->GetHelpId();
+ }
+ // Und die Parameterliste neu aufbauen
+ pInfo = new SbxInfo( aHelpFile, nHelpId );
+ pInfo->SetComment( aComment );
+ SbiSymPool* pPool = &pProc->GetParams();
+ // Das erste Element ist immer der Funktionswert!
+ for( USHORT i = 1; i < pPool->GetSize(); i++ )
+ {
+ SbiSymDef* pPar = pPool->Get( i );
+ SbxDataType t = pPar->GetType();
+ if( !pPar->IsByVal() )
+ t = (SbxDataType) ( t | SbxBYREF );
+ if( pPar->GetDims() )
+ t = (SbxDataType) ( t | SbxARRAY );
+ // #33677 Optional-Info durchreichen
+ USHORT nFlags = SBX_READ;
+ if( pPar->IsOptional() )
+ nFlags |= SBX_OPTIONAL;
+
+ pInfo->AddParam( pPar->GetName(), t, nFlags );
+
+ UINT32 nUserData = 0;
+ USHORT nDefaultId = pPar->GetDefaultId();
+ if( nDefaultId )
+ nUserData |= nDefaultId;
+ if( pPar->IsParamArray() )
+ nUserData |= PARAM_INFO_PARAMARRAY;
+ if( nUserData )
+ {
+ SbxParamInfo* pParam = (SbxParamInfo*)pInfo->GetParam( i );
+ pParam->nUserData = nUserData;
+ }
+ }
+ pMeth->SetInfo( pInfo );
+ }
+
+ } // for( iPass...
+ }
+ }
+ // Der Code
+ p->AddCode( aCode.GetBuffer(), aCode.GetSize() );
+
+ // Der globale StringPool. 0 ist nicht belegt.
+ SbiStringPool* pPool = &pParser->aGblStrings;
+ USHORT nSize = pPool->GetSize();
+ p->MakeStrings( nSize );
+ USHORT i;
+ for( i = 1; i <= nSize; i++ )
+ p->AddString( pPool->Find( i ) );
+
+ // Typen einfuegen
+ USHORT nCount = pParser->rTypeArray->Count();
+ for (i = 0; i < nCount; i++)
+ p->AddType((SbxObject *)pParser->rTypeArray->Get(i));
+
+ // Insert enum objects
+ nCount = pParser->rEnumArray->Count();
+ for (i = 0; i < nCount; i++)
+ p->AddEnum((SbxObject *)pParser->rEnumArray->Get(i));
+
+ if( !p->IsError() )
+ rMod.pImage = p;
+ else
+ delete p;
+
+ rMod.EndDefinitions();
+}
+
+template < class T >
+class PCodeVisitor
+{
+public:
+ virtual ~PCodeVisitor();
+
+ virtual void start( BYTE* pStart ) = 0;
+ virtual void processOpCode0( SbiOpcode eOp ) = 0;
+ virtual void processOpCode1( SbiOpcode eOp, T nOp1 ) = 0;
+ virtual void processOpCode2( SbiOpcode eOp, T nOp1, T nOp2 ) = 0;
+ virtual bool processParams() = 0;
+ virtual void end() = 0;
+};
+
+template <class T> PCodeVisitor< T >::~PCodeVisitor()
+{}
+
+template <class T>
+class PCodeBufferWalker
+{
+private:
+ T m_nBytes;
+ BYTE* m_pCode;
+ T readParam( BYTE*& pCode )
+ {
+ short nBytes = sizeof( T );
+ T nOp1=0;
+ for ( int i=0; i<nBytes; ++i )
+ nOp1 |= *pCode++ << ( i * 8);
+ return nOp1;
+ }
+public:
+ PCodeBufferWalker( BYTE* pCode, T nBytes ): m_nBytes( nBytes ), m_pCode( pCode )
+ {
+ }
+ void visitBuffer( PCodeVisitor< T >& visitor )
+ {
+ BYTE* pCode = m_pCode;
+ if ( !pCode )
+ return;
+ BYTE* pEnd = pCode + m_nBytes;
+ visitor.start( m_pCode );
+ T nOp1 = 0, nOp2 = 0;
+ for( ; pCode < pEnd; )
+ {
+ SbiOpcode eOp = (SbiOpcode)(*pCode++);
+
+ if ( eOp <= SbOP0_END )
+ visitor.processOpCode0( eOp );
+ else if( eOp >= SbOP1_START && eOp <= SbOP1_END )
+ {
+ if ( visitor.processParams() )
+ nOp1 = readParam( pCode );
+ else
+ pCode += sizeof( T );
+ visitor.processOpCode1( eOp, nOp1 );
+ }
+ else if( eOp >= SbOP2_START && eOp <= SbOP2_END )
+ {
+ if ( visitor.processParams() )
+ {
+ nOp1 = readParam( pCode );
+ nOp2 = readParam( pCode );
+ }
+ else
+ pCode += ( sizeof( T ) * 2 );
+ visitor.processOpCode2( eOp, nOp1, nOp2 );
+ }
+ }
+ visitor.end();
+ }
+};
+
+template < class T, class S >
+class OffSetAccumulator : public PCodeVisitor< T >
+{
+ T m_nNumOp0;
+ T m_nNumSingleParams;
+ T m_nNumDoubleParams;
+public:
+
+ OffSetAccumulator() : m_nNumOp0(0), m_nNumSingleParams(0), m_nNumDoubleParams(0){}
+ virtual void start( BYTE* /*pStart*/ ){}
+ virtual void processOpCode0( SbiOpcode /*eOp*/ ){ ++m_nNumOp0; }
+ virtual void processOpCode1( SbiOpcode /*eOp*/, T /*nOp1*/ ){ ++m_nNumSingleParams; }
+ virtual void processOpCode2( SbiOpcode /*eOp*/, T /*nOp1*/, T /*nOp2*/ ) { ++m_nNumDoubleParams; }
+ virtual void end(){}
+ S offset()
+ {
+ T result = 0 ;
+ static const S max = std::numeric_limits< S >::max();
+ result = m_nNumOp0 + ( ( sizeof(S) + 1 ) * m_nNumSingleParams ) + ( (( sizeof(S) * 2 )+ 1 ) * m_nNumDoubleParams );
+ if ( result > max )
+ return max;
+
+ return static_cast<S>(result);
+ }
+ virtual bool processParams(){ return false; }
+};
+
+
+
+template < class T, class S >
+
+class BufferTransformer : public PCodeVisitor< T >
+{
+ BYTE* m_pStart;
+ SbiBuffer m_ConvertedBuf;
+public:
+ BufferTransformer():m_pStart(NULL), m_ConvertedBuf( NULL, 1024 ) {}
+ virtual void start( BYTE* pStart ){ m_pStart = pStart; }
+ virtual void processOpCode0( SbiOpcode eOp )
+ {
+ m_ConvertedBuf += (UINT8)eOp;
+ }
+ virtual void processOpCode1( SbiOpcode eOp, T nOp1 )
+ {
+ m_ConvertedBuf += (UINT8)eOp;
+ switch( eOp )
+ {
+ case _JUMP:
+ case _JUMPT:
+ case _JUMPF:
+ case _GOSUB:
+ case _CASEIS:
+ case _RETURN:
+ case _ERRHDL:
+ case _TESTFOR:
+ nOp1 = static_cast<T>( convertBufferOffSet(m_pStart, nOp1) );
+ break;
+ case _RESUME:
+ if ( nOp1 > 1 )
+ nOp1 = static_cast<T>( convertBufferOffSet(m_pStart, nOp1) );
+ break;
+ default:
+ break; //
+
+ }
+ m_ConvertedBuf += (S)nOp1;
+ }
+ virtual void processOpCode2( SbiOpcode eOp, T nOp1, T nOp2 )
+ {
+ m_ConvertedBuf += (UINT8)eOp;
+ if ( eOp == _CASEIS )
+ if ( nOp1 )
+ nOp1 = static_cast<T>( convertBufferOffSet(m_pStart, nOp1) );
+ m_ConvertedBuf += (S)nOp1;
+ m_ConvertedBuf += (S)nOp2;
+
+ }
+ virtual bool processParams(){ return true; }
+ virtual void end() {}
+ // yeuch, careful here, you can only call
+ // GetBuffer on the returned SbiBuffer once, also
+ // you (as the caller) get to own the memory
+ SbiBuffer& buffer()
+ {
+ return m_ConvertedBuf;
+ }
+ static S convertBufferOffSet( BYTE* pStart, T nOp1 )
+ {
+ PCodeBufferWalker< T > aBuff( pStart, nOp1);
+ OffSetAccumulator< T, S > aVisitor;
+ aBuff.visitBuffer( aVisitor );
+ return aVisitor.offset();
+ }
+};
+
+UINT32
+SbiCodeGen::calcNewOffSet( BYTE* pCode, UINT16 nOffset )
+{
+ return BufferTransformer< UINT16, UINT32 >::convertBufferOffSet( pCode, nOffset );
+}
+
+UINT16
+SbiCodeGen::calcLegacyOffSet( BYTE* pCode, UINT32 nOffset )
+{
+ return BufferTransformer< UINT32, UINT16 >::convertBufferOffSet( pCode, nOffset );
+}
+
+template <class T, class S>
+void
+PCodeBuffConvertor<T,S>::convert()
+{
+ PCodeBufferWalker< T > aBuf( m_pStart, m_nSize );
+ BufferTransformer< T, S > aTrnsfrmer;
+ aBuf.visitBuffer( aTrnsfrmer );
+ m_pCnvtdBuf = (BYTE*)aTrnsfrmer.buffer().GetBuffer();
+ m_nCnvtdSize = static_cast<S>( aTrnsfrmer.buffer().GetSize() );
+}
+
+template class PCodeBuffConvertor< UINT16, UINT32 >;
+template class PCodeBuffConvertor< UINT32, UINT16 >;
diff --git a/basic/source/comp/dim.cxx b/basic/source/comp/dim.cxx
new file mode 100644
index 000000000000..59d77e3f3757
--- /dev/null
+++ b/basic/source/comp/dim.cxx
@@ -0,0 +1,1203 @@
+/*************************************************************************
+ *
+ * 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 <basic/sbx.hxx>
+#include "sbcomp.hxx"
+
+SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj );
+
+// Deklaration einer Variablen
+// Bei Fehlern wird bis zum Komma oder Newline geparst.
+// Returnwert: eine neue Instanz, die eingefuegt und dann geloescht wird.
+// Array-Indexe werden als SbiDimList zurueckgegeben
+
+SbiSymDef* SbiParser::VarDecl( SbiDimList** ppDim, BOOL bStatic, BOOL bConst )
+{
+ bool bWithEvents = false;
+ if( Peek() == WITHEVENTS )
+ {
+ Next();
+ bWithEvents = true;
+ }
+ if( !TestSymbol() ) return NULL;
+ SbxDataType t = eScanType;
+ SbiSymDef* pDef = bConst ? new SbiConstDef( aSym ) : new SbiSymDef( aSym );
+ SbiDimList* pDim = NULL;
+ // Klammern?
+ if( Peek() == LPAREN )
+ pDim = new SbiDimList( this );
+ pDef->SetType( t );
+ if( bStatic )
+ pDef->SetStatic();
+ if( bWithEvents )
+ pDef->SetWithEvents();
+ TypeDecl( *pDef );
+ if( !ppDim && pDim )
+ {
+ if(pDim->GetDims() )
+ Error( SbERR_EXPECTED, "()" );
+ delete pDim;
+ }
+ else if( ppDim )
+ *ppDim = pDim;
+ return pDef;
+}
+
+// Aufloesen einer AS-Typdeklaration
+// Der Datentyp wird in die uebergebene Variable eingetragen
+
+void SbiParser::TypeDecl( SbiSymDef& rDef, BOOL bAsNewAlreadyParsed )
+{
+ SbxDataType eType = rDef.GetType();
+ short nSize = 0;
+ if( bAsNewAlreadyParsed || Peek() == AS )
+ {
+ if( !bAsNewAlreadyParsed )
+ Next();
+ rDef.SetDefinedAs();
+ String aType;
+ SbiToken eTok = Next();
+ if( !bAsNewAlreadyParsed && eTok == NEW )
+ {
+ rDef.SetNew();
+ eTok = Next();
+ }
+ switch( eTok )
+ {
+ case ANY:
+ if( rDef.IsNew() )
+ Error( SbERR_SYNTAX );
+ eType = SbxVARIANT; break;
+ case TINTEGER:
+ case TLONG:
+ case TSINGLE:
+ case TDOUBLE:
+ case TCURRENCY:
+ case TDATE:
+ case TSTRING:
+ case TOBJECT:
+ case _ERROR_:
+ case TBOOLEAN:
+ case TVARIANT:
+ case TBYTE:
+ if( rDef.IsNew() )
+ Error( SbERR_SYNTAX );
+ eType = (eTok==TBYTE) ? SbxBYTE : SbxDataType( eTok - TINTEGER + SbxINTEGER );
+ if( eType == SbxSTRING )
+ {
+ // STRING*n ?
+ if( Peek() == MUL )
+ { // fixed size!
+ Next();
+ SbiConstExpression aSize( this );
+ nSize = aSize.GetShortValue();
+ if( nSize < 0 || (bVBASupportOn && nSize <= 0) )
+ Error( SbERR_OUT_OF_RANGE );
+ else
+ rDef.SetFixedStringLength( nSize );
+ }
+ }
+ break;
+ case SYMBOL: // kann nur ein TYPE oder eine Objektklasse sein!
+ if( eScanType != SbxVARIANT )
+ Error( SbERR_SYNTAX );
+ else
+ {
+ String aCompleteName = aSym;
+
+ // #52709 DIM AS NEW fuer Uno mit voll-qualifizierten Namen
+ if( Peek() == DOT )
+ {
+ String aDotStr( '.' );
+ while( Peek() == DOT )
+ {
+ aCompleteName += aDotStr;
+ Next();
+ SbiToken ePeekTok = Peek();
+ if( ePeekTok == SYMBOL || IsKwd( ePeekTok ) )
+ {
+ Next();
+ aCompleteName += aSym;
+ }
+ else
+ {
+ Next();
+ Error( SbERR_UNEXPECTED, SYMBOL );
+ break;
+ }
+ }
+ }
+ else if( rEnumArray->Find( aCompleteName, SbxCLASS_OBJECT ) )
+ {
+ eType = SbxLONG;
+ break;
+ }
+
+ // In den String-Pool uebernehmen
+ rDef.SetTypeId( aGblStrings.Add( aCompleteName ) );
+
+ if( rDef.IsNew() && pProc == NULL )
+ aRequiredTypes.push_back( aCompleteName );
+ }
+ eType = SbxOBJECT;
+ break;
+ case FIXSTRING: // new syntax for complex UNO types
+ rDef.SetTypeId( aGblStrings.Add( aSym ) );
+ eType = SbxOBJECT;
+ break;
+ default:
+ Error( SbERR_UNEXPECTED, eTok );
+ Next();
+ }
+ // Die Variable koennte mit Suffix deklariert sein
+ if( rDef.GetType() != SbxVARIANT )
+ {
+ if( rDef.GetType() != eType )
+ Error( SbERR_VAR_DEFINED, rDef.GetName() );
+ else if( eType == SbxSTRING && rDef.GetLen() != nSize )
+ Error( SbERR_VAR_DEFINED, rDef.GetName() );
+ }
+ rDef.SetType( eType );
+ rDef.SetLen( nSize );
+ }
+}
+
+// Hier werden Variable, Arrays und Strukturen definiert.
+// DIM/PRIVATE/PUBLIC/GLOBAL
+
+void SbiParser::Dim()
+{
+ DefVar( _DIM, ( pProc && bVBASupportOn ) ? pProc->IsStatic() : FALSE );
+}
+
+void SbiParser::DefVar( SbiOpcode eOp, BOOL bStatic )
+{
+ SbiSymPool* pOldPool = pPool;
+ BOOL bSwitchPool = FALSE;
+ BOOL bPersistantGlobal = FALSE;
+ SbiToken eFirstTok = eCurTok;
+ if( pProc && ( eCurTok == GLOBAL || eCurTok == PUBLIC || eCurTok == PRIVATE ) )
+ Error( SbERR_NOT_IN_SUBR, eCurTok );
+ if( eCurTok == PUBLIC || eCurTok == GLOBAL )
+ {
+ bSwitchPool = TRUE; // im richtigen Moment auf globalen Pool schalten
+ if( eCurTok == GLOBAL )
+ bPersistantGlobal = TRUE;
+ }
+ // behavior in VBA is that a module scope variable's lifetime is
+ // tied to the document. e.g. a module scope variable is global
+ if( GetBasic()->IsDocBasic() && bVBASupportOn && !pProc )
+ bPersistantGlobal = TRUE;
+ // PRIVATE ist Synonym fuer DIM
+ // _CONST_?
+ BOOL bConst = FALSE;
+ if( eCurTok == _CONST_ )
+ bConst = TRUE;
+ else if( Peek() == _CONST_ )
+ Next(), bConst = TRUE;
+
+ // #110004 It can also be a sub/function
+ if( !bConst && (eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY ||
+ eCurTok == STATIC || eCurTok == ENUM || eCurTok == DECLARE || eCurTok == TYPE) )
+ {
+ // Next token is read here, because !bConst
+ bool bPrivate = ( eFirstTok == PRIVATE );
+
+ if( eCurTok == STATIC )
+ {
+ Next();
+ DefStatic( bPrivate );
+ }
+ else if( eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY )
+ {
+ // End global chain if necessary (not done in
+ // SbiParser::Parse() under these conditions
+ if( bNewGblDefs && nGblChain == 0 )
+ {
+ nGblChain = aGen.Gen( _JUMP, 0 );
+ bNewGblDefs = FALSE;
+ }
+ Next();
+ DefProc( FALSE, bPrivate );
+ return;
+ }
+ else if( eCurTok == ENUM )
+ {
+ Next();
+ DefEnum( bPrivate );
+ return;
+ }
+ else if( eCurTok == DECLARE )
+ {
+ Next();
+ DefDeclare( bPrivate );
+ return;
+ }
+ // #i109049
+ else if( eCurTok == TYPE )
+ {
+ Next();
+ DefType( bPrivate );
+ return;
+ }
+ }
+
+#ifdef SHARED
+#define tmpSHARED
+#undef SHARED
+#endif
+ // SHARED wird ignoriert
+ if( Peek() == SHARED ) Next();
+#ifdef tmpSHARED
+#define SHARED
+#undef tmpSHARED
+#endif
+ // PRESERVE nur bei REDIM
+ if( Peek() == PRESERVE )
+ {
+ Next();
+ if( eOp == _REDIM )
+ eOp = _REDIMP;
+ else
+ Error( SbERR_UNEXPECTED, eCurTok );
+ }
+ SbiSymDef* pDef;
+ SbiDimList* pDim;
+
+ // AB 9.7.97, #40689, Statics -> Modul-Initialisierung, in Sub ueberspringen
+ UINT32 nEndOfStaticLbl = 0;
+ if( !bVBASupportOn && bStatic )
+ {
+ nEndOfStaticLbl = aGen.Gen( _JUMP, 0 );
+ aGen.Statement(); // bei static hier nachholen
+ }
+
+ BOOL bDefined = FALSE;
+ while( ( pDef = VarDecl( &pDim, bStatic, bConst ) ) != NULL )
+ {
+ EnableErrors();
+ // Variable suchen:
+ if( bSwitchPool )
+ pPool = &aGlobals;
+ SbiSymDef* pOld = pPool->Find( pDef->GetName() );
+ // AB 31.3.1996, #25651#, auch in Runtime-Library suchen
+ BOOL bRtlSym = FALSE;
+ if( !pOld )
+ {
+ pOld = CheckRTLForSym( pDef->GetName(), SbxVARIANT );
+ if( pOld )
+ bRtlSym = TRUE;
+ }
+ if( pOld && !(eOp == _REDIM || eOp == _REDIMP) )
+ {
+ if( pDef->GetScope() == SbLOCAL && pOld->GetScope() != SbLOCAL )
+ pOld = NULL;
+ }
+ if( pOld )
+ {
+ bDefined = TRUE;
+ // Bei RTL-Symbol immer Fehler
+ if( !bRtlSym && (eOp == _REDIM || eOp == _REDIMP) )
+ {
+ // Bei REDIM die Attribute vergleichen
+ SbxDataType eDefType;
+ bool bError_ = false;
+ if( pOld->IsStatic() )
+ {
+ bError_ = true;
+ }
+ else if( pOld->GetType() != ( eDefType = pDef->GetType() ) )
+ {
+ if( !( eDefType == SbxVARIANT && !pDef->IsDefinedAs() ) )
+ bError_ = true;
+ }
+ if( bError_ )
+ Error( SbERR_VAR_DEFINED, pDef->GetName() );
+ }
+ else
+ Error( SbERR_VAR_DEFINED, pDef->GetName() );
+ delete pDef; pDef = pOld;
+ }
+ else
+ pPool->Add( pDef );
+
+ // #36374: Variable vor Unterscheidung IsNew() anlegen
+ // Sonst Error bei Dim Identifier As New Type und option explicit
+ if( !bDefined && !(eOp == _REDIM || eOp == _REDIMP)
+ && ( !bConst || pDef->GetScope() == SbGLOBAL ) )
+ {
+ // Variable oder globale Konstante deklarieren
+ SbiOpcode eOp2;
+ switch ( pDef->GetScope() )
+ {
+ case SbGLOBAL: eOp2 = bPersistantGlobal ? _GLOBAL_P : _GLOBAL;
+ goto global;
+ case SbPUBLIC: eOp2 = bPersistantGlobal ? _PUBLIC_P : _PUBLIC;
+ // AB 9.7.97, #40689, kein eigener Opcode mehr
+ if( bVBASupportOn && bStatic )
+ {
+ eOp2 = _STATIC;
+ break;
+ }
+ global: aGen.BackChain( nGblChain );
+ nGblChain = 0;
+ bGblDefs = bNewGblDefs = TRUE;
+ break;
+ default: eOp2 = _LOCAL;
+ }
+ UINT32 nOpnd2 = sal::static_int_cast< UINT16 >( pDef->GetType() );
+ if( pDef->IsWithEvents() )
+ nOpnd2 |= SBX_TYPE_WITH_EVENTS_FLAG;
+
+ short nFixedStringLength = pDef->GetFixedStringLength();
+ if( nFixedStringLength >= 0 )
+ nOpnd2 |= (SBX_FIXED_LEN_STRING_FLAG + (UINT32(nFixedStringLength) << 17)); // len = all bits above 0x10000
+
+ aGen.Gen( eOp2, pDef->GetId(), nOpnd2 );
+ }
+
+ // Initialisierung fuer selbstdefinierte Datentypen
+ // und per NEW angelegte Variable
+ if( pDef->GetType() == SbxOBJECT
+ && pDef->GetTypeId() )
+ {
+ if( !bCompatible && !pDef->IsNew() )
+ {
+ String aTypeName( aGblStrings.Find( pDef->GetTypeId() ) );
+ if( rTypeArray->Find( aTypeName, SbxCLASS_OBJECT ) == NULL )
+ Error( SbERR_UNDEF_TYPE, aTypeName );
+ }
+
+ if( bConst )
+ {
+ Error( SbERR_SYNTAX );
+ }
+
+ if( pDim )
+ {
+ if( eOp == _REDIMP )
+ {
+ SbiExpression aExpr( this, *pDef, NULL );
+ aExpr.Gen();
+ aGen.Gen( _REDIMP_ERASE );
+
+ pDef->SetDims( pDim->GetDims() );
+ SbiExpression aExpr2( this, *pDef, pDim );
+ aExpr2.Gen();
+ aGen.Gen( _DCREATE_REDIMP, pDef->GetId(), pDef->GetTypeId() );
+ }
+ else
+ {
+ pDef->SetDims( pDim->GetDims() );
+ SbiExpression aExpr( this, *pDef, pDim );
+ aExpr.Gen();
+ aGen.Gen( _DCREATE, pDef->GetId(), pDef->GetTypeId() );
+ }
+ }
+ else
+ {
+ SbiExpression aExpr( this, *pDef );
+ aExpr.Gen();
+ SbiOpcode eOp_ = pDef->IsNew() ? _CREATE : _TCREATE;
+ aGen.Gen( eOp_, pDef->GetId(), pDef->GetTypeId() );
+ aGen.Gen( _SET );
+ }
+ }
+ else
+ {
+ if( bConst )
+ {
+ // Konstanten-Definition
+ if( pDim )
+ {
+ Error( SbERR_SYNTAX );
+ delete pDim;
+ }
+ SbiExpression aVar( this, *pDef );
+ if( !TestToken( EQ ) )
+ goto MyBreak; // AB 24.6.1996 (s.u.)
+ SbiConstExpression aExpr( this );
+ if( !bDefined && aExpr.IsValid() )
+ {
+ if( pDef->GetScope() == SbGLOBAL )
+ {
+ // Nur Code fuer globale Konstante erzeugen!
+ aVar.Gen();
+ aExpr.Gen();
+ aGen.Gen( _PUTC );
+ }
+ SbiConstDef* pConst = pDef->GetConstDef();
+ if( aExpr.GetType() == SbxSTRING )
+ pConst->Set( aExpr.GetString() );
+ else
+ pConst->Set( aExpr.GetValue(), aExpr.GetType() );
+ }
+ }
+ else if( pDim )
+ {
+ // Die Variable dimensionieren
+ // Bei REDIM die Var vorher loeschen
+ if( eOp == _REDIM )
+ {
+ SbiExpression aExpr( this, *pDef, NULL );
+ aExpr.Gen();
+ if ( bVBASupportOn )
+ // delete the array but
+ // clear the variable ( this
+ // allows the processing of
+ // the param to happen as normal without errors ( ordinary ERASE just clears the array )
+ aGen.Gen( _ERASE_CLEAR );
+ else
+ aGen.Gen( _ERASE );
+ }
+ else if( eOp == _REDIMP )
+ {
+ SbiExpression aExpr( this, *pDef, NULL );
+ aExpr.Gen();
+ aGen.Gen( _REDIMP_ERASE );
+ }
+ pDef->SetDims( pDim->GetDims() );
+ if( bPersistantGlobal )
+ pDef->SetGlobal( TRUE );
+ SbiExpression aExpr( this, *pDef, pDim );
+ aExpr.Gen();
+ pDef->SetGlobal( FALSE );
+ aGen.Gen( (eOp == _STATIC) ? _DIM : eOp );
+ }
+ }
+ if( !TestComma() )
+ goto MyBreak; // AB 24.6.1996 (s.u.)
+
+ // #27963# AB, 24.6.1996
+ // Einfuehrung bSwitchPool (s.o.): pPool darf beim VarDecl-Aufruf
+ // noch nicht auf &aGlobals gesetzt sein.
+ // Ansonsten soll das Verhalten aber absolut identisch bleiben,
+ // d.h. pPool muss immer am Schleifen-Ende zurueckgesetzt werden.
+ // auch bei break
+ pPool = pOldPool;
+ continue; // MyBreak überspingen
+ MyBreak:
+ pPool = pOldPool;
+ break;
+ }
+
+ // AB 9.7.97, #40689, Sprung ueber Statics-Deklaration abschliessen
+ if( !bVBASupportOn && bStatic )
+ {
+ // globalen Chain pflegen
+ nGblChain = aGen.Gen( _JUMP, 0 );
+ bGblDefs = bNewGblDefs = TRUE;
+
+ // fuer Sub Sprung auf Ende der statics eintragen
+ aGen.BackChain( nEndOfStaticLbl );
+ }
+
+ //pPool = pOldPool;
+}
+
+// Hier werden Arrays redimensioniert.
+
+void SbiParser::ReDim()
+{
+ DefVar( _REDIM, ( pProc && bVBASupportOn ) ? pProc->IsStatic() : FALSE );
+}
+
+// ERASE array, ...
+
+void SbiParser::Erase()
+{
+ while( !bAbort )
+ {
+ SbiExpression aExpr( this, SbLVALUE );
+ aExpr.Gen();
+ aGen.Gen( _ERASE );
+ if( !TestComma() ) break;
+ }
+}
+
+// Deklaration eines Datentyps
+
+void SbiParser::Type()
+{
+ DefType( FALSE );
+}
+
+void SbiParser::DefType( BOOL bPrivate )
+{
+ // TODO: Use bPrivate
+ (void)bPrivate;
+
+ // Neues Token lesen, es muss ein Symbol sein
+ if (!TestSymbol())
+ return;
+
+ if (rTypeArray->Find(aSym,SbxCLASS_OBJECT))
+ {
+ Error( SbERR_VAR_DEFINED, aSym );
+ return;
+ }
+
+ SbxObject *pType = new SbxObject(aSym);
+
+ SbiSymDef* pElem;
+ SbiDimList* pDim = NULL;
+ BOOL bDone = FALSE;
+
+ while( !bDone && !IsEof() )
+ {
+ switch( Peek() )
+ {
+ case ENDTYPE :
+ pElem = NULL;
+ bDone = TRUE;
+ Next();
+ break;
+
+ case EOLN :
+ case REM :
+ pElem = NULL;
+ Next();
+ break;
+
+ default:
+ pDim = NULL;
+ pElem = VarDecl(&pDim,FALSE,FALSE);
+ if( !pElem )
+ bDone = TRUE; // Error occured
+ }
+ if( pElem )
+ {
+ SbxArray *pTypeMembers = pType->GetProperties();
+ String aElemName = pElem->GetName();
+ if( pTypeMembers->Find( aElemName, SbxCLASS_DONTCARE) )
+ Error (SbERR_VAR_DEFINED);
+ else
+ {
+ SbxDataType eElemType = pElem->GetType();
+ SbxProperty *pTypeElem = new SbxProperty( aElemName, eElemType );
+ if( pDim )
+ {
+ SbxDimArray* pArray = new SbxDimArray( pElem->GetType() );
+ if ( pDim->GetSize() )
+ {
+ // Dimension the target array
+
+ for ( short i=0; i<pDim->GetSize();++i )
+ {
+ INT32 ub = -1;
+ INT32 lb = nBase;
+ SbiExprNode* pNode = pDim->Get(i)->GetExprNode();
+ ub = pNode->GetNumber();
+ if ( !pDim->Get( i )->IsBased() ) // each dim is low/up
+ {
+ if ( ++i >= pDim->GetSize() ) // trouble
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ pNode = pDim->Get(i)->GetExprNode();
+ lb = ub;
+ ub = pNode->GetNumber();
+ }
+ else if ( !bCompatible )
+ ub += nBase;
+ pArray->AddDim32( lb, ub );
+ }
+ pArray->setHasFixedSize( true );
+ }
+ else
+ pArray->unoAddDim( 0, -1 ); // variant array
+ USHORT nSavFlags = pTypeElem->GetFlags();
+ // need to reset the FIXED flag
+ // when calling PutObject ( because the type will not match Object )
+ pTypeElem->ResetFlag( SBX_FIXED );
+ pTypeElem->PutObject( pArray );
+ pTypeElem->SetFlags( nSavFlags );
+ }
+ // Nested user type?
+ if( eElemType == SbxOBJECT )
+ {
+ USHORT nElemTypeId = pElem->GetTypeId();
+ if( nElemTypeId != 0 )
+ {
+ String aTypeName( aGblStrings.Find( nElemTypeId ) );
+ SbxObject* pTypeObj = static_cast< SbxObject* >( rTypeArray->Find( aTypeName, SbxCLASS_OBJECT ) );
+ if( pTypeObj != NULL )
+ {
+ SbxObject* pCloneObj = cloneTypeObjectImpl( *pTypeObj );
+ pTypeElem->PutObject( pCloneObj );
+ }
+ }
+ }
+ delete pDim;
+ pTypeMembers->Insert( pTypeElem, pTypeMembers->Count() );
+ }
+ delete pElem;
+ }
+ }
+
+ pType->Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_DONTCARE );
+ pType->Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Parent") ), SbxCLASS_DONTCARE );
+
+ rTypeArray->Insert (pType,rTypeArray->Count());
+}
+
+
+// Declaration of Enum type
+
+void SbiParser::Enum()
+{
+ DefEnum( FALSE );
+}
+
+void SbiParser::DefEnum( BOOL bPrivate )
+{
+ // Neues Token lesen, es muss ein Symbol sein
+ if (!TestSymbol())
+ return;
+
+ String aEnumName = aSym;
+ if( rEnumArray->Find(aEnumName,SbxCLASS_OBJECT) )
+ {
+ Error( SbERR_VAR_DEFINED, aSym );
+ return;
+ }
+
+ SbxObject *pEnum = new SbxObject( aEnumName );
+ if( bPrivate )
+ pEnum->SetFlag( SBX_PRIVATE );
+
+ SbiSymDef* pElem;
+ SbiDimList* pDim;
+ BOOL bDone = FALSE;
+
+ // Starting with -1 to make first default value 0 after ++
+ sal_Int32 nCurrentEnumValue = -1;
+ while( !bDone && !IsEof() )
+ {
+ switch( Peek() )
+ {
+ case ENDENUM :
+ pElem = NULL;
+ bDone = TRUE;
+ Next();
+ break;
+
+ case EOLN :
+ case REM :
+ pElem = NULL;
+ Next();
+ break;
+
+ default:
+ {
+ // TODO: Check existing!
+ BOOL bDefined = FALSE;
+
+ pDim = NULL;
+ pElem = VarDecl( &pDim, FALSE, TRUE );
+ if( !pElem )
+ {
+ bDone = TRUE; // Error occured
+ break;
+ }
+ else if( pDim )
+ {
+ delete pDim;
+ Error( SbERR_SYNTAX );
+ bDone = TRUE; // Error occured
+ break;
+ }
+
+ SbiExpression aVar( this, *pElem );
+ if( Peek() == EQ )
+ {
+ Next();
+
+ SbiConstExpression aExpr( this );
+ if( !bDefined && aExpr.IsValid() )
+ {
+ SbxVariableRef xConvertVar = new SbxVariable();
+ if( aExpr.GetType() == SbxSTRING )
+ xConvertVar->PutString( aExpr.GetString() );
+ else
+ xConvertVar->PutDouble( aExpr.GetValue() );
+
+ nCurrentEnumValue = xConvertVar->GetLong();
+ }
+ }
+ else
+ nCurrentEnumValue++;
+
+ SbiSymPool* pPoolToUse = bPrivate ? pPool : &aGlobals;
+
+ SbiSymDef* pOld = pPoolToUse->Find( pElem->GetName() );
+ if( pOld )
+ {
+ Error( SbERR_VAR_DEFINED, pElem->GetName() );
+ bDone = TRUE; // Error occured
+ break;
+ }
+
+ pPool->Add( pElem );
+
+ if( !bPrivate )
+ {
+ SbiOpcode eOp = _GLOBAL;
+ aGen.BackChain( nGblChain );
+ nGblChain = 0;
+ bGblDefs = bNewGblDefs = TRUE;
+ aGen.Gen(
+ eOp, pElem->GetId(),
+ sal::static_int_cast< UINT16 >( pElem->GetType() ) );
+
+ aVar.Gen();
+ USHORT nStringId = aGen.GetParser()->aGblStrings.Add( nCurrentEnumValue, SbxLONG );
+ aGen.Gen( _NUMBER, nStringId );
+ aGen.Gen( _PUTC );
+ }
+
+ SbiConstDef* pConst = pElem->GetConstDef();
+ pConst->Set( nCurrentEnumValue, SbxLONG );
+ }
+ }
+ if( pElem )
+ {
+ SbxArray *pEnumMembers = pEnum->GetProperties();
+ SbxProperty *pEnumElem = new SbxProperty( pElem->GetName(), SbxLONG );
+ pEnumElem->PutLong( nCurrentEnumValue );
+ pEnumElem->ResetFlag( SBX_WRITE );
+ pEnumElem->SetFlag( SBX_CONST );
+ pEnumMembers->Insert( pEnumElem, pEnumMembers->Count() );
+ }
+ }
+
+ pEnum->Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_DONTCARE );
+ pEnum->Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Parent") ), SbxCLASS_DONTCARE );
+
+ rEnumArray->Insert( pEnum, rEnumArray->Count() );
+}
+
+
+// Prozedur-Deklaration
+// das erste Token ist bereits eingelesen (SUB/FUNCTION)
+// xxx Name [LIB "name"[ALIAS "name"]][(Parameter)][AS TYPE]
+
+SbiProcDef* SbiParser::ProcDecl( BOOL bDecl )
+{
+ BOOL bFunc = BOOL( eCurTok == FUNCTION );
+ BOOL bProp = BOOL( eCurTok == GET || eCurTok == SET || eCurTok == LET );
+ if( !TestSymbol() ) return NULL;
+ String aName( aSym );
+ SbxDataType eType = eScanType;
+ SbiProcDef* pDef = new SbiProcDef( this, aName, true );
+ pDef->SetType( eType );
+ if( Peek() == _CDECL_ )
+ {
+ Next(); pDef->SetCdecl();
+ }
+ if( Peek() == LIB )
+ {
+ Next();
+ if( Next() == FIXSTRING )
+ pDef->GetLib() = aSym;
+ else
+ Error( SbERR_SYNTAX );
+ }
+ if( Peek() == ALIAS )
+ {
+ Next();
+ if( Next() == FIXSTRING )
+ pDef->GetAlias() = aSym;
+ else
+ Error( SbERR_SYNTAX );
+ }
+ if( !bDecl )
+ {
+ // CDECL, LIB und ALIAS sind unzulaessig
+ if( pDef->GetLib().Len() )
+ Error( SbERR_UNEXPECTED, LIB );
+ if( pDef->GetAlias().Len() )
+ Error( SbERR_UNEXPECTED, ALIAS );
+ if( pDef->IsCdecl() )
+ Error( SbERR_UNEXPECTED, _CDECL_ );
+ pDef->SetCdecl( FALSE );
+ pDef->GetLib().Erase();
+ pDef->GetAlias().Erase();
+ }
+ else if( !pDef->GetLib().Len() )
+ {
+ // ALIAS und CDECL nur zusammen mit LIB
+ if( pDef->GetAlias().Len() )
+ Error( SbERR_UNEXPECTED, ALIAS );
+ if( pDef->IsCdecl() )
+ Error( SbERR_UNEXPECTED, _CDECL_ );
+ pDef->SetCdecl( FALSE );
+ pDef->GetAlias().Erase();
+ }
+ // Klammern?
+ if( Peek() == LPAREN )
+ {
+ Next();
+ if( Peek() == RPAREN )
+ Next();
+ else
+ for(;;) {
+ BOOL bByVal = FALSE;
+ BOOL bOptional = FALSE;
+ BOOL bParamArray = FALSE;
+ while( Peek() == BYVAL || Peek() == BYREF || Peek() == _OPTIONAL_ )
+ {
+ if ( Peek() == BYVAL ) Next(), bByVal = TRUE;
+ else if ( Peek() == BYREF ) Next(), bByVal = FALSE;
+ else if ( Peek() == _OPTIONAL_ ) Next(), bOptional = TRUE;
+ }
+ if( bCompatible && Peek() == PARAMARRAY )
+ {
+ if( bByVal || bOptional )
+ Error( SbERR_UNEXPECTED, PARAMARRAY );
+ Next();
+ bParamArray = TRUE;
+ }
+ SbiSymDef* pPar = VarDecl( NULL, FALSE, FALSE );
+ if( !pPar )
+ break;
+ if( bByVal )
+ pPar->SetByVal();
+ if( bOptional )
+ pPar->SetOptional();
+ if( bParamArray )
+ pPar->SetParamArray();
+ pDef->GetParams().Add( pPar );
+ SbiToken eTok = Next();
+ if( eTok != COMMA && eTok != RPAREN )
+ {
+ BOOL bError2 = TRUE;
+ if( bOptional && bCompatible && eTok == EQ )
+ {
+ SbiConstExpression* pDefaultExpr = new SbiConstExpression( this );
+ SbxDataType eType2 = pDefaultExpr->GetType();
+
+ USHORT nStringId;
+ if( eType2 == SbxSTRING )
+ nStringId = aGblStrings.Add( pDefaultExpr->GetString() );
+ else
+ nStringId = aGblStrings.Add( pDefaultExpr->GetValue(), eType2 );
+
+ pPar->SetDefaultId( nStringId );
+ delete pDefaultExpr;
+
+ eTok = Next();
+ if( eTok == COMMA || eTok == RPAREN )
+ bError2 = FALSE;
+ }
+ if( bError2 )
+ {
+ Error( SbERR_EXPECTED, RPAREN );
+ break;
+ }
+ }
+ if( eTok == RPAREN )
+ break;
+ }
+ }
+ TypeDecl( *pDef );
+ if( eType != SbxVARIANT && pDef->GetType() != eType )
+ Error( SbERR_BAD_DECLARATION, aName );
+// if( pDef->GetType() == SbxOBJECT )
+// pDef->SetType( SbxVARIANT ),
+// Error( SbERR_SYNTAX );
+ if( pDef->GetType() == SbxVARIANT && !( bFunc || bProp ) )
+ pDef->SetType( SbxEMPTY );
+ return pDef;
+}
+
+// DECLARE
+
+void SbiParser::Declare()
+{
+ DefDeclare( FALSE );
+}
+
+void SbiParser::DefDeclare( BOOL bPrivate )
+{
+ Next();
+ if( eCurTok != SUB && eCurTok != FUNCTION )
+ Error( SbERR_UNEXPECTED, eCurTok );
+ else
+ {
+ bool bFunction = (eCurTok == FUNCTION);
+
+ SbiProcDef* pDef = ProcDecl( TRUE );
+ if( pDef )
+ {
+ if( !pDef->GetLib().Len() )
+ Error( SbERR_EXPECTED, LIB );
+ // gibts den schon?
+ SbiSymDef* pOld = aPublics.Find( pDef->GetName() );
+ if( pOld )
+ {
+ SbiProcDef* p = pOld->GetProcDef();
+ if( !p )
+ {
+ // Als Variable deklariert
+ Error( SbERR_BAD_DECLARATION, pDef->GetName() );
+ delete pDef;
+ pDef = NULL;
+ }
+ else
+ pDef->Match( p );
+ }
+ else
+ aPublics.Add( pDef );
+
+ if ( pDef )
+ {
+ pDef->SetPublic( !bPrivate );
+
+ // New declare handling
+ if( pDef->GetLib().Len() > 0 )
+ {
+ if( bNewGblDefs && nGblChain == 0 )
+ {
+ nGblChain = aGen.Gen( _JUMP, 0 );
+ bNewGblDefs = FALSE;
+ }
+
+ USHORT nSavLine = nLine;
+ aGen.Statement();
+ pDef->Define();
+ pDef->SetLine1( nSavLine );
+ pDef->SetLine2( nSavLine );
+
+ SbiSymPool& rPool = pDef->GetParams();
+ USHORT nParCount = rPool.GetSize();
+
+ SbxDataType eType = pDef->GetType();
+ if( bFunction )
+ aGen.Gen( _PARAM, 0, sal::static_int_cast< UINT16 >( eType ) );
+
+ if( nParCount > 1 )
+ {
+ aGen.Gen( _ARGC );
+
+ for( USHORT i = 1 ; i < nParCount ; ++i )
+ {
+ SbiSymDef* pParDef = rPool.Get( i );
+ SbxDataType eParType = pParDef->GetType();
+
+ aGen.Gen( _PARAM, i, sal::static_int_cast< UINT16 >( eParType ) );
+ aGen.Gen( _ARGV );
+
+ USHORT nTyp = sal::static_int_cast< USHORT >( pParDef->GetType() );
+ if( pParDef->IsByVal() )
+ {
+ // Reset to avoid additional byval in call to wrapper function
+ pParDef->SetByVal( FALSE );
+ nTyp |= 0x8000;
+ }
+ aGen.Gen( _ARGTYP, nTyp );
+ }
+ }
+
+ aGen.Gen( _LIB, aGblStrings.Add( pDef->GetLib() ) );
+
+ SbiOpcode eOp = pDef->IsCdecl() ? _CALLC : _CALL;
+ USHORT nId = pDef->GetId();
+ if( pDef->GetAlias().Len() )
+ nId = ( nId & 0x8000 ) | aGblStrings.Add( pDef->GetAlias() );
+ if( nParCount > 1 )
+ nId |= 0x8000;
+ aGen.Gen( eOp, nId, sal::static_int_cast< UINT16 >( eType ) );
+
+ if( bFunction )
+ aGen.Gen( _PUT );
+
+ aGen.Gen( _LEAVE );
+ }
+ }
+ }
+ }
+}
+
+// Aufruf einer SUB oder FUNCTION
+
+void SbiParser::Call()
+{
+ String aName( aSym );
+ SbiExpression aVar( this, SbSYMBOL );
+ aVar.Gen( FORCE_CALL );
+ aGen.Gen( _GET );
+}
+
+// SUB/FUNCTION
+
+void SbiParser::SubFunc()
+{
+ DefProc( FALSE, FALSE );
+}
+
+// Einlesen einer Prozedur
+
+BOOL runsInSetup( void );
+
+void SbiParser::DefProc( BOOL bStatic, BOOL bPrivate )
+{
+ USHORT l1 = nLine, l2 = nLine;
+ BOOL bSub = BOOL( eCurTok == SUB );
+ BOOL bProperty = BOOL( eCurTok == PROPERTY );
+ PropertyMode ePropertyMode = PROPERTY_MODE_NONE;
+ if( bProperty )
+ {
+ Next();
+ if( eCurTok == GET )
+ ePropertyMode = PROPERTY_MODE_GET;
+ else if( eCurTok == LET )
+ ePropertyMode = PROPERTY_MODE_LET;
+ else if( eCurTok == SET )
+ ePropertyMode = PROPERTY_MODE_SET;
+ else
+ Error( SbERR_EXPECTED, "Get or Let or Set" );
+ }
+
+ SbiToken eExit = eCurTok;
+ SbiProcDef* pDef = ProcDecl( FALSE );
+ if( !pDef )
+ return;
+ pDef->setPropertyMode( ePropertyMode );
+
+ // Ist die Proc bereits deklariert?
+ SbiSymDef* pOld = aPublics.Find( pDef->GetName() );
+ if( pOld )
+ {
+ bool bError_ = false;
+
+ pProc = pOld->GetProcDef();
+ if( !pProc )
+ {
+ // Als Variable deklariert
+ Error( SbERR_BAD_DECLARATION, pDef->GetName() );
+ delete pDef;
+ pProc = NULL;
+ bError_ = true;
+ }
+ // #100027: Multiple declaration -> Error
+ // #112787: Not for setup, REMOVE for 8
+ else if( !runsInSetup() && pProc->IsUsedForProcDecl() )
+ {
+ PropertyMode ePropMode = pDef->getPropertyMode();
+ if( ePropMode == PROPERTY_MODE_NONE || ePropMode == pProc->getPropertyMode() )
+ {
+ Error( SbERR_PROC_DEFINED, pDef->GetName() );
+ delete pDef;
+ pProc = NULL;
+ bError_ = true;
+ }
+ }
+
+ if( !bError_ )
+ {
+ pDef->Match( pProc );
+ pProc = pDef;
+ }
+ }
+ else
+ aPublics.Add( pDef ), pProc = pDef;
+
+ if( !pProc )
+ return;
+ pProc->SetPublic( !bPrivate );
+
+ // Nun setzen wir die Suchhierarchie fuer Symbole sowie die aktuelle
+ // Prozedur.
+ aPublics.SetProcId( pProc->GetId() );
+ pProc->GetParams().SetParent( &aPublics );
+ if( bStatic )
+ {
+ if ( bVBASupportOn )
+ pProc->SetStatic( TRUE );
+ else
+ Error( SbERR_NOT_IMPLEMENTED ); // STATIC SUB ...
+ }
+ else
+ {
+ pProc->SetStatic( FALSE );
+ }
+ // Normalfall: Lokale Variable->Parameter->Globale Variable
+ pProc->GetLocals().SetParent( &pProc->GetParams() );
+ pPool = &pProc->GetLocals();
+
+ pProc->Define();
+ OpenBlock( eExit );
+ StmntBlock( bSub ? ENDSUB : (bProperty ? ENDPROPERTY : ENDFUNC) );
+ l2 = nLine;
+ pProc->SetLine1( l1 );
+ pProc->SetLine2( l2 );
+ pPool = &aPublics;
+ aPublics.SetProcId( 0 );
+ // Offene Labels?
+ pProc->GetLabels().CheckRefs();
+ CloseBlock();
+ aGen.Gen( _LEAVE );
+ pProc = NULL;
+}
+
+// STATIC variable|procedure
+
+void SbiParser::Static()
+{
+ DefStatic( FALSE );
+}
+
+void SbiParser::DefStatic( BOOL bPrivate )
+{
+ switch( Peek() )
+ {
+ case SUB:
+ case FUNCTION:
+ case PROPERTY:
+ // End global chain if necessary (not done in
+ // SbiParser::Parse() under these conditions
+ if( bNewGblDefs && nGblChain == 0 )
+ {
+ nGblChain = aGen.Gen( _JUMP, 0 );
+ bNewGblDefs = FALSE;
+ }
+ Next();
+ DefProc( TRUE, bPrivate );
+ break;
+ default: {
+ if( !pProc )
+ Error( SbERR_NOT_IN_SUBR );
+ // Pool umsetzen, damit STATIC-Deklarationen im globalen
+ // Pool landen
+ SbiSymPool* p = pPool; pPool = &aPublics;
+ DefVar( _STATIC, TRUE );
+ pPool = p;
+ } break;
+ }
+}
+
diff --git a/basic/source/comp/exprgen.cxx b/basic/source/comp/exprgen.cxx
new file mode 100644
index 000000000000..3e034af204f5
--- /dev/null
+++ b/basic/source/comp/exprgen.cxx
@@ -0,0 +1,270 @@
+/*************************************************************************
+ *
+ * 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 "sbcomp.hxx"
+#include "expr.hxx"
+
+// Umsetztabelle fuer Token-Operatoren und Opcodes
+
+typedef struct {
+ SbiToken eTok; // Token
+ SbiOpcode eOp; // Opcode
+} OpTable;
+
+static OpTable aOpTable [] = {
+ { EXPON,_EXP },
+ { MUL, _MUL },
+ { DIV, _DIV },
+ { IDIV, _IDIV },
+ { MOD, _MOD },
+ { PLUS, _PLUS },
+ { MINUS,_MINUS },
+ { EQ, _EQ },
+ { NE, _NE },
+ { LE, _LE },
+ { GE, _GE },
+ { LT, _LT },
+ { GT, _GT },
+ { AND, _AND },
+ { OR, _OR },
+ { XOR, _XOR },
+ { EQV, _EQV },
+ { IMP, _IMP },
+ { NOT, _NOT },
+ { NEG, _NEG },
+ { CAT, _CAT },
+ { LIKE, _LIKE },
+ { IS, _IS },
+ { NIL, _NOP }};
+
+// Ausgabe eines Elements
+void SbiExprNode::Gen( RecursiveMode eRecMode )
+{
+ if( IsConstant() )
+ {
+ switch( GetType() )
+ {
+ case SbxEMPTY: pGen->Gen( _EMPTY ); break;
+ case SbxINTEGER: pGen->Gen( _CONST, (short) nVal ); break;
+ case SbxSTRING:
+ {
+ USHORT nStringId = pGen->GetParser()->aGblStrings.Add( aStrVal, TRUE );
+ pGen->Gen( _SCONST, nStringId ); break;
+ }
+ default:
+ {
+ USHORT nStringId = pGen->GetParser()->aGblStrings.Add( nVal, eType );
+ pGen->Gen( _NUMBER, nStringId );
+ }
+ }
+ }
+ else if( IsOperand() )
+ {
+ SbiExprNode* pWithParent_ = NULL;
+ SbiOpcode eOp;
+ if( aVar.pDef->GetScope() == SbPARAM )
+ {
+ eOp = _PARAM;
+ if( 0 == aVar.pDef->GetPos() )
+ {
+ bool bTreatFunctionAsParam = true;
+ if( eRecMode == FORCE_CALL )
+ {
+ bTreatFunctionAsParam = false;
+ }
+ else if( eRecMode == UNDEFINED )
+ {
+ if( aVar.pPar && aVar.pPar->IsBracket() )
+ bTreatFunctionAsParam = false;
+ }
+ if( !bTreatFunctionAsParam )
+ eOp = aVar.pDef->IsGlobal() ? _FIND_G : _FIND;
+ }
+ }
+ // AB: 17.12.1995, Spezialbehandlung fuer WITH
+ else if( (pWithParent_ = GetWithParent()) != NULL )
+ {
+ eOp = _ELEM; // .-Ausdruck in WITH
+ }
+ else
+ {
+ eOp = ( aVar.pDef->GetScope() == SbRTL ) ? _RTL :
+ (aVar.pDef->IsGlobal() ? _FIND_G : _FIND);
+ }
+
+ if( eOp == _FIND )
+ {
+
+ SbiProcDef* pProc = aVar.pDef->GetProcDef();
+ if ( pGen->GetParser()->bClassModule )
+ eOp = _FIND_CM;
+ else if ( aVar.pDef->IsStatic() || (pProc && pProc->IsStatic()) )
+ {
+ eOp = _FIND_STATIC;
+ }
+ }
+ for( SbiExprNode* p = this; p; p = p->aVar.pNext )
+ {
+ if( p == this && pWithParent_ != NULL )
+ pWithParent_->Gen();
+ p->GenElement( eOp );
+ eOp = _ELEM;
+ }
+ }
+ else if( IsTypeOf() )
+ {
+ pLeft->Gen();
+ pGen->Gen( _TESTCLASS, nTypeStrId );
+ }
+ else if( IsNew() )
+ {
+ pGen->Gen( _CREATE, 0, nTypeStrId );
+ }
+ else
+ {
+ pLeft->Gen();
+ if( pRight )
+ pRight->Gen();
+ for( OpTable* p = aOpTable; p->eTok != NIL; p++ )
+ {
+ if( p->eTok == eTok )
+ {
+ pGen->Gen( p->eOp ); break;
+ }
+ }
+ }
+}
+
+// Ausgabe eines Operanden-Elements
+
+void SbiExprNode::GenElement( SbiOpcode eOp )
+{
+#ifdef DBG_UTIL
+ if( (eOp < _RTL || eOp > _CALLC) && eOp != _FIND_G && eOp != _FIND_CM )
+ pGen->GetParser()->Error( SbERR_INTERNAL_ERROR, "Opcode" );
+#endif
+ SbiSymDef* pDef = aVar.pDef;
+ // Das ID ist entweder die Position oder das String-ID
+ // Falls das Bit 0x8000 gesetzt ist, hat die Variable
+ // eine Parameterliste.
+ USHORT nId = ( eOp == _PARAM ) ? pDef->GetPos() : pDef->GetId();
+ // Parameterliste aufbauen
+ if( aVar.pPar && aVar.pPar->GetSize() )
+ {
+ nId |= 0x8000;
+ aVar.pPar->Gen();
+ }
+
+ pGen->Gen( eOp, nId, sal::static_int_cast< UINT16 >( GetType() ) );
+
+ if( aVar.pvMorePar )
+ {
+ SbiExprListVector* pvMorePar = aVar.pvMorePar;
+ SbiExprListVector::iterator it;
+ for( it = pvMorePar->begin() ; it != pvMorePar->end() ; ++it )
+ {
+ SbiExprList* pExprList = *it;
+ pExprList->Gen();
+ pGen->Gen( _ARRAYACCESS );
+ }
+ }
+}
+
+// Erzeugen einer Argv-Tabelle
+// Das erste Element bleibt immer frei fuer Returnwerte etc.
+// Siehe auch SbiProcDef::SbiProcDef() in symtbl.cxx
+
+void SbiExprList::Gen()
+{
+ if( pFirst )
+ {
+ pParser->aGen.Gen( _ARGC );
+ // AB 10.1.96: Typ-Anpassung bei DECLARE
+ USHORT nCount = 1 /*, nParAnz = 0*/;
+// SbiSymPool* pPool = NULL;
+ for( SbiExpression* pExpr = pFirst; pExpr; pExpr = pExpr->pNext,nCount++ )
+ {
+ pExpr->Gen();
+ if( pExpr->GetName().Len() )
+ {
+ // named arg
+ USHORT nSid = pParser->aGblStrings.Add( pExpr->GetName() );
+ pParser->aGen.Gen( _ARGN, nSid );
+
+ /* TODO: Check after Declare concept change
+ // AB 10.1.96: Typanpassung bei named -> passenden Parameter suchen
+ if( pProc )
+ {
+ // Vorerst: Error ausloesen
+ pParser->Error( SbERR_NO_NAMED_ARGS );
+
+ // Spaeter, wenn Named Args bei DECLARE moeglich
+ //for( USHORT i = 1 ; i < nParAnz ; i++ )
+ //{
+ // SbiSymDef* pDef = pPool->Get( i );
+ // const String& rName = pDef->GetName();
+ // if( rName.Len() )
+ // {
+ // if( pExpr->GetName().ICompare( rName )
+ // == COMPARE_EQUAL )
+ // {
+ // pParser->aGen.Gen( _ARGTYP, pDef->GetType() );
+ // break;
+ // }
+ // }
+ //}
+ }
+ */
+ }
+ else
+ {
+ pParser->aGen.Gen( _ARGV );
+ }
+ }
+ }
+}
+
+void SbiExpression::Gen( RecursiveMode eRecMode )
+{
+ // AB: 17.12.1995, Spezialbehandlung fuer WITH
+ // Wenn pExpr == .-Ausdruck in With, zunaechst Gen fuer Basis-Objekt
+ pExpr->Gen( eRecMode );
+ if( bByVal )
+ pParser->aGen.Gen( _BYVAL );
+ if( bBased )
+ {
+ USHORT uBase = pParser->nBase;
+ if( pParser->IsCompatible() )
+ uBase |= 0x8000; // #109275 Flag compatiblity
+ pParser->aGen.Gen( _BASED, uBase );
+ pParser->aGen.Gen( _ARGV );
+ }
+}
+
diff --git a/basic/source/comp/exprnode.cxx b/basic/source/comp/exprnode.cxx
new file mode 100644
index 000000000000..d47c86f86ea8
--- /dev/null
+++ b/basic/source/comp/exprnode.cxx
@@ -0,0 +1,488 @@
+/*************************************************************************
+ *
+ * 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 <math.h>
+
+#include <rtl/math.hxx>
+#include "sbcomp.hxx"
+#include "expr.hxx"
+
+//////////////////////////////////////////////////////////////////////////
+
+SbiExprNode::SbiExprNode( void )
+{
+ pLeft = NULL;
+ pRight = NULL;
+ eNodeType = SbxDUMMY;
+}
+
+SbiExprNode::SbiExprNode( SbiParser* p, SbiExprNode* l, SbiToken t, SbiExprNode* r )
+{
+ BaseInit( p );
+
+ pLeft = l;
+ pRight = r;
+ eTok = t;
+ nVal = 0;
+ eType = SbxVARIANT; // Nodes sind immer Variant
+ eNodeType = SbxNODE;
+ bComposite= TRUE;
+}
+
+SbiExprNode::SbiExprNode( SbiParser* p, double n, SbxDataType t )
+{
+ BaseInit( p );
+
+ eType = t;
+ eNodeType = SbxNUMVAL;
+ nVal = n;
+}
+
+SbiExprNode::SbiExprNode( SbiParser* p, const String& rVal )
+{
+ BaseInit( p );
+
+ eType = SbxSTRING;
+ eNodeType = SbxSTRVAL;
+ aStrVal = rVal;
+}
+
+SbiExprNode::SbiExprNode( SbiParser* p, const SbiSymDef& r, SbxDataType t, SbiExprList* l )
+{
+ BaseInit( p );
+
+ eType = ( t == SbxVARIANT ) ? r.GetType() : t;
+ eNodeType = SbxVARVAL;
+ aVar.pDef = (SbiSymDef*) &r;
+ aVar.pPar = l;
+ aVar.pvMorePar = NULL;
+ aVar.pNext= NULL;
+
+ // Funktionsergebnisse sind nie starr
+ bComposite= BOOL( aVar.pDef->GetProcDef() != NULL );
+}
+
+// #120061 TypeOf
+SbiExprNode::SbiExprNode( SbiParser* p, SbiExprNode* l, USHORT nId )
+{
+ BaseInit( p );
+
+ pLeft = l;
+ eType = SbxBOOL;
+ eNodeType = SbxTYPEOF;
+ nTypeStrId = nId;
+}
+
+// new <type>
+SbiExprNode::SbiExprNode( SbiParser* p, USHORT nId )
+{
+ BaseInit( p );
+
+ eType = SbxOBJECT;
+ eNodeType = SbxNEW;
+ nTypeStrId = nId;
+}
+
+// AB: 17.12.95, Hilfsfunktion fuer Ctor fuer einheitliche Initialisierung
+void SbiExprNode::BaseInit( SbiParser* p )
+{
+ pGen = &p->aGen;
+ eTok = NIL;
+ pLeft = NULL;
+ pRight = NULL;
+ pWithParent = NULL;
+ bComposite = FALSE;
+ bError = FALSE;
+}
+
+SbiExprNode::~SbiExprNode()
+{
+ delete pLeft;
+ delete pRight;
+ if( IsVariable() )
+ {
+ delete aVar.pPar;
+ delete aVar.pNext;
+ SbiExprListVector* pvMorePar = aVar.pvMorePar;
+ if( pvMorePar )
+ {
+ SbiExprListVector::iterator it;
+ for( it = pvMorePar->begin() ; it != pvMorePar->end() ; ++it )
+ delete *it;
+ delete pvMorePar;
+ }
+ }
+}
+
+SbiSymDef* SbiExprNode::GetVar()
+{
+ if( eNodeType == SbxVARVAL )
+ return aVar.pDef;
+ else
+ return NULL;
+}
+
+SbiSymDef* SbiExprNode::GetRealVar()
+{
+ SbiExprNode* p = GetRealNode();
+ if( p )
+ return p->GetVar();
+ else
+ return NULL;
+}
+
+// AB: 18.12.95
+SbiExprNode* SbiExprNode::GetRealNode()
+{
+ if( eNodeType == SbxVARVAL )
+ {
+ SbiExprNode* p = this;
+ while( p->aVar.pNext )
+ p = p->aVar.pNext;
+ return p;
+ }
+ else
+ return NULL;
+}
+
+// Diese Methode setzt den Typ um, falls er in den Integer-Bereich hineinpasst
+
+BOOL SbiExprNode::IsIntConst()
+{
+ if( eNodeType == SbxNUMVAL )
+ {
+ if( eType >= SbxINTEGER && eType <= SbxDOUBLE )
+ {
+ double n;
+ if( nVal >= SbxMININT && nVal <= SbxMAXINT && modf( nVal, &n ) == 0 )
+ {
+ nVal = (double) (short) nVal;
+ eType = SbxINTEGER;
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+BOOL SbiExprNode::IsNumber()
+{
+ return BOOL( eNodeType == SbxNUMVAL );
+}
+
+BOOL SbiExprNode::IsString()
+{
+ return BOOL( eNodeType == SbxSTRVAL );
+}
+
+BOOL SbiExprNode::IsVariable()
+{
+ return BOOL( eNodeType == SbxVARVAL );
+}
+
+BOOL SbiExprNode::IsLvalue()
+{
+ return IsVariable();
+}
+
+// Ermitteln der Tiefe eines Baumes
+
+short SbiExprNode::GetDepth()
+{
+ if( IsOperand() ) return 0;
+ else
+ {
+ short d1 = pLeft->GetDepth();
+ short d2 = pRight->GetDepth();
+ return( (d1 < d2 ) ? d2 : d1 ) + 1;
+ }
+}
+
+
+// Abgleich eines Baumes:
+// 1. Constant Folding
+// 2. Typabgleich
+// 3. Umwandlung der Operanden in Strings
+// 4. Hochziehen der Composite- und Error-Bits
+
+void SbiExprNode::Optimize()
+{
+ FoldConstants();
+ CollectBits();
+}
+
+// Hochziehen der Composite- und Fehlerbits
+
+void SbiExprNode::CollectBits()
+{
+ if( pLeft )
+ {
+ pLeft->CollectBits();
+ bError |= pLeft->bError;
+ bComposite |= pLeft->bComposite;
+ }
+ if( pRight )
+ {
+ pRight->CollectBits();
+ bError |= pRight->bError;
+ bComposite |= pRight->bComposite;
+ }
+}
+
+// Kann ein Zweig umgeformt werden, wird TRUE zurueckgeliefert. In diesem
+// Fall ist das Ergebnis im linken Zweig.
+
+void SbiExprNode::FoldConstants()
+{
+ if( IsOperand() || eTok == LIKE ) return;
+ if( pLeft )
+ pLeft->FoldConstants();
+ if( pRight )
+ {
+ pRight->FoldConstants();
+ if( pLeft->IsConstant() && pRight->IsConstant()
+ && pLeft->eNodeType == pRight->eNodeType )
+ {
+ CollectBits();
+ if( eTok == CAT )
+ // CAT verbindet auch zwei Zahlen miteinander!
+ eType = SbxSTRING;
+ if( pLeft->eType == SbxSTRING )
+ // Kein Type Mismatch!
+ eType = SbxSTRING;
+ if( eType == SbxSTRING )
+ {
+ String rl( pLeft->GetString() );
+ String rr( pRight->GetString() );
+ delete pLeft; pLeft = NULL;
+ delete pRight; pRight = NULL;
+ bComposite = FALSE;
+ if( eTok == PLUS || eTok == CAT )
+ {
+ eTok = CAT;
+ // Verkettung:
+ aStrVal = rl;
+ aStrVal += rr;
+ eType = SbxSTRING;
+ eNodeType = SbxSTRVAL;
+ }
+ else
+ {
+ eType = SbxDOUBLE;
+ eNodeType = SbxNUMVAL;
+ StringCompare eRes = rr.CompareTo( rl );
+ switch( eTok )
+ {
+ case EQ:
+ nVal = ( eRes == COMPARE_EQUAL ) ? SbxTRUE : SbxFALSE;
+ break;
+ case NE:
+ nVal = ( eRes != COMPARE_EQUAL ) ? SbxTRUE : SbxFALSE;
+ break;
+ case LT:
+ nVal = ( eRes == COMPARE_LESS ) ? SbxTRUE : SbxFALSE;
+ break;
+ case GT:
+ nVal = ( eRes == COMPARE_GREATER ) ? SbxTRUE : SbxFALSE;
+ break;
+ case LE:
+ nVal = ( eRes != COMPARE_GREATER ) ? SbxTRUE : SbxFALSE;
+ break;
+ case GE:
+ nVal = ( eRes != COMPARE_LESS ) ? SbxTRUE : SbxFALSE;
+ break;
+ default:
+ pGen->GetParser()->Error( SbERR_CONVERSION );
+ bError = TRUE;
+ }
+ }
+ }
+ else
+ {
+ double nl = pLeft->nVal;
+ double nr = pRight->nVal;
+ long ll = 0, lr = 0;
+ long llMod = 0, lrMod = 0;
+ if( ( eTok >= AND && eTok <= IMP )
+ || eTok == IDIV || eTok == MOD )
+ {
+ // Integer-Operationen
+ BOOL err = FALSE;
+ if( nl > SbxMAXLNG ) err = TRUE, nl = SbxMAXLNG;
+ else
+ if( nl < SbxMINLNG ) err = TRUE, nl = SbxMINLNG;
+ if( nr > SbxMAXLNG ) err = TRUE, nr = SbxMAXLNG;
+ else
+ if( nr < SbxMINLNG ) err = TRUE, nr = SbxMINLNG;
+ ll = (long) nl; lr = (long) nr;
+ llMod = (long) (nl < 0 ? nl - 0.5 : nl + 0.5);
+ lrMod = (long) (nr < 0 ? nr - 0.5 : nr + 0.5);
+ if( err )
+ {
+ pGen->GetParser()->Error( SbERR_MATH_OVERFLOW );
+ bError = TRUE;
+ }
+ }
+ BOOL bBothInt = BOOL( pLeft->eType < SbxSINGLE
+ && pRight->eType < SbxSINGLE );
+ delete pLeft; pLeft = NULL;
+ delete pRight; pRight = NULL;
+ nVal = 0;
+ eType = SbxDOUBLE;
+ eNodeType = SbxNUMVAL;
+ bComposite = FALSE;
+ BOOL bCheckType = FALSE;
+ switch( eTok )
+ {
+ case EXPON:
+ nVal = pow( nl, nr ); break;
+ case MUL:
+ bCheckType = TRUE;
+ nVal = nl * nr; break;
+ case DIV:
+ if( !nr )
+ {
+ pGen->GetParser()->Error( SbERR_ZERODIV ); nVal = HUGE_VAL;
+ bError = TRUE;
+ } else nVal = nl / nr;
+ break;
+ case PLUS:
+ bCheckType = TRUE;
+ nVal = nl + nr; break;
+ case MINUS:
+ bCheckType = TRUE;
+ nVal = nl - nr; break;
+ case EQ:
+ nVal = ( nl == nr ) ? SbxTRUE : SbxFALSE;
+ eType = SbxINTEGER; break;
+ case NE:
+ nVal = ( nl != nr ) ? SbxTRUE : SbxFALSE;
+ eType = SbxINTEGER; break;
+ case LT:
+ nVal = ( nl < nr ) ? SbxTRUE : SbxFALSE;
+ eType = SbxINTEGER; break;
+ case GT:
+ nVal = ( nl > nr ) ? SbxTRUE : SbxFALSE;
+ eType = SbxINTEGER; break;
+ case LE:
+ nVal = ( nl <= nr ) ? SbxTRUE : SbxFALSE;
+ eType = SbxINTEGER; break;
+ case GE:
+ nVal = ( nl >= nr ) ? SbxTRUE : SbxFALSE;
+ eType = SbxINTEGER; break;
+ case IDIV:
+ if( !lr )
+ {
+ pGen->GetParser()->Error( SbERR_ZERODIV ); nVal = HUGE_VAL;
+ bError = TRUE;
+ } else nVal = ll / lr;
+ eType = SbxLONG; break;
+ case MOD:
+ if( !lr )
+ {
+ pGen->GetParser()->Error( SbERR_ZERODIV ); nVal = HUGE_VAL;
+ bError = TRUE;
+ } else nVal = llMod % lrMod;
+ eType = SbxLONG; break;
+ case AND:
+ nVal = (double) ( ll & lr ); eType = SbxLONG; break;
+ case OR:
+ nVal = (double) ( ll | lr ); eType = SbxLONG; break;
+ case XOR:
+ nVal = (double) ( ll ^ lr ); eType = SbxLONG; break;
+ case EQV:
+ nVal = (double) ( ~ll ^ lr ); eType = SbxLONG; break;
+ case IMP:
+ nVal = (double) ( ~ll | lr ); eType = SbxLONG; break;
+ default: break;
+ }
+
+ if( !::rtl::math::isFinite( nVal ) )
+ pGen->GetParser()->Error( SbERR_MATH_OVERFLOW );
+
+ // Den Datentyp wiederherstellen, um Rundungsfehler
+ // zu killen
+ if( bCheckType && bBothInt
+ && nVal >= SbxMINLNG && nVal <= SbxMAXLNG )
+ {
+ // NK-Stellen weg
+ long n = (long) nVal;
+ nVal = n;
+ eType = ( n >= SbxMININT && n <= SbxMAXINT )
+ ? SbxINTEGER : SbxLONG;
+ }
+ }
+ }
+ }
+ else if( pLeft && pLeft->IsNumber() )
+ {
+ nVal = pLeft->nVal;
+ delete pLeft;
+ pLeft = NULL;
+ eType = SbxDOUBLE;
+ eNodeType = SbxNUMVAL;
+ bComposite = FALSE;
+ switch( eTok )
+ {
+ case NEG:
+ nVal = -nVal; break;
+ case NOT: {
+ // Integer-Operation!
+ BOOL err = FALSE;
+ if( nVal > SbxMAXLNG ) err = TRUE, nVal = SbxMAXLNG;
+ else
+ if( nVal < SbxMINLNG ) err = TRUE, nVal = SbxMINLNG;
+ if( err )
+ {
+ pGen->GetParser()->Error( SbERR_MATH_OVERFLOW );
+ bError = TRUE;
+ }
+ nVal = (double) ~((long) nVal);
+ eType = SbxLONG;
+ } break;
+ default: break;
+ }
+ }
+ if( eNodeType == SbxNUMVAL )
+ {
+ // Evtl auf INTEGER falten (wg. besserem Opcode)?
+ if( eType == SbxSINGLE || eType == SbxDOUBLE )
+ {
+ double x;
+ if( nVal >= SbxMINLNG && nVal <= SbxMAXLNG
+ && !modf( nVal, &x ) )
+ eType = SbxLONG;
+ }
+ if( eType == SbxLONG && nVal >= SbxMININT && nVal <= SbxMAXINT )
+ eType = SbxINTEGER;
+ }
+}
+
+
diff --git a/basic/source/comp/exprtree.cxx b/basic/source/comp/exprtree.cxx
new file mode 100644
index 000000000000..7a4ea5965558
--- /dev/null
+++ b/basic/source/comp/exprtree.cxx
@@ -0,0 +1,1136 @@
+/*************************************************************************
+ *
+ * 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 "sbcomp.hxx"
+#include <basic/sbx.hxx> // w.g. ...IMPL_REF(...sbxvariable)
+#include "expr.hxx"
+
+/***************************************************************************
+|*
+|* SbiExpression
+|*
+***************************************************************************/
+
+SbiExpression::SbiExpression( SbiParser* p, SbiExprType t,
+ SbiExprMode eMode, const KeywordSymbolInfo* pKeywordSymbolInfo )
+{
+ pParser = p;
+ bError = bByVal = bBased = bBracket = FALSE;
+ nParenLevel = 0;
+ eCurExpr = t;
+ m_eMode = eMode;
+ pNext = NULL;
+ pExpr = (t != SbSTDEXPR ) ? Term( pKeywordSymbolInfo ) : Boolean();
+ if( t != SbSYMBOL )
+ pExpr->Optimize();
+ if( t == SbLVALUE && !pExpr->IsLvalue() )
+ p->Error( SbERR_LVALUE_EXPECTED );
+ if( t == SbOPERAND && !IsVariable() )
+ p->Error( SbERR_VAR_EXPECTED );
+}
+
+SbiExpression::SbiExpression( SbiParser* p, double n, SbxDataType t )
+{
+ pParser = p;
+ eCurExpr = SbOPERAND;
+ pNext = NULL;
+ bError = bByVal = bBased = bBracket = FALSE;
+ pExpr = new SbiExprNode( pParser, n, t );
+ pExpr->Optimize();
+}
+
+SbiExpression::SbiExpression( SbiParser* p, const String& r )
+{
+ pParser = p;
+ pNext = NULL;
+ bError = bByVal = bBased = bBracket = FALSE;
+ eCurExpr = SbOPERAND;
+ pExpr = new SbiExprNode( pParser, r );
+}
+
+SbiExpression::SbiExpression( SbiParser* p, const SbiSymDef& r, SbiExprList* pPar )
+{
+ pParser = p;
+ pNext = NULL;
+ bError = bByVal = bBased = bBracket = FALSE;
+ eCurExpr = SbOPERAND;
+ pExpr = new SbiExprNode( pParser, r, SbxVARIANT, pPar );
+}
+
+SbiExpression::SbiExpression( SbiParser* p, SbiToken t )
+{
+ pParser = p;
+ pNext = NULL;
+ bError = bByVal = bBased = bBracket = FALSE;
+ eCurExpr = SbOPERAND;
+ pExpr = new SbiExprNode( pParser, NULL, t, NULL );
+}
+
+SbiExpression::~SbiExpression()
+{
+ delete pExpr;
+}
+
+// Einlesen eines kompletten Bezeichners
+// Ein Bezeichner hat folgende Form:
+// name[(Parameter)][.Name[(parameter)]]...
+// Strukturelemente werden ueber das Element pNext verkoppelt,
+// damit sie nicht im Baum stehen.
+
+// Folgen Parameter ohne Klammer? Dies kann eine Zahl, ein String,
+// ein Symbol oder auch ein Komma sein (wenn der 1. Parameter fehlt)
+
+static BOOL DoParametersFollow( SbiParser* p, SbiExprType eCurExpr, SbiToken eTok )
+{
+ if( eTok == LPAREN )
+ return TRUE;
+ // Aber nur, wenn CALL-aehnlich!
+ if( !p->WhiteSpace() || eCurExpr != SbSYMBOL )
+ return FALSE;
+ if ( eTok == NUMBER || eTok == MINUS || eTok == FIXSTRING
+ || eTok == SYMBOL || eTok == COMMA || eTok == DOT || eTok == NOT || eTok == BYVAL )
+ {
+ return TRUE;
+ }
+ else // check for default params with reserved names ( e.g. names of tokens )
+ {
+ SbiTokenizer tokens( *(SbiTokenizer*)p );
+ // Urk the Next() / Peek() symantics are... weird
+ tokens.Next();
+ if ( tokens.Peek() == ASSIGN )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// Definition eines neuen Symbols
+
+static SbiSymDef* AddSym
+ ( SbiToken eTok, SbiSymPool& rPool, SbiExprType eCurExpr,
+ const String& rName, SbxDataType eType, SbiParameters* pPar )
+{
+ SbiSymDef* pDef;
+ // A= ist keine Prozedur
+ BOOL bHasType = BOOL( eTok == EQ || eTok == DOT );
+ if( ( !bHasType && eCurExpr == SbSYMBOL ) || pPar )
+ {
+ // Dies ist also eine Prozedur
+ // da suche man doch den richtigen Pool raus, da Procs
+ // immer in einem Public-Pool landen muessen
+ SbiSymPool* pPool = &rPool;
+ if( pPool->GetScope() != SbPUBLIC )
+ pPool = &rPool.GetParser()->aPublics;
+ SbiProcDef* pProc = pPool->AddProc( rName );
+
+ // Sonderbehandlung fuer Colls wie Documents(1)
+ if( eCurExpr == SbSTDEXPR )
+ bHasType = TRUE;
+
+ pDef = pProc;
+ pDef->SetType( bHasType ? eType : SbxEMPTY );
+ if( pPar )
+ {
+ // Dummy-Parameter generieren
+ USHORT n = 1;
+ for( short i = 0; i < pPar->GetSize(); i++ )
+ {
+ String aPar = String::CreateFromAscii( "PAR" );
+ aPar += ++n;
+ pProc->GetParams().AddSym( aPar );
+ }
+ }
+ }
+ else
+ {
+ // oder ein normales Symbol
+ pDef = rPool.AddSym( rName );
+ pDef->SetType( eType );
+ }
+ return pDef;
+}
+
+// Zur Zeit sind sogar Keywords zugelassen (wg. gleichnamiger Dflt-Properties)
+
+SbiExprNode* SbiExpression::Term( const KeywordSymbolInfo* pKeywordSymbolInfo )
+{
+ if( pParser->Peek() == DOT )
+ {
+ // eine WITH-Variable
+ SbiExprNode* pWithVar = pParser->GetWithVar();
+ // #26608: Ans Ende der Node-Kette gehen, um richtiges Objekt zu uebergeben
+ SbiSymDef* pDef = pWithVar ? pWithVar->GetRealVar() : NULL;
+ SbiExprNode* pNd = NULL;
+ if( !pDef )
+ {
+ pParser->Next();
+ }
+ else
+ {
+ pNd = ObjTerm( *pDef );
+ if( pNd )
+ pNd->SetWithParent( pWithVar );
+ }
+ if( !pNd )
+ {
+ pParser->Error( SbERR_UNEXPECTED, DOT );
+ pNd = new SbiExprNode( pParser, 1.0, SbxDOUBLE );
+ }
+ return pNd;
+ }
+
+ SbiToken eTok = (pKeywordSymbolInfo == NULL) ? pParser->Next() : pKeywordSymbolInfo->m_eTok;
+ // Anfang des Parsings merken
+ pParser->LockColumn();
+ String aSym( (pKeywordSymbolInfo == NULL) ? pParser->GetSym() : pKeywordSymbolInfo->m_aKeywordSymbol );
+ SbxDataType eType = (pKeywordSymbolInfo == NULL) ? pParser->GetType() : pKeywordSymbolInfo->m_eSbxDataType;
+ SbiParameters* pPar = NULL;
+ SbiExprListVector* pvMoreParLcl = NULL;
+ // Folgen Parameter?
+ SbiToken eNextTok = pParser->Peek();
+ // Ist es ein benannter Parameter?
+ // Dann einfach eine Stringkonstante erzeugen. Diese wird
+ // im SbiParameters-ctor erkannt und weiterverarbeitet
+ if( eNextTok == ASSIGN )
+ {
+ pParser->UnlockColumn();
+ return new SbiExprNode( pParser, aSym );
+ }
+ // ab hier sind keine Keywords zugelassen!
+ if( pParser->IsKwd( eTok ) )
+ {
+ if( pParser->IsCompatible() && eTok == INPUT )
+ {
+ eTok = SYMBOL;
+ }
+ else
+ {
+ pParser->Error( SbERR_SYNTAX );
+ bError = TRUE;
+ }
+ }
+
+ if( DoParametersFollow( pParser, eCurExpr, eTok = eNextTok ) )
+ {
+ bool bStandaloneExpression = (m_eMode == EXPRMODE_STANDALONE);
+ pPar = new SbiParameters( pParser, bStandaloneExpression );
+ bError |= !pPar->IsValid();
+ if( !bError )
+ bBracket = pPar->IsBracket();
+ eTok = pParser->Peek();
+
+ // i75443 check for additional sets of parameters
+ while( eTok == LPAREN )
+ {
+ if( pvMoreParLcl == NULL )
+ pvMoreParLcl = new SbiExprListVector();
+ SbiParameters* pAddPar = new SbiParameters( pParser );
+ pvMoreParLcl->push_back( pAddPar );
+ bError |= !pPar->IsValid();
+ eTok = pParser->Peek();
+ }
+ }
+ // Es koennte ein Objektteil sein, wenn . oder ! folgt
+ // Bei . muss aber die Variable bereits definiert sein; wenn pDef
+ // nach der Suche NULL ist, isses ein Objekt!
+ BOOL bObj = BOOL( ( eTok == DOT || eTok == EXCLAM )
+ && !pParser->WhiteSpace() );
+ if( bObj )
+ {
+ bBracket = FALSE; // Now the bracket for the first term is obsolete
+ if( eType == SbxVARIANT )
+ eType = SbxOBJECT;
+ else
+ {
+ // Name%. geht wirklich nicht!
+ pParser->Error( SbERR_BAD_DECLARATION, aSym );
+ bError = TRUE;
+ }
+ }
+ // Suche:
+ SbiSymDef* pDef = pParser->pPool->Find( aSym );
+ if( !pDef )
+ {
+ // Teil der Runtime-Library?
+ // AB 31.3.1996: In Parser-Methode ausgelagert
+ // (wird auch in SbiParser::DefVar() in DIM.CXX benoetigt)
+ pDef = pParser->CheckRTLForSym( aSym, eType );
+
+ // #i109184: Check if symbol is or later will be defined inside module
+ SbModule& rMod = pParser->aGen.GetModule();
+ SbxArray* pModMethods = rMod.GetMethods();
+ if( pModMethods->Find( aSym, SbxCLASS_DONTCARE ) )
+ pDef = NULL;
+ }
+ if( !pDef )
+ {
+ // Falls ein Punkt angegeben war, isses Teil eines Objekts,
+ // also muss der Returnwert ein Objekt sein
+ if( bObj )
+ eType = SbxOBJECT;
+ pDef = AddSym( eTok, *pParser->pPool, eCurExpr, aSym, eType, pPar );
+ // Looks like this is a local ( but undefined variable )
+ // if it is in a static procedure then make this Symbol
+ // static
+ if ( !bObj && pParser->pProc && pParser->pProc->IsStatic() )
+ pDef->SetStatic();
+ }
+ else
+ {
+
+ // Symbol ist bereits definiert.
+ // Ist es eine Konstante?
+ SbiConstDef* pConst = pDef->GetConstDef();
+ if( pConst )
+ {
+ if( pConst->GetType() == SbxSTRING )
+ return new SbiExprNode( pParser, pConst->GetString() );
+ else
+ return new SbiExprNode( pParser, pConst->GetValue(), pConst->GetType() );
+ }
+ // Hat es Dimensionen,
+ // und sind auch Parameter angegeben?
+ // (Wobei 0 Parameter () entsprechen)
+ if( pDef->GetDims() )
+ {
+ if( pPar && pPar->GetSize() && pPar->GetSize() != pDef->GetDims() )
+ pParser->Error( SbERR_WRONG_DIMS );
+ }
+ if( pDef->IsDefinedAs() )
+ {
+ SbxDataType eDefType = pDef->GetType();
+ // #119187 Only error if types conflict
+ if( eType >= SbxINTEGER && eType <= SbxSTRING && eType != eDefType )
+ {
+ // Wie? Erst mit AS definieren und dann einen Suffix nehmen?
+ pParser->Error( SbERR_BAD_DECLARATION, aSym );
+ bError = TRUE;
+ }
+ else if ( eType == SbxVARIANT )
+ // Falls nix angegeben, den Typ des Eintrags nehmen
+ // aber nur, wenn die Var nicht mit AS XXX definiert ist
+ // damit erwischen wir n% = 5 : print n
+ eType = eDefType;
+ }
+ // Typcheck bei Variablen:
+ // ist explizit im Scanner etwas anderes angegeben?
+ // Bei Methoden ist dies OK!
+ if( eType != SbxVARIANT && // Variant nimmt alles
+ eType != pDef->GetType() &&
+ !pDef->GetProcDef() )
+ {
+ // Es kann sein, dass pDef ein Objekt beschreibt, das bisher
+ // nur als SbxVARIANT erkannt wurde, dann Typ von pDef aendern
+ // AB, 16.12.95 (Vielleicht noch aehnliche Faelle moeglich ?!?)
+ if( eType == SbxOBJECT && pDef->GetType() == SbxVARIANT )
+ {
+ pDef->SetType( SbxOBJECT );
+ }
+ else
+ {
+ pParser->Error( SbERR_BAD_DECLARATION, aSym );
+ bError = TRUE;
+ }
+ }
+ }
+ SbiExprNode* pNd = new SbiExprNode( pParser, *pDef, eType );
+ if( !pPar )
+ pPar = new SbiParameters( pParser,FALSE,FALSE );
+ pNd->aVar.pPar = pPar;
+ pNd->aVar.pvMorePar = pvMoreParLcl;
+ if( bObj )
+ {
+ // AB, 8.1.95: Objekt kann auch vom Typ SbxVARIANT sein
+ if( pDef->GetType() == SbxVARIANT )
+ pDef->SetType( SbxOBJECT );
+ // Falls wir etwas mit Punkt einscannen, muss der
+ // Typ SbxOBJECT sein
+ if( pDef->GetType() != SbxOBJECT && pDef->GetType() != SbxVARIANT )
+ {
+ pParser->Error( SbERR_BAD_DECLARATION, aSym );
+ bError = TRUE;
+ }
+ if( !bError )
+ pNd->aVar.pNext = ObjTerm( *pDef );
+ }
+ // Merken der Spalte 1 wieder freigeben
+ pParser->UnlockColumn();
+ return pNd;
+}
+
+// Aufbau eines Objekt-Terms. Ein derartiger Term ist Teil
+// eines Ausdrucks, der mit einer Objektvariablen beginnt.
+
+SbiExprNode* SbiExpression::ObjTerm( SbiSymDef& rObj )
+{
+ pParser->Next();
+ SbiToken eTok = pParser->Next();
+ if( eTok != SYMBOL && !pParser->IsKwd( eTok ) && !pParser->IsExtra( eTok ) )
+ {
+ // #66745 Einige Operatoren koennen in diesem Kontext auch
+ // als Identifier zugelassen werden, wichtig fuer StarOne
+ if( eTok != MOD && eTok != NOT && eTok != AND && eTok != OR &&
+ eTok != XOR && eTok != EQV && eTok != IMP && eTok != IS )
+ {
+ pParser->Error( SbERR_VAR_EXPECTED );
+ bError = TRUE;
+ }
+ }
+ /* #118410 Allow type for Class methods and RTL object, e.g. RTL.Chr$(97)
+ else
+ {
+ if( pParser->GetType() != SbxVARIANT )
+ pParser->Error( SbERR_SYNTAX ), bError = TRUE;
+ }
+ */
+ if( bError )
+ return NULL;
+
+ String aSym( pParser->GetSym() );
+ SbxDataType eType = pParser->GetType();
+ SbiParameters* pPar = NULL;
+ SbiExprListVector* pvMoreParLcl = NULL;
+ eTok = pParser->Peek();
+ // Parameter?
+ if( DoParametersFollow( pParser, eCurExpr, eTok ) )
+ {
+ bool bStandaloneExpression = false;
+ pPar = new SbiParameters( pParser, bStandaloneExpression );
+ bError |= !pPar->IsValid();
+ eTok = pParser->Peek();
+
+ // i109624 check for additional sets of parameters
+ while( eTok == LPAREN )
+ {
+ if( pvMoreParLcl == NULL )
+ pvMoreParLcl = new SbiExprListVector();
+ SbiParameters* pAddPar = new SbiParameters( pParser );
+ pvMoreParLcl->push_back( pAddPar );
+ bError |= !pPar->IsValid();
+ eTok = pParser->Peek();
+ }
+
+ }
+ BOOL bObj = BOOL( ( eTok == DOT || eTok == EXCLAM ) && !pParser->WhiteSpace() );
+ if( bObj )
+ {
+ if( eType == SbxVARIANT )
+ eType = SbxOBJECT;
+ else
+ {
+ // Name%. geht wirklich nicht!
+ pParser->Error( SbERR_BAD_DECLARATION, aSym );
+ bError = TRUE;
+ }
+ }
+
+ // Der Symbol-Pool eines Objekts ist immer PUBLIC
+ SbiSymPool& rPool = rObj.GetPool();
+ rPool.SetScope( SbPUBLIC );
+ SbiSymDef* pDef = rPool.Find( aSym );
+ if( !pDef )
+ {
+ pDef = AddSym( eTok, rPool, eCurExpr, aSym, eType, pPar );
+ pDef->SetType( eType );
+ }
+
+ SbiExprNode* pNd = new SbiExprNode( pParser, *pDef, eType );
+ pNd->aVar.pPar = pPar;
+ pNd->aVar.pvMorePar = pvMoreParLcl;
+ if( bObj )
+ {
+ // Falls wir etwas mit Punkt einscannen, muss der
+ // Typ SbxOBJECT sein
+
+ // AB, 3.1.96
+ // Es kann sein, dass pDef ein Objekt beschreibt, das bisher
+ // nur als SbxVARIANT erkannt wurde, dann Typ von pDef aendern
+ if( pDef->GetType() == SbxVARIANT )
+ pDef->SetType( SbxOBJECT );
+
+ if( pDef->GetType() != SbxOBJECT )
+ {
+ pParser->Error( SbERR_BAD_DECLARATION, aSym );
+ bError = TRUE;
+ }
+ if( !bError )
+ {
+ pNd->aVar.pNext = ObjTerm( *pDef );
+ pNd->eType = eType;
+ }
+ }
+ return pNd;
+}
+
+// Als Operanden kommen in Betracht:
+// Konstante
+// skalare Variable
+// Strukturelemente
+// Array-Elemente
+// Funktionen
+// geklammerte Ausdruecke
+
+SbiExprNode* SbiExpression::Operand( bool bUsedForTypeOf )
+{
+ SbiExprNode *pRes;
+ SbiToken eTok;
+
+ // Operand testen:
+ switch( eTok = pParser->Peek() )
+ {
+ case SYMBOL:
+ pRes = Term();
+ // process something like "IF Not r Is Nothing Then .."
+ if( !bUsedForTypeOf && pParser->IsVBASupportOn() && pParser->Peek() == IS )
+ {
+ eTok = pParser->Next();
+ pRes = new SbiExprNode( pParser, pRes, eTok, Like() );
+ }
+ break;
+ case DOT: // .with
+ pRes = Term(); break;
+ case NUMBER:
+ pParser->Next();
+ pRes = new SbiExprNode( pParser, pParser->GetDbl(), pParser->GetType() );
+ break;
+ case FIXSTRING:
+ pParser->Next();
+ pRes = new SbiExprNode( pParser, pParser->GetSym() ); break;
+ case LPAREN:
+ pParser->Next();
+ if( nParenLevel == 0 && m_eMode == EXPRMODE_LPAREN_PENDING && pParser->Peek() == RPAREN )
+ {
+ m_eMode = EXPRMODE_EMPTY_PAREN;
+ pRes = new SbiExprNode(); // Dummy node
+ pParser->Next();
+ break;
+ }
+ nParenLevel++;
+ pRes = Boolean();
+ if( pParser->Peek() != RPAREN )
+ {
+ // If there was a LPARAM, it does not belong to the expression
+ if( nParenLevel == 1 && m_eMode == EXPRMODE_LPAREN_PENDING )
+ m_eMode = EXPRMODE_LPAREN_NOT_NEEDED;
+ else
+ pParser->Error( SbERR_BAD_BRACKETS );
+ }
+ else
+ {
+ pParser->Next();
+ if( nParenLevel == 1 && m_eMode == EXPRMODE_LPAREN_PENDING )
+ {
+ SbiToken eTokAfterRParen = pParser->Peek();
+ if( eTokAfterRParen == EQ || eTokAfterRParen == LPAREN || eTokAfterRParen == DOT )
+ m_eMode = EXPRMODE_ARRAY_OR_OBJECT;
+ else
+ m_eMode = EXPRMODE_STANDARD;
+ }
+ }
+ nParenLevel--;
+ pRes->bComposite = TRUE;
+ break;
+ default:
+ // Zur Zeit sind Keywords hier OK!
+ if( pParser->IsKwd( eTok ) )
+ pRes = Term();
+ else
+ {
+ pParser->Next();
+ pRes = new SbiExprNode( pParser, 1.0, SbxDOUBLE ); // bei Fehlern
+ pParser->Error( SbERR_UNEXPECTED, eTok );
+ }
+ }
+ return pRes;
+}
+
+SbiExprNode* SbiExpression::Unary()
+{
+ SbiExprNode* pNd;
+ SbiToken eTok = pParser->Peek();
+ switch( eTok )
+ {
+ case MINUS:
+ eTok = NEG;
+ case NOT:
+ pParser->Next();
+ pNd = new SbiExprNode( pParser, Unary(), eTok, NULL );
+ break;
+ case PLUS:
+ pParser->Next();
+ pNd = Unary();
+ break;
+ case TYPEOF:
+ {
+ pParser->Next();
+ bool bUsedForTypeOf = true;
+ SbiExprNode* pObjNode = Operand( bUsedForTypeOf );
+ pParser->TestToken( IS );
+ String aDummy;
+ SbiSymDef* pTypeDef = new SbiSymDef( aDummy );
+ pParser->TypeDecl( *pTypeDef, TRUE );
+ pNd = new SbiExprNode( pParser, pObjNode, pTypeDef->GetTypeId() );
+ break;
+ }
+ case NEW:
+ {
+ pParser->Next();
+ String aStr;
+ SbiSymDef* pTypeDef = new SbiSymDef( aStr );
+ pParser->TypeDecl( *pTypeDef, TRUE );
+ pNd = new SbiExprNode( pParser, pTypeDef->GetTypeId() );
+ break;
+ }
+ default:
+ pNd = Operand();
+ }
+ return pNd;
+}
+
+SbiExprNode* SbiExpression::Exp()
+{
+ SbiExprNode* pNd = Unary();
+ if( m_eMode != EXPRMODE_EMPTY_PAREN )
+ {
+ while( pParser->Peek() == EXPON ) {
+ SbiToken eTok = pParser->Next();
+ pNd = new SbiExprNode( pParser, pNd, eTok, Unary() );
+ }
+ }
+ return pNd;
+}
+
+SbiExprNode* SbiExpression::MulDiv()
+{
+ SbiExprNode* pNd = Exp();
+ if( m_eMode != EXPRMODE_EMPTY_PAREN )
+ {
+ for( ;; )
+ {
+ SbiToken eTok = pParser->Peek();
+ if( eTok != MUL && eTok != DIV )
+ break;
+ eTok = pParser->Next();
+ pNd = new SbiExprNode( pParser, pNd, eTok, Exp() );
+ }
+ }
+ return pNd;
+}
+
+SbiExprNode* SbiExpression::IntDiv()
+{
+ SbiExprNode* pNd = MulDiv();
+ if( m_eMode != EXPRMODE_EMPTY_PAREN )
+ {
+ while( pParser->Peek() == IDIV ) {
+ SbiToken eTok = pParser->Next();
+ pNd = new SbiExprNode( pParser, pNd, eTok, MulDiv() );
+ }
+ }
+ return pNd;
+}
+
+SbiExprNode* SbiExpression::Mod()
+{
+ SbiExprNode* pNd = IntDiv();
+ if( m_eMode != EXPRMODE_EMPTY_PAREN )
+ {
+ while( pParser->Peek() == MOD ) {
+ SbiToken eTok = pParser->Next();
+ pNd = new SbiExprNode( pParser, pNd, eTok, IntDiv() );
+ }
+ }
+ return pNd;
+}
+
+SbiExprNode* SbiExpression::AddSub()
+{
+ SbiExprNode* pNd = Mod();
+ if( m_eMode != EXPRMODE_EMPTY_PAREN )
+ {
+ for( ;; )
+ {
+ SbiToken eTok = pParser->Peek();
+ if( eTok != PLUS && eTok != MINUS )
+ break;
+ eTok = pParser->Next();
+ pNd = new SbiExprNode( pParser, pNd, eTok, Mod() );
+ }
+ }
+ return pNd;
+}
+
+SbiExprNode* SbiExpression::Cat()
+{
+ SbiExprNode* pNd = AddSub();
+ if( m_eMode != EXPRMODE_EMPTY_PAREN )
+ {
+ for( ;; )
+ {
+ SbiToken eTok = pParser->Peek();
+ if( eTok != CAT )
+ break;
+ eTok = pParser->Next();
+ pNd = new SbiExprNode( pParser, pNd, eTok, AddSub() );
+ }
+ }
+ return pNd;
+}
+
+SbiExprNode* SbiExpression::Comp()
+{
+ SbiExprNode* pNd = Cat();
+ if( m_eMode != EXPRMODE_EMPTY_PAREN )
+ {
+ short nCount = 0;
+ for( ;; )
+ {
+ SbiToken eTok = pParser->Peek();
+ if( m_eMode == EXPRMODE_ARRAY_OR_OBJECT )
+ break;
+ if( eTok != EQ && eTok != NE && eTok != LT
+ && eTok != GT && eTok != LE && eTok != GE )
+ break;
+ eTok = pParser->Next();
+ pNd = new SbiExprNode( pParser, pNd, eTok, Cat() );
+ nCount++;
+ }
+ }
+ return pNd;
+}
+
+SbiExprNode* SbiExpression::Like()
+{
+ SbiExprNode* pNd = Comp();
+ if( m_eMode != EXPRMODE_EMPTY_PAREN )
+ {
+ short nCount = 0;
+ while( pParser->Peek() == LIKE ) {
+ SbiToken eTok = pParser->Next();
+ pNd = new SbiExprNode( pParser, pNd, eTok, Comp() ), nCount++;
+ }
+ // Mehrere Operatoren hintereinander gehen nicht
+ if( nCount > 1 )
+ {
+ pParser->Error( SbERR_SYNTAX );
+ bError = TRUE;
+ }
+ }
+ return pNd;
+}
+
+SbiExprNode* SbiExpression::Boolean()
+{
+ SbiExprNode* pNd = Like();
+ if( m_eMode != EXPRMODE_EMPTY_PAREN )
+ {
+ for( ;; )
+ {
+ SbiToken eTok = pParser->Peek();
+ if( eTok != AND && eTok != OR && eTok != XOR
+ && eTok != EQV && eTok != IMP && eTok != IS )
+ break;
+ eTok = pParser->Next();
+ pNd = new SbiExprNode( pParser, pNd, eTok, Like() );
+ }
+ }
+ return pNd;
+}
+
+/***************************************************************************
+|*
+|* SbiConstExpression
+|*
+***************************************************************************/
+
+// Parsing einer Expression, die sich zu einer numerischen
+// Konstanten verarbeiten laesst.
+
+SbiConstExpression::SbiConstExpression( SbiParser* p ) : SbiExpression( p )
+{
+ if( pExpr->IsConstant() )
+ {
+ eType = pExpr->GetType();
+ if( pExpr->IsNumber() )
+ {
+ nVal = pExpr->nVal;
+ }
+ else
+ {
+ nVal = 0;
+ aVal = pExpr->aStrVal;
+ }
+ }
+ else
+ {
+ // #40204 Spezialbehandlung fuer BOOL-Konstanten
+ BOOL bIsBool = FALSE;
+ if( pExpr->eNodeType == SbxVARVAL )
+ {
+ SbiSymDef* pVarDef = pExpr->GetVar();
+
+ // Ist es eine BOOL-Konstante?
+ BOOL bBoolVal = FALSE;
+ if( pVarDef->GetName().EqualsIgnoreCaseAscii( "true" ) )
+ //if( pVarDef->GetName().ICompare( "true" ) == COMPARE_EQUAL )
+ {
+ bIsBool = TRUE;
+ bBoolVal = TRUE;
+ }
+ else if( pVarDef->GetName().EqualsIgnoreCaseAscii( "false" ) )
+ //else if( pVarDef->GetName().ICompare( "false" ) == COMPARE_EQUAL )
+ {
+ bIsBool = TRUE;
+ bBoolVal = FALSE;
+ }
+
+ // Wenn es ein BOOL ist, Node austauschen
+ if( bIsBool )
+ {
+ delete pExpr;
+ pExpr = new SbiExprNode( pParser, (bBoolVal ? SbxTRUE : SbxFALSE), SbxINTEGER );
+ eType = pExpr->GetType();
+ nVal = pExpr->nVal;
+ }
+ }
+
+ if( !bIsBool )
+ {
+ pParser->Error( SbERR_SYNTAX );
+ eType = SbxDOUBLE;
+ nVal = 0;
+ }
+ }
+}
+
+short SbiConstExpression::GetShortValue()
+{
+ if( eType == SbxSTRING )
+ {
+ SbxVariableRef refConv = new SbxVariable;
+ refConv->PutString( aVal );
+ return refConv->GetInteger();
+ }
+ else
+ {
+ double n = nVal;
+ if( n > 0 ) n += .5; else n -= .5;
+ if( n > SbxMAXINT ) n = SbxMAXINT, pParser->Error( SbERR_OUT_OF_RANGE );
+ else
+ if( n < SbxMININT ) n = SbxMININT, pParser->Error( SbERR_OUT_OF_RANGE );
+ return (short) n;
+ }
+}
+
+
+/***************************************************************************
+|*
+|* SbiExprList
+|*
+***************************************************************************/
+
+SbiExprList::SbiExprList( SbiParser* p )
+{
+ pParser = p;
+ pFirst = NULL;
+ nExpr =
+ nDim = 0;
+ bError =
+ bBracket = FALSE;
+}
+
+SbiExprList::~SbiExprList()
+{
+ SbiExpression* p = pFirst;
+ while( p )
+ {
+ SbiExpression* q = p->pNext;
+ delete p;
+ p = q;
+ }
+}
+
+// Parameter anfordern (ab 0)
+
+SbiExpression* SbiExprList::Get( short n )
+{
+ SbiExpression* p = pFirst;
+ while( n-- && p )
+ p = p->pNext;
+ return p;
+}
+
+void SbiExprList::addExpression( SbiExpression* pExpr )
+{
+ SbiExpression* p = pFirst;
+ while( p && p->pNext )
+ p = p->pNext;
+
+ p->pNext = pExpr;
+}
+
+
+/***************************************************************************
+|*
+|* SbiParameters
+|*
+***************************************************************************/
+
+// Parsender Konstruktor:
+// Die Parameterliste wird komplett geparst.
+// "Prozedurname()" ist OK.
+// Dann handelt es sich um eine Funktion ohne Parameter
+// respektive um die Angabe eines Arrays als Prozedurparameter.
+
+// #i79918/#i80532: bConst has never been set to true
+// -> reused as bStandaloneExpression
+//SbiParameters::SbiParameters( SbiParser* p, BOOL bConst, BOOL bPar) :
+SbiParameters::SbiParameters( SbiParser* p, BOOL bStandaloneExpression, BOOL bPar) :
+ SbiExprList( p )
+{
+ if( !bPar )
+ return;
+
+ SbiExpression *pExpr;
+ SbiToken eTok = pParser->Peek();
+
+ // evtl. Klammer auf weg:
+ bool bAssumeExprLParenMode = false;
+ bool bAssumeArrayMode = false;
+ if( eTok == LPAREN )
+ {
+ if( bStandaloneExpression )
+ {
+ bAssumeExprLParenMode = true;
+ }
+ else
+ {
+ bBracket = TRUE;
+ pParser->Next();
+ eTok = pParser->Peek();
+ }
+ }
+
+ // Ende-Test
+ if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
+ {
+ if( eTok == RPAREN )
+ pParser->Next();
+ return;
+ }
+ // Parametertabelle einlesen und in richtiger Folge ablegen!
+ SbiExpression* pLast = NULL;
+ String aName;
+ while( !bError )
+ {
+ aName.Erase();
+ // Fehlendes Argument
+ if( eTok == COMMA )
+ {
+ pExpr = new SbiExpression( pParser, 0, SbxEMPTY );
+ //if( bConst )
+ // pParser->Error( SbERR_SYNTAX ), bError = TRUE;
+ }
+ // Benannte Argumente: entweder .name= oder name:=
+ else
+ {
+ bool bByVal = false;
+ if( eTok == BYVAL )
+ {
+ bByVal = true;
+ pParser->Next();
+ eTok = pParser->Peek();
+ }
+
+ if( bAssumeExprLParenMode )
+ {
+ pExpr = new SbiExpression( pParser, SbSTDEXPR, EXPRMODE_LPAREN_PENDING );
+ bAssumeExprLParenMode = FALSE;
+
+ SbiExprMode eModeAfter = pExpr->m_eMode;
+ if( eModeAfter == EXPRMODE_LPAREN_NOT_NEEDED )
+ {
+ bBracket = TRUE;
+ }
+ else if( eModeAfter == EXPRMODE_ARRAY_OR_OBJECT )
+ {
+ // Expression "looks" like an array assignment
+ // a(...)[(...)] = ? or a(...).b(...)
+ // RPAREN is already parsed
+ bBracket = TRUE;
+ bAssumeArrayMode = true;
+ eTok = NIL;
+ }
+ else if( eModeAfter == EXPRMODE_EMPTY_PAREN )
+ {
+ bBracket = TRUE;
+ delete pExpr;
+ if( bByVal )
+ pParser->Error( SbERR_LVALUE_EXPECTED );
+ return;
+ }
+ }
+ else
+ pExpr = new SbiExpression( pParser );
+
+ if( bByVal && pExpr->IsLvalue() )
+ pExpr->SetByVal();
+
+ //pExpr = bConst ? new SbiConstExpression( pParser )
+ // : new SbiExpression( pParser );
+ if( !bAssumeArrayMode )
+ {
+ if( pParser->Peek() == ASSIGN )
+ {
+ // VBA mode: name:=
+ // SbiExpression::Term() hat einen String daraus gemacht
+ aName = pExpr->GetString();
+ delete pExpr;
+ pParser->Next();
+ pExpr = new SbiExpression( pParser );
+ //if( bConst )
+ // pParser->Error( SbERR_SYNTAX ), bError = TRUE;
+ }
+ pExpr->GetName() = aName;
+ }
+ }
+ pExpr->pNext = NULL;
+ if( !pLast )
+ pFirst = pLast = pExpr;
+ else
+ pLast->pNext = pExpr, pLast = pExpr;
+ nExpr++;
+ bError |= !pExpr->IsValid();
+
+ if( bAssumeArrayMode )
+ break;
+
+ // Naechstes Element?
+ eTok = pParser->Peek();
+ if( eTok != COMMA )
+ {
+ if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
+ break;
+ pParser->Error( bBracket
+ ? SbERR_BAD_BRACKETS
+ : SbERR_EXPECTED, COMMA );
+ bError = TRUE;
+ }
+ else
+ {
+ pParser->Next();
+ eTok = pParser->Peek();
+ if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
+ break;
+ }
+ }
+ // Schliessende Klammer
+ if( eTok == RPAREN )
+ {
+ pParser->Next();
+ pParser->Peek();
+ if( !bBracket )
+ {
+ pParser->Error( SbERR_BAD_BRACKETS );
+ bError = TRUE;
+ }
+ }
+ nDim = nExpr;
+}
+
+/***************************************************************************
+|*
+|* SbiDimList
+|*
+***************************************************************************/
+
+// Parsender Konstruktor:
+// Eine Liste von Array-Dimensionen wird geparst. Die Ausdruecke werden
+// auf numerisch getestet. Das bCONST-Bit wird gesetzt, wenn alle Ausdruecke
+// Integer-Konstanten sind.
+
+SbiDimList::SbiDimList( SbiParser* p ) : SbiExprList( p )
+{
+ bConst = TRUE;
+
+ if( pParser->Next() != LPAREN )
+ {
+ pParser->Error( SbERR_EXPECTED, LPAREN );
+ bError = TRUE; return;
+ }
+
+ if( pParser->Peek() != RPAREN )
+ {
+ SbiExpression *pExpr1, *pExpr2, *pLast = NULL;
+ SbiToken eTok;
+ for( ;; )
+ {
+ pExpr1 = new SbiExpression( pParser );
+ eTok = pParser->Next();
+ if( eTok == TO )
+ {
+ pExpr2 = new SbiExpression( pParser );
+ eTok = pParser->Next();
+ bConst &= pExpr1->IsIntConstant() & pExpr2->IsIntConstant();
+ bError |= !pExpr1->IsValid();
+ bError |= !pExpr2->IsValid();
+ pExpr1->pNext = pExpr2;
+ if( !pLast )
+ pFirst = pExpr1;
+ else
+ pLast->pNext = pExpr1;
+ pLast = pExpr2;
+ nExpr += 2;
+ }
+ else
+ {
+ // Nur eine Dim-Angabe
+ pExpr1->SetBased();
+ pExpr1->pNext = NULL;
+ bConst &= pExpr1->IsIntConstant();
+ bError |= !pExpr1->IsValid();
+ if( !pLast )
+ pFirst = pLast = pExpr1;
+ else
+ pLast->pNext = pExpr1, pLast = pExpr1;
+ nExpr++;
+ }
+ nDim++;
+ if( eTok == RPAREN ) break;
+ if( eTok != COMMA )
+ {
+ pParser->Error( SbERR_BAD_BRACKETS );
+ pParser->Next();
+ break;
+ }
+ }
+ }
+ else pParser->Next();
+}
+
diff --git a/basic/source/comp/io.cxx b/basic/source/comp/io.cxx
new file mode 100644
index 000000000000..b211ea0b7b08
--- /dev/null
+++ b/basic/source/comp/io.cxx
@@ -0,0 +1,358 @@
+/*************************************************************************
+ *
+ * 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 "sbcomp.hxx"
+#include "iosys.hxx"
+
+// Test, ob ein I/O-Channel angegeben wurde
+
+BOOL SbiParser::Channel( BOOL bAlways )
+{
+ BOOL bRes = FALSE;
+ Peek();
+ if( IsHash() )
+ {
+ SbiExpression aExpr( this );
+ while( Peek() == COMMA || Peek() == SEMICOLON )
+ Next();
+ aExpr.Gen();
+ aGen.Gen( _CHANNEL );
+ bRes = TRUE;
+ }
+ else if( bAlways )
+ Error( SbERR_EXPECTED, "#" );
+ return bRes;
+}
+
+// Fuer PRINT und WRITE wird bei Objektvariablen versucht,
+// die Default-Property anzusprechen.
+
+// PRINT
+
+void SbiParser::Print()
+{
+ BOOL bChan = Channel();
+ // Die Ausdruecke zum Drucken:
+ while( !bAbort )
+ {
+ if( !IsEoln( Peek() ) )
+ {
+ SbiExpression* pExpr = new SbiExpression( this );
+ pExpr->Gen();
+ delete pExpr;
+ Peek();
+ aGen.Gen( eCurTok == COMMA ? _PRINTF : _BPRINT );
+ }
+ if( eCurTok == COMMA || eCurTok == SEMICOLON )
+ {
+ Next();
+ if( IsEoln( Peek() ) ) break;
+ }
+ else
+ {
+ aGen.Gen( _PRCHAR, '\n' );
+ break;
+ }
+ }
+ if( bChan )
+ aGen.Gen( _CHAN0 );
+}
+
+// WRITE #chan, expr, ...
+
+void SbiParser::Write()
+{
+ BOOL bChan = Channel();
+ // Die Ausdruecke zum Drucken:
+ while( !bAbort )
+ {
+ SbiExpression* pExpr = new SbiExpression( this );
+ pExpr->Gen();
+ delete pExpr;
+ aGen.Gen( _BWRITE );
+ if( Peek() == COMMA )
+ {
+ aGen.Gen( _PRCHAR, ',' );
+ Next();
+ if( IsEoln( Peek() ) ) break;
+ }
+ else
+ {
+ aGen.Gen( _PRCHAR, '\n' );
+ break;
+ }
+ }
+ if( bChan )
+ aGen.Gen( _CHAN0 );
+}
+
+
+// #i92642 Handle LINE keyword outside ::Next()
+void SbiParser::Line()
+{
+ // #i92642: Special handling to allow name as symbol
+ if( Peek() == INPUT )
+ {
+ Next();
+ LineInput();
+ }
+ else
+ {
+ aGen.Statement();
+
+ KeywordSymbolInfo aInfo;
+ aInfo.m_aKeywordSymbol = String( RTL_CONSTASCII_USTRINGPARAM( "line" ) );
+ aInfo.m_eSbxDataType = GetType();
+ aInfo.m_eTok = SYMBOL;
+
+ Symbol( &aInfo );
+ }
+}
+
+
+// LINE INPUT [prompt], var$
+
+void SbiParser::LineInput()
+{
+ Channel( TRUE );
+ // BOOL bChan = Channel( TRUE );
+ SbiExpression* pExpr = new SbiExpression( this, SbOPERAND );
+ /* AB 15.1.96: Keinen allgemeinen Ausdruck mehr zulassen
+ SbiExpression* pExpr = new SbiExpression( this );
+ if( !pExpr->IsVariable() )
+ {
+ SbiToken eTok = Peek();
+ if( eTok == COMMA || eTok == SEMICOLON ) Next();
+ else Error( SbERR_EXPECTED, COMMA );
+ // mit Prompt
+ if( !bChan )
+ {
+ pExpr->Gen();
+ aGen.Gen( _PROMPT );
+ }
+ else
+ Error( SbERR_VAR_EXPECTED );
+ delete pExpr;
+ pExpr = new SbiExpression( this, SbOPERAND );
+ }
+ */
+ if( !pExpr->IsVariable() )
+ Error( SbERR_VAR_EXPECTED );
+ if( pExpr->GetType() != SbxVARIANT && pExpr->GetType() != SbxSTRING )
+ Error( SbERR_CONVERSION );
+ pExpr->Gen();
+ aGen.Gen( _LINPUT );
+ delete pExpr;
+ aGen.Gen( _CHAN0 ); // ResetChannel() nicht mehr in StepLINPUT()
+}
+
+// INPUT
+
+void SbiParser::Input()
+{
+ aGen.Gen( _RESTART );
+ Channel( TRUE );
+ // BOOL bChan = Channel( TRUE );
+ SbiExpression* pExpr = new SbiExpression( this, SbOPERAND );
+ /* ALT: Jetzt keinen allgemeinen Ausdruck mehr zulassen
+ SbiExpression* pExpr = new SbiExpression( this );
+ ...
+ siehe LineInput
+ */
+ while( !bAbort )
+ {
+ if( !pExpr->IsVariable() )
+ Error( SbERR_VAR_EXPECTED );
+ pExpr->Gen();
+ aGen.Gen( _INPUT );
+ if( Peek() == COMMA )
+ {
+ Next();
+ delete pExpr;
+ pExpr = new SbiExpression( this, SbOPERAND );
+ }
+ else break;
+ }
+ delete pExpr;
+ aGen.Gen( _CHAN0 ); // ResetChannel() nicht mehr in StepINPUT()
+}
+
+// OPEN stringexpr FOR mode ACCCESS access mode AS Channel [Len=n]
+
+void SbiParser::Open()
+{
+ SbiExpression aFileName( this );
+ SbiToken eTok;
+ TestToken( FOR );
+ short nMode = 0;
+ short nFlags = 0;
+ switch( Next() )
+ {
+ case INPUT:
+ nMode = STREAM_READ; nFlags |= SBSTRM_INPUT; break;
+ case OUTPUT:
+ nMode = STREAM_WRITE | STREAM_TRUNC; nFlags |= SBSTRM_OUTPUT; break;
+ case APPEND:
+ nMode = STREAM_WRITE; nFlags |= SBSTRM_APPEND; break;
+ case RANDOM:
+ nMode = STREAM_READ | STREAM_WRITE; nFlags |= SBSTRM_RANDOM; break;
+ case BINARY:
+ nMode = STREAM_READ | STREAM_WRITE; nFlags |= SBSTRM_BINARY; break;
+ default:
+ Error( SbERR_SYNTAX );
+ }
+ if( Peek() == ACCESS )
+ {
+ Next();
+ eTok = Next();
+ // #27964# Nur STREAM_READ,STREAM_WRITE-Flags in nMode beeinflussen
+ nMode &= ~(STREAM_READ | STREAM_WRITE); // loeschen
+ if( eTok == READ )
+ {
+ if( Peek() == WRITE )
+ {
+ Next();
+ nMode |= (STREAM_READ | STREAM_WRITE);
+ }
+ else
+ nMode |= STREAM_READ;
+ }
+ else if( eTok == WRITE )
+ nMode |= STREAM_WRITE;
+ else
+ Error( SbERR_SYNTAX );
+ }
+ switch( Peek() )
+ {
+#ifdef SHARED
+#undef SHARED
+#define tmpSHARED
+#endif
+ case SHARED:
+ Next(); nMode |= STREAM_SHARE_DENYNONE; break;
+#ifdef tmpSHARED
+#define SHARED
+#undef tmpSHARED
+#endif
+ case LOCK:
+ Next();
+ eTok = Next();
+ if( eTok == READ )
+ {
+ if( Peek() == WRITE ) Next(), nMode |= STREAM_SHARE_DENYALL;
+ else nMode |= STREAM_SHARE_DENYREAD;
+ }
+ else if( eTok == WRITE )
+ nMode |= STREAM_SHARE_DENYWRITE;
+ else
+ Error( SbERR_SYNTAX );
+ break;
+ default: break;
+ }
+ TestToken( AS );
+ // Die Kanalnummer
+ SbiExpression* pChan = new SbiExpression( this );
+ if( !pChan )
+ Error( SbERR_SYNTAX );
+ SbiExpression* pLen = NULL;
+ if( Peek() == SYMBOL )
+ {
+ Next();
+ String aLen( aSym );
+ if( aLen.EqualsIgnoreCaseAscii( "LEN" ) )
+ {
+ TestToken( EQ );
+ pLen = new SbiExpression( this );
+ }
+ }
+ if( !pLen ) pLen = new SbiExpression( this, 128, SbxINTEGER );
+ // Der Stack fuer den OPEN-Befehl sieht wie folgt aus:
+ // Blocklaenge
+ // Kanalnummer
+ // Dateiname
+ pLen->Gen();
+ if( pChan )
+ pChan->Gen();
+ aFileName.Gen();
+ aGen.Gen( _OPEN, nMode, nFlags );
+ delete pLen;
+ delete pChan;
+}
+
+// NAME file AS file
+
+void SbiParser::Name()
+{
+ // #i92642: Special handling to allow name as symbol
+ if( Peek() == EQ )
+ {
+ aGen.Statement();
+
+ KeywordSymbolInfo aInfo;
+ aInfo.m_aKeywordSymbol = String( RTL_CONSTASCII_USTRINGPARAM( "name" ) );
+ aInfo.m_eSbxDataType = GetType();
+ aInfo.m_eTok = SYMBOL;
+
+ Symbol( &aInfo );
+ return;
+ }
+ SbiExpression aExpr1( this );
+ TestToken( AS );
+ SbiExpression aExpr2( this );
+ aExpr1.Gen();
+ aExpr2.Gen();
+ aGen.Gen( _RENAME );
+}
+
+// CLOSE [n,...]
+
+void SbiParser::Close()
+{
+ Peek();
+ if( IsEoln( eCurTok ) )
+ aGen.Gen( _CLOSE, 0 );
+ else
+ for( ;; )
+ {
+ SbiExpression aExpr( this );
+ while( Peek() == COMMA || Peek() == SEMICOLON )
+ Next();
+ aExpr.Gen();
+ aGen.Gen( _CHANNEL );
+ aGen.Gen( _CLOSE, 1 );
+
+ if( IsEoln( Peek() ) )
+ break;
+ }
+}
+
+
diff --git a/basic/source/comp/loops.cxx b/basic/source/comp/loops.cxx
new file mode 100644
index 000000000000..bd4540a8ffde
--- /dev/null
+++ b/basic/source/comp/loops.cxx
@@ -0,0 +1,558 @@
+/*************************************************************************
+ *
+ * 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 "sbcomp.hxx"
+
+// Single-line IF und Multiline IF
+
+void SbiParser::If()
+{
+ UINT32 nEndLbl;
+ SbiToken eTok = NIL;
+ // Ende-Tokens ignorieren:
+ SbiExpression aCond( this );
+ aCond.Gen();
+ TestToken( THEN );
+ if( IsEoln( Next() ) )
+ {
+ // AB 13.5.1996: #27720# Am Ende jeden Blocks muss ein Jump zu ENDIF
+ // eingefuegt werden, damit bei ELSEIF nicht erneut die Bedingung
+ // ausgewertet wird. Die Tabelle nimmt alle Absprungstellen auf.
+#define JMP_TABLE_SIZE 100
+ UINT32 pnJmpToEndLbl[JMP_TABLE_SIZE]; // 100 ELSEIFs zulaessig
+ USHORT iJmp = 0; // aktueller Tabellen-Index
+
+ // multiline IF
+ nEndLbl = aGen.Gen( _JUMPF, 0 );
+ eTok = Peek();
+ while( !( eTok == ELSEIF || eTok == ELSE || eTok == ENDIF ) &&
+ !bAbort && Parse() )
+ {
+ eTok = Peek();
+ if( IsEof() )
+ {
+ Error( SbERR_BAD_BLOCK, IF ); bAbort = TRUE; return;
+ }
+ }
+ // ELSEIF?
+ while( eTok == ELSEIF )
+ {
+ // #27720# Bei erfolgreichem IF/ELSEIF auf ENDIF springen
+ if( iJmp >= JMP_TABLE_SIZE )
+ {
+ Error( SbERR_PROG_TOO_LARGE ); bAbort = TRUE; return;
+ }
+ pnJmpToEndLbl[iJmp++] = aGen.Gen( _JUMP, 0 );
+
+ Next();
+ aGen.BackChain( nEndLbl );
+
+ aGen.Statement();
+ SbiExpression* pCond = new SbiExpression( this );
+ pCond->Gen();
+ nEndLbl = aGen.Gen( _JUMPF, 0 );
+ delete pCond;
+ TestToken( THEN );
+ eTok = Peek();
+ while( !( eTok == ELSEIF || eTok == ELSE || eTok == ENDIF ) &&
+ !bAbort && Parse() )
+ {
+ eTok = Peek();
+ if( IsEof() )
+ {
+ Error( SbERR_BAD_BLOCK, ELSEIF ); bAbort = TRUE; return;
+ }
+ }
+ }
+ if( eTok == ELSE )
+ {
+ Next();
+ UINT32 nElseLbl = nEndLbl;
+ nEndLbl = aGen.Gen( _JUMP, 0 );
+ aGen.BackChain( nElseLbl );
+
+ aGen.Statement();
+ StmntBlock( ENDIF );
+ }
+ else if( eTok == ENDIF )
+ Next();
+
+ // #27720# Jmp-Tabelle abarbeiten
+ while( iJmp > 0 )
+ {
+ iJmp--;
+ aGen.BackChain( pnJmpToEndLbl[iJmp] );
+ }
+ }
+ else
+ {
+ // single line IF
+ bSingleLineIf = TRUE;
+ nEndLbl = aGen.Gen( _JUMPF, 0 );
+ Push( eCurTok );
+ while( !bAbort )
+ {
+ if( !Parse() ) break;
+ eTok = Peek();
+ if( eTok == ELSE || eTok == EOLN || eTok == REM )
+ break;
+ }
+ if( eTok == ELSE )
+ {
+ Next();
+ UINT32 nElseLbl = nEndLbl;
+ nEndLbl = aGen.Gen( _JUMP, 0 );
+ aGen.BackChain( nElseLbl );
+ while( !bAbort )
+ {
+ if( !Parse() ) break;
+ eTok = Peek();
+ if( eTok == EOLN )
+ break;
+ }
+ }
+ bSingleLineIf = FALSE;
+ }
+ aGen.BackChain( nEndLbl );
+}
+
+// ELSE/ELSEIF/ENDIF ohne IF
+
+void SbiParser::NoIf()
+{
+ Error( SbERR_NO_IF );
+ StmntBlock( ENDIF );
+}
+
+// DO WHILE...LOOP
+// DO ... LOOP WHILE
+
+void SbiParser::DoLoop()
+{
+ UINT32 nStartLbl = aGen.GetPC();
+ OpenBlock( DO );
+ SbiToken eTok = Next();
+ if( IsEoln( eTok ) )
+ {
+ // DO ... LOOP [WHILE|UNTIL expr]
+ StmntBlock( LOOP );
+ eTok = Next();
+ if( eTok == UNTIL || eTok == WHILE )
+ {
+ SbiExpression aExpr( this );
+ aExpr.Gen();
+ aGen.Gen( eTok == UNTIL ? _JUMPF : _JUMPT, nStartLbl );
+ } else
+ if (eTok == EOLN || eTok == REM)
+ aGen.Gen (_JUMP, nStartLbl);
+ else
+ Error( SbERR_EXPECTED, WHILE );
+ }
+ else
+ {
+ // DO [WHILE|UNTIL expr] ... LOOP
+ if( eTok == UNTIL || eTok == WHILE )
+ {
+ SbiExpression aCond( this );
+ aCond.Gen();
+ }
+ UINT32 nEndLbl = aGen.Gen( eTok == UNTIL ? _JUMPT : _JUMPF, 0 );
+ StmntBlock( LOOP );
+ TestEoln();
+ aGen.Gen( _JUMP, nStartLbl );
+ aGen.BackChain( nEndLbl );
+ }
+ CloseBlock();
+}
+
+// WHILE ... WEND
+
+void SbiParser::While()
+{
+ SbiExpression aCond( this );
+ UINT32 nStartLbl = aGen.GetPC();
+ aCond.Gen();
+ UINT32 nEndLbl = aGen.Gen( _JUMPF, 0 );
+ StmntBlock( WEND );
+ aGen.Gen( _JUMP, nStartLbl );
+ aGen.BackChain( nEndLbl );
+}
+
+// FOR var = expr TO expr STEP
+
+void SbiParser::For()
+{
+ bool bForEach = ( Peek() == EACH );
+ if( bForEach )
+ Next();
+ SbiExpression aLvalue( this, SbOPERAND );
+ aLvalue.Gen(); // Variable auf dem Stack
+
+ if( bForEach )
+ {
+ TestToken( _IN_ );
+ SbiExpression aCollExpr( this, SbOPERAND );
+ aCollExpr.Gen(); // Colletion var to for stack
+ TestEoln();
+ aGen.Gen( _INITFOREACH );
+ }
+ else
+ {
+ TestToken( EQ );
+ SbiExpression aStartExpr( this );
+ aStartExpr.Gen(); // Startausdruck auf dem Stack
+ TestToken( TO );
+ SbiExpression aStopExpr( this );
+ aStopExpr.Gen(); // Endausdruck auf dem Stack
+ if( Peek() == STEP )
+ {
+ Next();
+ SbiExpression aStepExpr( this );
+ aStepExpr.Gen();
+ }
+ else
+ {
+ SbiExpression aOne( this, 1, SbxINTEGER );
+ aOne.Gen();
+ }
+ TestEoln();
+ // Der Stack hat jetzt 4 Elemente: Variable, Start, Ende, Inkrement
+ // Startwert binden
+ aGen.Gen( _INITFOR );
+ }
+
+ UINT32 nLoop = aGen.GetPC();
+ // Test durchfuehren, evtl. Stack freigeben
+ UINT32 nEndTarget = aGen.Gen( _TESTFOR, 0 );
+ OpenBlock( FOR );
+ StmntBlock( NEXT );
+ aGen.Gen( _NEXT );
+ aGen.Gen( _JUMP, nLoop );
+ // Kommen Variable nach NEXT?
+ if( Peek() == SYMBOL )
+ {
+ SbiExpression aVar( this, SbOPERAND );
+ if( aVar.GetRealVar() != aLvalue.GetRealVar() )
+ Error( SbERR_EXPECTED, aLvalue.GetRealVar()->GetName() );
+ }
+ aGen.BackChain( nEndTarget );
+ CloseBlock();
+}
+
+// WITH .. END WITH
+
+void SbiParser::With()
+{
+ SbiExpression aVar( this, SbOPERAND );
+
+ // Letzten Knoten in der Objekt-Kette ueberpruefen
+ SbiExprNode *pNode = aVar.GetExprNode()->GetRealNode();
+ SbiSymDef* pDef = pNode->GetVar();
+ // Variant, AB 27.6.1997, #41090: bzw. empty -> muß Object sein
+ if( pDef->GetType() == SbxVARIANT || pDef->GetType() == SbxEMPTY )
+ pDef->SetType( SbxOBJECT );
+ else if( pDef->GetType() != SbxOBJECT )
+ Error( SbERR_NEEDS_OBJECT );
+
+ // Knoten auch auf SbxOBJECT setzen, damit spaeter Gen() klappt
+ pNode->SetType( SbxOBJECT );
+
+ OpenBlock( NIL, aVar.GetExprNode() );
+ StmntBlock( ENDWITH );
+ CloseBlock();
+}
+
+// LOOP/NEXT/WEND ohne Konstrukt
+
+void SbiParser::BadBlock()
+{
+ if( eEndTok )
+ Error( SbERR_BAD_BLOCK, eEndTok );
+ else
+ Error( SbERR_BAD_BLOCK, "Loop/Next/Wend" );
+}
+
+// On expr Goto/Gosub n,n,n...
+
+void SbiParser::OnGoto()
+{
+ SbiExpression aCond( this );
+ aCond.Gen();
+ UINT32 nLabelsTarget = aGen.Gen( _ONJUMP, 0 );
+ SbiToken eTok = Next();
+ if( eTok != GOTO && eTok != GOSUB )
+ {
+ Error( SbERR_EXPECTED, "GoTo/GoSub" );
+ eTok = GOTO;
+ }
+ // Label-Tabelle einlesen:
+ UINT32 nLbl = 0;
+ do
+ {
+ SbiToken eTok2 = NIL;
+ eTok2 = Next(); // Label holen
+ if( MayBeLabel() )
+ {
+ UINT32 nOff = pProc->GetLabels().Reference( aSym );
+ aGen.Gen( _JUMP, nOff );
+ nLbl++;
+ }
+ else Error( SbERR_LABEL_EXPECTED );
+ }
+ while( !bAbort && TestComma() );
+ if( eTok == GOSUB )
+ nLbl |= 0x8000;
+ aGen.Patch( nLabelsTarget, nLbl );
+}
+
+// GOTO/GOSUB
+
+void SbiParser::Goto()
+{
+ SbiOpcode eOp = eCurTok == GOTO ? _JUMP : _GOSUB;
+ Next();
+ if( MayBeLabel() )
+ {
+ UINT32 nOff = pProc->GetLabels().Reference( aSym );
+ aGen.Gen( eOp, nOff );
+ }
+ else Error( SbERR_LABEL_EXPECTED );
+}
+
+// RETURN [label]
+
+void SbiParser::Return()
+{
+ Next();
+ if( MayBeLabel() )
+ {
+ UINT32 nOff = pProc->GetLabels().Reference( aSym );
+ aGen.Gen( _RETURN, nOff );
+ }
+ else aGen.Gen( _RETURN, 0 );
+}
+
+// SELECT CASE
+
+void SbiParser::Select()
+{
+ TestToken( CASE );
+ SbiExpression aCase( this );
+ SbiToken eTok = NIL;
+ aCase.Gen();
+ aGen.Gen( _CASE );
+ TestEoln();
+ UINT32 nNextTarget = 0;
+ UINT32 nDoneTarget = 0;
+ BOOL bElse = FALSE;
+ // Die Cases einlesen:
+ while( !bAbort )
+ {
+ eTok = Next();
+ if( eTok == CASE )
+ {
+ if( nNextTarget )
+ aGen.BackChain( nNextTarget ), nNextTarget = 0;
+ aGen.Statement();
+ // Jeden Case einlesen
+ BOOL bDone = FALSE;
+ UINT32 nTrueTarget = 0;
+ if( Peek() == ELSE )
+ {
+ // CASE ELSE
+ Next();
+ bElse = TRUE;
+ }
+ else while( !bDone )
+ {
+ if( bElse )
+ Error( SbERR_SYNTAX );
+ SbiToken eTok2 = Peek();
+ if( eTok2 == IS || ( eTok2 >= EQ && eTok2 <= GE ) )
+ { // CASE [IS] operator expr
+ if( eTok2 == IS )
+ Next();
+ eTok2 = Peek();
+ if( eTok2 < EQ || eTok2 > GE )
+ Error( SbERR_SYNTAX );
+ else Next();
+ SbiExpression aCompare( this );
+ aCompare.Gen();
+ nTrueTarget = aGen.Gen(
+ _CASEIS, nTrueTarget,
+ sal::static_int_cast< UINT16 >(
+ SbxEQ + ( eTok2 - EQ ) ) );
+ }
+ else
+ { // CASE expr | expr TO expr
+ SbiExpression aCase1( this );
+ aCase1.Gen();
+ if( Peek() == TO )
+ {
+ // CASE a TO b
+ Next();
+ SbiExpression aCase2( this );
+ aCase2.Gen();
+ nTrueTarget = aGen.Gen( _CASETO, nTrueTarget );
+ }
+ else
+ // CASE a
+ nTrueTarget = aGen.Gen( _CASEIS, nTrueTarget, SbxEQ );
+
+ }
+ if( Peek() == COMMA ) Next();
+ else TestEoln(), bDone = TRUE;
+ }
+ // Alle Cases abgearbeitet
+ if( !bElse )
+ {
+ nNextTarget = aGen.Gen( _JUMP, nNextTarget );
+ aGen.BackChain( nTrueTarget );
+ }
+ // den Statement-Rumpf bauen
+ while( !bAbort )
+ {
+ eTok = Peek();
+ if( eTok == CASE || eTok == ENDSELECT )
+ break;
+ if( !Parse() ) goto done;
+ eTok = Peek();
+ if( eTok == CASE || eTok == ENDSELECT )
+ break;
+ }
+ if( !bElse )
+ nDoneTarget = aGen.Gen( _JUMP, nDoneTarget );
+ }
+ else if( !IsEoln( eTok ) )
+ break;
+ }
+done:
+ if( eTok != ENDSELECT )
+ Error( SbERR_EXPECTED, ENDSELECT );
+ if( nNextTarget )
+ aGen.BackChain( nNextTarget );
+ aGen.BackChain( nDoneTarget );
+ aGen.Gen( _ENDCASE );
+}
+
+// ON Error/Variable
+
+#ifdef _MSC_VER
+#pragma optimize("",off)
+#endif
+
+void SbiParser::On()
+{
+ SbiToken eTok = Peek();
+ String aString = SbiTokenizer::Symbol(eTok);
+ if (aString.EqualsIgnoreCaseAscii("ERROR"))
+ //if (!aString.ICompare("ERROR"))
+ eTok = _ERROR_; // Error kommt als SYMBOL
+ if( eTok != _ERROR_ && eTok != LOCAL ) OnGoto();
+ else
+ {
+ if( eTok == LOCAL ) Next();
+ Next (); // Kein TestToken mehr, da es sonst einen Fehler gibt
+
+ Next(); // Token nach Error holen
+ if( eCurTok == GOTO )
+ {
+ // ON ERROR GOTO label|0
+ Next();
+ bool bError_ = false;
+ if( MayBeLabel() )
+ {
+ if( eCurTok == NUMBER && !nVal )
+ aGen.Gen( _STDERROR );
+ else
+ {
+ UINT32 nOff = pProc->GetLabels().Reference( aSym );
+ aGen.Gen( _ERRHDL, nOff );
+ }
+ }
+ else if( eCurTok == MINUS )
+ {
+ Next();
+ if( eCurTok == NUMBER && nVal == 1 )
+ aGen.Gen( _STDERROR );
+ else
+ bError_ = true;
+ }
+ if( bError_ )
+ Error( SbERR_LABEL_EXPECTED );
+ }
+ else if( eCurTok == RESUME )
+ {
+ TestToken( NEXT );
+ aGen.Gen( _NOERROR );
+ }
+ else Error( SbERR_EXPECTED, "GoTo/Resume" );
+ }
+}
+
+#ifdef _MSC_VER
+#pragma optimize("",off)
+#endif
+
+// RESUME [0]|NEXT|label
+
+void SbiParser::Resume()
+{
+ UINT32 nLbl;
+
+ switch( Next() )
+ {
+ case EOS:
+ case EOLN:
+ aGen.Gen( _RESUME, 0 );
+ break;
+ case NEXT:
+ aGen.Gen( _RESUME, 1 );
+ Next();
+ break;
+ case NUMBER:
+ if( !nVal )
+ {
+ aGen.Gen( _RESUME, 0 );
+ break;
+ } // fall thru
+ case SYMBOL:
+ if( MayBeLabel() )
+ {
+ nLbl = pProc->GetLabels().Reference( aSym );
+ aGen.Gen( _RESUME, nLbl );
+ Next();
+ break;
+ } // fall thru
+ default:
+ Error( SbERR_LABEL_EXPECTED );
+ }
+}
+
diff --git a/basic/source/comp/makefile.mk b/basic/source/comp/makefile.mk
new file mode 100644
index 000000000000..d65f6a431e43
--- /dev/null
+++ b/basic/source/comp/makefile.mk
@@ -0,0 +1,60 @@
+#*************************************************************************
+#
+# 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=comp
+
+# --- Settings ------------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+SLOFILES= \
+ $(SLO)$/buffer.obj \
+ $(SLO)$/codegen.obj \
+ $(SLO)$/dim.obj \
+ $(SLO)$/exprgen.obj \
+ $(SLO)$/exprnode.obj \
+ $(SLO)$/exprtree.obj \
+ $(SLO)$/io.obj \
+ $(SLO)$/loops.obj \
+ $(SLO)$/parser.obj \
+ $(SLO)$/sbcomp.obj \
+ $(SLO)$/scanner.obj \
+ $(SLO)$/symtbl.obj \
+ $(SLO)$/token.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/codegen.obj \
+ $(SLO)$/dim.obj \
+ $(SLO)$/exprtree.obj \
+ $(SLO)$/parser.obj
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/basic/source/comp/parser.cxx b/basic/source/comp/parser.cxx
new file mode 100644
index 000000000000..3d7178ae7688
--- /dev/null
+++ b/basic/source/comp/parser.cxx
@@ -0,0 +1,863 @@
+/*************************************************************************
+ *
+ * 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 <basic/sbx.hxx>
+#include "sbcomp.hxx"
+#include <com/sun/star/script/ModuleType.hpp>
+
+struct SbiParseStack { // "Stack" fuer Statement-Blocks
+ SbiParseStack* pNext; // Chain
+ SbiExprNode* pWithVar; // Variable fuer WITH
+ SbiToken eExitTok; // Exit-Token
+ UINT32 nChain; // JUMP-Chain
+};
+
+struct SbiStatement {
+ SbiToken eTok;
+ void( SbiParser::*Func )(); // Verarbeitungsroutine
+ BOOL bMain; // TRUE: ausserhalb SUBs OK
+ BOOL bSubr; // TRUE: in SUBs OK
+};
+
+#define Y TRUE
+#define N FALSE
+
+static SbiStatement StmntTable [] = {
+{ CALL, &SbiParser::Call, N, Y, }, // CALL
+{ CLOSE, &SbiParser::Close, N, Y, }, // CLOSE
+{ _CONST_, &SbiParser::Dim, Y, Y, }, // CONST
+{ DECLARE, &SbiParser::Declare, Y, N, }, // DECLARE
+{ DEFBOOL, &SbiParser::DefXXX, Y, N, }, // DEFBOOL
+{ DEFCUR, &SbiParser::DefXXX, Y, N, }, // DEFCUR
+{ DEFDATE, &SbiParser::DefXXX, Y, N, }, // DEFDATE
+{ DEFDBL, &SbiParser::DefXXX, Y, N, }, // DEFDBL
+{ DEFERR, &SbiParser::DefXXX, Y, N, }, // DEFERR
+{ DEFINT, &SbiParser::DefXXX, Y, N, }, // DEFINT
+{ DEFLNG, &SbiParser::DefXXX, Y, N, }, // DEFLNG
+{ DEFOBJ, &SbiParser::DefXXX, Y, N, }, // DEFOBJ
+{ DEFSNG, &SbiParser::DefXXX, Y, N, }, // DEFSNG
+{ DEFSTR, &SbiParser::DefXXX, Y, N, }, // DEFSTR
+{ DEFVAR, &SbiParser::DefXXX, Y, N, }, // DEFVAR
+{ DIM, &SbiParser::Dim, Y, Y, }, // DIM
+{ DO, &SbiParser::DoLoop, N, Y, }, // DO
+{ ELSE, &SbiParser::NoIf, N, Y, }, // ELSE
+{ ELSEIF, &SbiParser::NoIf, N, Y, }, // ELSEIF
+{ ENDIF, &SbiParser::NoIf, N, Y, }, // ENDIF
+{ END, &SbiParser::Stop, N, Y, }, // END
+{ ENUM, &SbiParser::Enum, Y, N, }, // TYPE
+{ ERASE, &SbiParser::Erase, N, Y, }, // ERASE
+{ _ERROR_, &SbiParser::ErrorStmnt, N, Y, }, // ERROR
+{ EXIT, &SbiParser::Exit, N, Y, }, // EXIT
+{ FOR, &SbiParser::For, N, Y, }, // FOR
+{ FUNCTION, &SbiParser::SubFunc, Y, N, }, // FUNCTION
+{ GOSUB, &SbiParser::Goto, N, Y, }, // GOSUB
+{ GLOBAL, &SbiParser::Dim, Y, N, }, // GLOBAL
+{ GOTO, &SbiParser::Goto, N, Y, }, // GOTO
+{ IF, &SbiParser::If, N, Y, }, // IF
+{ IMPLEMENTS, &SbiParser::Implements, Y, N, }, // IMPLEMENTS
+{ INPUT, &SbiParser::Input, N, Y, }, // INPUT
+{ LET, &SbiParser::Assign, N, Y, }, // LET
+{ LINE, &SbiParser::Line, N, Y, }, // LINE, -> LINE INPUT (#i92642)
+{ LINEINPUT,&SbiParser::LineInput, N, Y, }, // LINE INPUT
+{ LOOP, &SbiParser::BadBlock, N, Y, }, // LOOP
+{ LSET, &SbiParser::LSet, N, Y, }, // LSET
+{ NAME, &SbiParser::Name, N, Y, }, // NAME
+{ NEXT, &SbiParser::BadBlock, N, Y, }, // NEXT
+{ ON, &SbiParser::On, N, Y, }, // ON
+{ OPEN, &SbiParser::Open, N, Y, }, // OPEN
+{ OPTION, &SbiParser::Option, Y, N, }, // OPTION
+{ PRINT, &SbiParser::Print, N, Y, }, // PRINT
+{ PRIVATE, &SbiParser::Dim, Y, N, }, // PRIVATE
+{ PROPERTY, &SbiParser::SubFunc, Y, N, }, // FUNCTION
+{ PUBLIC, &SbiParser::Dim, Y, N, }, // PUBLIC
+{ REDIM, &SbiParser::ReDim, N, Y, }, // DIM
+{ RESUME, &SbiParser::Resume, N, Y, }, // RESUME
+{ RETURN, &SbiParser::Return, N, Y, }, // RETURN
+{ RSET, &SbiParser::RSet, N, Y, }, // RSET
+{ SELECT, &SbiParser::Select, N, Y, }, // SELECT
+{ SET, &SbiParser::Set, N, Y, }, // SET
+{ STATIC, &SbiParser::Static, Y, Y, }, // STATIC
+{ STOP, &SbiParser::Stop, N, Y, }, // STOP
+{ SUB, &SbiParser::SubFunc, Y, N, }, // SUB
+{ TYPE, &SbiParser::Type, Y, N, }, // TYPE
+{ UNTIL, &SbiParser::BadBlock, N, Y, }, // UNTIL
+{ WHILE, &SbiParser::While, N, Y, }, // WHILE
+{ WEND, &SbiParser::BadBlock, N, Y, }, // WEND
+{ WITH, &SbiParser::With, N, Y, }, // WITH
+{ WRITE, &SbiParser::Write, N, Y, }, // WRITE
+
+{ NIL, NULL, N, N }
+};
+
+
+#ifdef _MSC_VER
+// 'this' : used in base member initializer list
+#pragma warning( disable: 4355 )
+#endif
+
+SbiParser::SbiParser( StarBASIC* pb, SbModule* pm )
+ : SbiTokenizer( pm->GetSource32(), pb ),
+ aGblStrings( this ),
+ aLclStrings( this ),
+ aGlobals( aGblStrings, SbGLOBAL ),
+ aPublics( aGblStrings, SbPUBLIC ),
+ aRtlSyms( aGblStrings, SbRTL ),
+ aGen( *pm, this, 1024 )
+{
+ pBasic = pb;
+ eCurExpr = SbSYMBOL;
+ eEndTok = NIL;
+ pProc = NULL;
+ pStack = NULL;
+ pWithVar = NULL;
+ nBase = 0;
+ bText =
+ bGblDefs =
+ bNewGblDefs =
+ bSingleLineIf =
+ bExplicit = FALSE;
+ bClassModule = ( pm->GetModuleType() == com::sun::star::script::ModuleType::CLASS );
+ OSL_TRACE("Parser - %s, bClassModule %d", rtl::OUStringToOString( pm->GetName(), RTL_TEXTENCODING_UTF8 ).getStr(), bClassModule );
+ pPool = &aPublics;
+ for( short i = 0; i < 26; i++ )
+ eDefTypes[ i ] = SbxVARIANT; // Kein expliziter Defaulttyp
+
+ aPublics.SetParent( &aGlobals );
+ aGlobals.SetParent( &aRtlSyms );
+
+ // Die globale Chainkette faengt bei Adresse 0 an:
+ nGblChain = aGen.Gen( _JUMP, 0 );
+
+ rTypeArray = new SbxArray; // Array fuer Benutzerdefinierte Typen
+ rEnumArray = new SbxArray; // Array for Enum types
+ bVBASupportOn = pm->IsVBACompat();
+ if ( bVBASupportOn )
+ EnableCompatibility();
+
+}
+
+
+// Ist Teil der Runtime-Library?
+SbiSymDef* SbiParser::CheckRTLForSym( const String& rSym, SbxDataType eType )
+{
+ SbxVariable* pVar = GetBasic()->GetRtl()->Find( rSym, SbxCLASS_DONTCARE );
+ SbiSymDef* pDef = NULL;
+ if( pVar )
+ {
+ if( pVar->IsA( TYPE(SbxMethod) ) )
+ {
+ SbiProcDef* pProc_ = aRtlSyms.AddProc( rSym );
+ pProc_->SetType( pVar->GetType() );
+ pDef = pProc_;
+ }
+ else
+ {
+ pDef = aRtlSyms.AddSym( rSym );
+ pDef->SetType( eType );
+ }
+ }
+ return pDef;
+}
+
+// Globale Chainkette schliessen
+
+BOOL SbiParser::HasGlobalCode()
+{
+ if( bGblDefs && nGblChain )
+ {
+ aGen.BackChain( nGblChain );
+ aGen.Gen( _LEAVE );
+ // aGen.Gen( _STOP );
+ nGblChain = 0;
+ }
+ return bGblDefs;
+}
+
+void SbiParser::OpenBlock( SbiToken eTok, SbiExprNode* pVar )
+{
+ SbiParseStack* p = new SbiParseStack;
+ p->eExitTok = eTok;
+ p->nChain = 0;
+ p->pWithVar = pWithVar;
+ p->pNext = pStack;
+ pStack = p;
+ pWithVar = pVar;
+
+ // #29955 for-Schleifen-Ebene pflegen
+ if( eTok == FOR )
+ aGen.IncForLevel();
+}
+
+void SbiParser::CloseBlock()
+{
+ if( pStack )
+ {
+ SbiParseStack* p = pStack;
+
+ // #29955 for-Schleifen-Ebene pflegen
+ if( p->eExitTok == FOR )
+ aGen.DecForLevel();
+
+ aGen.BackChain( p->nChain );
+ pStack = p->pNext;
+ pWithVar = p->pWithVar;
+ delete p;
+ }
+}
+
+// EXIT ...
+
+void SbiParser::Exit()
+{
+ SbiToken eTok = Next();
+ for( SbiParseStack* p = pStack; p; p = p->pNext )
+ {
+ SbiToken eExitTok = p->eExitTok;
+ if( eTok == eExitTok ||
+ (eTok == PROPERTY && (eExitTok == GET || eExitTok == LET) ) ) // #i109051
+ {
+ p->nChain = aGen.Gen( _JUMP, p->nChain );
+ return;
+ }
+ }
+ if( pStack )
+ Error( SbERR_EXPECTED, pStack->eExitTok );
+ else
+ Error( SbERR_BAD_EXIT );
+}
+
+BOOL SbiParser::TestSymbol( BOOL bKwdOk )
+{
+ Peek();
+ if( eCurTok == SYMBOL || ( bKwdOk && IsKwd( eCurTok ) ) )
+ {
+ Next(); return TRUE;
+ }
+ Error( SbERR_SYMBOL_EXPECTED );
+ return FALSE;
+}
+
+// Testen auf ein bestimmtes Token
+
+BOOL SbiParser::TestToken( SbiToken t )
+{
+ if( Peek() == t )
+ {
+ Next(); return TRUE;
+ }
+ else
+ {
+ Error( SbERR_EXPECTED, t );
+ return FALSE;
+ }
+}
+
+// Testen auf Komma oder EOLN
+
+BOOL SbiParser::TestComma()
+{
+ SbiToken eTok = Peek();
+ if( IsEoln( eTok ) )
+ {
+ Next();
+ return FALSE;
+ }
+ else if( eTok != COMMA )
+ {
+ Error( SbERR_EXPECTED, COMMA );
+ return FALSE;
+ }
+ Next();
+ return TRUE;
+}
+
+// Testen, ob EOLN vorliegt
+
+void SbiParser::TestEoln()
+{
+ if( !IsEoln( Next() ) )
+ {
+ Error( SbERR_EXPECTED, EOLN );
+ while( !IsEoln( Next() ) ) {}
+ }
+}
+
+// Parsing eines Statement-Blocks
+// Das Parsing laeuft bis zum Ende-Token.
+
+void SbiParser::StmntBlock( SbiToken eEnd )
+{
+ SbiToken xe = eEndTok;
+ eEndTok = eEnd;
+ while( !bAbort && Parse() ) {}
+ eEndTok = xe;
+ if( IsEof() )
+ {
+ Error( SbERR_BAD_BLOCK, eEnd );
+ bAbort = TRUE;
+ }
+}
+
+// Die Hauptroutine. Durch wiederholten Aufrufs dieser Routine wird
+// die Quelle geparst. Returnwert FALSE bei Ende/Fehlern.
+
+BOOL SbiParser::Parse()
+{
+ if( bAbort ) return FALSE;
+
+ EnableErrors();
+
+ bErrorIsSymbol = false;
+ Peek();
+ bErrorIsSymbol = true;
+ // Dateiende?
+ if( IsEof() )
+ {
+ // AB #33133: Falls keine Sub angelegt wurde, muss hier
+ // der globale Chain abgeschlossen werden!
+ // AB #40689: Durch die neue static-Behandlung kann noch
+ // ein nGblChain vorhanden sein, daher vorher abfragen
+ if( bNewGblDefs && nGblChain == 0 )
+ nGblChain = aGen.Gen( _JUMP, 0 );
+ return FALSE;
+ }
+
+ // Leerstatement?
+ if( IsEoln( eCurTok ) )
+ {
+ Next(); return TRUE;
+ }
+
+ if( !bSingleLineIf && MayBeLabel( TRUE ) )
+ {
+ // Ist ein Label
+ if( !pProc )
+ Error( SbERR_NOT_IN_MAIN, aSym );
+ else
+ pProc->GetLabels().Define( aSym );
+ Next(); Peek();
+ // Leerstatement?
+ if( IsEoln( eCurTok ) )
+ {
+ Next(); return TRUE;
+ }
+ }
+
+ // Ende des Parsings?
+ if( eCurTok == eEndTok ||
+ ( bVBASupportOn && // #i109075
+ (eCurTok == ENDFUNC || eCurTok == ENDPROPERTY || eCurTok == ENDSUB) &&
+ (eEndTok == ENDFUNC || eEndTok == ENDPROPERTY || eEndTok == ENDSUB) ) )
+ {
+ Next();
+ if( eCurTok != NIL )
+ aGen.Statement();
+ return FALSE;
+ }
+
+ // Kommentar?
+ if( eCurTok == REM )
+ {
+ Next(); return TRUE;
+ }
+
+ // Kommt ein Symbol, ist es entweder eine Variable( LET )
+ // oder eine SUB-Prozedur( CALL ohne Klammern )
+ // DOT fuer Zuweisungen im WITH-Block: .A=5
+ if( eCurTok == SYMBOL || eCurTok == DOT )
+ {
+ if( !pProc )
+ Error( SbERR_EXPECTED, SUB );
+ else
+ {
+ // Damit Zeile & Spalte stimmen...
+ Next();
+ Push( eCurTok );
+ aGen.Statement();
+ Symbol();
+ }
+ }
+ else
+ {
+ Next();
+
+ // Hier folgen nun die Statement-Parser.
+
+ SbiStatement* p;
+ for( p = StmntTable; p->eTok != NIL; p++ )
+ if( p->eTok == eCurTok )
+ break;
+ if( p->eTok != NIL )
+ {
+ if( !pProc && !p->bMain )
+ Error( SbERR_NOT_IN_MAIN, eCurTok );
+ else if( pProc && !p->bSubr )
+ Error( SbERR_NOT_IN_SUBR, eCurTok );
+ else
+ {
+ // globalen Chain pflegen
+ // AB #41606/#40689: Durch die neue static-Behandlung kann noch
+ // ein nGblChain vorhanden sein, daher vorher abfragen
+ if( bNewGblDefs && nGblChain == 0 &&
+ ( eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY ) )
+ {
+ nGblChain = aGen.Gen( _JUMP, 0 );
+ bNewGblDefs = FALSE;
+ }
+ // Statement-Opcode bitte auch am Anfang einer Sub
+ if( ( p->bSubr && (eCurTok != STATIC || Peek() == SUB || Peek() == FUNCTION ) ) ||
+ eCurTok == SUB || eCurTok == FUNCTION )
+ aGen.Statement();
+ (this->*( p->Func ) )();
+ SbxError nSbxErr = SbxBase::GetError();
+ if( nSbxErr )
+ SbxBase::ResetError(), Error( (SbError)nSbxErr );
+ }
+ }
+ else
+ Error( SbERR_UNEXPECTED, eCurTok );
+ }
+
+ // Test auf Ende des Statements:
+ // Kann auch ein ELSE sein, da vor dem ELSE kein : stehen muss!
+
+ if( !IsEos() )
+ {
+ Peek();
+ if( !IsEos() && eCurTok != ELSE )
+ {
+ // falls das Parsing abgebrochen wurde, bis zum ":" vorgehen:
+ Error( SbERR_UNEXPECTED, eCurTok );
+ while( !IsEos() ) Next();
+ }
+ }
+ // Der Parser bricht am Ende ab, das naechste Token ist noch nicht
+ // geholt!
+ return TRUE;
+}
+
+// Innerste With-Variable liefern
+SbiExprNode* SbiParser::GetWithVar()
+{
+ if( pWithVar )
+ return pWithVar;
+
+ // Sonst im Stack suchen
+ SbiParseStack* p = pStack;
+ while( p )
+ {
+ // LoopVar kann zur Zeit nur fuer with sein
+ if( p->pWithVar )
+ return p->pWithVar;
+ p = p->pNext;
+ }
+ return NULL;
+}
+
+
+// Zuweisung oder Subroutine Call
+
+void SbiParser::Symbol( const KeywordSymbolInfo* pKeywordSymbolInfo )
+{
+ SbiExprMode eMode = bVBASupportOn ? EXPRMODE_STANDALONE : EXPRMODE_STANDARD;
+ SbiExpression aVar( this, SbSYMBOL, eMode, pKeywordSymbolInfo );
+
+ bool bEQ = ( Peek() == EQ );
+ if( !bEQ && bVBASupportOn && aVar.IsBracket() )
+ Error( SbERR_EXPECTED, "=" );
+
+ RecursiveMode eRecMode = ( bEQ ? PREVENT_CALL : FORCE_CALL );
+ bool bSpecialMidHandling = false;
+ SbiSymDef* pDef = aVar.GetRealVar();
+ if( bEQ && pDef && pDef->GetScope() == SbRTL )
+ {
+ String aRtlName = pDef->GetName();
+ if( aRtlName.EqualsIgnoreCaseAscii("Mid") )
+ {
+ SbiExprNode* pExprNode = aVar.GetExprNode();
+ // SbiNodeType eNodeType;
+ if( pExprNode && pExprNode->GetNodeType() == SbxVARVAL )
+ {
+ SbiExprList* pPar = pExprNode->GetParameters();
+ short nParCount = pPar ? pPar->GetSize() : 0;
+ if( nParCount == 2 || nParCount == 3 )
+ {
+ if( nParCount == 2 )
+ pPar->addExpression( new SbiExpression( this, -1, SbxLONG ) );
+
+ TestToken( EQ );
+ pPar->addExpression( new SbiExpression( this ) );
+
+ bSpecialMidHandling = true;
+ }
+ }
+ }
+ }
+ aVar.Gen( eRecMode );
+ if( !bSpecialMidHandling )
+ {
+ if( !bEQ )
+ {
+ aGen.Gen( _GET );
+ }
+ else
+ {
+ // Dann muss es eine Zuweisung sein. Was anderes gibts nicht!
+ if( !aVar.IsLvalue() )
+ Error( SbERR_LVALUE_EXPECTED );
+ TestToken( EQ );
+ SbiExpression aExpr( this );
+ aExpr.Gen();
+ SbiOpcode eOp = _PUT;
+ // SbiSymDef* pDef = aVar.GetRealVar();
+ if( pDef )
+ {
+ if( pDef->GetConstDef() )
+ Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
+ if( pDef->GetType() == SbxOBJECT )
+ {
+ eOp = _SET;
+ if( pDef->GetTypeId() )
+ {
+ aGen.Gen( _SETCLASS, pDef->GetTypeId() );
+ return;
+ }
+ }
+ }
+ aGen.Gen( eOp );
+ }
+ }
+}
+
+// Zuweisungen
+
+void SbiParser::Assign()
+{
+ SbiExpression aLvalue( this, SbLVALUE );
+ TestToken( EQ );
+ SbiExpression aExpr( this );
+ aLvalue.Gen();
+ aExpr.Gen();
+ USHORT nLen = 0;
+ SbiSymDef* pDef = aLvalue.GetRealVar();
+ {
+ if( pDef->GetConstDef() )
+ Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
+ nLen = aLvalue.GetRealVar()->GetLen();
+ }
+ if( nLen )
+ aGen.Gen( _PAD, nLen );
+ aGen.Gen( _PUT );
+}
+
+// Zuweisungen einer Objektvariablen
+
+void SbiParser::Set()
+{
+ SbiExpression aLvalue( this, SbLVALUE );
+ SbxDataType eType = aLvalue.GetType();
+ if( eType != SbxOBJECT && eType != SbxEMPTY && eType != SbxVARIANT )
+ Error( SbERR_INVALID_OBJECT );
+ TestToken( EQ );
+ SbiSymDef* pDef = aLvalue.GetRealVar();
+ if( pDef && pDef->GetConstDef() )
+ Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
+
+ SbiToken eTok = Peek();
+ if( eTok == NEW )
+ {
+ Next();
+ String aStr;
+ SbiSymDef* pTypeDef = new SbiSymDef( aStr );
+ TypeDecl( *pTypeDef, TRUE );
+
+ aLvalue.Gen();
+ // aGen.Gen( _CLASS, pDef->GetTypeId() | 0x8000 );
+ aGen.Gen( _CREATE, pDef->GetId(), pTypeDef->GetTypeId() );
+ aGen.Gen( _SETCLASS, pDef->GetTypeId() );
+ }
+ else
+ {
+ SbiExpression aExpr( this );
+ aLvalue.Gen();
+ aExpr.Gen();
+ // Its a good idea to distinguish between
+ // set someting = another &
+ // someting = another
+ // ( its necessary for vba objects where set is object
+ // specific and also doesn't involve processing default params )
+ if( pDef->GetTypeId() )
+ {
+ if ( bVBASupportOn )
+ aGen.Gen( _VBASETCLASS, pDef->GetTypeId() );
+ else
+ aGen.Gen( _SETCLASS, pDef->GetTypeId() );
+ }
+ else
+ {
+ if ( bVBASupportOn )
+ aGen.Gen( _VBASET );
+ else
+ aGen.Gen( _SET );
+ }
+ }
+ // aGen.Gen( _SET );
+}
+
+// JSM 07.10.95
+void SbiParser::LSet()
+{
+ SbiExpression aLvalue( this, SbLVALUE );
+ if( aLvalue.GetType() != SbxSTRING )
+ Error( SbERR_INVALID_OBJECT );
+ TestToken( EQ );
+ SbiSymDef* pDef = aLvalue.GetRealVar();
+ if( pDef && pDef->GetConstDef() )
+ Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
+ SbiExpression aExpr( this );
+ aLvalue.Gen();
+ aExpr.Gen();
+ aGen.Gen( _LSET );
+}
+
+// JSM 07.10.95
+void SbiParser::RSet()
+{
+ SbiExpression aLvalue( this, SbLVALUE );
+ if( aLvalue.GetType() != SbxSTRING )
+ Error( SbERR_INVALID_OBJECT );
+ TestToken( EQ );
+ SbiSymDef* pDef = aLvalue.GetRealVar();
+ if( pDef && pDef->GetConstDef() )
+ Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
+ SbiExpression aExpr( this );
+ aLvalue.Gen();
+ aExpr.Gen();
+ aGen.Gen( _RSET );
+}
+
+// DEFINT, DEFLNG, DEFSNG, DEFDBL, DEFSTR und so weiter
+
+void SbiParser::DefXXX()
+{
+ sal_Unicode ch1, ch2;
+ SbxDataType t = SbxDataType( eCurTok - DEFINT + SbxINTEGER );
+
+ while( !bAbort )
+ {
+ if( Next() != SYMBOL ) break;
+ ch1 = aSym.ToUpperAscii().GetBuffer()[0];
+ ch2 = 0;
+ if( Peek() == MINUS )
+ {
+ Next();
+ if( Next() != SYMBOL ) Error( SbERR_SYMBOL_EXPECTED );
+ else
+ {
+ ch2 = aSym.ToUpperAscii().GetBuffer()[0];
+ //ch2 = aSym.Upper();
+ if( ch2 < ch1 ) Error( SbERR_SYNTAX ), ch2 = 0;
+ }
+ }
+ if (!ch2) ch2 = ch1;
+ ch1 -= 'A'; ch2 -= 'A';
+ for (; ch1 <= ch2; ch1++) eDefTypes[ ch1 ] = t;
+ if( !TestComma() ) break;
+ }
+}
+
+// STOP/SYSTEM
+
+void SbiParser::Stop()
+{
+ aGen.Gen( _STOP );
+ Peek(); // #35694: Nur Peek(), damit EOL in Single-Line-If erkannt wird
+}
+
+// IMPLEMENTS
+
+void SbiParser::Implements()
+{
+ if( !bClassModule )
+ {
+ Error( SbERR_UNEXPECTED, IMPLEMENTS );
+ return;
+ }
+
+ Peek();
+ if( eCurTok != SYMBOL )
+ {
+ Error( SbERR_SYMBOL_EXPECTED );
+ return;
+ }
+
+ String aImplementedIface = aSym;
+ Next();
+ if( Peek() == DOT )
+ {
+ String aDotStr( '.' );
+ while( Peek() == DOT )
+ {
+ aImplementedIface += aDotStr;
+ Next();
+ SbiToken ePeekTok = Peek();
+ if( ePeekTok == SYMBOL || IsKwd( ePeekTok ) )
+ {
+ Next();
+ aImplementedIface += aSym;
+ }
+ else
+ {
+ Next();
+ Error( SbERR_SYMBOL_EXPECTED );
+ break;
+ }
+ }
+ }
+ aIfaceVector.push_back( aImplementedIface );
+}
+
+void SbiParser::EnableCompatibility()
+{
+ if( !bCompatible )
+ AddConstants();
+ bCompatible = TRUE;
+}
+
+// OPTION
+
+void SbiParser::Option()
+{
+ switch( Next() )
+ {
+ case EXPLICIT:
+ bExplicit = TRUE; break;
+ case BASE:
+ if( Next() == NUMBER )
+ {
+ if( nVal == 0 || nVal == 1 )
+ {
+ nBase = (short) nVal;
+ break;
+ }
+ }
+ Error( SbERR_EXPECTED, "0/1" );
+ break;
+ case PRIVATE:
+ {
+ String aString = SbiTokenizer::Symbol(Next());
+ if( !aString.EqualsIgnoreCaseAscii("Module") )
+ Error( SbERR_EXPECTED, "Module" );
+ break;
+ }
+ case COMPARE:
+ {
+ SbiToken eTok = Next();
+ if( eTok == BINARY )
+ bText = FALSE;
+ else if( eTok == SYMBOL && GetSym().EqualsIgnoreCaseAscii("text") )
+ bText = TRUE;
+ else
+ Error( SbERR_EXPECTED, "Text/Binary" );
+ break;
+ }
+ case COMPATIBLE:
+ EnableCompatibility();
+ break;
+
+ case CLASSMODULE:
+ bClassModule = TRUE;
+ aGen.GetModule().SetModuleType( com::sun::star::script::ModuleType::CLASS );
+ break;
+ case VBASUPPORT:
+ if( Next() == NUMBER )
+ {
+ if ( nVal == 1 || nVal == 0 )
+ {
+ bVBASupportOn = ( nVal == 1 );
+ if ( bVBASupportOn )
+ EnableCompatibility();
+ // if the module setting is different
+ // reset it to what the Option tells us
+ if ( bVBASupportOn != aGen.GetModule().IsVBACompat() )
+ aGen.GetModule().SetVBACompat( bVBASupportOn );
+ break;
+ }
+ }
+ Error( SbERR_EXPECTED, "0/1" );
+ break;
+ default:
+ Error( SbERR_BAD_OPTION, eCurTok );
+ }
+}
+
+void addStringConst( SbiSymPool& rPool, const char* pSym, const String& rStr )
+{
+ SbiConstDef* pConst = new SbiConstDef( String::CreateFromAscii( pSym ) );
+ pConst->SetType( SbxSTRING );
+ pConst->Set( rStr );
+ rPool.Add( pConst );
+}
+
+inline void addStringConst( SbiSymPool& rPool, const char* pSym, const char* pStr )
+{
+ addStringConst( rPool, pSym, String::CreateFromAscii( pStr ) );
+}
+
+void SbiParser::AddConstants( void )
+{
+ // #113063 Create constant RTL symbols
+ addStringConst( aPublics, "vbCr", "\x0D" );
+ addStringConst( aPublics, "vbCrLf", "\x0D\x0A" );
+ addStringConst( aPublics, "vbFormFeed", "\x0C" );
+ addStringConst( aPublics, "vbLf", "\x0A" );
+#if defined(UNX)
+ addStringConst( aPublics, "vbNewLine", "\x0A" );
+#else
+ addStringConst( aPublics, "vbNewLine", "\x0D\x0A" );
+#endif
+ addStringConst( aPublics, "vbNullString", "" );
+ addStringConst( aPublics, "vbTab", "\x09" );
+ addStringConst( aPublics, "vbVerticalTab", "\x0B" );
+
+ // Force length 1 and make char 0 afterwards
+ String aNullCharStr( String::CreateFromAscii( " " ) );
+ aNullCharStr.SetChar( 0, 0 );
+ addStringConst( aPublics, "vbNullChar", aNullCharStr );
+}
+
+// ERROR n
+
+void SbiParser::ErrorStmnt()
+{
+ SbiExpression aPar( this );
+ aPar.Gen();
+ aGen.Gen( _ERROR );
+}
+
diff --git a/basic/source/comp/sbcomp.cxx b/basic/source/comp/sbcomp.cxx
new file mode 100755
index 000000000000..5b7e5c70591d
--- /dev/null
+++ b/basic/source/comp/sbcomp.cxx
@@ -0,0 +1,477 @@
+/*************************************************************************
+ *
+ * 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 <basic/sbx.hxx>
+#include "sbcomp.hxx"
+#include "image.hxx"
+#include "sbtrace.hxx"
+
+
+//==========================================================================
+// Tracing, for debugging only
+
+// To activate tracing enable in sbtrace.hxx
+#ifdef DBG_TRACE_BASIC
+
+#include <hash_map>
+
+// Trace Settings
+static const char* GpTraceFileName = "d:\\zBasic.Asm\\BasicTrace.txt";
+static const bool GbIncludePCodes = false;
+static const int GnIndentPerCallLevel = 4;
+static const int GnIndentForPCode = 2;
+
+struct TraceTextData
+{
+ rtl::OString m_aTraceStr_STMNT;
+ rtl::OString m_aTraceStr_PCode;
+};
+typedef std::hash_map< sal_Int32, TraceTextData > PCToTextDataMap;
+typedef std::hash_map< ::rtl::OUString, PCToTextDataMap*, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > ModuleTraceMap;
+
+ModuleTraceMap GaModuleTraceMap;
+ModuleTraceMap& rModuleTraceMap = GaModuleTraceMap;
+
+static void lcl_PrepareTraceForModule( SbModule* pModule )
+{
+ String aModuleName = pModule->GetName();
+ ModuleTraceMap::iterator it = rModuleTraceMap.find( aModuleName );
+ if( it != rModuleTraceMap.end() )
+ {
+ PCToTextDataMap* pInnerMap = it->second;
+ delete pInnerMap;
+ rModuleTraceMap.erase( it );
+ }
+
+ String aDisassemblyStr;
+ pModule->Disassemble( aDisassemblyStr );
+}
+
+static void lcl_lineOut( const char* pFileName, const char* pStr, const char* pPreStr = NULL )
+{
+ const char* pPrintFirst = (pPreStr != NULL) ? pPreStr : "";
+ FILE* pFile = fopen( pFileName, "a+" );
+ if( pFile != NULL )
+ {
+ fprintf( pFile, "%s%s\n", pPrintFirst, pStr );
+ fclose( pFile );
+ }
+}
+
+const char* lcl_getSpaces( int nSpaceCount )
+{
+ static sal_Char Spaces[] = " "
+ " "
+ " ";
+ static int nAvailableSpaceCount = strlen( Spaces );
+ static sal_Char* pSpacesEnd = Spaces + nAvailableSpaceCount;
+
+ if( nSpaceCount > nAvailableSpaceCount )
+ nSpaceCount = nAvailableSpaceCount;
+
+ return pSpacesEnd - nSpaceCount;
+}
+
+static rtl::OString lcl_toOStringSkipLeadingWhites( const String& aStr )
+{
+ static sal_Char Buffer[1000];
+
+ rtl::OString aOStr = OUStringToOString( rtl::OUString( aStr ), RTL_TEXTENCODING_ASCII_US );
+ const sal_Char* pStr = aOStr.getStr();
+
+ // Skip whitespace
+ sal_Char c = *pStr;
+ while( c == ' ' || c == '\t' )
+ {
+ pStr++;
+ c = *pStr;
+ }
+
+ int nLen = strlen( pStr );
+ strncpy( Buffer, pStr, nLen );
+ Buffer[nLen] = 0;
+
+ rtl::OString aORetStr( Buffer );
+ return aORetStr;
+}
+
+String dumpMethodParameters( SbMethod* pMethod )
+{
+ String aStr;
+ if( pMethod == NULL )
+ return aStr;
+
+ SbxError eOld = SbxBase::GetError();
+
+ SbxArray* pParams = pMethod->GetParameters();
+ SbxInfo* pInfo = pMethod->GetInfo();
+ if ( pParams )
+ {
+ aStr += '(';
+ // 0 is sub itself
+ for ( USHORT nParam = 1; nParam < pParams->Count(); nParam++ )
+ {
+ SbxVariable* pVar = pParams->Get( nParam );
+ DBG_ASSERT( pVar, "Parameter?!" );
+ if ( pVar->GetName().Len() )
+ aStr += pVar->GetName();
+ else if ( pInfo )
+ {
+ const SbxParamInfo* pParam = pInfo->GetParam( nParam );
+ if ( pParam )
+ aStr += pParam->aName;
+ }
+ aStr += '=';
+ if( pVar->GetType() & SbxARRAY )
+ aStr += String( RTL_CONSTASCII_USTRINGPARAM( "..." ) );
+ else
+ aStr += pVar->GetString();
+ if ( nParam < ( pParams->Count() - 1 ) )
+ aStr += String( RTL_CONSTASCII_USTRINGPARAM( ", " ) );
+ }
+ aStr += ')';
+ }
+
+ SbxBase::ResetError();
+ if( eOld != SbxERR_OK )
+ SbxBase::SetError( eOld );
+
+ return aStr;
+}
+
+// Public functions
+void dbg_InitTrace( void )
+{
+ FILE* pFile = fopen( GpTraceFileName, "w" );
+ if( pFile != NULL )
+ fclose( pFile );
+}
+
+void dbg_traceStep( SbModule* pModule, UINT32 nPC, INT32 nCallLvl )
+{
+ SbModule* pTraceMod = pModule;
+ if( pTraceMod->ISA(SbClassModuleObject) )
+ {
+ SbClassModuleObject* pClassModuleObj = (SbClassModuleObject*)(SbxBase*)pTraceMod;
+ pTraceMod = pClassModuleObj->getClassModule();
+ }
+
+ String aModuleName = pTraceMod->GetName();
+ ModuleTraceMap::iterator it = rModuleTraceMap.find( aModuleName );
+ if( it == rModuleTraceMap.end() )
+ {
+ const char* pModuleNameStr = OUStringToOString( rtl::OUString( aModuleName ), RTL_TEXTENCODING_ASCII_US ).getStr();
+ char Buffer[200];
+ sprintf( Buffer, "TRACE ERROR: Unknown module \"%s\"", pModuleNameStr );
+ lcl_lineOut( GpTraceFileName, Buffer );
+ return;
+ }
+
+ PCToTextDataMap* pInnerMap = it->second;
+ if( pInnerMap == NULL )
+ {
+ lcl_lineOut( GpTraceFileName, "TRACE INTERNAL ERROR: No inner map" );
+ return;
+ }
+
+ PCToTextDataMap::iterator itInner = pInnerMap->find( nPC );
+ if( itInner == pInnerMap->end() )
+ {
+ const char* pModuleNameStr = OUStringToOString( rtl::OUString( aModuleName ), RTL_TEXTENCODING_ASCII_US ).getStr();
+ char Buffer[200];
+ sprintf( Buffer, "TRACE ERROR: No info for PC = %d in module \"%s\"", nPC, pModuleNameStr );
+ lcl_lineOut( GpTraceFileName, Buffer );
+ return;
+ }
+
+ //nCallLvl--;
+ //if( nCallLvl < 0 )
+ // nCallLvl = 0;
+ int nIndent = nCallLvl * GnIndentPerCallLevel;
+
+ const TraceTextData& rTraceTextData = itInner->second;
+ const rtl::OString& rStr_STMNT = rTraceTextData.m_aTraceStr_STMNT;
+ if( rStr_STMNT.getLength() )
+ lcl_lineOut( GpTraceFileName, rStr_STMNT.getStr(), lcl_getSpaces( nIndent ) );
+
+ if( !GbIncludePCodes )
+ return;
+
+ nIndent += GnIndentForPCode;
+ const rtl::OString& rStr_PCode = rTraceTextData.m_aTraceStr_PCode;
+ if( rStr_PCode.getLength() )
+ lcl_lineOut( GpTraceFileName, rStr_PCode.getStr(), lcl_getSpaces( nIndent ) );
+}
+
+void dbg_traceNotifyCall( SbModule* pModule, SbMethod* pMethod, INT32 nCallLvl, bool bLeave )
+{
+ static const char* pSeparator = "' ================================================================================";
+
+ SbModule* pTraceMod = pModule;
+ SbClassModuleObject* pClassModuleObj = NULL;
+ if( pTraceMod->ISA(SbClassModuleObject) )
+ {
+ pClassModuleObj = (SbClassModuleObject*)(SbxBase*)pTraceMod;
+ pTraceMod = pClassModuleObj->getClassModule();
+ }
+
+ if( nCallLvl > 0 )
+ nCallLvl--;
+ int nIndent = nCallLvl * GnIndentPerCallLevel;
+ if( !bLeave )
+ {
+ lcl_lineOut( GpTraceFileName, "" );
+ lcl_lineOut( GpTraceFileName, pSeparator, lcl_getSpaces( nIndent ) );
+ }
+
+ String aStr;
+ if( bLeave )
+ {
+ lcl_lineOut( GpTraceFileName, "}", lcl_getSpaces( nIndent ) );
+ aStr.AppendAscii( "' Leaving " );
+ }
+ else
+ {
+ aStr.AppendAscii( "Entering " );
+ }
+ String aModuleName = pTraceMod->GetName();
+ aStr += aModuleName;
+ if( pMethod != NULL )
+ {
+ aStr.AppendAscii( "::" );
+ String aMethodName = pMethod->GetName();
+ aStr += aMethodName;
+ }
+ else
+ {
+ aStr.AppendAscii( "/RunInit" );
+ }
+
+ if( pClassModuleObj != NULL )
+ {
+ aStr.AppendAscii( "[this=" );
+ aStr += pClassModuleObj->GetName();
+ aStr.AppendAscii( "]" );
+ }
+ if( !bLeave )
+ aStr += dumpMethodParameters( pMethod );
+
+ lcl_lineOut( GpTraceFileName, OUStringToOString( rtl::OUString( aStr ), RTL_TEXTENCODING_ASCII_US ).getStr(), lcl_getSpaces( nIndent ) );
+ if( !bLeave )
+ lcl_lineOut( GpTraceFileName, "{", lcl_getSpaces( nIndent ) );
+
+ if( bLeave )
+ lcl_lineOut( GpTraceFileName, "" );
+}
+
+void dbg_traceNotifyError( SbError nTraceErr, const String& aTraceErrMsg, bool bTraceErrHandled, INT32 nCallLvl )
+{
+ rtl::OString aOTraceErrMsg = OUStringToOString( rtl::OUString( aTraceErrMsg ), RTL_TEXTENCODING_ASCII_US );
+
+ char Buffer[200];
+ const char* pHandledStr = bTraceErrHandled ? " / HANDLED" : "";
+ sprintf( Buffer, "*** ERROR%s, Id = %d, Msg = \"%s\" ***", pHandledStr, (int)nTraceErr, aOTraceErrMsg.getStr() );
+ int nIndent = nCallLvl * GnIndentPerCallLevel;
+ lcl_lineOut( GpTraceFileName, Buffer, lcl_getSpaces( nIndent ) );
+}
+
+void dbg_RegisterTraceTextForPC( SbModule* pModule, UINT32 nPC,
+ const String& aTraceStr_STMNT, const String& aTraceStr_PCode )
+{
+ String aModuleName = pModule->GetName();
+ ModuleTraceMap::iterator it = rModuleTraceMap.find( aModuleName );
+ PCToTextDataMap* pInnerMap;
+ if( it == rModuleTraceMap.end() )
+ {
+ pInnerMap = new PCToTextDataMap();
+ rModuleTraceMap[ aModuleName ] = pInnerMap;
+ }
+ else
+ {
+ pInnerMap = it->second;
+ }
+
+ TraceTextData aData;
+
+ rtl::OString aOTraceStr_STMNT = lcl_toOStringSkipLeadingWhites( aTraceStr_STMNT );
+ aData.m_aTraceStr_STMNT = aOTraceStr_STMNT;
+
+ rtl::OString aOTraceStr_PCode = lcl_toOStringSkipLeadingWhites( aTraceStr_PCode );
+ aData.m_aTraceStr_PCode = aOTraceStr_PCode;
+
+ (*pInnerMap)[nPC] = aData;
+}
+
+#endif
+
+
+//==========================================================================
+// For debugging only
+//#define DBG_SAVE_DISASSEMBLY
+
+#ifdef DBG_SAVE_DISASSEMBLY
+static bool dbg_bDisassemble = true;
+#include <comphelper/processfactory.hxx>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
+#include <com/sun/star/io/XTextOutputStream.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+
+using namespace comphelper;
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::io;
+
+void dbg_SaveDisassembly( SbModule* pModule )
+{
+ bool bDisassemble = dbg_bDisassemble;
+ if( bDisassemble )
+ {
+ Reference< XSimpleFileAccess3 > xSFI;
+ Reference< XTextOutputStream > xTextOut;
+ Reference< XOutputStream > xOut;
+ Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
+ if( xSMgr.is() )
+ {
+ Reference< XSimpleFileAccess3 > xSFI = Reference< XSimpleFileAccess3 >( xSMgr->createInstance
+ ( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
+ if( xSFI.is() )
+ {
+ String aFile( RTL_CONSTASCII_USTRINGPARAM("file:///d:/zBasic.Asm/Asm_") );
+ StarBASIC* pBasic = (StarBASIC*)pModule->GetParent();
+ if( pBasic )
+ {
+ aFile += pBasic->GetName();
+ aFile.AppendAscii( "_" );
+ }
+ aFile += pModule->GetName();
+ aFile.AppendAscii( ".txt" );
+
+ // String aFile( RTL_CONSTASCII_USTRINGPARAM("file:///d:/BasicAsm.txt") );
+ if( xSFI->exists( aFile ) )
+ xSFI->kill( aFile );
+ xOut = xSFI->openFileWrite( aFile );
+ Reference< XInterface > x = xSMgr->createInstance( OUString::createFromAscii( "com.sun.star.io.TextOutputStream" ) );
+ Reference< XActiveDataSource > xADS( x, UNO_QUERY );
+ xADS->setOutputStream( xOut );
+ xTextOut = Reference< XTextOutputStream >( x, UNO_QUERY );
+ }
+ }
+
+ if( xTextOut.is() )
+ {
+ String aDisassemblyStr;
+ pModule->Disassemble( aDisassemblyStr );
+ xTextOut->writeString( aDisassemblyStr );
+ }
+ xOut->closeOutput();
+ }
+}
+#endif
+
+
+// Diese Routine ist hier definiert, damit der Compiler als eigenes Segment
+// geladen werden kann.
+
+BOOL SbModule::Compile()
+{
+ if( pImage )
+ return TRUE;
+ StarBASIC* pBasic = PTR_CAST(StarBASIC,GetParent());
+ if( !pBasic )
+ return FALSE;
+ SbxBase::ResetError();
+ // Aktuelles Modul!
+ SbModule* pOld = pCMOD;
+ pCMOD = this;
+
+ SbiParser* pParser = new SbiParser( (StarBASIC*) GetParent(), this );
+ while( pParser->Parse() ) {}
+ if( !pParser->GetErrors() )
+ pParser->aGen.Save();
+ delete pParser;
+ // fuer den Disassembler
+ if( pImage )
+ pImage->aOUSource = aOUSource;
+
+ pCMOD = pOld;
+
+ // Beim Compilieren eines Moduls werden die Modul-globalen
+ // Variablen aller Module ungueltig
+ BOOL bRet = IsCompiled();
+ if( bRet )
+ {
+ pBasic->ClearAllModuleVars();
+ RemoveVars(); // remove 'this' Modules variables
+ // clear all method statics
+ for( USHORT i = 0; i < pMethods->Count(); i++ )
+ {
+ SbMethod* p = PTR_CAST(SbMethod,pMethods->Get( i ) );
+ if( p )
+ p->ClearStatics();
+ }
+
+ // #i31510 Init other libs only if Basic isn't running
+ if( pINST == NULL )
+ {
+ SbxObject* pParent_ = pBasic->GetParent();
+ if( pParent_ )
+ pBasic = PTR_CAST(StarBASIC,pParent_);
+ if( pBasic )
+ pBasic->ClearAllModuleVars();
+ }
+ }
+
+#ifdef DBG_SAVE_DISASSEMBLY
+ dbg_SaveDisassembly( this );
+#endif
+
+#ifdef DBG_TRACE_BASIC
+ lcl_PrepareTraceForModule( this );
+#endif
+
+ return bRet;
+}
+
+/**************************************************************************
+*
+* Syntax-Highlighting
+*
+**************************************************************************/
+
+void StarBASIC::Highlight( const String& rSrc, SbTextPortions& rList )
+{
+ SbiTokenizer aTok( rSrc );
+ aTok.Hilite( rList );
+}
+
diff --git a/basic/source/comp/scanner.cxx b/basic/source/comp/scanner.cxx
new file mode 100644
index 000000000000..dd68f20893f5
--- /dev/null
+++ b/basic/source/comp/scanner.cxx
@@ -0,0 +1,582 @@
+/*************************************************************************
+ *
+ * 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 "sbcomp.hxx"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#if defined UNX
+#include <stdlib.h>
+#else
+#include <math.h> // atof()
+#endif
+#include <rtl/math.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/charclass.hxx>
+
+#include <runtime.hxx>
+
+SbiScanner::SbiScanner( const ::rtl::OUString& rBuf, StarBASIC* p ) : aBuf( rBuf )
+{
+ pBasic = p;
+ pLine = NULL;
+ nVal = 0;
+ eScanType = SbxVARIANT;
+ nErrors = 0;
+ nBufPos = 0;
+ nCurCol1 = 0;
+ nSavedCol1 = 0;
+ nColLock = 0;
+ nLine = 0;
+ nCol1 = 0;
+ nCol2 = 0;
+ nCol = 0;
+ bError =
+ bAbort =
+ bSpaces =
+ bNumber =
+ bSymbol =
+ bUsedForHilite =
+ bCompatible =
+ bVBASupportOn =
+ bPrevLineExtentsComment = FALSE;
+ bHash =
+ bErrors = TRUE;
+}
+
+SbiScanner::~SbiScanner()
+{}
+
+void SbiScanner::LockColumn()
+{
+ if( !nColLock++ )
+ nSavedCol1 = nCol1;
+}
+
+void SbiScanner::UnlockColumn()
+{
+ if( nColLock )
+ nColLock--;
+}
+
+void SbiScanner::GenError( SbError code )
+{
+ if( GetSbData()->bBlockCompilerError )
+ {
+ bAbort = TRUE;
+ return;
+ }
+ if( !bError && bErrors )
+ {
+ BOOL bRes = TRUE;
+ // Nur einen Fehler pro Statement reporten
+ bError = TRUE;
+ if( pBasic )
+ {
+ // Falls EXPECTED oder UNEXPECTED kommen sollte, bezieht es sich
+ // immer auf das letzte Token, also die Col1 uebernehmen
+ USHORT nc = nColLock ? nSavedCol1 : nCol1;
+ switch( code )
+ {
+ case SbERR_EXPECTED:
+ case SbERR_UNEXPECTED:
+ case SbERR_SYMBOL_EXPECTED:
+ case SbERR_LABEL_EXPECTED:
+ nc = nCol1;
+ if( nc > nCol2 ) nCol2 = nc;
+ break;
+ }
+ bRes = pBasic->CError( code, aError, nLine, nc, nCol2 );
+ }
+ bAbort |= !bRes |
+ ( code == SbERR_NO_MEMORY || code == SbERR_PROG_TOO_LARGE );
+ }
+ if( bErrors )
+ nErrors++;
+}
+
+// Falls sofort ein Doppelpunkt folgt, wird TRUE zurueckgeliefert.
+// Wird von SbiTokenizer::MayBeLabel() verwendet, um einen Label zu erkennen
+
+BOOL SbiScanner::DoesColonFollow()
+{
+ if( pLine && *pLine == ':' )
+ {
+ pLine++; nCol++; return TRUE;
+ }
+ else return FALSE;
+}
+
+// Testen auf ein legales Suffix
+
+static SbxDataType GetSuffixType( sal_Unicode c )
+{
+ static String aSuffixesStr = String::CreateFromAscii( "%&!#@ $" );
+ if( c )
+ {
+ sal_uInt32 n = aSuffixesStr.Search( c );
+ if( STRING_NOTFOUND != n && c != ' ' )
+ return SbxDataType( (USHORT) n + SbxINTEGER );
+ }
+ return SbxVARIANT;
+}
+
+// Einlesen des naechsten Symbols in die Variablen aSym, nVal und eType
+// Returnwert ist FALSE bei EOF oder Fehlern
+#define BUF_SIZE 80
+
+BOOL SbiScanner::NextSym()
+{
+ // Fuer den EOLN-Fall merken
+ USHORT nOldLine = nLine;
+ USHORT nOldCol1 = nCol1;
+ USHORT nOldCol2 = nCol2;
+ sal_Unicode buf[ BUF_SIZE ], *p = buf;
+ bHash = FALSE;
+
+ eScanType = SbxVARIANT;
+ aSym.Erase();
+ bSymbol =
+ bNumber = bSpaces = FALSE;
+
+ // Zeile einlesen?
+ if( !pLine )
+ {
+ INT32 n = nBufPos;
+ INT32 nLen = aBuf.getLength();
+ if( nBufPos >= nLen )
+ return FALSE;
+ const sal_Unicode* p2 = aBuf.getStr();
+ p2 += n;
+ while( ( n < nLen ) && ( *p2 != '\n' ) && ( *p2 != '\r' ) )
+ p2++, n++;
+ aLine = aBuf.copy( nBufPos, n - nBufPos );
+ if( n < nLen )
+ {
+ if( *p2 == '\r' && *( p2+1 ) == '\n' )
+ n += 2;
+ else
+ n++;
+ }
+ nBufPos = n;
+ pLine = aLine.getStr();
+ nOldLine = ++nLine;
+ nCol = nCol1 = nCol2 = nOldCol1 = nOldCol2 = 0;
+ nColLock = 0;
+ }
+
+ // Leerstellen weg:
+ while( *pLine && (( *pLine == ' ' ) || ( *pLine == '\t' ) || ( *pLine == '\f' )) )
+ pLine++, nCol++, bSpaces = TRUE;
+
+ nCol1 = nCol;
+
+ // nur Leerzeile?
+ if( !*pLine )
+ goto eoln;
+
+ if( bPrevLineExtentsComment )
+ goto PrevLineCommentLbl;
+
+ if( *pLine == '#' )
+ {
+ pLine++;
+ nCol++;
+ bHash = TRUE;
+ }
+
+ // Symbol? Dann Zeichen kopieren.
+ if( BasicSimpleCharClass::isAlpha( *pLine, bCompatible ) || *pLine == '_' )
+ {
+ // Wenn nach '_' nichts kommt, ist es ein Zeilenabschluss!
+ if( *pLine == '_' && !*(pLine+1) )
+ { pLine++;
+ goto eoln; }
+ bSymbol = TRUE;
+ short n = nCol;
+ for ( ; (BasicSimpleCharClass::isAlphaNumeric( *pLine, bCompatible ) || ( *pLine == '_' ) ); pLine++ )
+ nCol++;
+ aSym = aLine.copy( n, nCol - n );
+ // Abschliessendes '_' durch Space ersetzen, wenn Zeilenende folgt
+ // (sonst falsche Zeilenfortsetzung)
+ if( !bUsedForHilite && !*pLine && *(pLine-1) == '_' )
+ {
+ aSym.GetBufferAccess(); // #109693 force copy if necessary
+ *((sal_Unicode*)(pLine-1)) = ' '; // cast wegen const
+ }
+ // Typkennung?
+ // Das Ausrufezeichen bitte nicht testen, wenn
+ // danach noch ein Symbol anschliesst
+ else if( *pLine != '!' || !BasicSimpleCharClass::isAlpha( pLine[ 1 ], bCompatible ) )
+ {
+ SbxDataType t = GetSuffixType( *pLine );
+ if( t != SbxVARIANT )
+ {
+ eScanType = t;
+ pLine++;
+ nCol++;
+ }
+ }
+ }
+
+ // Zahl? Dann einlesen und konvertieren.
+ else if( BasicSimpleCharClass::isDigit( *pLine & 0xFF )
+ || ( *pLine == '.' && BasicSimpleCharClass::isDigit( *(pLine+1) & 0xFF ) ) )
+ {
+ short exp = 0;
+ short comma = 0;
+ short ndig = 0;
+ short ncdig = 0;
+ eScanType = SbxDOUBLE;
+ BOOL bBufOverflow = FALSE;
+ while( strchr( "0123456789.DEde", *pLine ) && *pLine )
+ {
+ // AB 4.1.1996: Buffer voll? -> leer weiter scannen
+ if( (p-buf) == (BUF_SIZE-1) )
+ {
+ bBufOverflow = TRUE;
+ pLine++, nCol++;
+ continue;
+ }
+ // Komma oder Exponent?
+ if( *pLine == '.' )
+ {
+ if( ++comma > 1 )
+ {
+ pLine++; nCol++; continue;
+ }
+ else *p++ = *pLine++, nCol++;
+ }
+ else if( strchr( "DdEe", *pLine ) )
+ {
+ if (++exp > 1)
+ {
+ pLine++; nCol++; continue;
+ }
+// if( toupper( *pLine ) == 'D' )
+// eScanType = SbxDOUBLE;
+ *p++ = 'E'; pLine++; nCol++;
+ // Vorzeichen hinter Exponent?
+ if( *pLine == '+' )
+ pLine++, nCol++;
+ else
+ if( *pLine == '-' )
+ *p++ = *pLine++, nCol++;
+ }
+ else
+ {
+ *p++ = *pLine++, nCol++;
+ if( comma && !exp ) ncdig++;
+ }
+ if (!exp) ndig++;
+ }
+ *p = 0;
+ aSym = p; bNumber = TRUE;
+ // Komma, Exponent mehrfach vorhanden?
+ if( comma > 1 || exp > 1 )
+ { aError = '.';
+ GenError( SbERR_BAD_CHAR_IN_NUMBER ); }
+
+ // #57844 Lokalisierte Funktion benutzen
+ nVal = rtl_math_uStringToDouble( buf, buf+(p-buf), '.', ',', NULL, NULL );
+ // ALT: nVal = atof( buf );
+
+ ndig = ndig - comma;
+ if( !comma && !exp )
+ {
+ if( nVal >= SbxMININT && nVal <= SbxMAXINT )
+ eScanType = SbxINTEGER;
+ else
+ if( nVal >= SbxMINLNG && nVal <= SbxMAXLNG )
+ eScanType = SbxLONG;
+ }
+ if( bBufOverflow )
+ GenError( SbERR_MATH_OVERFLOW );
+ // zu viele Zahlen fuer SINGLE?
+// if (ndig > 15 || ncdig > 6)
+// eScanType = SbxDOUBLE;
+// else
+// if( nVal > SbxMAXSNG || nVal < SbxMINSNG )
+// eScanType = SbxDOUBLE;
+
+ // Typkennung?
+ SbxDataType t = GetSuffixType( *pLine );
+ if( t != SbxVARIANT )
+ {
+ eScanType = t;
+ pLine++;
+ nCol++;
+ }
+ }
+
+ // Hex/Oktalzahl? Einlesen und konvertieren:
+ else if( *pLine == '&' )
+ {
+ pLine++; nCol++;
+ sal_Unicode cmp1[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', 0 };
+ sal_Unicode cmp2[] = { '0', '1', '2', '3', '4', '5', '6', '7', 0 };
+ sal_Unicode *cmp = cmp1;
+ //char *cmp = "0123456789ABCDEF";
+ sal_Unicode base = 16;
+ sal_Unicode ndig = 8;
+ sal_Unicode xch = *pLine++ & 0xFF; nCol++;
+ switch( toupper( xch ) )
+ {
+ case 'O':
+ cmp = cmp2; base = 8; ndig = 11; break;
+ //cmp = "01234567"; base = 8; ndig = 11; break;
+ case 'H':
+ break;
+ default :
+ // Wird als Operator angesehen
+ pLine--; nCol--; nCol1 = nCol-1; aSym = '&'; return SYMBOL;
+ }
+ bNumber = TRUE;
+ long l = 0;
+ int i;
+ BOOL bBufOverflow = FALSE;
+ while( BasicSimpleCharClass::isAlphaNumeric( *pLine & 0xFF, bCompatible ) )
+ {
+ sal_Unicode ch = sal::static_int_cast< sal_Unicode >(
+ toupper( *pLine & 0xFF ) );
+ pLine++; nCol++;
+ // AB 4.1.1996: Buffer voll, leer weiter scannen
+ if( (p-buf) == (BUF_SIZE-1) )
+ bBufOverflow = TRUE;
+ else if( String( cmp ).Search( ch ) != STRING_NOTFOUND )
+ //else if( strchr( cmp, ch ) )
+ *p++ = ch;
+ else
+ {
+ aError = ch;
+ GenError( SbERR_BAD_CHAR_IN_NUMBER );
+ }
+ }
+ *p = 0;
+ for( p = buf; *p; p++ )
+ {
+ i = (*p & 0xFF) - '0';
+ if( i > 9 ) i -= 7;
+ l = ( l * base ) + i;
+ if( !ndig-- )
+ {
+ GenError( SbERR_MATH_OVERFLOW ); break;
+ }
+ }
+ if( *pLine == '&' ) pLine++, nCol++;
+ nVal = (double) l;
+ eScanType = ( l >= SbxMININT && l <= SbxMAXINT ) ? SbxINTEGER : SbxLONG;
+ if( bBufOverflow )
+ GenError( SbERR_MATH_OVERFLOW );
+ }
+
+ // Strings:
+ else if( *pLine == '"' || *pLine == '[' )
+ {
+ sal_Unicode cSep = *pLine;
+ if( cSep == '[' )
+ bSymbol = TRUE, cSep = ']';
+ short n = nCol+1;
+ while( *pLine )
+ {
+ do pLine++, nCol++;
+ while( *pLine && ( *pLine != cSep ) );
+ if( *pLine == cSep )
+ {
+ pLine++; nCol++;
+ if( *pLine != cSep || cSep == ']' ) break;
+ } else aError = cSep, GenError( SbERR_EXPECTED );
+ }
+ // If VBA Interop then doen't eat the [] chars
+ if ( cSep == ']' && bVBASupportOn )
+ aSym = aLine.copy( n - 1, nCol - n + 1);
+ else
+ aSym = aLine.copy( n, nCol - n - 1 );
+ // Doppelte Stringbegrenzer raus
+ String s( cSep );
+ s += cSep;
+ USHORT nIdx = 0;
+ do
+ {
+ nIdx = aSym.Search( s, nIdx );
+ if( nIdx == STRING_NOTFOUND )
+ break;
+ aSym.Erase( nIdx, 1 );
+ nIdx++;
+ }
+ while( true );
+ if( cSep != ']' )
+ eScanType = ( cSep == '#' ) ? SbxDATE : SbxSTRING;
+ }
+ // ungueltige Zeichen:
+ else if( ( *pLine & 0xFF ) >= 0x7F )
+ {
+ GenError( SbERR_SYNTAX ); pLine++; nCol++;
+ }
+ // andere Gruppen:
+ else
+ {
+ short n = 1;
+ switch( *pLine++ )
+ {
+ case '<': if( *pLine == '>' || *pLine == '=' ) n = 2; break;
+ case '>': if( *pLine == '=' ) n = 2; break;
+ case ':': if( *pLine == '=' ) n = 2; break;
+ }
+ aSym = aLine.copy( nCol, n );
+ pLine += n-1; nCol = nCol + n;
+ }
+
+ nCol2 = nCol-1;
+
+PrevLineCommentLbl:
+ // Kommentar?
+ if( bPrevLineExtentsComment || (eScanType != SbxSTRING &&
+ ( aSym.GetBuffer()[0] == '\'' || aSym.EqualsIgnoreCaseAscii( "REM" ) ) ) )
+ {
+ bPrevLineExtentsComment = FALSE;
+ aSym = String::CreateFromAscii( "REM" );
+ USHORT nLen = String( pLine ).Len();
+ if( bCompatible && pLine[ nLen - 1 ] == '_' && pLine[ nLen - 2 ] == ' ' )
+ bPrevLineExtentsComment = TRUE;
+ nCol2 = nCol2 + nLen;
+ pLine = NULL;
+ }
+ return TRUE;
+
+ // Sonst Zeilen-Ende: aber bitte auf '_' testen, ob die
+ // Zeile nicht weitergeht!
+eoln:
+ if( nCol && *--pLine == '_' )
+ {
+ pLine = NULL;
+ bool bRes = NextSym();
+ if( bVBASupportOn && aSym.GetBuffer()[0] == '.' )
+ {
+ // object _
+ // .Method
+ // ^^^ <- spaces is legal in MSO VBA
+ OSL_TRACE("*** resetting bSpaces***");
+ bSpaces = FALSE;
+ }
+ return bRes;
+ }
+ else
+ {
+ pLine = NULL;
+ nLine = nOldLine;
+ nCol1 = nOldCol1;
+ nCol2 = nOldCol2;
+ aSym = '\n';
+ nColLock = 0;
+ return TRUE;
+ }
+}
+
+LetterTable BasicSimpleCharClass::aLetterTable;
+
+LetterTable::LetterTable( void )
+{
+ for( int i = 0 ; i < 256 ; ++i )
+ IsLetterTab[i] = false;
+
+ IsLetterTab[0xC0] = true; // À , CAPITAL LETTER A WITH GRAVE ACCENT
+ IsLetterTab[0xC1] = true; // Á , CAPITAL LETTER A WITH ACUTE ACCENT
+ IsLetterTab[0xC2] = true; // Â , CAPITAL LETTER A WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xC3] = true; // Ã , CAPITAL LETTER A WITH TILDE
+ IsLetterTab[0xC4] = true; // Ä , CAPITAL LETTER A WITH DIAERESIS
+ IsLetterTab[0xC5] = true; // Å , CAPITAL LETTER A WITH RING ABOVE
+ IsLetterTab[0xC6] = true; // Æ , CAPITAL LIGATURE AE
+ IsLetterTab[0xC7] = true; // Ç , CAPITAL LETTER C WITH CEDILLA
+ IsLetterTab[0xC8] = true; // È , CAPITAL LETTER E WITH GRAVE ACCENT
+ IsLetterTab[0xC9] = true; // É , CAPITAL LETTER E WITH ACUTE ACCENT
+ IsLetterTab[0xCA] = true; // Ê , CAPITAL LETTER E WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xCB] = true; // Ë , CAPITAL LETTER E WITH DIAERESIS
+ IsLetterTab[0xCC] = true; // Ì , CAPITAL LETTER I WITH GRAVE ACCENT
+ IsLetterTab[0xCD] = true; // Í , CAPITAL LETTER I WITH ACUTE ACCENT
+ IsLetterTab[0xCE] = true; // Î , CAPITAL LETTER I WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xCF] = true; // Ï , CAPITAL LETTER I WITH DIAERESIS
+ IsLetterTab[0xD0] = true; // Ð , CAPITAL LETTER ETH
+ IsLetterTab[0xD1] = true; // Ñ , CAPITAL LETTER N WITH TILDE
+ IsLetterTab[0xD2] = true; // Ò , CAPITAL LETTER O WITH GRAVE ACCENT
+ IsLetterTab[0xD3] = true; // Ó , CAPITAL LETTER O WITH ACUTE ACCENT
+ IsLetterTab[0xD4] = true; // Ô , CAPITAL LETTER O WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xD5] = true; // Õ , CAPITAL LETTER O WITH TILDE
+ IsLetterTab[0xD6] = true; // Ö , CAPITAL LETTER O WITH DIAERESIS
+ IsLetterTab[0xD8] = true; // Ø , CAPITAL LETTER O WITH STROKE
+ IsLetterTab[0xD9] = true; // Ù , CAPITAL LETTER U WITH GRAVE ACCENT
+ IsLetterTab[0xDA] = true; // Ú , CAPITAL LETTER U WITH ACUTE ACCENT
+ IsLetterTab[0xDB] = true; // Û , CAPITAL LETTER U WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xDC] = true; // Ü , CAPITAL LETTER U WITH DIAERESIS
+ IsLetterTab[0xDD] = true; // Ý , CAPITAL LETTER Y WITH ACUTE ACCENT
+ IsLetterTab[0xDE] = true; // Þ , CAPITAL LETTER THORN
+ IsLetterTab[0xDF] = true; // ß , SMALL LETTER SHARP S
+ IsLetterTab[0xE0] = true; // à , SMALL LETTER A WITH GRAVE ACCENT
+ IsLetterTab[0xE1] = true; // á , SMALL LETTER A WITH ACUTE ACCENT
+ IsLetterTab[0xE2] = true; // â , SMALL LETTER A WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xE3] = true; // ã , SMALL LETTER A WITH TILDE
+ IsLetterTab[0xE4] = true; // ä , SMALL LETTER A WITH DIAERESIS
+ IsLetterTab[0xE5] = true; // å , SMALL LETTER A WITH RING ABOVE
+ IsLetterTab[0xE6] = true; // æ , SMALL LIGATURE AE
+ IsLetterTab[0xE7] = true; // ç , SMALL LETTER C WITH CEDILLA
+ IsLetterTab[0xE8] = true; // è , SMALL LETTER E WITH GRAVE ACCENT
+ IsLetterTab[0xE9] = true; // é , SMALL LETTER E WITH ACUTE ACCENT
+ IsLetterTab[0xEA] = true; // ê , SMALL LETTER E WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xEB] = true; // ë , SMALL LETTER E WITH DIAERESIS
+ IsLetterTab[0xEC] = true; // ì , SMALL LETTER I WITH GRAVE ACCENT
+ IsLetterTab[0xED] = true; // í , SMALL LETTER I WITH ACUTE ACCENT
+ IsLetterTab[0xEE] = true; // î , SMALL LETTER I WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xEF] = true; // ï , SMALL LETTER I WITH DIAERESIS
+ IsLetterTab[0xF0] = true; // ð , SMALL LETTER ETH
+ IsLetterTab[0xF1] = true; // ñ , SMALL LETTER N WITH TILDE
+ IsLetterTab[0xF2] = true; // ò , SMALL LETTER O WITH GRAVE ACCENT
+ IsLetterTab[0xF3] = true; // ó , SMALL LETTER O WITH ACUTE ACCENT
+ IsLetterTab[0xF4] = true; // ô , SMALL LETTER O WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xF5] = true; // õ , SMALL LETTER O WITH TILDE
+ IsLetterTab[0xF6] = true; // ö , SMALL LETTER O WITH DIAERESIS
+ IsLetterTab[0xF8] = true; // ø , SMALL LETTER O WITH OBLIQUE BAR
+ IsLetterTab[0xF9] = true; // ù , SMALL LETTER U WITH GRAVE ACCENT
+ IsLetterTab[0xFA] = true; // ú , SMALL LETTER U WITH ACUTE ACCENT
+ IsLetterTab[0xFB] = true; // û , SMALL LETTER U WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xFC] = true; // ü , SMALL LETTER U WITH DIAERESIS
+ IsLetterTab[0xFD] = true; // ý , SMALL LETTER Y WITH ACUTE ACCENT
+ IsLetterTab[0xFE] = true; // þ , SMALL LETTER THORN
+ IsLetterTab[0xFF] = true; // ÿ , SMALL LETTER Y WITH DIAERESIS
+}
+
+bool LetterTable::isLetterUnicode( sal_Unicode c )
+{
+ static CharClass* pCharClass = NULL;
+ if( pCharClass == NULL )
+ pCharClass = new CharClass( Application::GetSettings().GetLocale() );
+ String aStr( c );
+ bool bRet = pCharClass->isLetter( aStr, 0 );
+ return bRet;
+}
diff --git a/basic/source/comp/symtbl.cxx b/basic/source/comp/symtbl.cxx
new file mode 100644
index 000000000000..d6b3dbb878fc
--- /dev/null
+++ b/basic/source/comp/symtbl.cxx
@@ -0,0 +1,536 @@
+/*************************************************************************
+ *
+ * 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 "sbcomp.hxx"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+SV_IMPL_PTRARR(SbiStrings,String*)
+SV_IMPL_PTRARR(SbiSymbols,SbiSymDef*)
+
+// Alle Symbolnamen werden im Stringpool des Symbol-Pools abgelegt, damit
+// alle Symbole im gleichen Case verarbeitet werden. Beim Speichern des
+// Code-Images wird der globale Stringpool mit den entsprechenden Sympools
+// gespeichert. Der lokale Stringpool nimmt alle Symbole auf, die nicht
+// ins Image wandern (Labels, Konstantennamen etc).
+
+/***************************************************************************
+|*
+|* SbiStringPool
+|*
+***************************************************************************/
+
+SbiStringPool::SbiStringPool( SbiParser* p )
+{
+ pParser = p;
+}
+
+SbiStringPool::~SbiStringPool()
+{}
+
+// Suchen
+
+const String& SbiStringPool::Find( USHORT n ) const
+{
+ if( !n || n > aData.Count() )
+ return aEmpty;
+ else
+ return *aData.GetObject( n-1 );
+}
+
+// Hinzufuegen eines Strings. Der String wird Case-Insensitiv
+// verglichen.
+
+short SbiStringPool::Add( const String& rVal, BOOL bNoCase )
+{
+ USHORT n = aData.Count();
+ for( USHORT i = 0; i < n; i++ )
+ {
+ String* p = aData.GetObject( i );
+ if( ( bNoCase && p->Equals( rVal ) )
+ || ( !bNoCase && p->EqualsIgnoreCaseAscii( rVal ) ) )
+ return i+1;
+ }
+ const String* pNew = new String( rVal );
+ aData.Insert( pNew, n++ );
+ return (short) n;
+}
+
+short SbiStringPool::Add( double n, SbxDataType t )
+{
+ char buf[ 40 ];
+ switch( t )
+ {
+ case SbxINTEGER: snprintf( buf, sizeof(buf), "%d", (short) n ); break;
+ case SbxLONG: snprintf( buf, sizeof(buf), "%ld", (long) n ); break;
+ case SbxSINGLE: snprintf( buf, sizeof(buf), "%.6g", (float) n ); break;
+ case SbxDOUBLE: snprintf( buf, sizeof(buf), "%.16g", n ); break;
+ default: break;
+ }
+ return Add( String::CreateFromAscii( buf ) );
+}
+
+/***************************************************************************
+|*
+|* SbiSymPool
+|*
+***************************************************************************/
+
+SbiSymPool::SbiSymPool( SbiStringPool& r, SbiSymScope s ) : rStrings( r )
+{
+ pParser = r.GetParser();
+ eScope = s;
+ pParent = NULL;
+ nCur =
+ nProcId = 0;
+}
+
+SbiSymPool::~SbiSymPool()
+{}
+
+// Inhalt loeschen
+
+void SbiSymPool::Clear()
+{
+ aData.DeleteAndDestroy( 0, aData.Count() );
+}
+
+SbiSymDef* SbiSymPool::First()
+{
+ nCur = (USHORT) -1;
+ return Next();
+}
+
+SbiSymDef* SbiSymPool::Next()
+{
+ if( ++nCur >= aData.Count() )
+ return NULL;
+ else
+ return aData.GetObject( nCur );
+}
+
+// Hinzufuegen eines Symbols
+
+SbiSymDef* SbiSymPool::AddSym( const String& rName )
+{
+ SbiSymDef* p = new SbiSymDef( rName );
+ p->nPos = aData.Count();
+ p->nId = rStrings.Add( rName );
+ p->nProcId = nProcId;
+ p->pIn = this;
+ const SbiSymDef* q = p;
+ aData.Insert( q, q->nPos );
+ return p;
+}
+
+SbiProcDef* SbiSymPool::AddProc( const String& rName )
+{
+ SbiProcDef* p = new SbiProcDef( pParser, rName );
+ p->nPos = aData.Count();
+ p->nId = rStrings.Add( rName );
+ // Procs sind immer global
+ p->nProcId = 0;
+ p->pIn = this;
+ const SbiSymDef* q = p;
+ aData.Insert( q, q->nPos );
+ return p;
+}
+
+// Hinzufuegen einer extern aufgebauten Symboldefinition
+
+void SbiSymPool::Add( SbiSymDef* pDef )
+{
+ if( pDef && pDef->pIn != this )
+ {
+ if( pDef->pIn )
+ {
+#ifdef DBG_UTIL
+ // schon in einem anderen Pool drin!
+ pParser->Error( SbERR_INTERNAL_ERROR, "Dbl Pool" );
+#endif
+ return;
+ }
+
+ pDef->nPos = aData.Count();
+ if( !pDef->nId )
+ {
+ // Bei statischen Variablen muss ein eindeutiger Name
+ // im Stringpool erzeugt werden (Form ProcName:VarName)
+ String aName( pDef->aName );
+ if( pDef->IsStatic() )
+ {
+ aName = pParser->aGblStrings.Find( nProcId );
+ aName += ':';
+ aName += pDef->aName;
+ }
+ pDef->nId = rStrings.Add( aName );
+ }
+ // Procs sind immer global
+ if( !pDef->GetProcDef() )
+ pDef->nProcId = nProcId;
+ pDef->pIn = this;
+ const SbiSymDef* q = pDef;
+ aData.Insert( q, q->nPos );
+ }
+}
+
+// Suchen eines Eintrags ueber den Namen. Es wird auch im Parent gesucht.
+
+SbiSymDef* SbiSymPool::Find( const String& rName ) const
+{
+ for( USHORT i = 0; i < aData.Count(); i++ )
+ {
+ SbiSymDef* p = aData.GetObject( i );
+ if( ( !p->nProcId || ( p->nProcId == nProcId ) )
+ && ( p->aName.EqualsIgnoreCaseAscii( rName ) ) )
+ return p;
+ }
+ if( pParent )
+ return pParent->Find( rName );
+ else
+ return NULL;
+}
+
+// Suchen ueber ID-Nummer
+
+SbiSymDef* SbiSymPool::FindId( USHORT n ) const
+{
+ for( USHORT i = 0; i < aData.Count(); i++ )
+ {
+ SbiSymDef* p = aData.GetObject( i );
+ if( p->nId == n && ( !p->nProcId || ( p->nProcId == nProcId ) ) )
+ return p;
+ }
+ if( pParent )
+ return pParent->FindId( n );
+ else
+ return NULL;
+}
+
+// Suchen ueber Position (ab 0)
+
+SbiSymDef* SbiSymPool::Get( USHORT n ) const
+{
+ if( n >= aData.Count() )
+ return NULL;
+ else
+ return aData.GetObject( n );
+}
+
+UINT32 SbiSymPool::Define( const String& rName )
+{
+ SbiSymDef* p = Find( rName );
+ if( p )
+ { if( p->IsDefined() )
+ pParser->Error( SbERR_LABEL_DEFINED, rName );
+ }
+ else
+ p = AddSym( rName );
+ return p->Define();
+}
+
+UINT32 SbiSymPool::Reference( const String& rName )
+{
+ SbiSymDef* p = Find( rName );
+ if( !p )
+ p = AddSym( rName );
+ //Sicherheitshalber
+ pParser->aGen.GenStmnt();
+ return p->Reference();
+}
+
+// Alle offenen Referenzen anmaulen
+
+void SbiSymPool::CheckRefs()
+{
+ for( USHORT i = 0; i < aData.Count(); i++ )
+ {
+ SbiSymDef* p = aData.GetObject( i );
+ if( !p->IsDefined() )
+ pParser->Error( SbERR_UNDEF_LABEL, p->GetName() );
+ }
+}
+
+/***************************************************************************
+|*
+|* Symbol-Definitionen
+|*
+***************************************************************************/
+
+SbiSymDef::SbiSymDef( const String& rName ) : aName( rName )
+{
+ eType = SbxEMPTY;
+ nDims = 0;
+ nTypeId = 0;
+ nProcId = 0;
+ nId = 0;
+ nPos = 0;
+ nLen = 0;
+ nChain = 0;
+ bAs =
+ bNew =
+ bStatic =
+ bOpt =
+ bParamArray =
+ bWithEvents =
+ bByVal =
+ bChained =
+ bGlobal = FALSE;
+ pIn =
+ pPool = NULL;
+ nDefaultId = 0;
+ nFixedStringLength = -1;
+}
+
+SbiSymDef::~SbiSymDef()
+{
+ delete pPool;
+}
+
+SbiProcDef* SbiSymDef::GetProcDef()
+{
+ return NULL;
+}
+
+SbiConstDef* SbiSymDef::GetConstDef()
+{
+ return NULL;
+}
+
+// Wenn der Name benoetigt wird, den aktuellen Namen
+// aus dem Stringpool nehmen
+
+const String& SbiSymDef::GetName()
+{
+ if( pIn )
+ aName = pIn->rStrings.Find( nId );
+ return aName;
+}
+
+// Eintragen eines Datentyps
+
+void SbiSymDef::SetType( SbxDataType t )
+{
+ if( t == SbxVARIANT && pIn )
+ {
+ sal_Unicode cu = aName.GetBuffer()[0];
+ if( cu < 256 )
+ {
+ char ch = (char)aName.GetBuffer()[0];
+ if( ch == '_' ) ch = 'Z';
+ int ch2 = toupper( ch );
+ unsigned char c = (unsigned char)ch2;
+ if( c > 0 && c < 128 )
+ t = pIn->pParser->eDefTypes[ ch2 - 'A' ];
+ }
+ }
+ eType = t;
+}
+
+// Aufbau einer Backchain, falls noch nicht definiert
+// Es wird der Wert zurueckgeliefert, der als Operand gespeichert
+// werden soll.
+
+UINT32 SbiSymDef::Reference()
+{
+ if( !bChained )
+ {
+ UINT32 n = nChain;
+ nChain = pIn->pParser->aGen.GetOffset();
+ return n;
+ }
+ else return nChain;
+}
+
+// Definition eines Symbols.
+// Hier wird der Backchain aufgeloest, falls vorhanden
+
+UINT32 SbiSymDef::Define()
+{
+ UINT32 n = pIn->pParser->aGen.GetPC();
+ pIn->pParser->aGen.GenStmnt();
+ if( nChain ) pIn->pParser->aGen.BackChain( nChain );
+ nChain = n;
+ bChained = TRUE;
+ return nChain;
+}
+
+// Eine Symboldefinition kann einen eigenen Pool haben. Dies ist
+// der Fall bei Objekten und Prozeduren (lokale Variable)
+
+SbiSymPool& SbiSymDef::GetPool()
+{
+ if( !pPool )
+ pPool = new SbiSymPool( pIn->pParser->aGblStrings, SbLOCAL ); // wird gedumpt
+ return *pPool;
+}
+
+SbiSymScope SbiSymDef::GetScope() const
+{
+ return pIn ? pIn->GetScope() : SbLOCAL;
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+// Die Prozedur-Definition hat drei Pools:
+// 1) aParams: wird durch die Definition gefuellt. Enthaelt die Namen
+// der Parameter, wie sie innerhalb des Rumpfes verwendet werden.
+// Das erste Element ist der Returnwert.
+// 2) pPool: saemtliche lokale Variable
+// 3) aLabels: Labels
+
+SbiProcDef::SbiProcDef( SbiParser* pParser, const String& rName,
+ BOOL bProcDecl )
+ : SbiSymDef( rName )
+ , aParams( pParser->aGblStrings, SbPARAM ) // wird gedumpt
+ , aLabels( pParser->aLclStrings, SbLOCAL ) // wird nicht gedumpt
+ , mbProcDecl( bProcDecl )
+{
+ aParams.SetParent( &pParser->aPublics );
+ pPool = new SbiSymPool( pParser->aGblStrings, SbLOCAL ); // Locals
+ pPool->SetParent( &aParams );
+ nLine1 =
+ nLine2 = 0;
+ mePropMode = PROPERTY_MODE_NONE;
+ bPublic = TRUE;
+ bCdecl = FALSE;
+ bStatic = FALSE;
+ // Fuer Returnwerte ist das erste Element der Parameterliste
+ // immer mit dem Namen und dem Typ der Proc definiert
+ aParams.AddSym( aName );
+}
+
+SbiProcDef::~SbiProcDef()
+{}
+
+SbiProcDef* SbiProcDef::GetProcDef()
+{
+ return this;
+}
+
+void SbiProcDef::SetType( SbxDataType t )
+{
+ SbiSymDef::SetType( t );
+ aParams.Get( 0 )->SetType( eType );
+}
+
+// Match mit einer Forward-Deklaration
+// Falls der Match OK ist, wird pOld durch this im Pool ersetzt
+// pOld wird immer geloescht!
+
+void SbiProcDef::Match( SbiProcDef* pOld )
+{
+ SbiSymDef* po, *pn=NULL;
+ // Parameter 0 ist der Funktionsname
+ USHORT i;
+ for( i = 1; i < aParams.GetSize(); i++ )
+ {
+ po = pOld->aParams.Get( i );
+ pn = aParams.Get( i );
+ // Kein Typabgleich; das wird beim Laufen erledigt
+ // aber ist sie evtl. mit zu wenigen Parametern aufgerufen
+ // worden?
+ if( !po && !pn->IsOptional() && !pn->IsParamArray() )
+ break;
+ po = pOld->aParams.Next();
+ }
+ // Wurden zu viele Parameter angegeben?
+ if( pn && i < aParams.GetSize() && pOld->pIn )
+ {
+ // Die ganze Zeile markieren
+ pOld->pIn->GetParser()->SetCol1( 0 );
+ pOld->pIn->GetParser()->Error( SbERR_BAD_DECLARATION, aName );
+ }
+ if( !pIn && pOld->pIn )
+ {
+ // Alten Eintrag durch neuen ersetzen
+ SbiSymDef** pData = (SbiSymDef**) pOld->pIn->aData.GetData();
+ pData[ pOld->nPos ] = this;
+ nPos = pOld->nPos;
+ nId = pOld->nId;
+ pIn = pOld->pIn;
+ }
+ delete pOld;
+}
+
+void SbiProcDef::setPropertyMode( PropertyMode ePropMode )
+{
+ mePropMode = ePropMode;
+ if( mePropMode != PROPERTY_MODE_NONE )
+ {
+ // Prop name = original scanned procedure name
+ maPropName = aName;
+
+ // CompleteProcName includes "Property xxx "
+ // to avoid conflicts with other symbols
+ String aCompleteProcName;
+ aCompleteProcName.AppendAscii( "Property " );
+ switch( mePropMode )
+ {
+ case PROPERTY_MODE_GET: aCompleteProcName.AppendAscii( "Get " ); break;
+ case PROPERTY_MODE_LET: aCompleteProcName.AppendAscii( "Let " ); break;
+ case PROPERTY_MODE_SET: aCompleteProcName.AppendAscii( "Set " ); break;
+ case PROPERTY_MODE_NONE:
+ DBG_ERROR( "Illegal PropertyMode PROPERTY_MODE_NONE" );
+ break;
+ }
+ aCompleteProcName += aName;
+ aName = aCompleteProcName;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+
+SbiConstDef::SbiConstDef( const String& rName )
+ : SbiSymDef( rName )
+{
+ nVal = 0; eType = SbxINTEGER;
+}
+
+void SbiConstDef::Set( double n, SbxDataType t )
+{
+ aVal.Erase(); nVal = n; eType = t;
+}
+
+void SbiConstDef::Set( const String& n )
+{
+ aVal = n; nVal = 0; eType = SbxSTRING;
+}
+
+SbiConstDef::~SbiConstDef()
+{}
+
+SbiConstDef* SbiConstDef::GetConstDef()
+{
+ return this;
+}
+
diff --git a/basic/source/comp/token.cxx b/basic/source/comp/token.cxx
new file mode 100644
index 000000000000..8cb3126f03f1
--- /dev/null
+++ b/basic/source/comp/token.cxx
@@ -0,0 +1,714 @@
+/*************************************************************************
+ *
+ * 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 <ctype.h>
+#include "sbcomp.hxx"
+
+struct TokenTable { SbiToken t; const char *s; };
+
+static short nToken; // Anzahl der Tokens
+
+static TokenTable* pTokTable;
+
+static TokenTable aTokTable_Basic [] = { // Token-Tabelle:
+
+ { CAT, "&" },
+ { MUL, "*" },
+ { PLUS, "+" },
+ { MINUS, "-" },
+ { DIV, "/" },
+ { EOS, ":" },
+ { ASSIGN, ":=" },
+ { LT, "<" },
+ { LE, "<=" },
+ { NE, "<>" },
+ { EQ, "=" },
+ { GT, ">" },
+ { GE, ">=" },
+ { ACCESS, "Access" },
+ { ALIAS, "Alias" },
+ { AND, "And" },
+ { ANY, "Any" },
+ { APPEND, "Append" },
+ { AS, "As" },
+ { BASE, "Base" },
+ { BINARY, "Binary" },
+ { TBOOLEAN, "Boolean" },
+ { BYREF, "ByRef", },
+ { TBYTE, "Byte", },
+ { BYVAL, "ByVal", },
+ { CALL, "Call" },
+ { CASE, "Case" },
+ { _CDECL_, "Cdecl" },
+ { CLASSMODULE, "ClassModule" },
+ { CLOSE, "Close" },
+ { COMPARE, "Compare" },
+ { COMPATIBLE,"Compatible" },
+ { _CONST_, "Const" },
+ { TCURRENCY,"Currency" },
+ { TDATE, "Date" },
+ { DECLARE, "Declare" },
+ { DEFBOOL, "DefBool" },
+ { DEFCUR, "DefCur" },
+ { DEFDATE, "DefDate" },
+ { DEFDBL, "DefDbl" },
+ { DEFERR, "DefErr" },
+ { DEFINT, "DefInt" },
+ { DEFLNG, "DefLng" },
+ { DEFOBJ, "DefObj" },
+ { DEFSNG, "DefSng" },
+ { DEFSTR, "DefStr" },
+ { DEFVAR, "DefVar" },
+ { DIM, "Dim" },
+ { DO, "Do" },
+ { TDOUBLE, "Double" },
+ { EACH, "Each" },
+ { ELSE, "Else" },
+ { ELSEIF, "ElseIf" },
+ { END, "End" },
+ { ENDENUM, "End Enum" },
+ { ENDFUNC, "End Function" },
+ { ENDIF, "End If" },
+ { ENDPROPERTY, "End Property" },
+ { ENDSELECT,"End Select" },
+ { ENDSUB, "End Sub" },
+ { ENDTYPE, "End Type" },
+ { ENDIF, "EndIf" },
+ { ENUM, "Enum" },
+ { EQV, "Eqv" },
+ { ERASE, "Erase" },
+ { _ERROR_, "Error" },
+ { EXIT, "Exit" },
+ { EXPLICIT, "Explicit" },
+ { FOR, "For" },
+ { FUNCTION, "Function" },
+ { GET, "Get" },
+ { GLOBAL, "Global" },
+ { GOSUB, "GoSub" },
+ { GOTO, "GoTo" },
+ { IF, "If" },
+ { IMP, "Imp" },
+ { IMPLEMENTS, "Implements" },
+ { _IN_, "In" },
+ { INPUT, "Input" }, // auch INPUT #
+ { TINTEGER, "Integer" },
+ { IS, "Is" },
+ { LET, "Let" },
+ { LIB, "Lib" },
+ { LIKE, "Like" },
+ { LINE, "Line" },
+ { LINEINPUT,"Line Input" },
+ { LOCAL, "Local" },
+ { LOCK, "Lock" },
+ { TLONG, "Long" },
+ { LOOP, "Loop" },
+ { LPRINT, "LPrint" },
+ { LSET, "LSet" }, // JSM
+ { MOD, "Mod" },
+ { NAME, "Name" },
+ { NEW, "New" },
+ { NEXT, "Next" },
+ { NOT, "Not" },
+ { TOBJECT, "Object" },
+ { ON, "On" },
+ { OPEN, "Open" },
+ { OPTION, "Option" },
+ { _OPTIONAL_, "Optional" },
+ { OR, "Or" },
+ { OUTPUT, "Output" },
+ { PARAMARRAY, "ParamArray" },
+ { PRESERVE, "Preserve" },
+ { PRINT, "Print" },
+ { PRIVATE, "Private" },
+ { PROPERTY, "Property" },
+ { PUBLIC, "Public" },
+ { RANDOM, "Random" },
+ { READ, "Read" },
+ { REDIM, "ReDim" },
+ { REM, "Rem" },
+ { RESUME, "Resume" },
+ { RETURN, "Return" },
+ { RSET, "RSet" }, // JSM
+ { SELECT, "Select" },
+ { SET, "Set" },
+#ifdef SHARED
+#undef SHARED
+#define tmpSHARED
+#endif
+ { SHARED, "Shared" },
+#ifdef tmpSHARED
+#define SHARED
+#undef tmpSHARED
+#endif
+ { TSINGLE, "Single" },
+ { STATIC, "Static" },
+ { STEP, "Step" },
+ { STOP, "Stop" },
+ { TSTRING, "String" },
+ { SUB, "Sub" },
+ { STOP, "System" },
+ { TEXT, "Text" },
+ { THEN, "Then" },
+ { TO, "To", },
+ { TYPE, "Type" },
+ { TYPEOF, "TypeOf" },
+ { UNTIL, "Until" },
+ { TVARIANT, "Variant" },
+ { VBASUPPORT, "VbaSupport" },
+ { WEND, "Wend" },
+ { WHILE, "While" },
+ { WITH, "With" },
+ { WITHEVENTS, "WithEvents" },
+ { WRITE, "Write" }, // auch WRITE #
+ { XOR, "Xor" },
+ { NIL, "" }
+};
+
+/*
+TokenTable aTokTable_Java [] = { // Token-Tabelle:
+
+ { JS_LOG_NOT, "!" },
+ { JS_NE, "!=" },
+ { JS_MOD, "%" },
+ { JS_ASS_MOD, "%=" },
+ { JS_BIT_AND, "&" },
+ { JS_LOG_AND, "&&" },
+ { JS_ASS_AND, "&=" },
+ { JS_LPAREN, "(" },
+ { JS_RPAREN, ")" },
+ { JS_MUL, "*" },
+ { JS_ASS_MUL, "*=" },
+ { JS_PLUS, "+" },
+ { JS_INC, "++" },
+ { JS_ASS_PLUS, "+=" },
+ { JS_COMMA, "," },
+ { JS_MINUS, "-" },
+ { JS_DEC, "--" },
+ { JS_ASS_MINUS, "-=" },
+ { JS_DIV, "/" },
+ { JS_ASS_DIV, "/=" },
+ { JS_COND_SEL, ":" },
+ { JS_LT, "<" },
+ { JS_LSHIFT, "<<" },
+ { JS_ASS_LSHIFT,"<<=" },
+ { JS_LE, "<=" },
+ { JS_NE, "<>" },
+ { JS_ASSIGNMENT,"=" },
+ { JS_EQ, "==" },
+ { JS_GT, ">" },
+ { JS_RSHIFT, ">>" },
+ { JS_ASS_RSHIFT,">>=" },
+ { JS_RSHIFT_Z, ">>>" },
+ { JS_ASS_RSHIFT_Z,">>>=" },
+ { JS_GE, ">=" },
+ { JS_COND_QUEST,"?" },
+ { ACCESS, "Access" },
+ { ALIAS, "Alias" },
+ { AND, "And" },
+ { ANY, "Any" },
+ { APPEND, "Append" },
+ { AS, "As" },
+ { BASE, "Base" },
+ { BINARY, "Binary" },
+ { TBOOLEAN, "Boolean" },
+ { BYVAL, "ByVal", },
+ { CALL, "Call" },
+ { CASE, "Case" },
+ { _CDECL_, "Cdecl" },
+ { CLOSE, "Close" },
+ { COMPARE, "Compare" },
+ { _CONST_, "Const" },
+ { TCURRENCY,"Currency" },
+ { TDATE, "Date" },
+ { DECLARE, "Declare" },
+ { DEFBOOL, "DefBool" },
+ { DEFCUR, "DefCur" },
+ { DEFDATE, "DefDate" },
+ { DEFDBL, "DefDbl" },
+ { DEFERR, "DefErr" },
+ { DEFINT, "DefInt" },
+ { DEFLNG, "DefLng" },
+ { DEFOBJ, "DefObj" },
+ { DEFSNG, "DefSng" },
+ { DEFSTR, "DefStr" },
+ { DEFVAR, "DefVar" },
+ { DIM, "Dim" },
+ { DO, "Do" },
+ { TDOUBLE, "Double" },
+ { EACH, "Each" },
+ { ELSE, "Else" },
+ { ELSEIF, "ElseIf" },
+ { END, "End" },
+ { ENDFUNC, "End Function" },
+ { ENDIF, "End If" },
+ { ENDSELECT,"End Select" },
+ { ENDSUB, "End Sub" },
+ { ENDTYPE, "End Type" },
+ { ENDIF, "EndIf" },
+ { EQV, "Eqv" },
+ { ERASE, "Erase" },
+ { _ERROR_, "Error" },
+ { EXIT, "Exit" },
+ { EXPLICIT, "Explicit" },
+ { FOR, "For" },
+ { FUNCTION, "Function" },
+ { GLOBAL, "Global" },
+ { GOSUB, "GoSub" },
+ { GOTO, "GoTo" },
+ { IF, "If" },
+ { IMP, "Imp" },
+ { _IN_, "In" },
+ { INPUT, "Input" }, // auch INPUT #
+ { TINTEGER, "Integer" },
+ { IS, "Is" },
+ { LET, "Let" },
+ { LIB, "Lib" },
+ { LINE, "Line" },
+ { LINEINPUT,"Line Input" },
+ { LOCAL, "Local" },
+ { LOCK, "Lock" },
+ { TLONG, "Long" },
+ { LOOP, "Loop" },
+ { LPRINT, "LPrint" },
+ { LSET, "LSet" }, // JSM
+ { MOD, "Mod" },
+ { NAME, "Name" },
+ { NEW, "New" },
+ { NEXT, "Next" },
+ { NOT, "Not" },
+ { TOBJECT, "Object" },
+ { ON, "On" },
+ { OPEN, "Open" },
+ { OPTION, "Option" },
+ { _OPTIONAL_, "Optional" },
+ { OR, "Or" },
+ { OUTPUT, "Output" },
+ { PRESERVE, "Preserve" },
+ { PRINT, "Print" },
+ { PRIVATE, "Private" },
+ { PUBLIC, "Public" },
+ { RANDOM, "Random" },
+ { READ, "Read" },
+ { REDIM, "ReDim" },
+ { REM, "Rem" },
+ { RESUME, "Resume" },
+ { RETURN, "Return" },
+ { RSET, "RSet" }, // JSM
+ { SELECT, "Select" },
+ { SET, "Set" },
+ { SHARED, "Shared" },
+ { TSINGLE, "Single" },
+ { STATIC, "Static" },
+ { STEP, "Step" },
+ { STOP, "Stop" },
+ { TSTRING, "String" },
+ { SUB, "Sub" },
+ { STOP, "System" },
+ { TEXT, "Text" },
+ { THEN, "Then" },
+ { TO, "To", },
+ { TYPE, "Type" },
+ { UNTIL, "Until" },
+ { TVARIANT, "Variant" },
+ { WEND, "Wend" },
+ { WHILE, "While" },
+ { WITH, "With" },
+ { WRITE, "Write" }, // auch WRITE #
+ { XOR, "Xor" },
+ { JS_LINDEX, "[" },
+ { JS_RINDEX, "]" },
+ { JS_BIT_XOR, "^" },
+ { JS_ASS_XOR, "^=" },
+ { JS_BIT_OR, "|" },
+ { JS_ASS_OR, "|=" },
+ { JS_LOG_OR, "||" },
+ { JS_BIT_NOT, "~" },
+ { NIL }
+};
+*/
+
+// #i109076
+TokenLabelInfo::TokenLabelInfo( void )
+{
+ m_pTokenCanBeLabelTab = new bool[VBASUPPORT+1];
+ for( int i = 0 ; i <= VBASUPPORT ; ++i )
+ m_pTokenCanBeLabelTab[i] = false;
+
+ // Token accepted as label by VBA
+ SbiToken eLabelToken[] = { ACCESS, ALIAS, APPEND, BASE, BINARY, CLASSMODULE,
+ COMPARE, COMPATIBLE, DEFERR, _ERROR_, EXPLICIT, LIB, LINE, LPRINT, NAME,
+ TOBJECT, OUTPUT, PROPERTY, RANDOM, READ, STEP, STOP, TEXT, VBASUPPORT, NIL };
+ SbiToken* pTok = eLabelToken;
+ SbiToken eTok;
+ for( pTok = eLabelToken ; (eTok = *pTok) != NIL ; ++pTok )
+ m_pTokenCanBeLabelTab[eTok] = true;
+}
+
+TokenLabelInfo::~TokenLabelInfo()
+{
+ delete[] m_pTokenCanBeLabelTab;
+}
+
+
+// Der Konstruktor ermittelt die Laenge der Token-Tabelle.
+
+SbiTokenizer::SbiTokenizer( const ::rtl::OUString& rSrc, StarBASIC* pb )
+ : SbiScanner( rSrc, pb )
+{
+ pTokTable = aTokTable_Basic;
+ //if( StarBASIC::GetGlobalLanguageMode() == SB_LANG_JAVASCRIPT )
+ // pTokTable = aTokTable_Java;
+ TokenTable *tp;
+ bEof = bAs = FALSE;
+ eCurTok = NIL;
+ ePush = NIL;
+ bEos = bKeywords = bErrorIsSymbol = TRUE;
+ if( !nToken )
+ for( nToken = 0, tp = pTokTable; tp->t; nToken++, tp++ ) {}
+}
+
+SbiTokenizer::~SbiTokenizer()
+{
+}
+
+// Wiederablage (Pushback) eines Tokens. (Bis zu 2 Tokens)
+
+void SbiTokenizer::Push( SbiToken t )
+{
+ if( ePush != NIL )
+ Error( SbERR_INTERNAL_ERROR, "PUSH" );
+ else ePush = t;
+}
+
+void SbiTokenizer::Error( SbError code, const char* pMsg )
+{
+ aError = String::CreateFromAscii( pMsg );
+ Error( code );
+}
+
+void SbiTokenizer::Error( SbError code, String aMsg )
+{
+ aError = aMsg;
+ Error( code );
+}
+
+void SbiTokenizer::Error( SbError code, SbiToken tok )
+{
+ aError = Symbol( tok );
+ Error( code );
+}
+
+// Einlesen des naechsten Tokens, ohne dass das Token geschluckt wird
+
+SbiToken SbiTokenizer::Peek()
+{
+ if( ePush == NIL )
+ {
+ USHORT nOldLine = nLine;
+ USHORT nOldCol1 = nCol1;
+ USHORT nOldCol2 = nCol2;
+ ePush = Next();
+ nPLine = nLine; nLine = nOldLine;
+ nPCol1 = nCol1; nCol1 = nOldCol1;
+ nPCol2 = nCol2; nCol2 = nOldCol2;
+ }
+ return eCurTok = ePush;
+}
+
+// Dies ist fuer die Decompilation.
+// Zahlen und Symbole liefern einen Leerstring zurueck.
+
+const String& SbiTokenizer::Symbol( SbiToken t )
+{
+ // Zeichen-Token?
+ if( t < FIRSTKWD )
+ {
+ aSym = (char) t;
+ return aSym;
+ }
+ switch( t )
+ {
+ case NEG : aSym = '-'; return aSym;
+ case EOS : aSym = String::CreateFromAscii( ":/CRLF" ); return aSym;
+ case EOLN : aSym = String::CreateFromAscii( "CRLF" ); return aSym;
+ default: break;
+ }
+ TokenTable* tp = pTokTable;
+ for( short i = 0; i < nToken; i++, tp++ )
+ {
+ if( tp->t == t )
+ {
+ aSym = String::CreateFromAscii( tp->s );
+ return aSym;
+ }
+ }
+ const sal_Unicode *p = aSym.GetBuffer();
+ if (*p <= ' ') aSym = String::CreateFromAscii( "???" );
+ return aSym;
+}
+
+// Einlesen des naechsten Tokens und Ablage desselben
+// Tokens, die nicht in der Token-Tabelle vorkommen, werden
+// direkt als Zeichen zurueckgeliefert.
+// Einige Worte werden gesondert behandelt.
+
+SbiToken SbiTokenizer::Next()
+{
+ if (bEof) return EOLN;
+ // Schon eines eingelesen?
+ if( ePush != NIL )
+ {
+ eCurTok = ePush;
+ ePush = NIL;
+ nLine = nPLine;
+ nCol1 = nPCol1;
+ nCol2 = nPCol2;
+ bEos = IsEoln( eCurTok );
+ return eCurTok;
+ }
+ TokenTable *tp;
+
+ // Sonst einlesen:
+ if( !NextSym() )
+ {
+ bEof = bEos = TRUE;
+ return eCurTok = EOLN;
+ }
+ // Zeilenende?
+ if( aSym.GetBuffer()[0] == '\n' )
+ {
+ bEos = TRUE; return eCurTok = EOLN;
+ }
+ bEos = FALSE;
+
+ // Zahl?
+ if( bNumber )
+ return eCurTok = NUMBER;
+
+ // String?
+ else if( ( eScanType == SbxDATE || eScanType == SbxSTRING ) && !bSymbol )
+ return eCurTok = FIXSTRING;
+ // Sonderfaelle von Zeichen, die zwischen "Z" und "a" liegen. ICompare()
+ // wertet die Position dieser Zeichen unterschiedlich aus.
+ else if( aSym.GetBuffer()[0] == '^' )
+ return eCurTok = EXPON;
+ else if( aSym.GetBuffer()[0] == '\\' )
+ return eCurTok = IDIV;
+ else
+ {
+ // Mit Typkennung oder ein Symbol und keine Keyword-Erkennung?
+ // Dann kein Token-Test
+ if( eScanType != SbxVARIANT
+ || ( !bKeywords && bSymbol ) )
+ return eCurTok = SYMBOL;
+ // Gueltiges Token?
+ short lb = 0;
+ short ub = nToken-1;
+ short delta;
+ do
+ {
+ delta = (ub - lb) >> 1;
+ tp = &pTokTable[ lb + delta ];
+ StringCompare res = aSym.CompareIgnoreCaseToAscii( tp->s );
+ // Gefunden?
+ if( res == COMPARE_EQUAL )
+ goto special;
+ // Groesser? Dann untere Haelfte
+ if( res == COMPARE_LESS )
+ {
+ if ((ub - lb) == 2) ub = lb;
+ else ub = ub - delta;
+ }
+ // Kleiner? Dann obere Haelfte
+ else
+ {
+ if ((ub -lb) == 2) lb = ub;
+ else lb = lb + delta;
+ }
+ } while( delta );
+ // Symbol? Wenn nicht >= Token
+ sal_Unicode ch = aSym.GetBuffer()[0];
+ if( !BasicSimpleCharClass::isAlpha( ch, bCompatible ) && !bSymbol )
+ return eCurTok = (SbiToken) (ch & 0x00FF);
+ return eCurTok = SYMBOL;
+ }
+special:
+ // #i92642
+ if( eCurTok != NIL && eCurTok != REM && eCurTok != EOLN && (tp->t == NAME || tp->t == LINE) )
+ return eCurTok = SYMBOL;
+ else if( tp->t == TEXT )
+ return eCurTok = SYMBOL;
+
+ // #i92642: Special LINE token handling -> SbiParser::Line()
+
+ // END IF, CASE, SUB, DEF, FUNCTION, TYPE, CLASS, WITH
+ if( tp->t == END )
+ {
+ // AB, 15.3.96, Spezialbehandlung fuer END, beim Peek() geht die
+ // aktuelle Zeile verloren, daher alles merken und danach restaurieren
+ USHORT nOldLine = nLine;
+ USHORT nOldCol = nCol;
+ USHORT nOldCol1 = nCol1;
+ USHORT nOldCol2 = nCol2;
+ String aOldSym = aSym;
+ SaveLine(); // pLine im Scanner sichern
+
+ eCurTok = Peek();
+ switch( eCurTok )
+ {
+ case IF: Next(); eCurTok = ENDIF; break;
+ case SELECT: Next(); eCurTok = ENDSELECT; break;
+ case SUB: Next(); eCurTok = ENDSUB; break;
+ case FUNCTION: Next(); eCurTok = ENDFUNC; break;
+ case PROPERTY: Next(); eCurTok = ENDPROPERTY; break;
+ case TYPE: Next(); eCurTok = ENDTYPE; break;
+ case ENUM: Next(); eCurTok = ENDENUM; break;
+ case WITH: Next(); eCurTok = ENDWITH; break;
+ default : eCurTok = END;
+ }
+ nCol1 = nOldCol1;
+ if( eCurTok == END )
+ {
+ // Alles zuruecksetzen, damit Token nach END ganz neu gelesen wird
+ ePush = NIL;
+ nLine = nOldLine;
+ nCol = nOldCol;
+ nCol2 = nOldCol2;
+ aSym = aOldSym;
+ RestoreLine(); // pLine im Scanner restaurieren
+ }
+ return eCurTok;
+ }
+ // Sind Datentypen Keywords?
+ // Nur nach AS, sonst sind es Symbole!
+ // Es gibt ja ERROR(), DATA(), STRING() etc.
+ eCurTok = tp->t;
+ // AS: Datentypen sind Keywords
+ if( tp->t == AS )
+ bAs = TRUE;
+ else
+ {
+ if( bAs )
+ bAs = FALSE;
+ else if( eCurTok >= DATATYPE1 && eCurTok <= DATATYPE2 && (bErrorIsSymbol || eCurTok != _ERROR_) )
+ eCurTok = SYMBOL;
+ }
+
+ // CLASSMODULE, PROPERTY, GET, ENUM token only visible in compatible mode
+ SbiToken eTok = tp->t;
+ if( bCompatible )
+ {
+ // #129904 Suppress system
+ if( eTok == STOP && aSym.CompareIgnoreCaseToAscii( "system" ) == COMPARE_EQUAL )
+ eCurTok = SYMBOL;
+ }
+ else
+ {
+ if( eTok == CLASSMODULE ||
+ eTok == IMPLEMENTS ||
+ eTok == PARAMARRAY ||
+ eTok == ENUM ||
+ eTok == PROPERTY ||
+ eTok == GET ||
+ eTok == TYPEOF )
+ {
+ eCurTok = SYMBOL;
+ }
+ }
+
+ bEos = IsEoln( eCurTok );
+ return eCurTok;
+}
+
+#ifdef _MSC_VER
+#pragma optimize("",off)
+#endif
+
+// Kann das aktuell eingelesene Token ein Label sein?
+
+BOOL SbiTokenizer::MayBeLabel( BOOL bNeedsColon )
+{
+ if( eCurTok == SYMBOL || m_aTokenLabelInfo.canTokenBeLabel( eCurTok ) )
+ return bNeedsColon ? DoesColonFollow() : TRUE;
+ else
+ return BOOL( eCurTok == NUMBER
+ && eScanType == SbxINTEGER
+ && nVal >= 0 );
+}
+
+#ifdef _MSC_VER
+#pragma optimize("",off)
+#endif
+
+
+void SbiTokenizer::Hilite( SbTextPortions& rList )
+{
+ bErrors = FALSE;
+ bUsedForHilite = TRUE;
+ SbiToken eLastTok = NIL;
+ for( ;; )
+ {
+ Next();
+ if( IsEof() )
+ break;
+ SbTextPortion aRes;
+ aRes.nLine = nLine;
+ aRes.nStart = nCol1;
+ aRes.nEnd = nCol2;
+ switch( eCurTok )
+ {
+ case REM:
+ aRes.eType = SB_COMMENT; break;
+ case SYMBOL:
+ aRes.eType = SB_SYMBOL; break;
+ case FIXSTRING:
+ aRes.eType = SB_STRING; break;
+ case NUMBER:
+ aRes.eType = SB_NUMBER; break;
+ default:
+ if( ( eCurTok >= FIRSTKWD && eCurTok <= LASTKWD )
+ || (eCurTok >= _CDECL_ ) )
+ aRes.eType = SB_KEYWORD;
+ else
+ aRes.eType = SB_PUNCTUATION;
+ }
+ // Die Folge xxx.Keyword sollte nicht als Kwd geflagt werden
+ if( aRes.eType == SB_KEYWORD
+ && ( eLastTok == DOT|| eLastTok == EXCLAM ) )
+ aRes.eType = SB_SYMBOL;
+ if( eCurTok != EOLN && aRes.nStart <= aRes.nEnd )
+ rList.Insert( aRes, rList.Count() );
+ if( aRes.eType == SB_COMMENT )
+ break;
+ eLastTok = eCurTok;
+ }
+ bUsedForHilite = FALSE;
+}
+
diff --git a/basic/source/inc/buffer.hxx b/basic/source/inc/buffer.hxx
new file mode 100644
index 000000000000..cbb1a1702354
--- /dev/null
+++ b/basic/source/inc/buffer.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _BUFFER_HXX
+#define _BUFFER_HXX
+
+#include <tools/solar.h>
+#include <tools/string.hxx>
+
+class SbiParser;
+
+class SbiBuffer { // Code/Konstanten-Puffer:
+ SbiParser* pParser; // fuer Fehlermeldungen
+ char* pBuf; // Puffer-Pointer
+ char* pCur; // aktueller Puffer-Pointer
+ UINT32 nOff; // aktuelles Offset
+ UINT32 nSize; // aktuelle Groesse
+ short nInc; // Inkrement
+ BOOL Check( USHORT ); // Buffergroesse testen
+public:
+ SbiBuffer( SbiParser*, short ); // Inkrement
+ ~SbiBuffer();
+ void Patch( UINT32, UINT32 ); // Patchen
+ void Chain( UINT32 ); // Back-Chain
+ void Align( INT32 ); // Alignment
+ BOOL Add( const void*, USHORT );// Element anfuegen
+ BOOL operator += (const String&);// Basic-String speichern
+ BOOL operator += (INT8); // Zeichen speichern
+ BOOL operator += (INT16); // Integer speichern
+ BOOL operator += (UINT8); // Zeichen speichern
+ BOOL operator += (UINT16); // Integer speichern
+ BOOL operator += (UINT32); // Integer speichern
+ BOOL operator += (INT32); // Integer speichern
+ char* GetBuffer(); // Puffer rausgeben (selbst loeschen!)
+ char* GetBufferPtr(){ return pBuf; }
+ UINT32 GetSize() { return nOff; }
+};
+
+#endif
diff --git a/basic/source/inc/codegen.hxx b/basic/source/inc/codegen.hxx
new file mode 100644
index 000000000000..a3fe02227cfd
--- /dev/null
+++ b/basic/source/inc/codegen.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _CODEGEN_HXX
+#define _CODEGEN_HXX
+
+class SbiImage;
+class SbiParser;
+class SbModule;
+#include "opcodes.hxx"
+#include "buffer.hxx"
+
+class SbiCodeGen { // Code-Erzeugung:
+ SbiParser* pParser; // fuer Fehlermeldungen, Line, Column etc.
+ SbModule& rMod; // aktuelles Modul
+ SbiBuffer aCode; // Code-Puffer
+ short nLine, nCol; // Zeile, Spalte fuer Stmnt-Befehl
+ short nForLevel; // #29955 for-Schleifen-Ebene
+ BOOL bStmnt; // TRUE: Statement-Opcode liegt an
+public:
+ SbiCodeGen( SbModule&, SbiParser*, short );
+ SbiParser* GetParser() { return pParser; }
+ SbModule& GetModule() { return rMod; }
+ UINT32 Gen( SbiOpcode );
+ UINT32 Gen( SbiOpcode, UINT32 );
+ UINT32 Gen( SbiOpcode, UINT32, UINT32 );
+ void Patch( UINT32 o, UINT32 v ){ aCode.Patch( o, v ); }
+ void BackChain( UINT32 off ) { aCode.Chain( off ); }
+ void Statement();
+ void GenStmnt(); // evtl. Statement-Opcode erzeugen
+ UINT32 GetPC();
+ UINT32 GetOffset() { return GetPC() + 1; }
+ void Save();
+
+ // #29955 for-Schleifen-Ebene pflegen
+ void IncForLevel( void ) { nForLevel++; }
+ void DecForLevel( void ) { nForLevel--; }
+
+ static UINT32 calcNewOffSet( BYTE* pCode, UINT16 nOffset );
+ static UINT16 calcLegacyOffSet( BYTE* pCode, UINT32 nOffset );
+
+};
+
+template < class T, class S >
+class PCodeBuffConvertor
+{
+ T m_nSize; //
+ BYTE* m_pStart;
+ BYTE* m_pCnvtdBuf;
+ S m_nCnvtdSize; //
+
+ // Disable usual copying symantics and bodgy default ctor
+ PCodeBuffConvertor();
+ PCodeBuffConvertor(const PCodeBuffConvertor& );
+ PCodeBuffConvertor& operator = ( const PCodeBuffConvertor& );
+public:
+ PCodeBuffConvertor( BYTE* pCode, T nSize ): m_nSize( nSize ), m_pStart( pCode ), m_pCnvtdBuf( NULL ), m_nCnvtdSize( 0 ){ convert(); }
+ S GetSize(){ return m_nCnvtdSize; }
+ void convert();
+ // Caller owns the buffer returned
+ BYTE* GetBuffer() { return m_pCnvtdBuf; }
+};
+
+// #111897 PARAM_INFO flags start at 0x00010000 to not
+// conflict with DefaultId in SbxParamInfo::nUserData
+#define PARAM_INFO_PARAMARRAY 0x0010000
+
+#endif
diff --git a/basic/source/inc/collelem.hxx b/basic/source/inc/collelem.hxx
new file mode 100644
index 000000000000..cd1787d6ff01
--- /dev/null
+++ b/basic/source/inc/collelem.hxx
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SAMPLE_COLLELEM_HXX
+#define _SAMPLE_COLLELEM_HXX
+
+#include <basic/sbxobj.hxx>
+
+// Das Sample-Element ist ein kleines Objekt, das die Properties
+// Name und Value enth„lt sowie die Methode Say, die den bergebenen
+// Text mit dem eigenen Namen verkoppelt. Der Name ist von aussen setzbar.
+// Die Implementation arbeitet ausschliesslich mit dynamischen Elementen.
+
+class SampleElement : public SbxObject
+{
+ // Broadcaster Notification
+ virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType );
+public:
+ SampleElement( const String& );
+};
+
+#endif
diff --git a/basic/source/inc/disas.hxx b/basic/source/inc/disas.hxx
new file mode 100644
index 000000000000..328a085e6c29
--- /dev/null
+++ b/basic/source/inc/disas.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _DISAS_HXX
+#define _DISAS_HXX
+
+#include "image.hxx"
+#include "opcodes.hxx"
+// find a place for this limit ( also used in
+class SvStream;
+#define MAX_LABELS 0x2000L
+class SbiDisas {
+ const SbiImage& rImg;
+ SbModule* pMod;
+ char cLabels[ MAX_LABELS ]; // Bitvektor fuer Labels
+ UINT32 nOff; // aktuelle Position
+ UINT32 nPC; // Position des Opcodes
+ SbiOpcode eOp; // Opcode
+ UINT32 nOp1, nOp2; // Operanden
+ UINT32 nParts; // 1, 2 oder 3
+ UINT32 nLine; // aktuelle Zeile
+ BOOL DisasLine( String& );
+ BOOL Fetch(); // naechster Opcode
+public:
+ SbiDisas( SbModule*, const SbiImage* );
+ void Disas( SvStream& );
+ void Disas( String& );
+ // NICHT AUFRUFEN
+ void StrOp( String& );
+ void Str2Op( String& );
+ void ImmOp( String& );
+ void OnOp( String& );
+ void LblOp( String& );
+ void ReturnOp( String& );
+ void ResumeOp( String& );
+ void PromptOp( String& );
+ void CloseOp( String& );
+ void CharOp( String& );
+ void VarOp( String& );
+ void VarDefOp( String& );
+ void OffOp( String& );
+ void TypeOp( String& );
+ void CaseOp( String& );
+ void StmntOp( String& );
+ void StrmOp( String& );
+};
+
+#endif
diff --git a/basic/source/inc/dlgcont.hxx b/basic/source/inc/dlgcont.hxx
new file mode 100644
index 000000000000..2c927a8286f4
--- /dev/null
+++ b/basic/source/inc/dlgcont.hxx
@@ -0,0 +1,175 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef BASIC_DIALOGCONTAINER_HXX
+#define BASIC_DIALOGCONTAINER_HXX
+
+#include "namecont.hxx"
+
+#ifndef _COM_SUN_STAR_AWT_XSTRINGRESOURCESUPPLIER_HPP_
+#include <com/sun/star/resource/XStringResourceSupplier.hpp>
+#endif
+#include "com/sun/star/resource/XStringResourcePersistence.hpp"
+
+#include <cppuhelper/implbase1.hxx>
+#include <comphelper/uno3.hxx>
+
+namespace basic
+{
+
+//============================================================================
+
+class SfxDialogLibraryContainer : public SfxLibraryContainer
+{
+ // Methods to distinguish between different library types
+ virtual SfxLibrary* SAL_CALL implCreateLibrary( const ::rtl::OUString& aName );
+ virtual SfxLibrary* SAL_CALL implCreateLibraryLink
+ ( const ::rtl::OUString& aName, const ::rtl::OUString& aLibInfoFileURL,
+ const ::rtl::OUString& StorageURL, sal_Bool ReadOnly );
+ virtual ::com::sun::star::uno::Any SAL_CALL createEmptyLibraryElement( void );
+ virtual bool SAL_CALL isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const;
+ virtual void SAL_CALL writeLibraryElement
+ (
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>& xLibrary,
+ const ::rtl::OUString& aElementName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutput
+ )
+ throw(::com::sun::star::uno::Exception);
+
+ virtual ::com::sun::star::uno::Any SAL_CALL importLibraryElement
+ (
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>& xLibrary,
+ const ::rtl::OUString& aElementName,
+ const ::rtl::OUString& aFile,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xElementStream );
+
+ virtual void SAL_CALL importFromOldStorage( const ::rtl::OUString& aFile );
+
+ virtual SfxLibraryContainer* createInstanceImpl( void );
+
+ virtual void onNewRootStorage();
+
+ virtual const sal_Char* SAL_CALL getInfoFileName() const;
+ virtual const sal_Char* SAL_CALL getOldInfoFileName() const;
+ virtual const sal_Char* SAL_CALL getLibElementFileExtension() const;
+ virtual const sal_Char* SAL_CALL getLibrariesDir() const;
+
+public:
+ SfxDialogLibraryContainer( void );
+ SfxDialogLibraryContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage );
+
+ // Methods XStorageBasedLibraryContainer
+ virtual void SAL_CALL storeLibrariesToStorage(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& RootStorage )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // Resource handling
+ ::com::sun::star::uno::Reference< ::com::sun::star::resource::XStringResourcePersistence >
+ implCreateStringResource( class SfxDialogLibrary* pDialog );
+
+ // Methods XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // Service
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static();
+ static ::rtl::OUString getImplementationName_static();
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL Create
+ ( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xServiceManager )
+ throw( ::com::sun::star::uno::Exception );
+};
+
+//============================================================================
+
+typedef ::cppu::ImplHelper1 < ::com::sun::star::resource::XStringResourceSupplier
+ > SfxDialogLibrary_BASE;
+
+class SfxDialogLibrary :public SfxLibrary
+ ,public SfxDialogLibrary_BASE
+{
+ SfxDialogLibraryContainer* m_pParent;
+ ::com::sun::star::uno::Reference
+ < ::com::sun::star::resource::XStringResourcePersistence> m_xStringResourcePersistence;
+ ::rtl::OUString m_aName;
+
+ // Provide modify state including resources
+ virtual sal_Bool isModified( void );
+ virtual void storeResources( void );
+ virtual void storeResourcesAsURL( const ::rtl::OUString& URL, const ::rtl::OUString& NewName );
+ virtual void storeResourcesToURL( const ::rtl::OUString& URL,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler );
+ virtual void storeResourcesToStorage( const ::com::sun::star::uno::Reference
+ < ::com::sun::star::embed::XStorage >& xStorage );
+
+public:
+ SfxDialogLibrary
+ (
+ ModifiableHelper& _rModifiable,
+ const ::rtl::OUString& aName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xMSF,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xSFI,
+ SfxDialogLibraryContainer* pParent
+ );
+
+ SfxDialogLibrary
+ (
+ ModifiableHelper& _rModifiable,
+ const ::rtl::OUString& aName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xMSF,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xSFI,
+ const ::rtl::OUString& aLibInfoFileURL, const ::rtl::OUString& aStorageURL, sal_Bool ReadOnly,
+ SfxDialogLibraryContainer* pParent
+ );
+
+ DECLARE_XINTERFACE()
+ DECLARE_XTYPEPROVIDER()
+
+ // XStringResourceSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::resource::XStringResourceResolver >
+ SAL_CALL getStringResource( ) throw (::com::sun::star::uno::RuntimeException);
+
+ ::rtl::OUString getName( void )
+ { return m_aName; }
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::resource::XStringResourcePersistence >
+ getStringResourcePersistence( void )
+ {
+ return m_xStringResourcePersistence;
+ }
+
+ static bool containsValidDialog( const ::com::sun::star::uno::Any& aElement );
+
+protected:
+ virtual bool SAL_CALL isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const;
+};
+
+} // namespace basic
+
+#endif
+
diff --git a/basic/source/inc/errobject.hxx b/basic/source/inc/errobject.hxx
new file mode 100644
index 000000000000..39e6e319caae
--- /dev/null
+++ b/basic/source/inc/errobject.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+*
+* 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.
+*
+************************************************************************/
+
+#ifndef ERROBJECT_HXX
+#define ERROBJECT_HXX
+#include "sbunoobj.hxx"
+#include <ooo/vba/XErrObject.hpp>
+
+
+class SbxErrObject : public SbUnoObject
+{
+ class ErrObject* m_pErrObject;
+ com::sun::star::uno::Reference< ooo::vba::XErrObject > m_xErr;
+
+ SbxErrObject( const String& aName_, const com::sun::star::uno::Any& aUnoObj_ );
+ ~SbxErrObject();
+
+ class ErrObject* getImplErrObject( void )
+ { return m_pErrObject; }
+
+public:
+ static SbxVariableRef getErrObject();
+ static com::sun::star::uno::Reference< ooo::vba::XErrObject > getUnoErrObject();
+
+ void setNumberAndDescription( ::sal_Int32 _number, const ::rtl::OUString& _description )
+ throw (com::sun::star::uno::RuntimeException);
+};
+#endif
diff --git a/basic/source/inc/expr.hxx b/basic/source/inc/expr.hxx
new file mode 100644
index 000000000000..851d0d6f1fe5
--- /dev/null
+++ b/basic/source/inc/expr.hxx
@@ -0,0 +1,266 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _EXPR_HXX
+#define _EXPR_HXX
+
+#include "opcodes.hxx"
+#include "token.hxx"
+
+class SbiExprNode;
+class SbiExpression;
+class SbiExprList;
+class SbiDimList;
+class SbiParameters;
+class SbiParser;
+class SbiCodeGen;
+class SbiSymDef;
+class SbiProcDef;
+
+
+#include <vector>
+typedef ::std::vector<SbiExprList*> SbiExprListVector;
+
+struct SbVar { // Variablen-Element:
+ SbiExprNode* pNext; // Weiteres Element (bei Strukturen)
+ SbiSymDef* pDef; // Symboldefinition
+ SbiExprList* pPar; // optionale Parameter (wird geloescht)
+ SbiExprListVector* pvMorePar; // Array of arrays foo(pPar)(avMorePar[0])(avMorePar[1])...
+};
+
+struct KeywordSymbolInfo
+{
+ String m_aKeywordSymbol;
+ SbxDataType m_eSbxDataType;
+ SbiToken m_eTok;
+};
+
+enum SbiExprType { // Expression-Typen:
+ SbSTDEXPR, // normaler Ausdruck
+ SbLVALUE, // beliebiger lValue
+ SbSYMBOL, // beliebiges zusammengesetztes Symbol
+ SbOPERAND // Variable/Funktion
+};
+
+enum SbiExprMode { // Expression context:
+ EXPRMODE_STANDARD, // default
+ EXPRMODE_STANDALONE, // a param1, param2 OR a( param1, param2 ) = 42
+ EXPRMODE_LPAREN_PENDING, // start of parameter list with bracket, special handling
+ EXPRMODE_LPAREN_NOT_NEEDED, // pending LPAREN has not been used
+ EXPRMODE_ARRAY_OR_OBJECT, // '=' or '(' or '.' found after ')' on ParenLevel 0, stopping
+ // expression, assuming array syntax a(...)[(...)] = ?
+ // or a(...).b(...)
+ EXPRMODE_EMPTY_PAREN // It turned out that the paren don't contain anything: a()
+};
+
+enum SbiNodeType {
+ SbxNUMVAL, // nVal = Wert
+ SbxSTRVAL, // aStrVal = Wert, before #i59791/#i45570: nStringId = Wert
+ SbxVARVAL, // aVar = Wert
+ SbxTYPEOF, // TypeOf ObjExpr Is Type
+ SbxNODE, // Node
+ SbxNEW, // new <type> expression
+ SbxDUMMY
+};
+
+enum RecursiveMode
+{
+ UNDEFINED,
+ FORCE_CALL,
+ PREVENT_CALL
+};
+
+class SbiExprNode { // Operatoren (und Operanden)
+ friend class SbiExpression;
+ friend class SbiConstExpression;
+ union {
+ USHORT nTypeStrId; // gepoolter String-ID, #i59791/#i45570 Now only for TypeOf
+ double nVal; // numerischer Wert
+ SbVar aVar; // oder Variable
+ };
+ String aStrVal; // #i59791/#i45570 Store string directly
+ SbiExprNode* pLeft; // linker Zweig
+ SbiExprNode* pRight; // rechter Zweig (NULL bei unaeren Ops)
+ SbiExprNode* pWithParent; // Knoten, dessen Member this per with ist
+ SbiCodeGen* pGen; // Code-Generator
+ SbiNodeType eNodeType; // Art des Nodes
+ SbxDataType eType; // aktueller Datentyp
+ SbiToken eTok; // Token des Operators
+ BOOL bComposite; // TRUE: Zusammengesetzter Ausdruck
+ BOOL bError; // TRUE: Fehlerhaft
+ void FoldConstants(); // Constant Folding durchfuehren
+ void CollectBits(); // Umwandeln von Zahlen in Strings
+ BOOL IsOperand() // TRUE, wenn Operand
+ { return BOOL( eNodeType != SbxNODE && eNodeType != SbxTYPEOF && eNodeType != SbxNEW ); }
+ BOOL IsTypeOf()
+ { return BOOL( eNodeType == SbxTYPEOF ); }
+ BOOL IsNew()
+ { return BOOL( eNodeType == SbxNEW ); }
+ BOOL IsNumber(); // TRUE bei Zahlen
+ BOOL IsString(); // TRUE bei Strings
+ BOOL IsLvalue(); // TRUE, falls als Lvalue verwendbar
+ void GenElement( SbiOpcode ); // Element
+ void BaseInit( SbiParser* p ); // Hilfsfunktion fuer Ctor, AB 17.12.95
+public:
+ SbiExprNode( void );
+ SbiExprNode( SbiParser*, double, SbxDataType );
+ SbiExprNode( SbiParser*, const String& );
+ SbiExprNode( SbiParser*, const SbiSymDef&, SbxDataType, SbiExprList* = NULL );
+ SbiExprNode( SbiParser*, SbiExprNode*, SbiToken, SbiExprNode* );
+ SbiExprNode( SbiParser*, SbiExprNode*, USHORT ); // #120061 TypeOf
+ SbiExprNode( SbiParser*, USHORT ); // new <type>
+ virtual ~SbiExprNode();
+
+ BOOL IsValid() { return BOOL( !bError ); }
+ BOOL IsConstant() // TRUE bei konstantem Operanden
+ { return BOOL( eNodeType == SbxSTRVAL || eNodeType == SbxNUMVAL ); }
+ BOOL IsIntConst(); // TRUE bei Integer-Konstanten
+ BOOL IsVariable(); // TRUE, wenn Variable
+
+ SbiExprNode* GetWithParent() { return pWithParent; }
+ void SetWithParent( SbiExprNode* p ) { pWithParent = p; }
+
+ SbxDataType GetType() { return eType; }
+ void SetType( SbxDataType eTp ) { eType = eTp; }
+ SbiNodeType GetNodeType() { return eNodeType; }
+ SbiSymDef* GetVar(); // Variable (falls vorhanden)
+ SbiSymDef* GetRealVar(); // letzte Variable in x.y.z
+ SbiExprNode* GetRealNode(); // letzter Knoten in x.y.z
+ short GetDepth(); // Tiefe eines Baumes berechnen
+ const String& GetString() { return aStrVal; }
+ short GetNumber() { return (short)nVal; }
+ SbiExprList* GetParameters() { return aVar.pPar; }
+ SbiExprListVector* GetMoreParameters() { return aVar.pvMorePar; }
+
+ void Optimize(); // Baumabgleich
+
+ void Gen( RecursiveMode eRecMode = UNDEFINED ); // Ausgabe eines Nodes
+};
+
+class SbiExpression { // der Ausdruck:
+ friend class SbiExprList;
+ friend class SbiParameters;
+ friend class SbiDimList;
+protected:
+ String aArgName; // Name fuer bananntes Argument
+ SbiParser* pParser; // fuer Fehlermeldungen, Parsing
+ SbiExpression* pNext; // Link bei Parameterlisten
+ SbiExprNode* pExpr; // Der Expression-Baum
+ SbiExprType eCurExpr; // Art des Ausdrucks
+ SbiExprMode m_eMode; // Expression context
+ BOOL bBased; // TRUE: einfacher DIM-Teil (+BASE)
+ BOOL bError; // TRUE: Fehler
+ BOOL bByVal; // TRUE: ByVal-Parameter
+ BOOL bBracket; // TRUE: Parameter list with brackets
+ USHORT nParenLevel;
+ SbiExprNode* Term( const KeywordSymbolInfo* pKeywordSymbolInfo = NULL );
+ SbiExprNode* ObjTerm( SbiSymDef& );
+ SbiExprNode* Operand( bool bUsedForTypeOf = false );
+ SbiExprNode* Unary();
+ SbiExprNode* Exp();
+ SbiExprNode* MulDiv();
+ SbiExprNode* IntDiv();
+ SbiExprNode* Mod();
+ SbiExprNode* AddSub();
+ SbiExprNode* Cat();
+ SbiExprNode* Like();
+ SbiExprNode* Comp();
+ SbiExprNode* Boolean();
+public:
+ SbiExpression( SbiParser*, SbiExprType = SbSTDEXPR,
+ SbiExprMode eMode = EXPRMODE_STANDARD, const KeywordSymbolInfo* pKeywordSymbolInfo = NULL ); // Parsender Ctor
+ SbiExpression( SbiParser*, const String& );
+ SbiExpression( SbiParser*, double, SbxDataType = SbxDOUBLE );
+ SbiExpression( SbiParser*, const SbiSymDef&, SbiExprList* = NULL );
+ SbiExpression( SbiParser*, SbiToken ); // Spezial-Expr mit Spezial-Tokens
+ ~SbiExpression();
+ String& GetName() { return aArgName; }
+ void SetBased() { bBased = TRUE; }
+ BOOL IsBased() { return bBased; }
+ void SetByVal() { bByVal = TRUE; }
+ BOOL IsByVal() { return bByVal; }
+ BOOL IsBracket() { return bBracket; }
+ BOOL IsValid() { return pExpr->IsValid(); }
+ BOOL IsConstant() { return pExpr->IsConstant(); }
+ BOOL IsVariable() { return pExpr->IsVariable(); }
+ BOOL IsLvalue() { return pExpr->IsLvalue(); }
+ BOOL IsIntConstant() { return pExpr->IsIntConst(); }
+ const String& GetString() { return pExpr->GetString(); }
+ SbiSymDef* GetVar() { return pExpr->GetVar(); }
+ SbiSymDef* GetRealVar() { return pExpr->GetRealVar(); }
+ SbiExprNode* GetExprNode() { return pExpr; }
+ SbxDataType GetType() { return pExpr->GetType(); }
+ void SetType( SbxDataType eType){ pExpr->eType = eType; }
+ void Gen( RecursiveMode eRecMode = UNDEFINED ); // Ausgabe eines Nodes
+};
+
+class SbiConstExpression : public SbiExpression {
+ double nVal;
+ String aVal;
+ SbxDataType eType;
+public: // numerische Konstante
+ SbiConstExpression( SbiParser* );
+ SbxDataType GetType() { return eType; }
+ const String& GetString() { return aVal; }
+ double GetValue() { return nVal; }
+ short GetShortValue();
+};
+
+class SbiExprList { // Basisklasse fuer Parameter und Dims
+protected:
+ SbiParser* pParser; // Parser
+ SbiExpression* pFirst; // Expressions
+ short nExpr; // Anzahl Expressions
+ short nDim; // Anzahl Dimensionen
+ BOOL bError; // TRUE: Fehler
+ BOOL bBracket; // TRUE: Klammern
+public:
+ SbiExprList( SbiParser* );
+ virtual ~SbiExprList();
+ BOOL IsBracket() { return bBracket; }
+ BOOL IsValid() { return BOOL( !bError ); }
+ short GetSize() { return nExpr; }
+ short GetDims() { return nDim; }
+ SbiExpression* Get( short );
+ BOOL Test( const SbiProcDef& ); // Parameter-Checks
+ void Gen(); // Code-Erzeugung
+ void addExpression( SbiExpression* pExpr );
+};
+
+class SbiParameters : public SbiExprList {
+public:
+ SbiParameters( SbiParser*, BOOL bConst = FALSE, BOOL bPar = TRUE);// parsender Ctor
+};
+
+class SbiDimList : public SbiExprList {
+ BOOL bConst; // TRUE: Alles sind Integer-Konstanten
+public:
+ SbiDimList( SbiParser* ); // Parsender Ctor
+ BOOL IsConstant() { return bConst; }
+};
+
+#endif
diff --git a/basic/source/inc/filefmt.hxx b/basic/source/inc/filefmt.hxx
new file mode 100644
index 000000000000..dccdec703dd3
--- /dev/null
+++ b/basic/source/inc/filefmt.hxx
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SB_FILEFMT_HXX
+#define _SB_FILEFMT_HXX
+
+#include <tools/solar.h>
+
+class SvStream;
+
+// Version 2: Datentyp des Returnwerts fuer Publics
+// Version 3: neue Opcodes
+// Version 4: neue Opcodes
+// Version 5: Bug (Ansprung von STATIC-Variablen im Init-Code)
+// Version 6: Neue Opcodes und Bug (Globals anlegen, ohne BASIC zu beenden)
+// Version 7: Korrektur im WITH-Parsing
+// Version 8: Korrektur im IF-Parsing
+// Version 9: Init-Code auch mit LEAVE beenden, wenn keine SUB/FUNCTION folgt
+// Version A: #36374 Bei DIM AS NEW... auch Variablen anlegen
+// Version B: #40689 Static umgestellt
+// Version C: #41606 Bug bei Static
+// Version D: #42678 Bug bei RTL-Function spc
+// Version E: #56204 DCREATE, um auch bei DIM AS NEW Arrays anzulegen
+// Version F: #57844 Einfuehrung von SvNumberformat::StringToDouble
+// Version 10: #29955 For-Schleifen-Level in Statement-PCodes generieren
+// Version 11: #29955 Wegen Build-Inkonsistenzen Neu-Compilieren erzwingen
+
+#define B_LEGACYVERSION 0x00000011L
+#define B_CURVERSION 0x00000012L
+#define B_EXT_IMG_VERSION 0x00000012L
+
+// Eine Datei enthaelt entweder einen Modul- oder einen Library-Record.
+// Diese Records enthalten wiederum weitere Records. Jeder Record hat
+// den folgenden Header:
+
+// UINT16 Kennung
+// UINT32 Laenge des Records ohne Header
+// UINT16 Anzahl Unterelemente
+
+// Alle Datei-Offsets in Records sind relativ zum Start des Moduls!
+
+#define B_LIBRARY 0x4C42 // BL Library Record
+#define B_MODULE 0x4D42 // BM Module Record
+#define B_NAME 0x4E4D // MN module name
+#define B_COMMENT 0x434D // MC comment
+#define B_SOURCE 0x4353 // SC source code
+#define B_PCODE 0x4350 // PC p-code
+#define B_OLDPUBLICS 0x7550 // Pu publics
+#define B_PUBLICS 0x5550 // PU publics
+#define B_POOLDIR 0x4450 // PD symbol pool directory
+#define B_SYMPOOL 0x5953 // SY symbol pool
+#define B_STRINGPOOL 0x5453 // ST symbol pool
+#define B_LINERANGES 0x524C // LR line ranges for publics
+#define B_MODEND 0x454D // ME module end
+#define B_SBXOBJECTS 0x5853 // SX SBX objects
+
+#define EXTENDED_BINARY_MODULES
+#ifdef EXTENDED_BINARY_MODULES
+#define B_EXTSOURCE 0x5345 // ES extended source
+#endif
+
+// Ein Library Record enthaelt nur Module Records
+// UINT16 Kennung BL
+// UINT32 Laenge des Records
+// UINT16 Anzahl Module
+
+// Ein Modul-Record enthaelt alle anderen Recordtypen
+// UINT16 Kennung BM
+// UINT32 Laenge des Records
+// UINT16 1
+// Daten:
+// UINT32 Versionsnummer
+// UINT32 Zeichensatz
+// UINT32 Startadresse Initialisierungscode
+// UINT32 Startadresse Sub Main
+// UINT32 Reserviert
+// UINT32 Reserviert
+
+// Modulname, Kommentar und Quellcode:
+// UINT16 Kennung MN, MC oder SC
+// UINT32 Laenge des Records
+// UINT16 1
+// Daten:
+// String-Instanz
+
+// P-Code:
+// UINT16 Kennung PC
+// UINT32 Laenge des Records
+// UINT16 1
+// Daten:
+// Der P-Code als Bytesack
+
+// Alle Symbole und Strings werden in einem String-Pool gehalten.
+// Verweise auf diese Strings sind in Form eines Indexes in diesen Pool.
+
+// Liste aller Publics:
+// UINT16 Kennung PU oder Pu
+// UINT32 Laenge des Records
+// UINT16 Anzahl der Publics
+// Daten fuer jeden Public-Eintrag:
+// UINT16 String-Index
+// UINT32 Startadresse im P-Code-Image (UINT16 fuer alte Publics)
+// UINT16 Datentyp des Returnwertes (ab Version 2)
+
+// Verzeichnis der Symbol-Tabellen:
+// UINT16 Kennung SP
+// UINT32 Laenge des Records
+// UINT16 Anzahl der Symboltabellen
+// Daten fuer jede Symboltabelle:
+// UINT16 Stringindex des Namens
+// UINT16 Anzahl Symbole
+// UINT16 Scope-Kennung
+
+// Symboltabelle:
+// UINT16 Kennung SY
+// UINT32 Laenge des Records
+// UINT16 Anzahl der Symbole
+// Daten:
+// UINT16 Stringindex des Namens
+// UINT16 Anzahl Symbole
+// Daten fuer jedes Symbol:
+// UINT16 Stringindex des Namens
+// UINT16 Datentyp
+// UINT16 Laenge bei STRING*n-Symbolen (0x8000: STATIC-Variable)
+
+// Stringpool:
+// UINT16 Kennung ST
+// UINT32 Laenge des Records
+// UINT16 Anzahl der Strings
+// Daten fuer jeden String:
+// UINT32 Offset in den Block aller Strings
+// Danach folgt der Block aller Strings, die dort als ASCIIZ-Strings liegen.
+
+// Line Ranges:
+// UINT16 Kennung LR
+// UINT32 Laenge des Records
+// UINT16 Anzahl der Strings
+// Daten fuer jedes Public:
+// UINT16 1. Zeile (Sub XXX)
+// UINT16 2. Zeile (End Sub)
+
+// SBX-Objekte:
+// UINT16 Anzahl Objekte
+// .... Objektdaten
+
+////////////////////////////////////////////////////////////////////////////
+
+// Service-Routinen (in IMAGE.CXX)
+
+BOOL SbGood( SvStream& r );
+ULONG SbOpenRecord( SvStream&, UINT16 nSignature, UINT16 nElem );
+void SbCloseRecord( SvStream&, ULONG );
+
+#endif
diff --git a/basic/source/inc/image.hxx b/basic/source/inc/image.hxx
new file mode 100644
index 000000000000..d674b91faf71
--- /dev/null
+++ b/basic/source/inc/image.hxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBIMAGE_HXX
+#define _SBIMAGE_HXX
+
+#include "sbintern.hxx"
+#ifndef _RTL_USTRING_HXX
+#include <rtl/ustring.hxx>
+#endif
+#include <filefmt.hxx>
+
+// Diese Klasse liest das vom Compiler erzeugte Image ein und verwaltet
+// den Zugriff auf die einzelnen Elemente.
+
+struct SbPublicEntry;
+
+class SbiImage {
+ friend class SbiCodeGen; // Compiler-Klassen, die die private-
+
+ SbxArrayRef rTypes; // User defined types
+ SbxArrayRef rEnums; // Enum types
+ UINT32* pStringOff; // StringId-Offsets
+ sal_Unicode* pStrings; // StringPool
+ char* pCode; // Code-Image
+ char* pLegacyPCode; // Code-Image
+ BOOL bError; // TRUE: Fehler
+ USHORT nFlags; // Flags (s.u.)
+ short nStrings; // Anzahl Strings
+ UINT32 nStringSize; // Groesse des String-Puffers
+ UINT32 nCodeSize; // Groesse des Code-Blocks
+ UINT16 nLegacyCodeSize; // Groesse des Code-Blocks
+ UINT16 nDimBase; // OPTION BASE-Wert
+ rtl_TextEncoding eCharSet; // Zeichensatz fuer Strings
+ // temporaere Verwaltungs-Variable:
+ short nStringIdx; // aktueller String-Index
+ UINT32 nStringOff; // aktuelle Pos im Stringpuffer
+ // Routinen fuer Compiler:
+ void MakeStrings( short ); // StringPool einrichten
+ void AddString( const String& );// String zufuegen
+ void AddCode( char*, UINT32 ); // Codeblock dazu
+ void AddType(SbxObject *); // User-Type mit aufnehmen
+ void AddEnum(SbxObject *); // Register enum type
+
+public:
+ String aName; // Makroname
+ ::rtl::OUString aOUSource; // Quellcode
+ String aComment; // Kommentar
+ BOOL bInit; // TRUE: Init-Code ist gelaufen
+ BOOL bFirstInit; // TRUE, wenn das Image das erste mal nach
+ // dem Compilieren initialisiert wird.
+ SbiImage();
+ ~SbiImage();
+ void Clear(); // Inhalt loeschen
+ BOOL Load( SvStream&, UINT32& nVer ); // Loads image from stream
+ // nVer is set to version
+ // of image
+ BOOL Load( SvStream& );
+ BOOL Save( SvStream&, UINT32 = B_CURVERSION );
+ BOOL IsError() { return bError; }
+
+ const char* GetCode() const { return pCode; }
+ UINT32 GetCodeSize() const { return nCodeSize; }
+ ::rtl::OUString& GetSource32() { return aOUSource; }
+ USHORT GetBase() const { return nDimBase; }
+ String GetString( short nId ) const;
+ //const char* GetString( short nId ) const;
+ const SbxObject* FindType (String aTypeName) const;
+
+ SbxArrayRef GetEnums() { return rEnums; }
+
+ void SetFlag( USHORT n ) { nFlags |= n; }
+ USHORT GetFlag( USHORT n ) const { return nFlags & n; }
+ UINT16 CalcLegacyOffset( INT32 nOffset );
+ UINT32 CalcNewOffset( INT16 nOffset );
+ void ReleaseLegacyBuffer();
+ BOOL ExceedsLegacyLimits();
+
+};
+
+#define SBIMG_EXPLICIT 0x0001 // OPTION EXPLICIT ist aktiv
+#define SBIMG_COMPARETEXT 0x0002 // OPTION COMPARE TEXT ist aktiv
+#define SBIMG_INITCODE 0x0004 // Init-Code vorhanden
+#define SBIMG_CLASSMODULE 0x0008 // OPTION ClassModule is active
+
+#endif
diff --git a/basic/source/inc/iosys.hxx b/basic/source/inc/iosys.hxx
new file mode 100644
index 000000000000..b0ebcb0e87f0
--- /dev/null
+++ b/basic/source/inc/iosys.hxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBIOSYS_HXX
+#define _SBIOSYS_HXX
+
+#include <tools/stream.hxx>
+#ifndef _SBERRORS_HXX
+#include <basic/sberrors.hxx>
+#endif
+
+class SvStream;
+
+// Zur Zeit sind globale Dateien (Kanalnummern 256 bis 511)
+// nicht implementiert.
+
+#define CHANNELS 256
+#define CONSOLE 0
+
+#define SBSTRM_INPUT 0x0001 // Input
+#define SBSTRM_OUTPUT 0x0002 // Output
+#define SBSTRM_RANDOM 0x0004 // Random
+#define SBSTRM_APPEND 0x0008 // Append
+#define SBSTRM_BINARY 0x0010 // Binary
+
+class SbiStream {
+ SvStream* pStrm; // der Stream
+ ULONG nExpandOnWriteTo; // bei Schreibzugriff, den Stream
+ // bis zu dieser Groesse aufblasen
+ ByteString aLine; // aktuelle Zeile
+ ULONG nLine; // aktuelle Zeilennummer
+ short nLen; // Pufferlaenge
+ short nMode; // Bits:
+ short nChan; // aktueller Kanal
+ SbError nError; // letzter Fehlercode
+ void MapError(); // Fehlercode mappen
+
+public:
+ SbiStream();
+ ~SbiStream();
+ SbError Open( short, const ByteString&, short, short, short );
+ SbError Close();
+ SbError Read( ByteString&, USHORT = 0, bool bForceReadingPerByte=false );
+ SbError Read( char& );
+ SbError Write( const ByteString&, USHORT = 0 );
+
+ bool IsText() const { return (nMode & SBSTRM_BINARY) == 0; }
+ bool IsRandom() const { return (nMode & SBSTRM_RANDOM) != 0; }
+ bool IsBinary() const { return (nMode & SBSTRM_BINARY) != 0; }
+ bool IsSeq() const { return (nMode & SBSTRM_RANDOM) == 0; }
+ bool IsAppend() const { return (nMode & SBSTRM_APPEND) != 0; }
+ short GetBlockLen() const { return nLen; }
+ short GetMode() const { return nMode; }
+ ULONG GetLine() const { return nLine; }
+ void SetExpandOnWriteTo( ULONG n ) { nExpandOnWriteTo = n; }
+ void ExpandFile();
+ SvStream* GetStrm() { return pStrm; }
+};
+
+class SbiIoSystem {
+ SbiStream* pChan[ CHANNELS ];
+ ByteString aPrompt; // Input-Prompt
+ ByteString aIn, aOut; // Console-Buffer
+ short nChan; // aktueller Kanal
+ SbError nError; // letzter Fehlercode
+ void ReadCon( ByteString& );
+ void WriteCon( const ByteString& );
+public:
+ SbiIoSystem();
+ ~SbiIoSystem();
+ SbError GetError();
+ void Shutdown();
+ void SetPrompt( const ByteString& r ) { aPrompt = r; }
+ void SetChannel( short n ) { nChan = n; }
+ short GetChannel() const { return nChan;}
+ void ResetChannel() { nChan = 0; }
+ void Open( short, const ByteString&, short, short, short );
+ void Close();
+ void Read( ByteString&, short = 0 );
+ char Read();
+ void Write( const ByteString&, short = 0 );
+ short NextChannel();
+ // 0 == bad channel or no SvStream (nChannel=0..CHANNELS-1)
+ SbiStream* GetStream( short nChannel ) const;
+ void CloseAll(); // JSM
+};
+
+#endif
+
diff --git a/basic/source/inc/namecont.hxx b/basic/source/inc/namecont.hxx
new file mode 100644
index 000000000000..7fd6eb06f607
--- /dev/null
+++ b/basic/source/inc/namecont.hxx
@@ -0,0 +1,766 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef BASIC_NAMECONTAINER_HXX
+#define BASIC_NAMECONTAINER_HXX
+
+#include <hash_map>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/script/XStorageBasedLibraryContainer.hpp>
+#include <com/sun/star/script/XLibraryContainerPassword.hpp>
+#include <com/sun/star/script/XLibraryContainerExport.hpp>
+#include <com/sun/star/script/XLibraryContainer3.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/util/XMacroExpander.hpp>
+#include <com/sun/star/util/XStringSubstitution.hpp>
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <osl/mutex.hxx>
+#include <unotools/eventlisteneradapter.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <cppuhelper/component.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <sot/storage.hxx>
+#include <xmlscript/xmllib_imexp.hxx>
+#include <com/sun/star/deployment/XPackage.hpp>
+
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/compbase8.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <com/sun/star/script/vba/XVBACompatibility.hpp>
+
+class BasicManager;
+
+namespace basic
+{
+
+typedef ::cppu::WeakComponentImplHelper8<
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::script::XStorageBasedLibraryContainer,
+ ::com::sun::star::script::XLibraryContainerPassword,
+ ::com::sun::star::script::XLibraryContainerExport,
+ ::com::sun::star::script::XLibraryContainer3,
+ ::com::sun::star::container::XContainer,
+ ::com::sun::star::script::vba::XVBACompatibility,
+ ::com::sun::star::lang::XServiceInfo > LibraryContainerHelper;
+
+typedef ::cppu::WeakImplHelper2< ::com::sun::star::container::XNameContainer,
+ ::com::sun::star::container::XContainer > NameContainerHelper;
+
+
+struct hashName_Impl
+{
+ size_t operator()(const ::rtl::OUString Str) const
+ {
+ return (size_t)Str.hashCode();
+ }
+};
+
+struct eqName_Impl
+{
+ sal_Bool operator()(const ::rtl::OUString Str1, const ::rtl::OUString Str2) const
+ {
+ return ( Str1 == Str2 );
+ }
+};
+
+typedef std::hash_map
+<
+ ::rtl::OUString,
+ sal_Int32,
+ hashName_Impl,
+ eqName_Impl
+>
+NameContainerNameMap;
+
+
+//============================================================================
+
+class NameContainer : public ::cppu::BaseMutex, public NameContainerHelper
+{
+ NameContainerNameMap mHashMap;
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > mNames;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > mValues;
+ sal_Int32 mnElementCount;
+
+ ::com::sun::star::uno::Type mType;
+ ::com::sun::star::uno::XInterface* mpxEventSource;
+
+ ::cppu::OInterfaceContainerHelper maListenerContainer;
+
+public:
+ NameContainer( const ::com::sun::star::uno::Type& rType )
+ : mnElementCount( 0 )
+ , mType( rType )
+ , mpxEventSource( NULL )
+ , maListenerContainer( m_aMutex )
+ {}
+
+ void setEventSource( ::com::sun::star::uno::XInterface* pxEventSource )
+ { mpxEventSource = pxEventSource; }
+
+ // Methods XElementAccess
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType( )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements( )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // Methods XNameAccess
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
+ throw(::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // Methods XNameReplace
+ virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement )
+ throw(::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ // Methods XNameContainer
+ virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement )
+ throw(::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeByName( const ::rtl::OUString& Name )
+ throw(::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ // Methods XContainer
+ virtual void SAL_CALL addContainerListener( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XContainerListener >& xListener )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeContainerListener( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XContainerListener >& xListener )
+ throw (::com::sun::star::uno::RuntimeException);
+};
+
+//============================================================================
+
+class SfxLibrary;
+
+enum InitMode
+{
+ DEFAULT,
+ CONTAINER_INIT_FILE,
+ LIBRARY_INIT_FILE,
+ OFFICE_DOCUMENT,
+ OLD_BASIC_STORAGE
+};
+
+class ModifiableHelper
+{
+private:
+ ::cppu::OInterfaceContainerHelper m_aModifyListeners;
+ ::cppu::OWeakObject& m_rEventSource;
+ sal_Bool mbModified;
+
+public:
+ ModifiableHelper( ::cppu::OWeakObject& _rEventSource, ::osl::Mutex& _rMutex )
+ :m_aModifyListeners( _rMutex )
+ ,m_rEventSource( _rEventSource )
+ ,mbModified( sal_False )
+ {
+ }
+
+ inline sal_Bool isModified() const { return mbModified; }
+ void setModified( sal_Bool _bModified );
+
+ inline void addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& _rxListener )
+ {
+ m_aModifyListeners.addInterface( _rxListener );
+ }
+
+ inline void removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& _rxListener )
+ {
+ m_aModifyListeners.removeInterface( _rxListener );
+ }
+};
+
+class SfxLibraryContainer :public LibraryContainerHelper
+ ,public ::utl::OEventListenerAdapter
+{
+ sal_Bool mbVBACompat;
+protected:
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxMSF;
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > mxSFI;
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XMacroExpander > mxMacroExpander;
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XStringSubstitution > mxStringSubstitution;
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XModel > mxOwnerDocument;
+
+ ::osl::Mutex maMutex;
+ ModifiableHelper maModifiable;
+
+ NameContainer maNameContainer;
+ sal_Bool mbOldInfoFormat;
+ sal_Bool mbOasis2OOoFormat;
+
+ ::rtl::OUString maInitialDocumentURL;
+ ::rtl::OUString maInfoFileName;
+ ::rtl::OUString maOldInfoFileName;
+ ::rtl::OUString maLibElementFileExtension;
+ ::rtl::OUString maLibraryPath;
+ ::rtl::OUString maLibrariesDir;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > mxStorage;
+ BasicManager* mpBasMgr;
+ sal_Bool mbOwnBasMgr;
+
+ InitMode meInitMode;
+
+ void implStoreLibrary( SfxLibrary* pLib,
+ const ::rtl::OUString& aName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage );
+
+ // New variant for library export
+ void implStoreLibrary( SfxLibrary* pLib,
+ const ::rtl::OUString& aName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage,
+ const ::rtl::OUString& aTargetURL,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xToUseSFI,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler );
+
+ void implStoreLibraryIndexFile( SfxLibrary* pLib, const ::xmlscript::LibDescriptor& rLib,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage );
+
+ // New variant for library export
+ void implStoreLibraryIndexFile( SfxLibrary* pLib, const ::xmlscript::LibDescriptor& rLib,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage,
+ const ::rtl::OUString& aTargetURL,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xToUseSFI );
+
+ sal_Bool implLoadLibraryIndexFile( SfxLibrary* pLib,
+ ::xmlscript::LibDescriptor& rLib,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage,
+ const ::rtl::OUString& aIndexFileName );
+
+ void implImportLibDescriptor( SfxLibrary* pLib, ::xmlscript::LibDescriptor& rLib );
+
+ // Methods to distinguish between deffirent library types
+ virtual SfxLibrary* SAL_CALL implCreateLibrary( const ::rtl::OUString& aName ) = 0;
+ virtual SfxLibrary* SAL_CALL implCreateLibraryLink
+ ( const ::rtl::OUString& aName, const ::rtl::OUString& aLibInfoFileURL,
+ const ::rtl::OUString& StorageURL, sal_Bool ReadOnly ) = 0;
+ virtual ::com::sun::star::uno::Any SAL_CALL createEmptyLibraryElement( void ) = 0;
+ virtual bool SAL_CALL isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const = 0;
+ virtual void SAL_CALL writeLibraryElement
+ (
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>& xLibrary,
+ const ::rtl::OUString& aElementName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutput
+ )
+ throw(::com::sun::star::uno::Exception) = 0;
+
+ virtual ::com::sun::star::uno::Any SAL_CALL importLibraryElement
+ (
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>& xLibrary,
+ const ::rtl::OUString& aElementName,
+ const ::rtl::OUString& aFile,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xElementStream ) = 0;
+ virtual void SAL_CALL importFromOldStorage( const ::rtl::OUString& aFile ) = 0;
+
+ // Password encryption
+ virtual sal_Bool implStorePasswordLibrary( SfxLibrary* pLib, const ::rtl::OUString& aName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler );
+
+ // New variant for library export
+ virtual sal_Bool implStorePasswordLibrary( SfxLibrary* pLib, const ::rtl::OUString& aName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage,
+ const ::rtl::OUString& aTargetURL,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xToUseSFI, const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler );
+
+ virtual sal_Bool implLoadPasswordLibrary( SfxLibrary* pLib, const ::rtl::OUString& Name,
+ sal_Bool bVerifyPasswordOnly=false )
+ throw(::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void onNewRootStorage() = 0;
+
+
+ // #56666, Creates another library container
+ // instance of the same derived class
+ virtual SfxLibraryContainer* createInstanceImpl( void ) = 0;
+
+
+ // Interface to get the BasicManager (Hack for password implementation)
+ BasicManager* getBasicManager( void );
+ ::rtl::OUString createAppLibraryFolder( SfxLibrary* pLib, const ::rtl::OUString& aName );
+
+ sal_Bool init( const ::rtl::OUString& rInitialDocumentURL,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxInitialStorage );
+
+ virtual const sal_Char* SAL_CALL getInfoFileName() const = 0;
+ virtual const sal_Char* SAL_CALL getOldInfoFileName() const = 0;
+ virtual const sal_Char* SAL_CALL getLibElementFileExtension() const = 0;
+ virtual const sal_Char* SAL_CALL getLibrariesDir() const = 0;
+
+ // Handle maLibInfoFileURL and maStorageURL correctly
+ void checkStorageURL
+ (
+ const ::rtl::OUString& aSourceURL,
+ ::rtl::OUString& aLibInfoFileURL,
+ ::rtl::OUString& aStorageURL,
+ ::rtl::OUString& aUnexpandedStorageURL
+ );
+ ::rtl::OUString expand_url( const ::rtl::OUString& url )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ SfxLibrary* getImplLib( const String& rLibraryName );
+
+ void storeLibraries_Impl(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage,
+ sal_Bool bComplete );
+
+ void SAL_CALL initializeFromDocumentURL( const ::rtl::OUString& _rInitialDocumentURL );
+ void SAL_CALL initializeFromDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XStorageBasedDocument >& _rxDocument );
+
+ // OEventListenerAdapter
+ virtual void _disposing( const ::com::sun::star::lang::EventObject& _rSource );
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+private:
+ sal_Bool init_Impl( const ::rtl::OUString& rInitialDocumentURL,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxInitialStorage );
+ void implScanExtensions( void );
+
+public:
+ SfxLibraryContainer( void );
+ ~SfxLibraryContainer();
+
+
+ // Interface to set the BasicManager (Hack for password implementation)
+ void setBasicManager( BasicManager* pBasMgr )
+ {
+ mpBasMgr = pBasMgr;
+ }
+
+ void enterMethod();
+ void leaveMethod();
+ bool isDisposed() const { return rBHelper.bInDispose || rBHelper.bDisposed; }
+ void checkDisposed() const;
+
+ // Methods XElementAccess
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType()
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements()
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // Methods XNameAccess
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
+ throw(::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames()
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // Members XStorageBasedLibraryContainer
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > SAL_CALL getRootStorage() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setRootStorage( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rootstorage ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL storeLibrariesToStorage( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& RootStorage ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // Methods XModifiable (base of XPersistentLibraryContainer)
+ virtual ::sal_Bool SAL_CALL isModified( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setModified( ::sal_Bool bModified ) throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // Methods XPersistentLibraryContainer (base of XStorageBasedLibraryContainer)
+ virtual ::com::sun::star::uno::Any SAL_CALL getRootLocation() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getContainerLocationName() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL storeLibraries( ) throw (::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ //Methods XLibraryContainer3
+ virtual ::rtl::OUString SAL_CALL getOriginalLibraryLinkURL( const ::rtl::OUString& Name )
+ throw (::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+
+ // Methods XLibraryContainer2 (base of XPersistentLibraryContainer)
+ virtual sal_Bool SAL_CALL isLibraryLink( const ::rtl::OUString& Name )
+ throw (::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getLibraryLinkURL( const ::rtl::OUString& Name )
+ throw (::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isLibraryReadOnly( const ::rtl::OUString& Name )
+ throw (::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setLibraryReadOnly( const ::rtl::OUString& Name, sal_Bool bReadOnly )
+ throw (::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL renameLibrary( const ::rtl::OUString& Name, const ::rtl::OUString& NewName )
+ throw (::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::uno::RuntimeException);
+
+ // Methods XLibraryContainer (base of XLibraryContainer2)
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > SAL_CALL
+ createLibrary( const ::rtl::OUString& Name )
+ throw(::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL createLibraryLink
+ ( const ::rtl::OUString& Name, const ::rtl::OUString& StorageURL, sal_Bool ReadOnly )
+ throw(::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeLibrary( const ::rtl::OUString& Name )
+ throw(::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isLibraryLoaded( const ::rtl::OUString& Name )
+ throw(::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL loadLibrary( const ::rtl::OUString& Name )
+ throw(::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ // Methods XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Any >& aArguments )
+ throw (::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException);
+
+ // Methods XLibraryContainerPassword
+ virtual sal_Bool SAL_CALL isLibraryPasswordProtected( const ::rtl::OUString& Name )
+ throw (::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isLibraryPasswordVerified( const ::rtl::OUString& Name )
+ throw (::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL verifyLibraryPassword( const ::rtl::OUString& Name, const ::rtl::OUString& Password )
+ throw (::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL changeLibraryPassword( const ::rtl::OUString& Name,
+ const ::rtl::OUString& OldPassword, const ::rtl::OUString& NewPassword )
+ throw (::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+
+ // Methods XContainer
+ virtual void SAL_CALL addContainerListener( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XContainerListener >& xListener )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeContainerListener( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XContainerListener >& xListener )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // Methods XLibraryContainerExport
+ virtual void SAL_CALL exportLibrary( const ::rtl::OUString& Name, const ::rtl::OUString& URL,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler )
+ throw (::com::sun::star::uno::Exception,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+
+ // Methods XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw (::com::sun::star::uno::RuntimeException) = 0;
+ virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw (::com::sun::star::uno::RuntimeException) = 0;
+ // Methods XVBACompatibility
+ virtual ::sal_Bool SAL_CALL getVBACompatibilityMode() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setVBACompatibilityMode( ::sal_Bool _vbacompatmodeon ) throw (::com::sun::star::uno::RuntimeException);
+};
+
+class LibraryContainerMethodGuard
+{
+private:
+ SfxLibraryContainer& m_rContainer;
+public:
+ LibraryContainerMethodGuard( SfxLibraryContainer& _rContainer )
+ :m_rContainer( _rContainer )
+ {
+ m_rContainer.enterMethod();
+ }
+
+ ~LibraryContainerMethodGuard()
+ {
+ m_rContainer.leaveMethod();
+ }
+};
+
+
+//============================================================================
+
+class SfxLibrary
+ : public ::com::sun::star::container::XNameContainer
+ , public ::com::sun::star::container::XContainer
+ , public ::cppu::BaseMutex
+ , public ::cppu::OComponentHelper
+{
+ friend class SfxLibraryContainer;
+ friend class SfxDialogLibraryContainer;
+ friend class SfxScriptLibraryContainer;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxMSF;
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > mxSFI;
+
+ ModifiableHelper& mrModifiable;
+ NameContainer maNameContainer;
+
+ sal_Bool mbLoaded;
+ sal_Bool mbIsModified;
+ sal_Bool mbInitialised;
+
+private:
+
+ ::rtl::OUString maLibElementFileExtension;
+ ::rtl::OUString maLibInfoFileURL;
+ ::rtl::OUString maStorageURL;
+ ::rtl::OUString maUnexpandedStorageURL;
+ ::rtl::OUString maOrignialStorageURL;
+
+ sal_Bool mbLink;
+ sal_Bool mbReadOnly;
+ sal_Bool mbReadOnlyLink;
+ sal_Bool mbPreload;
+
+ sal_Bool mbPasswordProtected;
+ sal_Bool mbPasswordVerified;
+ sal_Bool mbDoc50Password;
+ ::rtl::OUString maPassword;
+
+ sal_Bool mbSharedIndexFile;
+ sal_Bool mbExtension;
+
+ // Additional functionality for localisation
+ // Provide modify state including resources
+ virtual sal_Bool isModified( void ) = 0;
+ virtual void storeResources( void ) = 0;
+ virtual void storeResourcesAsURL( const ::rtl::OUString& URL, const ::rtl::OUString& NewName ) = 0;
+ virtual void storeResourcesToURL( const ::rtl::OUString& URL,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler ) = 0;
+ virtual void storeResourcesToStorage( const ::com::sun::star::uno::Reference
+ < ::com::sun::star::embed::XStorage >& xStorage ) = 0;
+
+protected:
+ inline sal_Bool implIsModified() const { return mbIsModified; }
+ void implSetModified( sal_Bool _bIsModified );
+
+private:
+ /** checks whether the lib is readonly, or a readonly link, throws an IllegalArgumentException if so
+ */
+ void impl_checkReadOnly();
+ /** checks whether the library is loaded, throws a LibraryNotLoadedException (wrapped in a WrappedTargetException),
+ if not.
+ */
+ void impl_checkLoaded();
+
+private:
+ void impl_removeWithoutChecks( const ::rtl::OUString& _rElementName );
+
+public:
+ SfxLibrary(
+ ModifiableHelper& _rModifiable,
+ const ::com::sun::star::uno::Type& aType,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xMSF,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xSFI
+ );
+ SfxLibrary(
+ ModifiableHelper& _rModifiable,
+ const ::com::sun::star::uno::Type& aType,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xMSF,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xSFI,
+ const ::rtl::OUString& aLibInfoFileURL,
+ const ::rtl::OUString&
+ aStorageURL,
+ sal_Bool ReadOnly
+ );
+
+ // Methods XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); }
+ virtual void SAL_CALL release() throw() { OComponentHelper::release(); }
+
+ // Methods XElementAccess
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType( )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements( )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // Methods XNameAccess
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
+ throw(::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // Methods XNameReplace
+ virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement )
+ throw(::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ // Methods XNameContainer
+ virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement )
+ throw(::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeByName( const ::rtl::OUString& Name )
+ throw(::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ // XTypeProvider
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( )
+ throw( ::com::sun::star::uno::RuntimeException );
+ ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL getImplementationId( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // Methods XContainer
+ virtual void SAL_CALL addContainerListener( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XContainerListener >& xListener )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeContainerListener( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XContainerListener >& xListener )
+ throw (::com::sun::star::uno::RuntimeException);
+
+public:
+ struct LibraryContainerAccess { friend class SfxLibraryContainer; private: LibraryContainerAccess() { } };
+ void removeElementWithoutChecks( const ::rtl::OUString& _rElementName, LibraryContainerAccess )
+ {
+ impl_removeWithoutChecks( _rElementName );
+ }
+
+protected:
+ virtual bool SAL_CALL isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const = 0;
+};
+
+//===================================================================
+class ScriptSubPackageIterator
+{
+ com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > m_xMainPackage;
+
+ bool m_bIsValid;
+ bool m_bIsBundle;
+
+ com::sun::star::uno::Sequence< com::sun::star::uno::Reference
+ < com::sun::star::deployment::XPackage > > m_aSubPkgSeq;
+ sal_Int32 m_nSubPkgCount;
+ sal_Int32 m_iNextSubPkg;
+
+ com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >
+ implDetectScriptPackage( const com::sun::star::uno::Reference
+ < com::sun::star::deployment::XPackage > xPackage, bool& rbPureDialogLib );
+
+public:
+ ScriptSubPackageIterator( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xMainPackage );
+
+ com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > getNextScriptSubPackage( bool& rbPureDialogLib );
+};
+
+enum IteratorState
+{
+ USER_EXTENSIONS,
+ SHARED_EXTENSIONS,
+ BUNDLED_EXTENSIONS,
+ END_REACHED
+};
+
+class ScriptExtensionIterator
+{
+public:
+ ScriptExtensionIterator( void );
+ rtl::OUString nextBasicOrDialogLibrary( bool& rbPureDialogLib );
+
+private:
+ com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetScriptPackageFromPackage
+ ( const com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage,
+ bool& rbPureDialogLib );
+
+protected:
+ com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >
+ implGetNextUserScriptPackage( bool& rbPureDialogLib );
+ com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >
+ implGetNextSharedScriptPackage( bool& rbPureDialogLib );
+ com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >
+ implGetNextBundledScriptPackage( bool& rbPureDialogLib );
+
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > m_xContext;
+
+ IteratorState m_eState;
+
+ com::sun::star::uno::Sequence< com::sun::star::uno::Reference
+ < com::sun::star::deployment::XPackage > > m_aUserPackagesSeq;
+ bool m_bUserPackagesLoaded;
+
+ com::sun::star::uno::Sequence< com::sun::star::uno::Reference
+ < com::sun::star::deployment::XPackage > > m_aSharedPackagesSeq;
+ bool m_bSharedPackagesLoaded;
+
+ com::sun::star::uno::Sequence< com::sun::star::uno::Reference
+ < com::sun::star::deployment::XPackage > > m_aBundledPackagesSeq;
+ bool m_bBundledPackagesLoaded;
+
+
+ int m_iUserPackage;
+ int m_iSharedPackage;
+ int m_iBundledPackage;
+
+
+
+ ScriptSubPackageIterator* m_pScriptSubPackageIterator;
+
+}; // end class ScriptExtensionIterator
+
+
+
+} // namespace basic
+
+#endif
+
diff --git a/basic/source/inc/object.hxx b/basic/source/inc/object.hxx
new file mode 100644
index 000000000000..29e4f68cc133
--- /dev/null
+++ b/basic/source/inc/object.hxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SAMPLE_OBJECT_HXX
+#define _SAMPLE_OBJECT_HXX
+
+#include <basic/sbxfac.hxx>
+#ifndef __SBX_SBXVARIABLE_HXX //autogen
+#include <basic/sbxvar.hxx>
+#endif
+#include <basic/sbxobj.hxx>
+
+// 1) Properties:
+// Name der Name, R/O
+// Value ein double-Wert, R/W
+// 2) Methoden:
+// Display Ausgabe eines Textes
+// Square Argument * Argument
+// Event Aufruf eines Basic-Programms
+// 3) Unterobjekte:
+// eine Collection names "Elements". Der Zugriff ist sowohl als
+// Property (fuer das gesamte Objekt) als auch als Methode (fuer
+// einzelne Elemente, wird durchgereicht) implementiert.
+// Diese Implementation ist ein Beispiel fuer eine tabellengesteuerte
+// Version, die sehr viele Elemente enthalten kann.
+// Die Collection findet sich in COLLECTN.*, die in der Collection
+// enthaltenen Objekte in COLLELEM.*
+
+class SampleObject : public SbxObject
+{
+using SbxVariable::GetInfo;
+ // Definition eines Tabelleneintrags. Dies wird hier gemacht,
+ // da dadurch die Methoden und Properties als private deklariert
+ // werden koennen.
+#if defined ( ICC ) || defined ( HPUX ) || defined ( C50 ) || defined ( C52 )
+public:
+#endif
+ typedef void( SampleObject::*pMeth )
+ ( SbxVariable* pThis, SbxArray* pArgs, BOOL bWrite );
+#if defined ( ICC ) || defined ( HPUX )
+private:
+#endif
+
+ struct Methods {
+ const char* pName; // Name des Eintrags
+ SbxDataType eType; // Datentyp
+ pMeth pFunc; // Function Pointer
+ short nArgs; // Argumente und Flags
+ };
+ static Methods aMethods[]; // Methodentabelle
+
+ // Methoden
+ void Display( SbxVariable*, SbxArray*, BOOL );
+ void Event( SbxVariable*, SbxArray*, BOOL );
+ void Square( SbxVariable*, SbxArray*, BOOL );
+ void Create( SbxVariable*, SbxArray*, BOOL );
+ // Infoblock auffuellen
+ SbxInfo* GetInfo( short nIdx );
+ // Broadcaster Notification
+ virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType );
+public:
+ SampleObject( const String& );
+ // Suchen eines Elements
+ virtual SbxVariable* Find( const String&, SbxClassType );
+};
+
+// Die dazugehoerige Factory:
+
+class SampleObjectFac : public SbxFactory
+{
+public:
+ virtual SbxObject* CreateObject( const String& );
+};
+
+#endif
diff --git a/basic/source/inc/opcodes.hxx b/basic/source/inc/opcodes.hxx
new file mode 100644
index 000000000000..ff7eff027f83
--- /dev/null
+++ b/basic/source/inc/opcodes.hxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _OPCODES_HXX
+#define _OPCODES_HXX
+
+#include "sbintern.hxx"
+
+#ifdef MTW
+#undef _NUMBER
+#endif
+
+// Ein Opcode ist entweder 1, 3 oder 5 Bytes lang, je nach numerischen
+// Wert des Opcodes (s.u.).
+
+enum SbiOpcode {
+ // Alle Opcodes ohne Operanden
+ _NOP = 0,
+
+ SbOP0_START = _NOP,
+
+ // Operatoren
+ // die folgenden Operatoren sind genauso angeordnet
+ // wie der enum SbxVarOp
+ _EXP, _MUL, _DIV, _MOD, _PLUS, _MINUS, _NEG,
+ _EQ, _NE, _LT, _GT, _LE, _GE,
+ _IDIV, _AND, _OR, _XOR, _EQV, _IMP, _NOT,
+ _CAT,
+ // Ende enum SbxVarOp
+ _LIKE, _IS,
+ // Laden/speichern
+ _ARGC, // neuen Argv einrichten
+ _ARGV, // TOS ==> aktueller Argv
+ _INPUT, // Input ==> TOS
+ _LINPUT, // Line Input ==> TOS
+ _GET, // TOS anfassen
+ _SET, // Speichern Objekt TOS ==> TOS-1
+ _PUT, // TOS ==> TOS-1
+ _PUTC, // TOS ==> TOS-1, dann ReadOnly
+ _DIM, // DIM
+ _REDIM, // REDIM
+ _REDIMP, // REDIM PRESERVE
+ _ERASE, // TOS loeschen
+ // Verzweigen
+ _STOP, // Programmende
+ _INITFOR, // FOR-Variable initialisieren
+ _NEXT, // FOR-Variable inkrementieren
+ _CASE, // Anfang CASE
+ _ENDCASE, // Ende CASE
+ _STDERROR, // Standard-Fehlerbehandlung
+ _NOERROR, // keine Fehlerbehandlung
+ _LEAVE, // UP verlassen
+ // E/A
+ _CHANNEL, // TOS = Kanalnummer
+ _BPRINT, // print TOS
+ _PRINTF, // print TOS in field
+ _BWRITE, // write TOS
+ _RENAME, // Rename Tos+1 to Tos
+ _PROMPT, // TOS = Prompt for Input
+ _RESTART, // Restartpunkt definieren
+ _CHAN0, // I/O-Kanal 0
+ // Sonstiges
+ _EMPTY, // Leeren Ausdruck auf Stack
+ _ERROR, // TOS = Fehlercode
+ _LSET, // Speichern Objekt TOS ==> TOS-1
+ _RSET, // Speichern Objekt TOS ==> TOS-1
+ _REDIMP_ERASE, // Copies array to be later used by REDIM PRESERVE before erasing it
+ _INITFOREACH,
+ _VBASET, // VBA-like Set
+ _ERASE_CLEAR, // Erase array and clear variable
+ _ARRAYACCESS, // Assign parameters to TOS and get value, used for array of arrays
+ _BYVAL, // byref -> byval for lvalue parameter passed in call
+ SbOP0_END,
+
+ // Alle Opcodes mit einem Operanden
+
+ _NUMBER = 0x40, // Laden einer numerischen Konstanten (+ID)
+
+ SbOP1_START = _NUMBER,
+
+ _SCONST, // Laden einer Stringkonstanten (+ID)
+ _CONST, // Immediate Load (+Wert)
+ _ARGN, // Speichern eines named Args in Argv (+StringID)
+ _PAD, // String auf feste Laenge bringen (+Laenge)
+ // Verzweigungen
+ _JUMP, // Sprung (+Target)
+ _JUMPT, // TOS auswerten, bedingter Sprung (+Target)
+ _JUMPF, // TOS auswerten, bedingter Sprung (+Target)
+ _ONJUMP, // TOS auswerten, Sprung in JUMP-Tabelle (+MaxVal)
+ _GOSUB, // UP-Aufruf (+Target)
+ _RETURN, // UP-Return (+0 oder Target)
+ _TESTFOR, // FOR-Variable testen, inkrementieren (+Endlabel)
+ _CASETO, // Tos+1 <= Case <= Tos, 2xremove (+Target)
+ _ERRHDL, // Fehler-Handler (+Offset)
+ _RESUME, // Resume nach Fehlern (+0 or 1 or Label)
+ // E/A
+ _CLOSE, // (+Kanal/0)
+ _PRCHAR, // (+char)
+ // Verwaltung
+ _SETCLASS, // Set + Klassennamen testen (+StringId)
+ _TESTCLASS, // Check TOS class (+StringId)
+ _LIB, // Libnamen fuer Declare-Procs setzen (+StringId)
+ _BASED, // TOS wird um BASE erhoeht, BASE davor gepusht (+base)
+ // Typanpassung im Argv
+ _ARGTYP, // Letzten Parameter in Argv konvertieren (+Typ)
+ _VBASETCLASS, // VBA-like Set
+ SbOP1_END,
+
+ // Alle Opcodes mit zwei Operanden
+
+ _RTL = 0x80, // Laden aus RTL (+StringID+Typ)
+
+ SbOP2_START = _RTL,
+
+ _FIND, // Laden (+StringID+Typ)
+ _ELEM, // Laden Element (+StringID+Typ)
+ _PARAM, // Parameter (+Offset+Typ)
+ // Verzweigen
+ _CALL, // DECLARE-Methode rufen (+StringID+Typ)
+ _CALLC, // Cdecl-DECLARE-Methode rufen (+StringID+Typ)
+ _CASEIS, // Case-Test (+Test-Opcode+True-Target)
+ // Verwaltung
+ _STMNT, // Beginn eines Statements (+Line+Col)
+ // E/A
+ _OPEN, // (+SvStreamFlags+Flags)
+ // Objekte
+ _LOCAL, // Lokale Variable definieren (+StringID+Typ)
+ _PUBLIC, // Modulglobale Variable (+StringID+Typ)
+ _GLOBAL, // Globale Variable definieren, public-Anweisung (+StringID+Typ)
+ _CREATE, // Objekt kreieren (+StringId+StringID)
+ _STATIC, // Statische Variabl (+StringID+Typ) JSM
+ _TCREATE, // User Defined Objekt kreieren
+ _DCREATE, // Objekt-Array kreieren (+StringId+StringID)
+ _GLOBAL_P, // Globale Variable definieren, die beim Neustart von Basic
+ // nicht ueberschrieben wird, P=PERSIST (+StringID+Typ)
+ _FIND_G, // Sucht globale Variable mit Spezialbehandlung wegen _GLOBAL_P
+ _DCREATE_REDIMP, // Objekt-Array redimensionieren (+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)
+
+ SbOP2_END
+
+};
+
+
+
+#endif
diff --git a/basic/source/inc/parser.hxx b/basic/source/inc/parser.hxx
new file mode 100644
index 000000000000..733a65db7f61
--- /dev/null
+++ b/basic/source/inc/parser.hxx
@@ -0,0 +1,153 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _PARSER_HXX
+#define _PARSER_HXX
+
+#include "expr.hxx"
+#include "codegen.hxx"
+#include "symtbl.hxx"
+
+
+#include <vector>
+typedef ::std::vector< String > StringVector;
+
+struct SbiParseStack;
+
+class SbiParser : public SbiTokenizer
+{
+ friend class SbiExpression;
+
+ SbiParseStack* pStack; // Block-Stack
+ SbiProcDef* pProc; // aktuelle Prozedur
+ SbiExprNode* pWithVar; // aktuelle With-Variable
+ SbiToken eEndTok; // das Ende-Token
+ UINT32 nGblChain; // Chainkette fuer globale DIMs
+ BOOL bGblDefs; // TRUE globale Definitionen allgemein
+ BOOL bNewGblDefs; // TRUE globale Definitionen vor Sub
+ BOOL bSingleLineIf; // TRUE einzeiliges if-Statement
+
+ SbiSymDef* VarDecl( SbiDimList**,BOOL,BOOL );// Variablen-Deklaration
+ SbiProcDef* ProcDecl(BOOL bDecl);// Prozedur-Deklaration
+ void DefStatic( BOOL bPrivate );
+ void DefProc( BOOL bStatic, BOOL bPrivate ); // Prozedur einlesen
+ void DefVar( SbiOpcode eOp, BOOL bStatic ); // DIM/REDIM einlesen
+ void TypeDecl( SbiSymDef&, BOOL bAsNewAlreadyParsed=FALSE ); // AS-Deklaration
+ void OpenBlock( SbiToken, SbiExprNode* = NULL ); // Block oeffnen
+ void CloseBlock(); // Block aufloesen
+ BOOL Channel( BOOL=FALSE ); // Kanalnummer parsen
+ void StmntBlock( SbiToken ); // Statement-Block abarbeiten
+ void DefType( BOOL bPrivate ); // Parse type declaration
+ void DefEnum( BOOL bPrivate ); // Parse enum declaration
+ void DefDeclare( BOOL bPrivate );
+ void EnableCompatibility();
+public:
+ SbxArrayRef rTypeArray; // das Type-Array
+ SbxArrayRef rEnumArray; // Enum types
+ SbiStringPool aGblStrings; // der String-Pool
+ SbiStringPool aLclStrings; // der String-Pool
+ SbiSymPool aGlobals; // globale Variable
+ SbiSymPool aPublics; // modulglobale Variable
+ SbiSymPool aRtlSyms; // Runtime-Library
+ SbiCodeGen aGen; // Code-Generator
+ StarBASIC* pBasic; // StarBASIC-Instanz
+ SbiSymPool* pPool; // aktueller Pool
+ SbiExprType eCurExpr; // aktueller Expr-Typ
+ short nBase; // OPTION BASE-Wert
+ BOOL bText; // OPTION COMPARE TEXT
+ BOOL bExplicit; // TRUE: OPTION EXPLICIT
+ BOOL bClassModule; // TRUE: OPTION ClassModule
+ StringVector aIfaceVector; // Holds all interfaces implemented by a class module
+ StringVector aRequiredTypes; // Types used in Dim As New <type> outside subs
+ SbxDataType eDefTypes[26]; // DEFxxx-Datentypen
+
+ SbiParser( StarBASIC*, SbModule* );
+ BOOL Parse(); // die Aktion
+ SbiExprNode* GetWithVar(); // Innerste With-Variable liefern
+
+ // AB 31.3.1996, Symbol in Runtime-Library suchen
+ SbiSymDef* CheckRTLForSym( const String& rSym, SbxDataType eType );
+ void AddConstants( void );
+
+ BOOL HasGlobalCode(); // Globaler Code definiert?
+
+ BOOL TestToken( SbiToken ); // bestimmtes TOken?
+ BOOL TestSymbol( BOOL=FALSE ); // Symbol?
+ BOOL TestComma(); // Komma oder EOLN?
+ void TestEoln(); // EOLN?
+
+ void Symbol( const KeywordSymbolInfo* pKeywordSymbolInfo = NULL ); // Let oder Call
+ void ErrorStmnt(); // ERROR n
+ void NotImp(); // nicht implementiert
+ void BadBlock(); // LOOP/WEND/NEXT
+ void BadSyntax(); // Falsches SbiToken
+ void NoIf(); // ELSE/ELSE IF ohne IF
+ void Assign(); // LET
+ void Call(); // CALL
+ void Close(); // CLOSE
+ void Declare(); // DECLARE
+ void DefXXX(); // DEFxxx
+ void Dim(); // DIM
+ void ReDim(); // ReDim();
+ void Erase(); // ERASE
+ void Exit(); // EXIT
+ void For(); // FOR...NEXT
+ void Goto(); // GOTO / GOSUB
+ void If(); // IF
+ void Implements(); // IMPLEMENTS
+ void Input(); // INPUT, INPUT #
+ void Line(); // LINE -> LINE INPUT [#] (#i92642)
+ void LineInput(); // LINE INPUT, LINE INPUT #
+ void LSet(); // LSET
+ void Name(); // NAME .. AS ..
+ void On(); // ON ERROR/variable
+ void OnGoto(); // ON...GOTO / GOSUB
+ void Open(); // OPEN
+ void Option(); // OPTION
+ void Print(); // PRINT, PRINT #
+ void SubFunc(); // SUB / FUNCTION
+ void Resume(); // RESUME
+ void Return(); // RETURN
+ void RSet(); // RSET
+ void DoLoop(); // DO...LOOP
+ void Select(); // SELECT ... CASE
+ void Set(); // SET
+ void Static(); // STATIC
+ void Stop(); // STOP/SYSTEM
+ void Type(); // TYPE...AS...END TYPE
+ void Enum(); // TYPE...END ENUM
+ void While(); // WHILE/WEND
+ void With(); // WITH
+ void Write(); // WRITE
+};
+
+
+
+
+
+
+#endif
diff --git a/basic/source/inc/propacc.hxx b/basic/source/inc/propacc.hxx
new file mode 100644
index 000000000000..be396a426185
--- /dev/null
+++ b/basic/source/inc/propacc.hxx
@@ -0,0 +1,203 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _SFX_PROPBAG_HXX
+#define _SFX_PROPBAG_HXX
+
+#include <svl/svarray.hxx>
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HXX_
+#include <com/sun/star/beans/PropertyValue.hpp>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HXX_
+#include <com/sun/star/beans/XPropertySet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSETINFO_HXX_
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYACCESS_HXX_
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYCONTAINER_HXX_
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+#endif
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+
+#define NS_BEANS ::com::sun::star::beans
+#define NS_LANG ::com::sun::star::lang
+#define NS_UNO ::com::sun::star::uno
+
+typedef NS_BEANS::PropertyValue* SbPropertyValuePtr;
+SV_DECL_PTRARR( SbPropertyValueArr_Impl, SbPropertyValuePtr, 4, 4 )
+
+typedef ::cppu::WeakImplHelper2< NS_BEANS::XPropertySet,
+ NS_BEANS::XPropertyAccess > SbPropertyValuesHelper;
+
+
+//==========================================================================
+
+class SbPropertyValues: public SbPropertyValuesHelper
+{
+ SbPropertyValueArr_Impl _aPropVals;
+ NS_UNO::Reference< ::com::sun::star::beans::XPropertySetInfo > _xInfo;
+
+private:
+ INT32 GetIndex_Impl( const ::rtl::OUString &rPropName ) const;
+
+public:
+ SbPropertyValues();
+ virtual ~SbPropertyValues();
+
+ // XPropertySet
+ virtual NS_UNO::Reference< NS_BEANS::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo(void) throw( NS_UNO::RuntimeException );
+ virtual void SAL_CALL setPropertyValue(
+ const ::rtl::OUString& aPropertyName,
+ const NS_UNO::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);
+ virtual NS_UNO::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName )
+ throw( NS_BEANS::UnknownPropertyException,
+ NS_LANG::WrappedTargetException,
+ NS_UNO::RuntimeException);
+ virtual void SAL_CALL addPropertyChangeListener(
+ const ::rtl::OUString& aPropertyName,
+ const NS_UNO::Reference< NS_BEANS::XPropertyChangeListener >& )
+ throw ();
+ virtual void SAL_CALL removePropertyChangeListener(
+ const ::rtl::OUString& aPropertyName,
+ const NS_UNO::Reference< NS_BEANS::XPropertyChangeListener >& )
+ throw ();
+ virtual void SAL_CALL addVetoableChangeListener(
+ const ::rtl::OUString& aPropertyName,
+ const NS_UNO::Reference< NS_BEANS::XVetoableChangeListener >& )
+ throw ();
+ virtual void SAL_CALL removeVetoableChangeListener(
+ const ::rtl::OUString& aPropertyName,
+ const NS_UNO::Reference< NS_BEANS::XVetoableChangeListener >& )
+ throw ();
+
+ // XPropertyAccess
+ virtual NS_UNO::Sequence< NS_BEANS::PropertyValue > SAL_CALL getPropertyValues(void) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setPropertyValues(const NS_UNO::Sequence< NS_BEANS::PropertyValue >& PropertyValues_) 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);
+};
+
+//==========================================================================
+
+typedef ::cppu::WeakImplHelper1< NS_BEANS::XPropertySetInfo > SbPropertySetInfoHelper;
+
+// AB 20.3.2000 Help Class for XPropertySetInfo implementation
+class PropertySetInfoImpl
+{
+ friend class SbPropertySetInfo;
+ friend class SbPropertyContainer;
+
+ NS_UNO::Sequence< NS_BEANS::Property > _aProps;
+
+ sal_Int32 GetIndex_Impl( const ::rtl::OUString &rPropName ) const;
+
+public:
+ PropertySetInfoImpl();
+ PropertySetInfoImpl( NS_UNO::Sequence< NS_BEANS::Property >& rProps );
+
+ // XPropertySetInfo
+ NS_UNO::Sequence< NS_BEANS::Property > SAL_CALL getProperties(void) throw ();
+ NS_BEANS::Property SAL_CALL getPropertyByName(const ::rtl::OUString& Name)
+ throw( NS_UNO::RuntimeException );
+ sal_Bool SAL_CALL hasPropertyByName(const ::rtl::OUString& Name)
+ throw ( NS_UNO::RuntimeException );
+};
+
+class SbPropertySetInfo: public SbPropertySetInfoHelper
+{
+ PropertySetInfoImpl aImpl;
+
+public:
+ SbPropertySetInfo();
+ SbPropertySetInfo( const SbPropertyValueArr_Impl &rPropVals );
+ virtual ~SbPropertySetInfo();
+
+ // XPropertySetInfo
+ virtual NS_UNO::Sequence< NS_BEANS::Property > SAL_CALL getProperties(void)
+ throw( NS_UNO::RuntimeException );
+ virtual NS_BEANS::Property SAL_CALL getPropertyByName(const ::rtl::OUString& Name)
+ throw( NS_UNO::RuntimeException );
+ virtual sal_Bool SAL_CALL hasPropertyByName(const ::rtl::OUString& Name)
+ throw( NS_UNO::RuntimeException );
+};
+
+//==========================================================================
+
+typedef ::cppu::WeakImplHelper2< NS_BEANS::XPropertySetInfo, NS_BEANS::XPropertyContainer > SbPropertyContainerHelper;
+
+class SbPropertyContainer: public SbPropertyContainerHelper
+{
+ PropertySetInfoImpl aImpl;
+
+public:
+ SbPropertyContainer();
+ virtual ~SbPropertyContainer();
+
+ // XPropertyContainer
+ virtual void SAL_CALL addProperty( const ::rtl::OUString& Name,
+ INT16 Attributes,
+ const NS_UNO::Any& DefaultValue)
+ throw( NS_BEANS::PropertyExistException, NS_BEANS::IllegalTypeException,
+ NS_LANG::IllegalArgumentException, NS_UNO::RuntimeException );
+ virtual void SAL_CALL removeProperty(const ::rtl::OUString& Name)
+ throw( NS_BEANS::UnknownPropertyException, NS_UNO::RuntimeException );
+
+ // XPropertySetInfo
+ virtual NS_UNO::Sequence< NS_BEANS::Property > SAL_CALL getProperties(void) throw();
+ virtual NS_BEANS::Property SAL_CALL getPropertyByName(const ::rtl::OUString& Name)
+ throw( NS_UNO::RuntimeException );
+ virtual sal_Bool SAL_CALL hasPropertyByName(const ::rtl::OUString& Name)
+ throw( NS_UNO::RuntimeException );
+
+ // XPropertyAccess
+ virtual NS_UNO::Sequence< NS_BEANS::PropertyValue > SAL_CALL getPropertyValues(void);
+ virtual void SAL_CALL setPropertyValues(const NS_UNO::Sequence< NS_BEANS::PropertyValue >& PropertyValues_);
+};
+
+//=========================================================================
+
+class StarBASIC;
+class SbxArray;
+
+void RTL_Impl_CreatePropertySet( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite );
+
+
+#undef NS_BEANS
+#undef NS_LANG
+#undef NS_UNO
+
+
+
+#endif
+
diff --git a/basic/source/inc/runtime.hxx b/basic/source/inc/runtime.hxx
new file mode 100644
index 000000000000..6ca69209a752
--- /dev/null
+++ b/basic/source/inc/runtime.hxx
@@ -0,0 +1,530 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBRUNTIME_HXX
+#define _SBRUNTIME_HXX
+
+#ifndef _SBX_HXX
+#include <basic/sbx.hxx>
+#endif
+
+#include "sb.hxx"
+
+// Define activates class UCBStream in iosys.cxx
+#define _USE_UNO
+
+#ifdef _USE_UNO
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <osl/file.hxx>
+#include <rtl/math.hxx>
+#include <i18npool/lang.h>
+
+#include <vector>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <unotools/localedatawrapper.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+
+
+// Define activates old file implementation
+// (only in non UCB case)
+// #define _OLD_FILE_IMPL
+
+
+//#include <sal/types.h>
+//#include <rtl/byteseq.hxx>
+//#include <rtl/ustring>
+
+
+namespace basicEncoder
+{
+
+// TODO: Use exported functionality (code is copied from deamons2/ucb)
+class AsciiEncoder
+{
+public:
+ static ::rtl::OUString decodeUnoUrlParamValue(const rtl::OUString & rSource);
+ //static ::rtl::OUString encodeUnoUrlParamValue(const rtl::OUString & rSource);
+ //static ::rtl::ByteSequence decode(const ::rtl::OUString & string);
+ //static ::rtl::OUString encode(const ::rtl::ByteSequence & bytes);
+ //static void test();
+};
+
+}
+
+#endif /* _USE_UNO */
+
+class SbiInstance; // aktiver StarBASIC-Prozess
+class SbiRuntime; // aktive StarBASIC-Prozedur-Instanz
+
+struct SbiArgvStack; // Argv stack element
+struct SbiGosubStack; // GOSUB stack element
+class SbiImage; // Code-Image
+class SbiIoSystem; // Dateisystem
+class SbiDdeControl; // DDE-Steuerung
+class SbiDllMgr; // Aufrufe in DLLs
+class SvNumberFormatter; // Zeit/Datumsfunktionen
+
+enum ForType
+{
+ FOR_TO,
+ FOR_EACH_ARRAY,
+ FOR_EACH_COLLECTION,
+ FOR_EACH_XENUMERATION
+};
+
+struct SbiForStack { // for/next stack:
+ SbiForStack* pNext; // Chain
+ SbxVariableRef refVar; // loop variable
+ SbxVariableRef refEnd; // end expression / for each: Array/BasicCollection object
+ SbxVariableRef refInc; // increment expression
+
+ // For each support
+ ForType eForType;
+ INT32 nCurCollectionIndex;
+ INT32* pArrayCurIndices;
+ INT32* pArrayLowerBounds;
+ INT32* pArrayUpperBounds;
+ Reference< XEnumeration > xEnumeration;
+
+ SbiForStack( void )
+ : pArrayCurIndices( NULL )
+ , pArrayLowerBounds( NULL )
+ , pArrayUpperBounds( NULL )
+ {}
+ ~SbiForStack()
+ {
+ delete[] pArrayCurIndices;
+ delete[] pArrayLowerBounds;
+ delete[] pArrayUpperBounds;
+ }
+};
+
+struct SbiGosubStack { // GOSUB-Stack:
+ SbiGosubStack* pNext; // Chain
+ const BYTE* pCode; // Return-Pointer
+ USHORT nStartForLvl; // #118235: For Level in moment of gosub
+};
+
+#define MAXRECURSION 500 // max. 500 Rekursionen
+
+#define Sb_ATTR_NORMAL 0x0000
+#define Sb_ATTR_HIDDEN 0x0002
+#define Sb_ATTR_SYSTEM 0x0004
+#define Sb_ATTR_VOLUME 0x0008
+#define Sb_ATTR_DIRECTORY 0x0010
+#define Sb_ATTR_ARCHIVE 0x0020
+
+
+class Dir;
+class WildCard;
+
+class SbiRTLData
+{
+public:
+
+#ifdef _OLD_FILE_IMPL
+ Dir* pDir;
+#else
+ ::osl::Directory* pDir;
+#endif
+ INT16 nDirFlags;
+ short nCurDirPos;
+
+ String sFullNameToBeChecked;
+ WildCard* pWildCard;
+
+#ifdef _USE_UNO
+ Sequence< ::rtl::OUString > aDirSeq;
+#endif /* _USE_UNO */
+
+ SbiRTLData();
+ ~SbiRTLData();
+};
+
+// Die Instanz entspricht einem laufenden StarBASIC. Mehrere gleichzeitig
+// laufende BASICs werden ueber verkettete Instanzen verwaltet. Hier liegen
+// alle Daten, die nur leben, wenn BASIC auch lebt, wie z.B. das I/O-System.
+
+typedef ::std::vector
+<
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >
+>
+ComponentVector_t;
+
+
+class SbiInstance
+{
+ friend class SbiRuntime;
+
+ SbiRTLData aRTLData;
+
+ SbiIoSystem* pIosys; // Dateisystem
+ SbiDdeControl* pDdeCtrl; // DDE
+ SbiDllMgr* pDllMgr; // DLL-Calls (DECLARE)
+ StarBASIC* pBasic;
+ SvNumberFormatter* pNumberFormatter;
+ LanguageType meFormatterLangType;
+ DateFormat meFormatterDateFormat;
+ sal_uInt32 nStdDateIdx, nStdTimeIdx, nStdDateTimeIdx;
+
+ SbError nErr; // aktueller Fehlercode
+ String aErrorMsg; // letzte Error-Message fuer $ARG
+ USHORT nErl; // aktuelle Fehlerzeile
+ BOOL bReschedule; // Flag: TRUE = Reschedule in Hauptschleife
+ BOOL bCompatibility; // Flag: TRUE = VBA runtime compatibility mode
+
+ ComponentVector_t ComponentVector;
+
+public:
+ SbiRuntime* pRun; // Call-Stack
+ SbiInstance* pNext; // Instanzen-Chain
+
+ // #31460 Neues Konzept fuer StepInto/Over/Out,
+ // Erklaerung siehe runtime.cxx bei SbiInstance::CalcBreakCallLevel()
+ USHORT nCallLvl; // Call-Level (wg. Rekursion)
+ USHORT nBreakCallLvl; // Call-Level zum Anhalten
+ void CalcBreakCallLevel( USHORT nFlags ); // Gemaess Flags setzen
+
+ SbiInstance( StarBASIC* );
+ ~SbiInstance();
+
+ void Error( SbError ); // trappable Error
+ void Error( SbError, const String& rMsg ); // trappable Error mit Message
+ void ErrorVB( sal_Int32 nVBNumber, const String& rMsg );
+ void setErrorVB( sal_Int32 nVBNumber, const String& rMsg );
+ void FatalError( SbError ); // non-trappable Error
+ void FatalError( SbError, const String& ); // non-trappable Error
+ void Abort(); // Abbruch mit aktuellem Fehlercode
+
+ void Stop();
+ SbError GetErr() { return nErr; }
+ String GetErrorMsg() { return aErrorMsg; }
+ xub_StrLen GetErl() { return nErl; }
+ void EnableReschedule( BOOL bEnable ) { bReschedule = bEnable; }
+ BOOL IsReschedule( void ) { return bReschedule; }
+ void EnableCompatibility( BOOL bEnable ) { bCompatibility = bEnable; }
+ BOOL IsCompatibility( void ) { return bCompatibility; }
+
+ ComponentVector_t& getComponentVector( void ) { return ComponentVector; }
+
+ SbMethod* GetCaller( USHORT );
+ SbModule* GetActiveModule();
+ SbxArray* GetLocals( SbMethod* );
+
+ SbiIoSystem* GetIoSystem() { return pIosys; }
+ SbiDdeControl* GetDdeControl() { return pDdeCtrl; }
+ StarBASIC* GetBasic( void ) { return pBasic; }
+ SbiDllMgr* GetDllMgr();
+ SbiRTLData* GetRTLData() const { return (SbiRTLData*)&aRTLData; }
+
+ SvNumberFormatter* GetNumberFormatter();
+ sal_uInt32 GetStdDateIdx() const { return nStdDateIdx; }
+ sal_uInt32 GetStdTimeIdx() const { return nStdTimeIdx; }
+ sal_uInt32 GetStdDateTimeIdx() const { return nStdDateTimeIdx; }
+
+ // #39629# NumberFormatter auch statisch anbieten
+ static void PrepareNumberFormatter( SvNumberFormatter*& rpNumberFormatter,
+ sal_uInt32 &rnStdDateIdx, sal_uInt32 &rnStdTimeIdx, sal_uInt32 &rnStdDateTimeIdx,
+ LanguageType* peFormatterLangType=NULL, DateFormat* peFormatterDateFormat=NULL );
+};
+
+SbiIoSystem* SbGetIoSystem(); // das aktuelle I/O-System
+
+
+// Verkettbare Items, um Referenzen temporaer zu halten
+struct RefSaveItem
+{
+ SbxVariableRef xRef;
+ RefSaveItem* pNext;
+
+ RefSaveItem() { pNext = NULL; }
+};
+
+
+// Eine Instanz dieser Klasse wird fuer jedes ausgefuehrte Unterprogramm
+// aufgesetzt. Diese Instanz ist das Herz der BASIC-Maschine und enthaelt
+// nur lokale Daten.
+
+class SbiRuntime
+{
+ typedef void( SbiRuntime::*pStep0 )();
+ typedef void( SbiRuntime::*pStep1 )( UINT32 nOp1 );
+ typedef void( SbiRuntime::*pStep2 )( UINT32 nOp1, UINT32 nOp2 );
+ static pStep0 aStep0[]; // Opcode-Tabelle Gruppe 0
+ static pStep1 aStep1[]; // Opcode-Tabelle Gruppe 1
+ static pStep2 aStep2[]; // Opcode-Tabelle Gruppe 2
+
+ StarBASIC& rBasic; // StarBASIC-Instanz
+ SbiInstance* pInst; // aktiver Thread
+ SbModule* pMod; // aktuelles Modul
+ SbMethod* pMeth; // Methoden-Instanz
+ SbiIoSystem* pIosys; // I/O-System
+ const SbiImage* pImg; // Code-Image
+ SbxArrayRef refExprStk; // expression stack
+ SbxArrayRef refCaseStk; // CASE expression stack
+ SbxArrayRef refRedimpArray; // Array saved to use for REDIM PRESERVE
+ SbxVariableRef xDummyVar; // Ersatz fuer nicht gefundene Variablen
+ SbiArgvStack* pArgvStk; // ARGV-Stack
+ SbiGosubStack* pGosubStk; // GOSUB stack
+ SbiForStack* pForStk; // FOR/NEXT-Stack
+ USHORT nExprLvl; // Tiefe des Expr-Stacks
+ USHORT nGosubLvl; // Zum Vermeiden von Tot-Rekursionen
+ USHORT nForLvl; // #118235: Maintain for level
+ const BYTE* pCode; // aktueller Code-Pointer
+ const BYTE* pStmnt; // Beginn des lezten Statements
+ const BYTE* pError; // Adresse des aktuellen Error-Handlers
+ const BYTE* pRestart; // Restart-Adresse
+ const BYTE* pErrCode; // Restart-Adresse RESUME NEXT
+ const BYTE* pErrStmnt; // Restart-Adresse RESUMT 0
+ String aLibName; // Lib-Name fuer Declare-Call
+ SbxArrayRef refParams; // aktuelle Prozedur-Parameter
+ SbxArrayRef refLocals; // lokale Variable
+ SbxArrayRef refArgv; // aktueller Argv
+ // AB, 28.3.2000 #74254, Ein refSaveObj reicht nicht! Neu: pRefSaveList (s.u.)
+ //SbxVariableRef refSaveObj; // #56368 Bei StepElem Referenz sichern
+ short nArgc; // aktueller Argc
+ BOOL bRun; // TRUE: Programm ist aktiv
+ BOOL bError; // TRUE: Fehler behandeln
+ BOOL bInError; // TRUE: in einem Fehler-Handler
+ BOOL bBlocked; // TRUE: blocked by next call level, #i48868
+ BOOL bVBAEnabled;
+ USHORT nFlags; // Debugging-Flags
+ SbError nError; // letzter Fehler
+ USHORT nOps; // Opcode-Zaehler
+ sal_uInt32 m_nLastTime;
+
+ RefSaveItem* pRefSaveList; // #74254 Temporaere Referenzen sichern
+ RefSaveItem* pItemStoreList; // Unbenutzte Items aufbewahren
+ void SaveRef( SbxVariable* pVar )
+ {
+ RefSaveItem* pItem = pItemStoreList;
+ if( pItem )
+ pItemStoreList = pItem->pNext;
+ else
+ pItem = new RefSaveItem();
+ pItem->pNext = pRefSaveList;
+ pItem->xRef = pVar;
+ pRefSaveList = pItem;
+ }
+ void ClearRefs( void )
+ {
+ while( pRefSaveList )
+ {
+ RefSaveItem* pToClearItem = pRefSaveList;
+ pRefSaveList = pToClearItem->pNext;
+ pToClearItem->xRef = NULL;
+ pToClearItem->pNext = pItemStoreList;
+ pItemStoreList = pToClearItem;
+ }
+ }
+
+ SbxVariable* FindElement
+ ( SbxObject* pObj, UINT32 nOp1, UINT32 nOp2, SbError, BOOL bLocal, BOOL bStatic = FALSE );
+ void SetupArgs( SbxVariable*, UINT32 );
+ SbxVariable* CheckArray( SbxVariable* );
+
+ void PushVar( SbxVariable* ); // Variable push
+ SbxVariableRef PopVar(); // Variable pop
+ SbxVariable* GetTOS( short=0 ); // Variable vom TOS holen
+ void TOSMakeTemp(); // TOS in temp. Variable wandeln
+ BOOL ClearExprStack(); // Expr-Stack freigeben
+
+ void PushGosub( const BYTE* ); // GOSUB-Element push
+ void PopGosub(); // GOSUB-Element pop
+ void ClearGosubStack(); // GOSUB-Stack freigeben
+
+ void PushArgv(); // Argv-Element push
+ void PopArgv(); // Argv-Element pop
+ void ClearArgvStack(); // Argv-Stack freigeben
+
+ void PushFor(); // For-Element push
+ void PushForEach(); // For-Each-Element push
+ void PopFor(); // For-Element pop
+ void ClearForStack(); // For-Stack freigeben
+
+ void StepArith( SbxOperator ); // arithmetische Verknuepfungen
+ void StepUnary( SbxOperator ); // unaere Verknuepfungen
+ void StepCompare( SbxOperator );// Vergleiche
+
+ void SetParameters( SbxArray* );// Parameter uebernehmen
+
+ // MUSS NOCH IMPLEMENTIERT WERDEN
+ void DllCall( const String&, const String&, SbxArray*, SbxDataType, BOOL );
+
+ // #56204 DIM-Funktionalitaet in Hilfsmethode auslagern (step0.cxx)
+ void DimImpl( SbxVariableRef refVar );
+
+ // #115829
+ bool implIsClass( SbxObject* pObj, const String& aClass );
+
+ void StepSETCLASS_impl( UINT32 nOp1, bool bHandleDflt = false );
+
+ // Die nachfolgenden Routinen werden vom Single Stepper
+ // gerufen und implementieren die einzelnen Opcodes
+ void StepNOP(), StepEXP(), StepMUL(), StepDIV();
+ void StepMOD(), StepPLUS(), StepMINUS(), StepNEG();
+ void StepEQ(), StepNE(), StepLT(), StepGT();
+ void StepLE(), StepGE(), StepIDIV(), StepAND();
+ void StepOR(), StepXOR(), StepEQV(), StepIMP();
+ void StepNOT(), StepCAT(), StepLIKE(), StepIS();
+ void StepCLONE(), StepOLDBASED(), StepARGC();
+ void StepARGV(), StepINPUT(), StepLINPUT(), StepSTOP();
+ void StepGET(), StepSET(), StepVBASET(), StepPUT(), StepPUTC();
+ void StepSET_Impl( SbxVariableRef& refVal, SbxVariableRef& refVar, bool bDefaultHandling = false );
+ void StepDIM(), StepREDIM(), StepREDIMP(), StepERASE();
+ void StepINITFOR(), StepNEXT(), StepERROR(), StepINITFOREACH();
+ void StepCASE(), StepENDCASE(), StepSTDERROR();
+ void StepNOERROR(), StepCHANNEL(), StepCHANNEL0(), StepPRINT();
+ void StepPRINTF(), StepWRITE(), StepRENAME(), StepPROMPT();
+ void StepRESTART(), StepEMPTY(), StepLEAVE();
+ void StepLSET(), StepRSET(), StepREDIMP_ERASE(), StepERASE_CLEAR();
+ void StepARRAYACCESS(), StepBYVAL();
+ // Alle Opcodes mit einem Operanden
+ void StepLOADNC( UINT32 ), StepLOADSC( UINT32 ), StepLOADI( UINT32 );
+ void StepARGN( UINT32 ), StepBASED( UINT32 ), StepPAD( UINT32 );
+ void StepJUMP( UINT32 ), StepJUMPT( UINT32 );
+ void StepJUMPF( UINT32 ), StepONJUMP( UINT32 );
+ void StepGOSUB( UINT32 ), StepRETURN( UINT32 );
+ void StepTESTFOR( UINT32 ), StepCASETO( UINT32 ), StepERRHDL( UINT32 );
+ void StepRESUME( UINT32 ), StepSETCLASS( UINT32 ), StepVBASETCLASS( UINT32 ), StepTESTCLASS( UINT32 ), StepLIB( UINT32 );
+ bool checkClass_Impl( const SbxVariableRef& refVal, const String& aClass, bool bRaiseErrors, bool bDefault = true );
+ void StepCLOSE( UINT32 ), StepPRCHAR( UINT32 ), StepARGTYP( UINT32 );
+ // Alle Opcodes mit zwei Operanden
+ void StepRTL( UINT32, UINT32 ), StepPUBLIC( UINT32, UINT32 ), StepPUBLIC_P( UINT32, UINT32 );
+ void StepPUBLIC_Impl( UINT32, UINT32, bool bUsedForClassModule );
+ void StepFIND_Impl( SbxObject* pObj, UINT32 nOp1, UINT32 nOp2, SbError, BOOL bLocal, BOOL bStatic = FALSE );
+ void StepFIND( UINT32, UINT32 ), StepELEM( UINT32, UINT32 );
+ void StepGLOBAL( UINT32, UINT32 ), StepLOCAL( UINT32, UINT32 );
+ void StepPARAM( UINT32, UINT32), StepCREATE( UINT32, UINT32 );
+ void StepCALL( UINT32, UINT32 ), StepCALLC( UINT32, UINT32 );
+ void StepCASEIS( UINT32, UINT32 ), StepSTMNT( UINT32, UINT32 );
+ SbxVariable* StepSTATIC_Impl( String& aName, SbxDataType& t );
+ void StepOPEN( UINT32, UINT32 ), StepSTATIC( UINT32, UINT32 );
+ void StepTCREATE(UINT32,UINT32), StepDCREATE(UINT32,UINT32);
+ void StepGLOBAL_P( UINT32, UINT32 ),StepFIND_G( UINT32, UINT32 );
+ void StepDCREATE_REDIMP(UINT32,UINT32), StepDCREATE_IMPL(UINT32,UINT32);
+ void StepFIND_CM( UINT32, UINT32 );
+ void StepFIND_STATIC( UINT32, UINT32 );
+ void implCreateFixedString( SbxVariable* pStrVar, UINT32 nOp2 );
+public:
+ void SetVBAEnabled( bool bEnabled );
+ USHORT GetImageFlag( USHORT n ) const;
+ USHORT GetBase();
+ xub_StrLen nLine,nCol1,nCol2; // aktuelle Zeile, Spaltenbereich
+ SbiRuntime* pNext; // Stack-Chain
+
+ SbiRuntime( SbModule*, SbMethod*, UINT32 );
+ ~SbiRuntime();
+ void Error( SbError, bool bVBATranslationAlreadyDone = false ); // Fehler setzen, falls != 0
+ void Error( SbError, const String& ); // Fehler setzen, falls != 0
+ void FatalError( SbError ); // Fehlerbehandlung=Standard, Fehler setzen
+ void FatalError( SbError, const String& ); // Fehlerbehandlung=Standard, Fehler setzen
+ static sal_Int32 translateErrorToVba( SbError nError, String& rMsg );
+ void DumpPCode();
+ BOOL Step(); // Einzelschritt (ein Opcode)
+ void Stop() { bRun = FALSE; }
+ BOOL IsRun() { return bRun; }
+ void block( void ) { bBlocked = TRUE; }
+ void unblock( void ) { bBlocked = FALSE; }
+ SbMethod* GetMethod() { return pMeth; }
+ SbModule* GetModule() { return pMod; }
+ USHORT GetDebugFlags() { return nFlags; }
+ void SetDebugFlags( USHORT nFl ) { nFlags = nFl; }
+ SbMethod* GetCaller();
+ SbxArray* GetLocals();
+ SbxArray* GetParams();
+
+ SbxBase* FindElementExtern( const String& rName );
+ static bool isVBAEnabled();
+
+};
+
+inline void checkArithmeticOverflow( double d )
+{
+ if( !::rtl::math::isFinite( d ) )
+ StarBASIC::Error( SbERR_MATH_OVERFLOW );
+}
+
+inline void checkArithmeticOverflow( SbxVariable* pVar )
+{
+ if( pVar->GetType() == SbxDOUBLE )
+ {
+ double d = pVar->GetDouble();
+ checkArithmeticOverflow( d );
+ }
+}
+
+// Hilfsfunktion, um aktives Basic zu finden
+StarBASIC* GetCurrentBasic( StarBASIC* pRTBasic );
+
+// Get information if security restrictions should be
+// used (File IO based on UCB, no RTL function SHELL
+// no DDE functionality, no DLLCALL) in basic because
+// of portal "virtual" users (portal user != UNIX user)
+// (Implemented in iosys.cxx)
+BOOL needSecurityRestrictions( void );
+
+// Returns TRUE if UNO is available, otherwise the old
+// file system implementation has to be used
+// (Implemented in iosys.cxx)
+BOOL hasUno( void );
+
+// Converts possibly relative paths to absolute paths
+// according to the setting done by ChDir/ChDrive
+// (Implemented in methods.cxx)
+String getFullPath( const String& aRelPath );
+
+// Sets (virtual) current path for UCB file access
+void implChDir( const String& aDir );
+
+// Sets (virtual) current drive for UCB file access
+void implChDrive( const String& aDrive );
+
+// Returns (virtual) current path for UCB file access
+String implGetCurDir( void );
+
+// Implementation of StepRENAME with UCB
+// (Implemented in methods.cxx, so step0.cxx
+// has not to be infected with UNO)
+void implStepRenameUCB( const String& aSource, const String& aDest );
+
+//*** OSL file access ***
+// #87427 OSL need File URLs, so map to getFullPath
+inline String getFullPathUNC( const String& aRelPath )
+{
+ return getFullPath( aRelPath );
+}
+void implStepRenameOSL( const String& aSource, const String& aDest );
+bool IsBaseIndexOne();
+
+#endif
+
diff --git a/basic/source/inc/sbcomp.hxx b/basic/source/inc/sbcomp.hxx
new file mode 100644
index 000000000000..6335a55da62f
--- /dev/null
+++ b/basic/source/inc/sbcomp.hxx
@@ -0,0 +1,38 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBCOMP_HXX
+#define _SBCOMP_HXX
+
+// das folgende habe ich der neuen Datei von MD entnommen! (MT)
+#include "sbintern.hxx"
+#include "token.hxx" // Tokenizer
+#include "symtbl.hxx" // Symbolverwaltung
+#include "parser.hxx" // Parser
+#include "codegen.hxx" // Code-Generator
+
+#endif
diff --git a/basic/source/inc/sbintern.hxx b/basic/source/inc/sbintern.hxx
new file mode 100644
index 000000000000..4c54e2301bd5
--- /dev/null
+++ b/basic/source/inc/sbintern.hxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SB_INTERN_HXX
+#define _SB_INTERN_HXX
+
+#include <basic/sbxfac.hxx>
+#include <unotools/transliterationwrapper.hxx>
+#include "sb.hxx"
+
+namespace utl
+{
+ class TransliterationWrapper;
+}
+class SbUnoFactory;
+class SbTypeFactory;
+class SbOLEFactory;
+class SbFormFactory;
+class SbiInstance;
+class SbModule;
+
+class SbiFactory : public SbxFactory
+{
+public:
+ virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX );
+ virtual SbxObject* CreateObject( const String& );
+};
+
+typedef ::std::vector< String > StringVector;
+
+struct SbClassData
+{
+ SbxArrayRef mxIfaces;
+
+ // types this module depends on because of use in Dim As New <type>
+ // needed for initialization order of class modules
+ StringVector maRequiredTypes;
+
+ SbClassData( void );
+ ~SbClassData( void )
+ { clear(); }
+ void clear( void );
+};
+
+// #115824: Factory class to create class objects (type command)
+// Implementation: sb.cxx
+class SbClassFactory : public SbxFactory
+{
+ SbxObjectRef xClassModules;
+
+public:
+ SbClassFactory( void );
+ virtual ~SbClassFactory();
+
+ void AddClassModule( SbModule* pClassModule );
+ void RemoveClassModule( SbModule* pClassModule );
+
+ virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX );
+ virtual SbxObject* CreateObject( const String& );
+
+ SbModule* FindClass( const String& rClassName );
+};
+
+// Stack fuer die im Fehlerfall abgebaute SbiRuntime Kette
+class SbErrorStackEntry
+{
+public:
+ SbErrorStackEntry(SbMethodRef aM, xub_StrLen nL, xub_StrLen nC1, xub_StrLen nC2)
+ : aMethod(aM), nLine(nL), nCol1(nC1), nCol2(nC2) {}
+ SbMethodRef aMethod;
+ xub_StrLen nLine;
+ xub_StrLen nCol1, nCol2;
+};
+
+SV_DECL_PTRARR_DEL(SbErrorStack, SbErrorStackEntry*, 1, 1)
+
+
+
+struct SbiGlobals
+{
+ SbiInstance* pInst; // alle aktiven Runtime-Instanzen
+ SbiFactory* pSbFac; // StarBASIC-Factory
+ SbUnoFactory* pUnoFac; // Factory fuer Uno-Structs bei DIM AS NEW
+ SbTypeFactory* pTypeFac; // Factory for user defined types
+ SbClassFactory* pClassFac; // Factory for user defined classes (based on class modules)
+ SbOLEFactory* pOLEFac; // Factory for OLE types
+ SbFormFactory* pFormFac; // Factory for user forms
+ SbModule* pMod; // aktuell aktives Modul
+ SbModule* pCompMod; // aktuell compiliertes Modul
+ short nInst; // Anzahl BASICs
+ Link aErrHdl; // globaler Error-Handler
+ Link aBreakHdl; // globaler Break-Handler
+ SbError nCode; // aktueller Fehlercode
+ xub_StrLen nLine; // aktuelle Zeile
+ xub_StrLen nCol1,nCol2; // aktuelle Spalten (von,bis)
+ BOOL bCompiler; // Flag fuer Compiler-Error
+ BOOL bGlobalInitErr; // Beim GlobalInit trat ein Compiler-Fehler auf
+ BOOL bRunInit; // TRUE, wenn RunInit vom Basic aktiv ist
+ String aErrMsg; // Puffer fuer GetErrorText()
+ SbLanguageMode eLanguageMode; // Flag fuer Visual-Basic-Script-Modus
+ SbErrorStack* pErrStack; // Stack fuer die im Fehlerfall abgebaute SbiRuntime Kette
+ ::utl::TransliterationWrapper* pTransliterationWrapper; // For StrComp
+ BOOL bBlockCompilerError;
+ BasicManager* pAppBasMgr;
+ StarBASIC* pMSOMacroRuntimLib; // Lib containing MSO Macro Runtime API entry symbols
+
+ SbiGlobals();
+ ~SbiGlobals();
+};
+
+// Utility-Makros und -Routinen
+
+SbiGlobals* GetSbData();
+
+#define pINST GetSbData()->pInst
+#define pMOD GetSbData()->pMod
+#define pCMOD GetSbData()->pCompMod
+#define pSBFAC GetSbData()->pSbFac
+#define pUNOFAC GetSbData()->pUnoFac
+#define pTYPEFAC GetSbData()->pTypeFac
+#define pCLASSFAC GetSbData()->pClassFac
+#define pOLEFAC GetSbData()->pOLEFac
+#define pFORMFAC GetSbData()->pFormFac
+
+#endif
+
diff --git a/basic/source/inc/sbjsmeth.hxx b/basic/source/inc/sbjsmeth.hxx
new file mode 100644
index 000000000000..80c301821884
--- /dev/null
+++ b/basic/source/inc/sbjsmeth.hxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+
+#ifndef _SB_SBJSMETH_HXX
+#define _SB_SBJSMETH_HXX
+
+#include <basic/sbmeth.hxx>
+
+// Basic-Modul fuer JavaScript-Sourcen.
+// Alle Basic-spezifischen Methoden muessen virtuell ueberladen und deaktiviert
+// werden. Die Unterscheidung von normalen Modulen erfolgt uebr RTTI.
+
+class SbJScriptMethod : public SbMethod
+{
+public:
+ SbJScriptMethod( const String&, SbxDataType, SbModule* );
+ virtual ~SbJScriptMethod();
+
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_JSCRIPTMETH,2);
+ TYPEINFO();
+};
+
+#ifndef __SB_SBJSCRIPTMETHODREF_HXX
+#define __SB_SBJSCRIPTMETHODREF_HXX
+SV_DECL_IMPL_REF(SbJScriptMethod)
+#endif
+
+#endif
diff --git a/basic/source/inc/sbjsmod.hxx b/basic/source/inc/sbjsmod.hxx
new file mode 100644
index 000000000000..a9b035e79da2
--- /dev/null
+++ b/basic/source/inc/sbjsmod.hxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SB_SBJSMOD_HXX
+#define _SB_SBJSMOD_HXX
+
+#include <basic/sbmod.hxx>
+
+// Basic-Modul fuer JavaScript-Sourcen.
+// Alle Basic-spezifischen Methoden muessen virtuell ueberladen und deaktiviert
+// werden. Die Unterscheidung von normalen Modulen erfolgt uebr RTTI.
+
+class SbJScriptModule : public SbModule
+{
+ virtual BOOL LoadData( SvStream&, USHORT );
+ virtual BOOL StoreData( SvStream& ) const;
+public:
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_JSCRIPTMOD,1);
+ TYPEINFO();
+ SbJScriptModule( const String& ); // DURCHREICHEN
+};
+
+#endif
+
+
+
diff --git a/basic/source/inc/sbtrace.hxx b/basic/source/inc/sbtrace.hxx
new file mode 100755
index 000000000000..e8a482c2f6e9
--- /dev/null
+++ b/basic/source/inc/sbtrace.hxx
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBTRACE_HXX
+#define _SBTRACE_HXX
+
+// #define DBG_TRACE_BASIC
+
+#ifdef DBG_TRACE_BASIC
+void dbg_InitTrace( void );
+void dbg_traceStep( SbModule* pModule, UINT32 nPC, INT32 nCallLvl );
+void dbg_traceNotifyCall( SbModule* pModule, SbMethod* pMethod, INT32 nCallLvl, bool bLeave = false );
+void dbg_traceNotifyError( SbError nTraceErr, const String& aTraceErrMsg, bool bTraceErrHandled, INT32 nCallLvl );
+void dbg_RegisterTraceTextForPC( SbModule* pModule, UINT32 nPC,
+ const String& aTraceStr_STMNT, const String& aTraceStr_PCode );
+#endif
+
+#endif
diff --git a/basic/source/inc/sbunoobj.hxx b/basic/source/inc/sbunoobj.hxx
new file mode 100644
index 000000000000..78afa9783ca8
--- /dev/null
+++ b/basic/source/inc/sbunoobj.hxx
@@ -0,0 +1,326 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef SB_UNO_OBJ
+#define SB_UNO_OBJ
+
+#include <basic/sbxobj.hxx>
+#include <basic/sbxmeth.hxx>
+#include <basic/sbxprop.hxx>
+#include <basic/sbxfac.hxx>
+#ifndef __SBX_SBX_HXX //autogen
+#include <basic/sbx.hxx>
+#endif
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/beans/XIntrospectionAccess.hpp>
+#include <com/sun/star/beans/XIntrospection.hpp>
+#include <com/sun/star/script/XInvocation.hpp>
+#include <com/sun/star/reflection/XIdlClass.hpp>
+#include <com/sun/star/reflection/XServiceTypeDescription2.hpp>
+#include <com/sun/star/reflection/XSingletonTypeDescription.hpp>
+#include <rtl/ustring.hxx>
+
+class SbUnoObject: public SbxObject
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess > mxUnoAccess;
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMaterialHolder > mxMaterialHolder;
+ ::com::sun::star::uno::Reference< ::com::sun::star::script::XInvocation > mxInvocation;
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XExactName > mxExactName;
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XExactName > mxExactNameInvocation;
+ BOOL bNeedIntrospection;
+ BOOL bIgnoreNativeCOMObjectMembers;
+ ::com::sun::star::uno::Any maTmpUnoObj; // Only to save obj for doIntrospection!
+
+ // Hilfs-Methode zum Anlegen der dbg_-Properties
+ void implCreateDbgProperties( void );
+
+ // Hilfs-Methode zum Anlegen aller Properties und Methoden
+ // (Beim on-demand-Mechanismus erforderlich fuer die dbg_-Properties)
+ void implCreateAll( void );
+
+public:
+ static bool getDefaultPropName( SbUnoObject* pUnoObj, String& sDfltProp );
+ TYPEINFO();
+ SbUnoObject( const String& aName_, const ::com::sun::star::uno::Any& aUnoObj_ );
+ ~SbUnoObject();
+
+ // #76470 Introspection on Demand durchfuehren
+ void doIntrospection( void );
+
+ // Find ueberladen, um z.B. NameAccess zu unterstuetzen
+ virtual SbxVariable* Find( const String&, SbxClassType );
+
+ // Force creation of all properties for debugging
+ void createAllProperties( void )
+ { implCreateAll(); }
+
+ // Wert rausgeben
+ ::com::sun::star::uno::Any getUnoAny( void );
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess > getIntrospectionAccess( void ) { return mxUnoAccess; }
+ ::com::sun::star::uno::Reference< ::com::sun::star::script::XInvocation > getInvocation( void ) { return mxInvocation; }
+
+ void SFX_NOTIFY( SfxBroadcaster&, const TypeId&, const SfxHint& rHint, const TypeId& );
+};
+SV_DECL_IMPL_REF(SbUnoObject);
+
+
+// #67781 Rueckgabewerte der Uno-Methoden loeschen
+void clearUnoMethods( void );
+
+class SbUnoMethod : public SbxMethod
+{
+ friend class SbUnoObject;
+ friend void clearUnoMethods( void );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::reflection::XIdlMethod > m_xUnoMethod;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::reflection::ParamInfo >* pParamInfoSeq;
+
+ // #67781 Verweis auf vorige und naechste Methode in der Methoden-Liste
+ SbUnoMethod* pPrev;
+ SbUnoMethod* pNext;
+
+ bool mbInvocation; // Method is based on invocation
+
+public:
+ TYPEINFO();
+
+ SbUnoMethod( const String& aName_, SbxDataType eSbxType, ::com::sun::star::uno::Reference< ::com::sun::star::reflection::XIdlMethod > xUnoMethod_,
+ bool bInvocation );
+ virtual ~SbUnoMethod();
+ virtual SbxInfo* GetInfo();
+
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::reflection::ParamInfo >& getParamInfos( void );
+
+ bool isInvocationBased( void )
+ { return mbInvocation; }
+};
+
+
+class SbUnoProperty : public SbxProperty
+{
+ friend class SbUnoObject;
+
+ // Daten der Uno-Property
+ ::com::sun::star::beans::Property aUnoProp;
+ INT32 nId;
+
+ bool mbInvocation; // Property is based on invocation
+
+ virtual ~SbUnoProperty();
+public:
+ TYPEINFO();
+ SbUnoProperty( const String& aName_, SbxDataType eSbxType,
+ const ::com::sun::star::beans::Property& aUnoProp_, INT32 nId_, bool bInvocation );
+
+ bool isInvocationBased( void )
+ { return mbInvocation; }
+};
+
+// Factory-Klasse fuer das Anlegen von Uno-Structs per DIM AS NEW
+class SbUnoFactory : public SbxFactory
+{
+public:
+ virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX );
+ virtual SbxObject* CreateObject( const String& );
+};
+
+// Wrapper fuer eine Uno-Klasse
+class SbUnoClass : public SbxObject
+{
+ const ::com::sun::star::uno::Reference< ::com::sun::star::reflection::XIdlClass > m_xClass;
+
+public:
+ TYPEINFO();
+ SbUnoClass( const String& aName_ )
+ : SbxObject( aName_ )
+ {}
+ SbUnoClass( const String& aName_, const ::com::sun::star::uno::Reference< ::com::sun::star::reflection::XIdlClass >& xClass_ )
+ : SbxObject( aName_ )
+ , m_xClass( xClass_ )
+ {}
+ //~SbUnoClass();
+
+ // Find ueberladen, um Elemente on Demand anzulegen
+ virtual SbxVariable* Find( const String&, SbxClassType );
+
+ // Wert rausgeben
+ const ::com::sun::star::uno::Reference< ::com::sun::star::reflection::XIdlClass >& getUnoClass( void ) { return m_xClass; }
+
+ //void SFX_NOTIFY( SfxBroadcaster&, const TypeId&, const SfxHint& rHint, const TypeId& );
+};
+SV_DECL_IMPL_REF(SbUnoClass);
+
+
+// Funktion, um einen globalen Bezeichner im
+// UnoScope zu suchen und fuer Sbx zu wrappen
+SbUnoClass* findUnoClass( const String& rName );
+
+
+// Wrapper for UNO Service
+class SbUnoService : public SbxObject
+{
+ const ::com::sun::star::uno::Reference< ::com::sun::star::reflection::XServiceTypeDescription2 > m_xServiceTypeDesc;
+ bool m_bNeedsInit;
+
+public:
+ TYPEINFO();
+ SbUnoService( const String& aName_,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::reflection::XServiceTypeDescription2 >& xServiceTypeDesc )
+ : SbxObject( aName_ )
+ , m_xServiceTypeDesc( xServiceTypeDesc )
+ , m_bNeedsInit( true )
+ {}
+
+ virtual SbxVariable* Find( const String&, SbxClassType );
+
+ void SFX_NOTIFY( SfxBroadcaster&, const TypeId&, const SfxHint& rHint, const TypeId& );
+};
+SV_DECL_IMPL_REF(SbUnoService);
+
+SbUnoService* findUnoService( const String& rName );
+
+
+void clearUnoServiceCtors( void );
+
+class SbUnoServiceCtor : public SbxMethod
+{
+ friend class SbUnoService;
+ friend void clearUnoServiceCtors( void );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::reflection::XServiceConstructorDescription > m_xServiceCtorDesc;
+
+ SbUnoServiceCtor* pPrev;
+ SbUnoServiceCtor* pNext;
+
+public:
+ TYPEINFO();
+
+ SbUnoServiceCtor( const String& aName_, ::com::sun::star::uno::Reference< ::com::sun::star::reflection::XServiceConstructorDescription > xServiceCtorDesc );
+ virtual ~SbUnoServiceCtor();
+ virtual SbxInfo* GetInfo();
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::reflection::XServiceConstructorDescription > getServiceCtorDesc( void )
+ { return m_xServiceCtorDesc; }
+};
+
+
+// Wrapper for UNO Singleton
+class SbUnoSingleton : public SbxObject
+{
+ const ::com::sun::star::uno::Reference< ::com::sun::star::reflection::XSingletonTypeDescription > m_xSingletonTypeDesc;
+
+public:
+ TYPEINFO();
+ SbUnoSingleton( const String& aName_,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::reflection::XSingletonTypeDescription >& xSingletonTypeDesc );
+
+ void SFX_NOTIFY( SfxBroadcaster&, const TypeId&, const SfxHint& rHint, const TypeId& );
+};
+SV_DECL_IMPL_REF(SbUnoSingleton);
+
+SbUnoSingleton* findUnoSingleton( const String& rName );
+
+
+// #105565 Special Object to wrap a strongly typed Uno Any
+class SbUnoAnyObject: public SbxObject
+{
+ ::com::sun::star::uno::Any mVal;
+
+public:
+ SbUnoAnyObject( const ::com::sun::star::uno::Any& rVal )
+ : SbxObject( String() )
+ , mVal( rVal )
+ {}
+
+ const ::com::sun::star::uno::Any& getValue( void )
+ { return mVal; }
+
+ TYPEINFO();
+};
+
+
+// #112509 Special SbxArray to transport named parameters for calls
+// to OLEAutomation objects through the UNO OLE automation bridge
+
+class AutomationNamedArgsSbxArray : public SbxArray
+{
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > maNameSeq;
+public:
+ TYPEINFO();
+ AutomationNamedArgsSbxArray( sal_Int32 nSeqSize )
+ : maNameSeq( nSeqSize )
+ {}
+
+ ::com::sun::star::uno::Sequence< ::rtl::OUString >& getNames( void )
+ { return maNameSeq; }
+};
+
+
+class StarBASIC;
+
+// Impl-Methoden fuer RTL
+void RTL_Impl_CreateUnoStruct( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite );
+void RTL_Impl_CreateUnoService( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite );
+void RTL_Impl_CreateUnoServiceWithArguments( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite );
+void RTL_Impl_CreateUnoValue( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite );
+void RTL_Impl_GetProcessServiceManager( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite );
+void RTL_Impl_HasInterfaces( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite );
+void RTL_Impl_IsUnoStruct( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite );
+void RTL_Impl_EqualUnoObjects( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite );
+void RTL_Impl_GetDefaultContext( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite );
+
+
+//========================================================================
+// #118116 Collection object
+
+class BasicCollection : public SbxObject
+{
+ friend class SbiRuntime;
+ SbxArrayRef xItemArray;
+ static SbxInfoRef xAddInfo;
+ static SbxInfoRef xItemInfo;
+
+ void Initialize();
+ virtual ~BasicCollection();
+ virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType );
+ INT32 implGetIndex( SbxVariable* pIndexVar );
+ INT32 implGetIndexForName( const String& rName );
+ void CollAdd( SbxArray* pPar_ );
+ void CollItem( SbxArray* pPar_ );
+ void CollRemove( SbxArray* pPar_ );
+
+public:
+ TYPEINFO();
+ BasicCollection( const String& rClassname );
+ virtual SbxVariable* Find( const String&, SbxClassType );
+ virtual void Clear();
+};
+
+#endif
+
+
diff --git a/basic/source/inc/scanner.hxx b/basic/source/inc/scanner.hxx
new file mode 100644
index 000000000000..9738e8763a1a
--- /dev/null
+++ b/basic/source/inc/scanner.hxx
@@ -0,0 +1,146 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SCANNER_HXX
+#define _SCANNER_HXX
+
+#include <tools/string.hxx>
+#ifndef _SBERRORS_HXX
+#include <basic/sberrors.hxx>
+#endif
+
+// Der Scanner ist stand-alone, d.h. er kann von ueberallher verwendet
+// werden. Eine BASIC-Instanz ist fuer Fehlermeldungen notwendig. Ohne
+// BASIC werden die Fehler nur gezaehlt. Auch ist Basic notwendig, wenn
+// eine erweiterte SBX-Variable zur Erkennung von Datentypen etc. verwendet
+// werden soll.
+
+class StarBASIC;
+
+class SbiScanner
+{
+ ::rtl::OUString aBuf; // Input-Puffer
+ ::rtl::OUString aLine; // aktuelle Zeile
+ const sal_Unicode* pLine; // Pointer
+ const sal_Unicode* pSaveLine; // Merker fuer Line
+protected:
+ String aSym; // Symbolpuffer
+ String aError; // Fehler-String
+ SbxDataType eScanType; // evtl. Datentyp
+ StarBASIC* pBasic; // Instanz fuer Fehler-Callbacks
+ double nVal; // numerischer Wert
+ short nCurCol1; // aktuelle Spalte 1
+ short nSavedCol1; // gerettete Spalte 1
+ short nCol; // aktuelle Spaltennummer
+ short nErrors; // Anzahl Fehler
+ short nColLock; // Lock-Zaehler fuer Col1
+ INT32 nBufPos; // aktuelle Buffer-Pos
+ USHORT nLine; // aktuelle Zeile
+ USHORT nCol1, nCol2; // aktuelle 1. und 2. Spalte
+ BOOL bSymbol; // TRUE: Symbol gescannt
+ BOOL bNumber; // TRUE: Zahl gescannt
+ BOOL bSpaces; // TRUE: Whitespace vor Token
+ BOOL bErrors; // TRUE: Fehler generieren
+ BOOL bAbort; // TRUE: abbrechen
+ BOOL bHash; // TRUE: # eingelesen
+ BOOL bError; // TRUE: Fehler generieren
+ BOOL bUsedForHilite; // TRUE: Nutzung fuer Highlighting
+ BOOL bCompatible; // TRUE: OPTION Compatibl
+ BOOL bVBASupportOn; // TRUE: OPTION VBASupport 1 otherwise default False
+ BOOL bPrevLineExtentsComment; // TRUE: Previous line is comment and ends on "... _"
+
+ void GenError( SbError );
+public:
+ SbiScanner( const ::rtl::OUString&, StarBASIC* = NULL );
+ ~SbiScanner();
+
+ void EnableErrors() { bError = FALSE; }
+ BOOL IsHash() { return bHash; }
+ BOOL IsCompatible() { return bCompatible; }
+ void SetCompatible( bool b ) { bCompatible = b; } // #118206
+ BOOL IsVBASupportOn() { return bVBASupportOn; }
+ void SetVBASupportOn( bool b ) { bVBASupportOn = b; }
+ BOOL WhiteSpace() { return bSpaces; }
+ short GetErrors() { return nErrors; }
+ short GetLine() { return nLine; }
+ short GetCol1() { return nCol1; }
+ short GetCol2() { return nCol2; }
+ void SetCol1( short n ) { nCol1 = n; }
+ StarBASIC* GetBasic() { return pBasic; }
+ void SaveLine(void) { pSaveLine = pLine; }
+ void RestoreLine(void) { pLine = pSaveLine; }
+ void LockColumn();
+ void UnlockColumn();
+ BOOL DoesColonFollow();
+
+ BOOL NextSym(); // naechstes Symbol lesen
+ const String& GetSym() { return aSym; }
+ SbxDataType GetType() { return eScanType; }
+ double GetDbl() { return nVal; }
+};
+
+class LetterTable
+{
+ bool IsLetterTab[256];
+
+public:
+ LetterTable( void );
+
+ inline bool isLetter( sal_Unicode c )
+ {
+ bool bRet = (c < 256) ? IsLetterTab[c] : isLetterUnicode( c );
+ return bRet;
+ }
+ bool isLetterUnicode( sal_Unicode c );
+};
+
+class BasicSimpleCharClass
+{
+ static LetterTable aLetterTable;
+
+public:
+ static BOOL isAlpha( sal_Unicode c, bool bCompatible )
+ {
+ BOOL bRet = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
+ || (bCompatible && aLetterTable.isLetter( c ));
+ return bRet;
+ }
+
+ static BOOL isDigit( sal_Unicode c )
+ {
+ BOOL bRet = (c >= '0' && c <= '9');
+ return bRet;
+ }
+
+ static BOOL isAlphaNumeric( sal_Unicode c, bool bCompatible )
+ {
+ BOOL bRet = isDigit( c ) || isAlpha( c, bCompatible );
+ return bRet;
+ }
+};
+
+#endif
diff --git a/basic/source/inc/scriptcont.hxx b/basic/source/inc/scriptcont.hxx
new file mode 100644
index 000000000000..091fbc24cdbe
--- /dev/null
+++ b/basic/source/inc/scriptcont.hxx
@@ -0,0 +1,199 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef BASIC_SCRIPTCONTAINER_HXX
+#define BASIC_SCRIPTCONTAINER_HXX
+
+#include "namecont.hxx"
+#include <basic/basmgr.hxx>
+#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
+#include <comphelper/uno3.hxx>
+
+class BasicManager;
+
+//============================================================================
+
+namespace basic
+{
+
+class SfxScriptLibraryContainer : public SfxLibraryContainer, public OldBasicPassword
+{
+ ::rtl::OUString maScriptLanguage;
+
+ // Methods to distinguish between deffirent library types
+ virtual SfxLibrary* SAL_CALL implCreateLibrary( const ::rtl::OUString& aName );
+ virtual SfxLibrary* SAL_CALL implCreateLibraryLink
+ ( const ::rtl::OUString& aName, const ::rtl::OUString& aLibInfoFileURL,
+ const ::rtl::OUString& StorageURL, sal_Bool ReadOnly );
+ virtual ::com::sun::star::uno::Any SAL_CALL createEmptyLibraryElement( void );
+ virtual bool SAL_CALL isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const;
+ virtual void SAL_CALL writeLibraryElement
+ (
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>& xLibrary,
+ const ::rtl::OUString& aElementName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutput
+ )
+ throw(::com::sun::star::uno::Exception);
+
+ virtual ::com::sun::star::uno::Any SAL_CALL importLibraryElement
+ (
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>& xLibrary,
+ const ::rtl::OUString& aElementName,
+ const ::rtl::OUString& aFile,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xElementStream );
+
+ virtual void SAL_CALL importFromOldStorage( const ::rtl::OUString& aFile );
+
+ virtual SfxLibraryContainer* createInstanceImpl( void );
+
+
+ // Password encryption
+ virtual sal_Bool implStorePasswordLibrary( SfxLibrary* pLib, const ::rtl::OUString& aName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage>& xStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler );
+
+ // New variant for library export
+ virtual sal_Bool implStorePasswordLibrary( SfxLibrary* pLib, const ::rtl::OUString& aName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage,
+ const ::rtl::OUString& aTargetURL,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xToUseSFI, const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler );
+
+ virtual sal_Bool implLoadPasswordLibrary( SfxLibrary* pLib, const ::rtl::OUString& Name,
+ sal_Bool bVerifyPasswordOnly=false )
+ throw(::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void onNewRootStorage();
+
+
+ // OldBasicPassword interface
+ virtual void setLibraryPassword( const String& rLibraryName, const String& rPassword );
+ virtual String getLibraryPassword( const String& rLibraryName );
+ virtual void clearLibraryPassword( const String& rLibraryName );
+ virtual sal_Bool hasLibraryPassword( const String& rLibraryName );
+
+ virtual const sal_Char* SAL_CALL getInfoFileName() const;
+ virtual const sal_Char* SAL_CALL getOldInfoFileName() const;
+ virtual const sal_Char* SAL_CALL getLibElementFileExtension() const;
+ virtual const sal_Char* SAL_CALL getLibrariesDir() const;
+
+public:
+ SfxScriptLibraryContainer( void );
+ SfxScriptLibraryContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage );
+
+
+ // Methods XLibraryContainerPassword
+ virtual sal_Bool SAL_CALL isLibraryPasswordProtected( const ::rtl::OUString& Name )
+ throw (::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isLibraryPasswordVerified( const ::rtl::OUString& Name )
+ throw (::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL verifyLibraryPassword( const ::rtl::OUString& Name, const ::rtl::OUString& Password )
+ throw (::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL changeLibraryPassword( const ::rtl::OUString& Name,
+ const ::rtl::OUString& OldPassword, const ::rtl::OUString& NewPassword )
+ throw (::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+
+ // Methods XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // Service
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static();
+ static ::rtl::OUString getImplementationName_static();
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL Create
+ ( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xServiceManager )
+ throw( ::com::sun::star::uno::Exception );
+
+};
+
+//============================================================================
+typedef std::hash_map< ::rtl::OUString, ::com::sun::star::script::ModuleInfo, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > ModuleInfoMap;
+
+typedef ::cppu::ImplHelper1 < ::com::sun::star::script::vba::XVBAModuleInfo
+ > SfxScriptLibrary_BASE;
+
+class SfxScriptLibrary : public SfxLibrary
+ , public SfxScriptLibrary_BASE
+{
+ friend class SfxScriptLibraryContainer;
+
+ sal_Bool mbLoadedSource;
+ sal_Bool mbLoadedBinary;
+ ModuleInfoMap mModuleInfos;
+
+ // Provide modify state including resources
+ virtual sal_Bool isModified( void );
+ virtual void storeResources( void );
+ virtual void storeResourcesAsURL( const ::rtl::OUString& URL, const ::rtl::OUString& NewName );
+ virtual void storeResourcesToURL( const ::rtl::OUString& URL,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler );
+ virtual void storeResourcesToStorage( const ::com::sun::star::uno::Reference
+ < ::com::sun::star::embed::XStorage >& xStorage );
+
+public:
+ SfxScriptLibrary
+ (
+ ModifiableHelper& _rModifiable,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xMSF,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xSFI
+ );
+
+ SfxScriptLibrary
+ (
+ ModifiableHelper& _rModifiable,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xMSF,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xSFI,
+ const ::rtl::OUString& aLibInfoFileURL, const ::rtl::OUString& aStorageURL, sal_Bool ReadOnly
+ );
+
+ DECLARE_XINTERFACE()
+ DECLARE_XTYPEPROVIDER()
+
+ // XVBAModuleInfo
+ virtual ::com::sun::star::script::ModuleInfo SAL_CALL getModuleInfo( const ::rtl::OUString& ModuleName ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasModuleInfo( const ::rtl::OUString& ModuleName ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL insertModuleInfo( const ::rtl::OUString& ModuleName, const ::com::sun::star::script::ModuleInfo& ModuleInfo ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeModuleInfo( const ::rtl::OUString& ModuleName ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ static bool containsValidModule( const ::com::sun::star::uno::Any& _rElement );
+
+protected:
+ virtual bool SAL_CALL isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const;
+};
+
+} // namespace base
+
+#endif
+
diff --git a/basic/source/inc/stdobj.hxx b/basic/source/inc/stdobj.hxx
new file mode 100644
index 000000000000..000e39973eb3
--- /dev/null
+++ b/basic/source/inc/stdobj.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBSTDOBJ_HXX
+#define _SBSTDOBJ_HXX
+
+#include <basic/sbxobj.hxx>
+
+class StarBASIC;
+class SbStdFactory;
+
+class SbiStdObject : public SbxObject
+{
+ SbStdFactory* pStdFactory;
+
+ ~SbiStdObject();
+ using SbxVariable::GetInfo;
+ SbxInfo* GetInfo( short );
+ virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType );
+public:
+ SbiStdObject( const String&, StarBASIC* );
+ virtual SbxVariable* Find( const String&, SbxClassType );
+ virtual void SetModified( BOOL );
+};
+
+#endif
diff --git a/basic/source/inc/symtbl.hxx b/basic/source/inc/symtbl.hxx
new file mode 100644
index 000000000000..f2fbaa0ac1f1
--- /dev/null
+++ b/basic/source/inc/symtbl.hxx
@@ -0,0 +1,250 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SYMTBL_HXX
+#define _SYMTBL_HXX
+
+#include <svl/svarray.hxx>
+#include <tools/string.hxx>
+#include <basic/sbxdef.hxx>
+#include <basic/sbdef.hxx>
+
+class SbiSymDef; // Basisklasse
+class SbiProcDef; // Prozedur
+class SbiConstDef; // Konstante
+class SbiSymPool; // Symbol-Pool
+class SbiStringPool; // gepoolte Strings
+
+class SvStream;
+class SbiParser;
+
+enum SbiSymScope { SbLOCAL, SbPARAM, SbPUBLIC, SbGLOBAL, SbRTL };
+
+///////////////////////////////////////////////////////////////////////////
+
+// Der String-Pool nimmt String-Eintraege auf und sorgt dafuer,
+// dass sie nicht doppelt vorkommen.
+
+SV_DECL_PTRARR_DEL(SbiStrings,String*,5,5)
+
+class SbiStringPool { // String-Pool
+ SbiStrings aData; // Daten
+ String aEmpty; // for convenience
+ SbiParser* pParser; // der Parser
+public:
+ SbiStringPool( SbiParser* );
+ ~SbiStringPool();
+ USHORT GetSize() const { return aData.Count(); }
+ // AB 8.4.1999, Default wegen #64236 auf TRUE geaendert
+ // Wenn der Bug sauber behoben ist, wieder auf FALSE aendern.
+ short Add( const String&, BOOL=TRUE );
+ short Add( double, SbxDataType );
+ const String& Find( USHORT ) const;
+ SbiParser* GetParser() { return pParser; }
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+SV_DECL_PTRARR_DEL(SbiSymbols,SbiSymDef*,5,5)
+
+class SbiSymPool { // Symbol-Pool
+ friend class SbiSymDef;
+ friend class SbiProcDef;
+protected:
+ SbiStringPool& rStrings; // verwendeter Stringpool
+ SbiSymbols aData; // Daten
+ SbiSymPool* pParent; // uebergeordneter Symbol-Pool
+ SbiParser* pParser; // der Parser
+ SbiSymScope eScope; // Scope des Pools
+ USHORT nProcId; // aktuelles ProcId fuer STATIC-Variable
+ USHORT nCur; // Iterator
+public:
+ SbiSymPool( SbiStringPool&, SbiSymScope );
+ ~SbiSymPool();
+
+ void Clear();
+
+ void SetParent( SbiSymPool* p ) { pParent = p; }
+ void SetProcId( short n ) { nProcId = n; }
+ USHORT GetSize() const { return aData.Count(); }
+ SbiSymScope GetScope() const { return eScope; }
+ void SetScope( SbiSymScope s ) { eScope = s; }
+ SbiParser* GetParser() { return pParser; }
+
+ SbiSymDef* AddSym( const String& ); // Symbol hinzufuegen
+ SbiProcDef* AddProc( const String& );// Prozedur hinzufuegen
+ void Add( SbiSymDef* ); // Symbol uebernehmen
+ SbiSymDef* Find( const String& ) const;// Variablenname
+ SbiSymDef* FindId( USHORT ) const; // Variable per ID suchen
+ SbiSymDef* Get( USHORT ) const; // Variable per Position suchen
+ SbiSymDef* First(), *Next(); // Iteratoren
+
+ UINT32 Define( const String& ); // Label definieren
+ UINT32 Reference( const String& ); // Label referenzieren
+ void CheckRefs(); // offene Referenzen suchen
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+class SbiSymDef { // Allgemeiner Symboleintrag
+ friend class SbiSymPool;
+protected:
+ String aName; // Name des Eintrags
+ SbxDataType eType; // Typ des Eintrags
+ SbiSymPool* pIn; // Parent-Pool
+ SbiSymPool* pPool; // Pool fuer Unterelemente
+ short nLen; // Stringlaenge bei STRING*n
+ short nDims; // Array-Dimensionen
+ USHORT nId; // Symbol-Nummer
+ USHORT nTypeId; // String-ID des Datentyps (Dim X AS Dytentyp)
+ USHORT nProcId; // aktuelles ProcId fuer STATIC-Variable
+ USHORT nPos; // Positions-Nummer
+ UINT32 nChain; // Backchain-Kette
+ BOOL bNew : 1; // TRUE: Dim As New...
+ BOOL bChained : 1; // TRUE: Symbol ist in Code definiert
+ BOOL bByVal : 1; // TRUE: ByVal-Parameter
+ BOOL bOpt : 1; // TRUE: optionaler Parameter
+ BOOL bStatic : 1; // TRUE: STATIC-Variable
+ BOOL bAs : 1; // TRUE: Datentyp per AS XXX definiert
+ BOOL bGlobal : 1; // TRUE: Global-Variable
+ BOOL bParamArray : 1; // TRUE: ParamArray parameter
+ BOOL bWithEvents : 1; // TRUE: Declared WithEvents
+ USHORT nDefaultId; // Symbol number of default value
+ short nFixedStringLength; // String length in: Dim foo As String*Length
+public:
+ SbiSymDef( const String& );
+ virtual ~SbiSymDef();
+ virtual SbiProcDef* GetProcDef();
+ virtual SbiConstDef* GetConstDef();
+
+ SbxDataType GetType() const { return eType; }
+ virtual void SetType( SbxDataType );
+ const String& GetName();
+ SbiSymScope GetScope() const;
+ USHORT GetProcId() const{ return nProcId; }
+ UINT32 GetAddr() const { return nChain; }
+ USHORT GetId() const { return nId; }
+ USHORT GetTypeId() const{ return nTypeId; }
+ void SetTypeId( USHORT n ) { nTypeId = n; eType = SbxOBJECT; }
+ USHORT GetPos() const { return nPos; }
+ void SetLen( short n ){ nLen = n; }
+ short GetLen() const { return nLen; }
+ void SetDims( short n ) { nDims = n; }
+ short GetDims() const { return nDims; }
+ BOOL IsDefined() const{ return bChained; }
+ void SetOptional() { bOpt = TRUE; }
+ void SetParamArray() { bParamArray = TRUE; }
+ void SetWithEvents() { bWithEvents = TRUE; }
+ void SetByVal( BOOL bByVal_ = TRUE )
+ { bByVal = bByVal_; }
+ void SetStatic( BOOL bAsStatic = TRUE ) { bStatic = bAsStatic; }
+ void SetNew() { bNew = TRUE; }
+ void SetDefinedAs() { bAs = TRUE; }
+ void SetGlobal(BOOL b){ bGlobal = b; }
+ void SetDefaultId( USHORT n ) { nDefaultId = n; }
+ USHORT GetDefaultId( void ) { return nDefaultId; }
+ BOOL IsOptional() const{ return bOpt; }
+ BOOL IsParamArray() const{ return bParamArray; }
+ BOOL IsWithEvents() const{ return bWithEvents; }
+ BOOL IsByVal() const { return bByVal; }
+ BOOL IsStatic() const { return bStatic; }
+ BOOL IsNew() const { return bNew; }
+ BOOL IsDefinedAs() const { return bAs; }
+ BOOL IsGlobal() const { return bGlobal; }
+ short GetFixedStringLength( void ) const { return nFixedStringLength; }
+ void SetFixedStringLength( short n ) { nFixedStringLength = n; }
+
+ SbiSymPool& GetPool();
+ UINT32 Define(); // Symbol in Code definieren
+ UINT32 Reference(); // Symbol in Code referenzieren
+
+private:
+ SbiSymDef( const SbiSymDef& );
+
+};
+
+class SbiProcDef : public SbiSymDef { // Prozedur-Definition (aus Basic):
+ SbiSymPool aParams; // Parameter
+ SbiSymPool aLabels; // lokale Sprungziele
+ String aLibName; // LIB "name"
+ String aAlias; // ALIAS "name"
+ USHORT nLine1, nLine2; // Zeilenbereich
+ PropertyMode mePropMode; // Marks if this is a property procedure and which
+ String maPropName; // Property name if property procedure (!= proc name)
+ BOOL bCdecl : 1; // TRUE: CDECL angegeben
+ BOOL bPublic : 1; // TRUE: proc ist PUBLIC
+ BOOL mbProcDecl : 1; // TRUE: instanciated by SbiParser::ProcDecl
+public:
+ SbiProcDef( SbiParser*, const String&, BOOL bProcDecl=false );
+ virtual ~SbiProcDef();
+ virtual SbiProcDef* GetProcDef();
+ virtual void SetType( SbxDataType );
+ SbiSymPool& GetParams() { return aParams; }
+ SbiSymPool& GetLabels() { return aLabels; }
+ SbiSymPool& GetLocals() { return GetPool();}
+ String& GetLib() { return aLibName; }
+ String& GetAlias() { return aAlias; }
+ void SetPublic( BOOL b ) { bPublic = b; }
+ BOOL IsPublic() const { return bPublic; }
+ void SetCdecl( BOOL b = TRUE) { bCdecl = b; }
+ BOOL IsCdecl() const { return bCdecl; }
+ BOOL IsUsedForProcDecl() const { return mbProcDecl; }
+ void SetLine1( USHORT n ) { nLine1 = n; }
+ USHORT GetLine1() const { return nLine1; }
+ void SetLine2( USHORT n ) { nLine2 = n; }
+ USHORT GetLine2() const { return nLine2; }
+ PropertyMode getPropertyMode() { return mePropMode; }
+ void setPropertyMode( PropertyMode ePropMode );
+ const String& GetPropName() { return maPropName; }
+
+ // Match mit einer Forward-Deklaration. Die Parameternamen
+ // werden abgeglichen und die Forward-Deklaration wird
+ // durch this ersetzt
+ void Match( SbiProcDef* pForward );
+
+private:
+ SbiProcDef( const SbiProcDef& );
+
+};
+
+class SbiConstDef : public SbiSymDef
+{
+ double nVal;
+ String aVal;
+public:
+ SbiConstDef( const String& );
+ virtual ~SbiConstDef();
+ virtual SbiConstDef* GetConstDef();
+ void Set( double, SbxDataType );
+ void Set( const String& );
+ double GetValue() { return nVal; }
+ const String& GetString() { return aVal; }
+};
+
+
+#endif
+
diff --git a/basic/source/inc/token.hxx b/basic/source/inc/token.hxx
new file mode 100644
index 000000000000..930f68910b78
--- /dev/null
+++ b/basic/source/inc/token.hxx
@@ -0,0 +1,183 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _TOKEN_HXX
+#define _TOKEN_HXX
+
+#include "scanner.hxx"
+#ifndef _SBDEF_HXX
+#include <basic/sbdef.hxx>
+#endif
+
+#if defined( SHARED )
+#define SbiTokenSHAREDTMPUNDEF
+#undef SHARED
+#endif
+
+// Der Tokenizer ist stand-alone, d.h. er kann von ueberallher verwendet
+// werden. Eine BASIC-Instanz ist fuer Fehlermeldungen notwendig. Ohne
+// BASIC werden die Fehler nur gezaehlt. Auch ist Basic notwendig, wenn
+// eine erweiterte SBX-Variable zur Erkennung von Datentypen etc. verwendet
+// werden soll.
+
+enum SbiToken {
+ NIL = 0,
+ // Token zwischen 0x20 und 0x3F sind Literale:
+ LPAREN = '(', RPAREN = ')', COMMA = ',', DOT = '.', EXCLAM = '!',
+ HASH = '#', SEMICOLON = ';',
+
+ // Anweisungen:
+ FIRSTKWD = 0x40,
+ AS = FIRSTKWD, ALIAS, ASSIGN,
+ CALL, CASE, CLOSE, COMPARE, _CONST_,
+ DECLARE, DIM, DO,
+
+ // in der Reihenfolge der Datentyp-Enums!
+ DEFINT, DEFLNG, DEFSNG, DEFDBL, DEFCUR, DEFDATE, DEFSTR, DEFOBJ,
+ DEFERR, DEFBOOL, DEFVAR,
+ // in der Reihenfolge der Datentyp-Enums!
+ DATATYPE1,
+ TINTEGER = DATATYPE1,
+ TLONG, TSINGLE, TDOUBLE, TCURRENCY, TDATE, TSTRING, TOBJECT,
+ _ERROR_, TBOOLEAN, TVARIANT, TBYTE,
+ DATATYPE2 = TBYTE,
+
+ EACH, ELSE, ELSEIF, END, ERASE, EXIT,
+ FOR, FUNCTION,
+ GET, GLOBAL, GOSUB, GOTO,
+ IF, _IN_, INPUT,
+ LET, LINE, LINEINPUT, LOCAL, LOOP, LPRINT, LSET,
+ NAME, NEW, NEXT,
+ ON, OPEN, OPTION, IMPLEMENTS,
+ PRINT, PRIVATE, PROPERTY, PUBLIC,
+ REDIM, REM, RESUME, RETURN, RSET,
+ SELECT, SET, SHARED, STATIC, STEP, STOP, SUB,
+ TEXT, THEN, TO, TYPE, ENUM,
+ UNTIL,
+ WEND, WHILE, WITH, WRITE,
+ ENDENUM, ENDIF, ENDFUNC, ENDPROPERTY, ENDSUB, ENDTYPE, ENDSELECT, ENDWITH,
+ // Ende aller Keywords
+ LASTKWD = ENDWITH,
+ // Statement-Ende
+ EOS, EOLN,
+ // Operatoren:
+ EXPON, NEG, MUL,
+ DIV, IDIV, MOD, PLUS, MINUS,
+ EQ, NE, LT, GT, LE, GE,
+ NOT, AND, OR, XOR, EQV,
+ IMP, CAT, LIKE, IS, TYPEOF,
+ // Sonstiges:
+ FIRSTEXTRA,
+ NUMBER=FIRSTEXTRA, FIXSTRING, SYMBOL, _CDECL_, BYVAL, BYREF,
+ OUTPUT, RANDOM, APPEND, BINARY, ACCESS,
+ LOCK, READ, PRESERVE, BASE, ANY, LIB, _OPTIONAL_,
+ EXPLICIT, COMPATIBLE, CLASSMODULE, PARAMARRAY, WITHEVENTS,
+
+ // Ab hier kommen JavaScript-Tokens (gleiches enum, damit gleicher Typ)
+ FIRSTJAVA,
+ JS_BREAK=FIRSTJAVA, JS_CONTINUE, JS_FOR, JS_FUNCTION, JS_IF, JS_NEW,
+ JS_RETURN, JS_THIS, JS_VAR, JS_WHILE, JS_WITH,
+
+ // JavaScript-Operatoren
+ // _ASS_ = Assignment
+ JS_COMMA, JS_ASSIGNMENT, JS_ASS_PLUS, JS_ASS_MINUS, JS_ASS_MUL,
+ JS_ASS_DIV, JS_ASS_MOD, JS_ASS_LSHIFT, JS_ASS_RSHIFT, JS_ASS_RSHIFT_Z,
+ JS_ASS_AND, JS_ASS_XOR, JS_ASS_OR,
+ JS_COND_QUEST, JS_COND_SEL, JS_LOG_OR, JS_LOG_AND, JS_BIT_OR,
+ JS_BIT_XOR, JS_BIT_AND, JS_EQ, JS_NE, JS_LT, JS_LE,
+ JS_GT, JS_GE, JS_LSHIFT, JS_RSHIFT, JS_RSHIFT_Z,
+ JS_PLUS, JS_MINUS, JS_MUL, JS_DIV, JS_MOD, JS_LOG_NOT, JS_BIT_NOT,
+ JS_INC, JS_DEC, JS_LPAREN, JS_RPAREN, JS_LINDEX, JS_RINDEX
+ , VBASUPPORT
+};
+
+#ifdef SbiTokenSHAREDTMPUNDEF
+#define SHARED
+#undef SbiTokenSHAREDTMPUNDEF
+#endif
+
+// #i109076
+class TokenLabelInfo
+{
+ bool* m_pTokenCanBeLabelTab;
+
+public:
+ TokenLabelInfo( void );
+ TokenLabelInfo( const TokenLabelInfo& rInfo )
+ : m_pTokenCanBeLabelTab( NULL )
+ { (void)rInfo; }
+ ~TokenLabelInfo();
+
+ bool canTokenBeLabel( SbiToken eTok )
+ { return m_pTokenCanBeLabelTab[eTok]; }
+};
+
+class SbiTokenizer : public SbiScanner {
+ TokenLabelInfo m_aTokenLabelInfo;
+
+protected:
+ SbiToken eCurTok; // aktuelles Token
+ SbiToken ePush; // Pushback-Token
+ USHORT nPLine, nPCol1, nPCol2; // Pushback-Location
+ BOOL bEof; // TRUE bei Dateiende
+ BOOL bEos; // TRUE bei Statement-Ende
+ BOOL bKeywords; // TRUE, falls Keywords geparst werden
+ BOOL bAs; // letztes Keyword war AS
+ BOOL bErrorIsSymbol; // Handle Error token as Symbol, not keyword
+public:
+ SbiTokenizer( const ::rtl::OUString&, StarBASIC* = NULL );
+ ~SbiTokenizer();
+
+ inline BOOL IsEof() { return bEof; }
+ inline BOOL IsEos() { return bEos; }
+
+ void Push( SbiToken ); // Pushback eines Tokens
+ const String& Symbol( SbiToken );// Rueckumwandlung
+
+ SbiToken Peek(); // das naechste Token lesen
+ SbiToken Next(); // Ein Token lesen
+ BOOL MayBeLabel( BOOL= FALSE ); // Kann es ein Label sein?
+
+ void Hilite( SbTextPortions& ); // Syntax-Highlighting
+
+ void Error( SbError c ) { GenError( c ); }
+ void Error( SbError, SbiToken );
+ void Error( SbError, const char* );
+ void Error( SbError, String );
+
+ void Keywords( BOOL b ) { bKeywords = b; }
+
+ static BOOL IsEoln( SbiToken t )
+ { return BOOL( t == EOS || t == EOLN || t == REM ); }
+ static BOOL IsKwd( SbiToken t )
+ { return BOOL( t >= FIRSTKWD && t <= LASTKWD ); }
+ static BOOL IsExtra( SbiToken t )
+ { return BOOL( t >= FIRSTEXTRA ); }
+};
+
+
+#endif
diff --git a/basic/source/runtime/basrdll.cxx b/basic/source/runtime/basrdll.cxx
new file mode 100644
index 000000000000..799caf0cd954
--- /dev/null
+++ b/basic/source/runtime/basrdll.cxx
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * 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 <vcl/svapp.hxx>
+#include <svl/solar.hrc>
+#include <tools/debug.hxx>
+#include <vcl/msgbox.hxx>
+
+#include <basic/sbstar.hxx>
+#include <basic/basrdll.hxx>
+#include <basrid.hxx>
+#include <sb.hrc>
+
+SttResId::SttResId( sal_uInt32 nId ) :
+ ResId( nId, *((*(BasicDLL**)GetAppData(SHL_BASIC))->GetSttResMgr()) )
+{
+}
+
+BasResId::BasResId( sal_uInt32 nId ) :
+ ResId( nId, *((*(BasicDLL**)GetAppData(SHL_BASIC))->GetBasResMgr()) )
+{
+}
+
+BasicDLL::BasicDLL()
+{
+ *(BasicDLL**)GetAppData(SHL_BASIC) = this;
+ ::com::sun::star::lang::Locale aLocale = Application::GetSettings().GetUILocale();
+ pSttResMgr = ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(stt), aLocale );
+ pBasResMgr = ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(sb), aLocale );
+ bDebugMode = FALSE;
+ bBreakEnabled = TRUE;
+}
+
+BasicDLL::~BasicDLL()
+{
+ delete pSttResMgr;
+ delete pBasResMgr;
+}
+
+void BasicDLL::EnableBreak( BOOL bEnable )
+{
+ BasicDLL* pThis = *(BasicDLL**)GetAppData(SHL_BASIC);
+ DBG_ASSERT( pThis, "BasicDLL::EnableBreak: Noch keine Instanz!" );
+ if ( pThis )
+ pThis->bBreakEnabled = bEnable;
+}
+
+void BasicDLL::SetDebugMode( BOOL bDebugMode )
+{
+ BasicDLL* pThis = *(BasicDLL**)GetAppData(SHL_BASIC);
+ DBG_ASSERT( pThis, "BasicDLL::EnableBreak: Noch keine Instanz!" );
+ if ( pThis )
+ pThis->bDebugMode = bDebugMode;
+}
+
+
+void BasicDLL::BasicBreak()
+{
+ //bJustStopping: Wenn jemand wie wild x-mal STOP drueckt, aber das Basic
+ // nicht schnell genug anhaelt, kommt die Box ggf. oefters...
+ static BOOL bJustStopping = FALSE;
+
+ BasicDLL* pThis = *(BasicDLL**)GetAppData(SHL_BASIC);
+ DBG_ASSERT( pThis, "BasicDLL::EnableBreak: Noch keine Instanz!" );
+ if ( pThis )
+ {
+ if ( StarBASIC::IsRunning() && !bJustStopping && ( pThis->bBreakEnabled || pThis->bDebugMode ) )
+ {
+ bJustStopping = TRUE;
+ StarBASIC::Stop();
+ String aMessageStr( BasResId( IDS_SBERR_TERMINATED ) );
+ InfoBox( 0, aMessageStr ).Execute();
+ bJustStopping = FALSE;
+ }
+ }
+}
+
diff --git a/basic/source/runtime/ddectrl.cxx b/basic/source/runtime/ddectrl.cxx
new file mode 100644
index 000000000000..89d473099f0b
--- /dev/null
+++ b/basic/source/runtime/ddectrl.cxx
@@ -0,0 +1,192 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#include <svl/svdde.hxx>
+#include "ddectrl.hxx"
+#ifndef _SBERRORS_HXX
+#include <basic/sberrors.hxx>
+#endif
+
+#define DDE_FREECHANNEL ((DdeConnection*)0xffffffff)
+
+#define DDE_FIRSTERR 0x4000
+#define DDE_LASTERR 0x4011
+
+static const SbError nDdeErrMap[] =
+{
+ /* DMLERR_ADVACKTIMEOUT */ 0x4000, SbERR_DDE_TIMEOUT,
+ /* DMLERR_BUSY */ 0x4001, SbERR_DDE_BUSY,
+ /* DMLERR_DATAACKTIMEOUT */ 0x4002, SbERR_DDE_TIMEOUT,
+ /* DMLERR_DLL_NOT_INITIALIZED */ 0x4003, SbERR_DDE_ERROR,
+ /* DMLERR_DLL_USAGE */ 0x4004, SbERR_DDE_ERROR,
+ /* DMLERR_EXECACKTIMEOUT */ 0x4005, SbERR_DDE_TIMEOUT,
+ /* DMLERR_INVALIDPARAMETER */ 0x4006, SbERR_DDE_ERROR,
+ /* DMLERR_LOW_MEMORY */ 0x4007, SbERR_DDE_ERROR,
+ /* DMLERR_MEMORY_ERROR */ 0x4008, SbERR_DDE_ERROR,
+ /* DMLERR_NOTPROCESSED */ 0x4009, SbERR_DDE_NOTPROCESSED,
+ /* DMLERR_NO_CONV_ESTABLISHED */ 0x400a, SbERR_DDE_NO_CHANNEL,
+ /* DMLERR_POKEACKTIMEOUT */ 0x400b, SbERR_DDE_TIMEOUT,
+ /* DMLERR_POSTMSG_FAILED */ 0x400c, SbERR_DDE_QUEUE_OVERFLOW,
+ /* DMLERR_REENTRANCY */ 0x400d, SbERR_DDE_ERROR,
+ /* DMLERR_SERVER_DIED */ 0x400e, SbERR_DDE_PARTNER_QUIT,
+ /* DMLERR_SYS_ERROR */ 0x400f, SbERR_DDE_ERROR,
+ /* DMLERR_UNADVACKTIMEOUT */ 0x4010, SbERR_DDE_TIMEOUT,
+ /* DMLERR_UNFOUND_QUEUE_ID */ 0x4011, SbERR_DDE_NO_CHANNEL
+};
+
+SbError SbiDdeControl::GetLastErr( DdeConnection* pConv )
+{
+ if( !pConv )
+ return 0;
+ long nErr = pConv->GetError();
+ if( !nErr )
+ return 0;
+ if( nErr < DDE_FIRSTERR || nErr > DDE_LASTERR )
+ return SbERR_DDE_ERROR;
+ return nDdeErrMap[ 2*(nErr - DDE_FIRSTERR) + 1 ];
+}
+
+IMPL_LINK_INLINE( SbiDdeControl,Data , DdeData*, pData,
+{
+ aData = String::CreateFromAscii( (char*)(const void*)*pData );
+ return 1;
+}
+)
+
+SbiDdeControl::SbiDdeControl()
+{
+ pConvList = new DdeConnections;
+ DdeConnection* pPtr = DDE_FREECHANNEL;
+ pConvList->Insert( pPtr );
+}
+
+SbiDdeControl::~SbiDdeControl()
+{
+ TerminateAll();
+ delete pConvList;
+}
+
+INT16 SbiDdeControl::GetFreeChannel()
+{
+ INT16 nListSize = (INT16)pConvList->Count();
+ DdeConnection* pPtr = pConvList->First();
+ pPtr = pConvList->Next(); // nullten eintrag ueberspringen
+ INT16 nChannel;
+ for( nChannel = 1; nChannel < nListSize; nChannel++ )
+ {
+ if( pPtr == DDE_FREECHANNEL )
+ return nChannel;
+ pPtr = pConvList->Next();
+ }
+ pPtr = DDE_FREECHANNEL;
+ pConvList->Insert( pPtr, LIST_APPEND );
+ return nChannel;
+}
+
+SbError SbiDdeControl::Initiate( const String& rService, const String& rTopic,
+ INT16& rnHandle )
+{
+ SbError nErr;
+ DdeConnection* pConv = new DdeConnection( rService, rTopic );
+ nErr = GetLastErr( pConv );
+ if( nErr )
+ {
+ delete pConv;
+ rnHandle = 0;
+ }
+ else
+ {
+ INT16 nChannel = GetFreeChannel();
+ pConvList->Replace( pConv, (ULONG)nChannel );
+ rnHandle = nChannel;
+ }
+ return 0;
+}
+
+SbError SbiDdeControl::Terminate( INT16 nChannel )
+{
+ DdeConnection* pConv = pConvList->GetObject( (ULONG)nChannel );
+ if( !nChannel || !pConv || pConv == DDE_FREECHANNEL )
+ return SbERR_DDE_NO_CHANNEL;
+ pConvList->Replace( DDE_FREECHANNEL, (ULONG)nChannel );
+ delete pConv;
+ return 0L;
+}
+
+SbError SbiDdeControl::TerminateAll()
+{
+ INT16 nChannel = (INT16)pConvList->Count();
+ while( nChannel )
+ {
+ nChannel--;
+ Terminate( nChannel );
+ }
+
+ pConvList->Clear();
+ DdeConnection* pPtr = DDE_FREECHANNEL;
+ pConvList->Insert( pPtr );
+
+ return 0;
+}
+
+SbError SbiDdeControl::Request( INT16 nChannel, const String& rItem, String& rResult )
+{
+ DdeConnection* pConv = pConvList->GetObject( (ULONG)nChannel );
+ if( !nChannel || !pConv || pConv == DDE_FREECHANNEL )
+ return SbERR_DDE_NO_CHANNEL;
+
+ DdeRequest aRequest( *pConv, rItem, 30000 );
+ aRequest.SetDataHdl( LINK( this, SbiDdeControl, Data ) );
+ aRequest.Execute();
+ rResult = aData;
+ return GetLastErr( pConv );
+}
+
+SbError SbiDdeControl::Execute( INT16 nChannel, const String& rCommand )
+{
+ DdeConnection* pConv = pConvList->GetObject( (ULONG)nChannel );
+ if( !nChannel || !pConv || pConv == DDE_FREECHANNEL )
+ return SbERR_DDE_NO_CHANNEL;
+ DdeExecute aRequest( *pConv, rCommand, 30000 );
+ aRequest.Execute();
+ return GetLastErr( pConv );
+}
+
+SbError SbiDdeControl::Poke( INT16 nChannel, const String& rItem, const String& rData )
+{
+ DdeConnection* pConv = pConvList->GetObject( (ULONG)nChannel );
+ if( !nChannel || !pConv || pConv == DDE_FREECHANNEL )
+ return SbERR_DDE_NO_CHANNEL;
+ DdePoke aRequest( *pConv, rItem, DdeData(rData), 30000 );
+ aRequest.Execute();
+ return GetLastErr( pConv );
+}
+
+
diff --git a/basic/source/runtime/ddectrl.hxx b/basic/source/runtime/ddectrl.hxx
new file mode 100644
index 000000000000..c1e9da823a20
--- /dev/null
+++ b/basic/source/runtime/ddectrl.hxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _DDECTRL_HXX
+#define _DDECTRL_HXX
+
+#include <tools/link.hxx>
+#ifndef _SBERRORS_HXX
+#include <basic/sberrors.hxx>
+#endif
+#include <tools/string.hxx>
+
+class DdeConnection;
+class DdeConnections;
+class DdeData;
+
+class SbiDdeControl
+{
+private:
+ DECL_LINK( Data, DdeData* );
+ SbError GetLastErr( DdeConnection* );
+ INT16 GetFreeChannel();
+ DdeConnections* pConvList;
+ String aData;
+
+public:
+
+ SbiDdeControl();
+ ~SbiDdeControl();
+
+ SbError Initiate( const String& rService, const String& rTopic,
+ INT16& rnHandle );
+ SbError Terminate( INT16 nChannel );
+ SbError TerminateAll();
+ SbError Request( INT16 nChannel, const String& rItem, String& rResult );
+ SbError Execute( INT16 nChannel, const String& rCommand );
+ SbError Poke( INT16 nChannel, const String& rItem, const String& rData );
+};
+
+#endif
diff --git a/basic/source/runtime/dllmgr.cxx b/basic/source/runtime/dllmgr.cxx
new file mode 100644
index 000000000000..04f1ee0a8acc
--- /dev/null
+++ b/basic/source/runtime/dllmgr.cxx
@@ -0,0 +1,738 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include "precompiled_basic.hxx"
+#include "sal/config.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <list>
+#include <map>
+#include <vector>
+
+#include "basic/sbx.hxx"
+#include "basic/sbxvar.hxx"
+#include "osl/thread.h"
+#include "rtl/ref.hxx"
+#include "rtl/string.hxx"
+#include "rtl/ustring.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+#include "tools/svwin.h"
+
+#undef max
+
+#include "dllmgr.hxx"
+
+/* Open issues:
+
+ Only 32-bit Windows for now.
+
+ Missing support for functions returning structs (see TODO in call()).
+
+ Missing support for additional data types (64 bit integers, Any, ...; would
+ trigger OSL_ASSERT(false) in various switches).
+
+ It is assumed that the variables passed into SbiDllMgr::Call to represent
+ the arguments and return value have types that exactly match the Declare
+ statement; it would be better if this code had access to the function
+ signature from the Declare statement, so that it could convert the passed
+ variables accordingly.
+*/
+
+#if defined WNT // only 32-bit Windows, actually
+
+extern "C" {
+
+int __stdcall DllMgr_call32(FARPROC, void const * stack, std::size_t size);
+double __stdcall DllMgr_callFp(FARPROC, void const * stack, std::size_t size);
+
+}
+
+namespace {
+
+char * address(std::vector< char > & blob) {
+ return blob.empty() ? 0 : &blob[0];
+}
+
+SbError convert(rtl::OUString const & source, rtl::OString * target) {
+ return
+ source.convertToString(
+ target, osl_getThreadTextEncoding(),
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
+ ? ERRCODE_NONE : ERRCODE_BASIC_BAD_ARGUMENT;
+ //TODO: more specific errcode?
+}
+
+SbError convert(char const * source, sal_Int32 length, rtl::OUString * target) {
+ return
+ rtl_convertStringToUString(
+ &target->pData, source, length, osl_getThreadTextEncoding(),
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))
+ ? ERRCODE_NONE : ERRCODE_BASIC_BAD_ARGUMENT;
+ //TODO: more specific errcode?
+}
+
+struct UnmarshalData {
+ UnmarshalData(SbxVariable * theVariable, void * theBuffer):
+ variable(theVariable), buffer(theBuffer) {}
+
+ SbxVariable * variable;
+ void * buffer;
+};
+
+struct StringData: public UnmarshalData {
+ StringData(SbxVariable * theVariable, void * theBuffer, bool theSpecial):
+ UnmarshalData(theVariable, theBuffer), special(theSpecial) {}
+
+ bool special;
+};
+
+class MarshalData: private boost::noncopyable {
+public:
+ std::vector< char > * newBlob() {
+ blobs_.push_front(std::vector< char >());
+ return &blobs_.front();
+ }
+
+ std::vector< UnmarshalData > unmarshal;
+
+ std::vector< StringData > unmarshalStrings;
+
+private:
+ std::list< std::vector< char > > blobs_;
+};
+
+std::size_t align(std::size_t address, std::size_t alignment) {
+ // alignment = 2^k for some k >= 0
+ return (address + (alignment - 1)) & ~(alignment - 1);
+}
+
+char * align(
+ std::vector< char > & blob, std::size_t alignment, std::size_t offset,
+ std::size_t add)
+{
+ std::vector< char >::size_type n = blob.size();
+ n = align(n - offset, alignment) + offset; //TODO: overflow in align()
+ blob.resize(n + add); //TODO: overflow
+ return address(blob) + n;
+}
+
+template< typename T > void add(
+ std::vector< char > & blob, T const & data, std::size_t alignment,
+ std::size_t offset)
+{
+ *reinterpret_cast< T * >(align(blob, alignment, offset, sizeof (T))) = data;
+}
+
+std::size_t alignment(SbxVariable * variable) {
+ OSL_ASSERT(variable != 0);
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
+ case SbxINTEGER:
+ return 2;
+ case SbxLONG:
+ case SbxSINGLE:
+ case SbxSTRING:
+ return 4;
+ case SbxDOUBLE:
+ return 8;
+ case SbxOBJECT:
+ {
+ std::size_t n = 1;
+ SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())->
+ GetProperties();
+ for (USHORT i = 0; i < props->Count(); ++i) {
+ n = std::max(n, alignment(props->Get(i)));
+ }
+ return n;
+ }
+ case SbxBOOL:
+ case SbxBYTE:
+ return 1;
+ default:
+ OSL_ASSERT(false);
+ return 1;
+ }
+ } else {
+ SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject());
+ int dims = arr->GetDims();
+ std::vector< INT32 > low(dims);
+ for (int i = 0; i < dims; ++i) {
+ INT32 up;
+ arr->GetDim32(i + 1, low[i], up);
+ }
+ return alignment(arr->Get32(&low[0]));
+ }
+}
+
+SbError marshal(
+ bool outer, SbxVariable * variable, bool special,
+ std::vector< char > & blob, std::size_t offset, MarshalData & data);
+
+SbError marshalString(
+ SbxVariable * variable, bool special, MarshalData & data, void ** buffer)
+{
+ OSL_ASSERT(variable != 0 && buffer != 0);
+ rtl::OString str;
+ SbError e = convert(variable->GetString(), &str);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ std::vector< char > * blob = data.newBlob();
+ blob->insert(blob->begin(), str.getStr(), str.getStr() + str.getLength());
+ *buffer = address(*blob);
+ data.unmarshalStrings.push_back(StringData(variable, *buffer, special));
+ return ERRCODE_NONE;
+}
+
+SbError marshalStruct(
+ SbxVariable * variable, std::vector< char > & blob, std::size_t offset,
+ MarshalData & data)
+{
+ OSL_ASSERT(variable != 0);
+ SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())->
+ GetProperties();
+ for (USHORT i = 0; i < props->Count(); ++i) {
+ SbError e = marshal(false, props->Get(i), false, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ }
+ return ERRCODE_NONE;
+}
+
+SbError marshalArray(
+ SbxVariable * variable, std::vector< char > & blob, std::size_t offset,
+ MarshalData & data)
+{
+ OSL_ASSERT(variable != 0);
+ SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject());
+ int dims = arr->GetDims();
+ std::vector< INT32 > low(dims);
+ std::vector< INT32 > up(dims);
+ for (int i = 0; i < dims; ++i) {
+ arr->GetDim32(i + 1, low[i], up[i]);
+ }
+ for (std::vector< INT32 > idx = low;;) {
+ SbError e = marshal(
+ false, arr->Get32(&idx[0]), false, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ int i = dims - 1;
+ while (idx[i] == up[i]) {
+ idx[i] = low[i];
+ if (i == 0) {
+ return ERRCODE_NONE;
+ }
+ --i;
+ }
+ ++idx[i];
+ }
+}
+
+// 8-aligned structs are only 4-aligned on stack, so alignment of members in
+// such structs must take that into account via "offset"
+SbError marshal(
+ bool outer, SbxVariable * variable, bool special,
+ std::vector< char > & blob, std::size_t offset, MarshalData & data)
+{
+ OSL_ASSERT(variable != 0);
+ if ((variable->GetFlags() & SBX_REFERENCE) == 0) {
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
+ case SbxINTEGER:
+ add(blob, variable->GetInteger(), outer ? 4 : 2, offset);
+ break;
+ case SbxLONG:
+ add(blob, variable->GetLong(), 4, offset);
+ break;
+ case SbxSINGLE:
+ add(blob, variable->GetSingle(), 4, offset);
+ break;
+ case SbxDOUBLE:
+ add(blob, variable->GetDouble(), outer ? 4 : 8, offset);
+ break;
+ case SbxSTRING:
+ {
+ void * p;
+ SbError e = marshalString(variable, special, data, &p);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ add(blob, p, 4, offset);
+ break;
+ }
+ case SbxOBJECT:
+ {
+ align(blob, outer ? 4 : alignment(variable), offset, 0);
+ SbError e = marshalStruct(variable, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ break;
+ }
+ case SbxBOOL:
+ add(blob, variable->GetBool(), outer ? 4 : 1, offset);
+ break;
+ case SbxBYTE:
+ add(blob, variable->GetByte(), outer ? 4 : 1, offset);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ } else {
+ SbError e = marshalArray(variable, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ }
+ } else {
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
+ case SbxINTEGER:
+ case SbxLONG:
+ case SbxSINGLE:
+ case SbxDOUBLE:
+ case SbxBOOL:
+ case SbxBYTE:
+ add(blob, variable->data(), 4, offset);
+ break;
+ case SbxSTRING:
+ {
+ std::vector< char > * blob2 = data.newBlob();
+ void * p;
+ SbError e = marshalString(variable, special, data, &p);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ add(*blob2, p, 4, 0);
+ add(blob, address(*blob2), 4, offset);
+ break;
+ }
+ case SbxOBJECT:
+ {
+ std::vector< char > * blob2 = data.newBlob();
+ SbError e = marshalStruct(variable, *blob2, 0, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ void * p = address(*blob2);
+ if (outer) {
+ data.unmarshal.push_back(UnmarshalData(variable, p));
+ }
+ add(blob, p, 4, offset);
+ break;
+ }
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ } else {
+ std::vector< char > * blob2 = data.newBlob();
+ SbError e = marshalArray(variable, *blob2, 0, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ void * p = address(*blob2);
+ if (outer) {
+ data.unmarshal.push_back(UnmarshalData(variable, p));
+ }
+ add(blob, p, 4, offset);
+ }
+ }
+ return ERRCODE_NONE;
+}
+
+template< typename T > T read(void const ** pointer) {
+ T const * p = static_cast< T const * >(*pointer);
+ *pointer = static_cast< void const * >(p + 1);
+ return *p;
+}
+
+void const * unmarshal(SbxVariable * variable, void const * data) {
+ OSL_ASSERT(variable != 0);
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
+ case SbxINTEGER:
+ variable->PutInteger(read< sal_Int16 >(&data));
+ break;
+ case SbxLONG:
+ variable->PutLong(read< sal_Int32 >(&data));
+ break;
+ case SbxSINGLE:
+ variable->PutSingle(read< float >(&data));
+ break;
+ case SbxDOUBLE:
+ variable->PutDouble(read< double >(&data));
+ break;
+ case SbxSTRING:
+ read< char * >(&data); // handled by unmarshalString
+ break;
+ case SbxOBJECT:
+ {
+ data = reinterpret_cast< void const * >(
+ align(
+ reinterpret_cast< sal_uIntPtr >(data),
+ alignment(variable)));
+ SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())->
+ GetProperties();
+ for (USHORT i = 0; i < props->Count(); ++i) {
+ data = unmarshal(props->Get(i), data);
+ }
+ break;
+ }
+ case SbxBOOL:
+ variable->PutBool(read< sal_Bool >(&data));
+ break;
+ case SbxBYTE:
+ variable->PutByte(read< sal_uInt8 >(&data));
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ } else {
+ SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject());
+ int dims = arr->GetDims();
+ std::vector< INT32 > low(dims);
+ std::vector< INT32 > up(dims);
+ for (int i = 0; i < dims; ++i) {
+ arr->GetDim32(i + 1, low[i], up[i]);
+ }
+ for (std::vector< INT32 > idx = low;;) {
+ data = unmarshal(arr->Get32(&idx[0]), data);
+ int i = dims - 1;
+ while (idx[i] == up[i]) {
+ idx[i] = low[i];
+ if (i == 0) {
+ goto done;
+ }
+ --i;
+ }
+ ++idx[i];
+ }
+ done:;
+ }
+ return data;
+}
+
+SbError unmarshalString(StringData const & data, SbxVariable & result) {
+ rtl::OUString str;
+ if (data.buffer != 0) {
+ char const * p = static_cast< char const * >(data.buffer);
+ sal_Int32 len;
+ if (data.special) {
+ len = static_cast< sal_Int32 >(result.GetULong());
+ if (len < 0) { // i.e., DWORD result >= 2^31
+ return ERRCODE_BASIC_BAD_ARGUMENT;
+ //TODO: more specific errcode?
+ }
+ } else {
+ len = rtl_str_getLength(p);
+ }
+ SbError e = convert(p, len, &str);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ }
+ data.variable->PutString(String(str));
+ return ERRCODE_NONE;
+}
+
+struct ProcData {
+ rtl::OString name;
+ FARPROC proc;
+};
+
+SbError call(
+ rtl::OUString const & dll, ProcData const & proc, SbxArray * arguments,
+ SbxVariable & result)
+{
+ std::vector< char > stack;
+ MarshalData data;
+ // For DWORD GetLogicalDriveStringsA(DWORD nBufferLength, LPSTR lpBuffer)
+ // from kernel32, upon return, filled lpBuffer length is result DWORD, which
+ // requires special handling in unmarshalString; other functions might
+ // require similar treatment, too:
+ bool special =
+ dll.equalsIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("KERNEL32.DLL")) &&
+ (proc.name ==
+ rtl::OString(RTL_CONSTASCII_STRINGPARAM("GetLogicalDriveStringsA")));
+ for (USHORT i = 1; i < (arguments == 0 ? 0 : arguments->Count()); ++i) {
+ SbError e = marshal(
+ true, arguments->Get(i), special && i == 2, stack, stack.size(),
+ data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ align(stack, 4, 0, 0);
+ }
+ switch (result.GetType()) {
+ case SbxEMPTY:
+ DllMgr_call32(proc.proc, address(stack), stack.size());
+ break;
+ case SbxINTEGER:
+ result.PutInteger(
+ static_cast< sal_Int16 >(
+ DllMgr_call32(proc.proc, address(stack), stack.size())));
+ break;
+ case SbxLONG:
+ result.PutLong(
+ static_cast< sal_Int32 >(
+ DllMgr_call32(proc.proc, address(stack), stack.size())));
+ break;
+ case SbxSINGLE:
+ result.PutSingle(
+ static_cast< float >(
+ DllMgr_callFp(proc.proc, address(stack), stack.size())));
+ break;
+ case SbxDOUBLE:
+ result.PutDouble(
+ DllMgr_callFp(proc.proc, address(stack), stack.size()));
+ break;
+ case SbxSTRING:
+ {
+ char const * s1 = reinterpret_cast< char const * >(
+ DllMgr_call32(proc.proc, address(stack), stack.size()));
+ rtl::OUString s2;
+ SbError e = convert(s1, rtl_str_getLength(s1), &s2);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ result.PutString(String(s2));
+ break;
+ }
+ case SbxOBJECT:
+ //TODO
+ DllMgr_call32(proc.proc, address(stack), stack.size());
+ break;
+ case SbxBOOL:
+ result.PutBool(
+ static_cast< sal_Bool >(
+ DllMgr_call32(proc.proc, address(stack), stack.size())));
+ break;
+ case SbxBYTE:
+ result.PutByte(
+ static_cast< sal_uInt8 >(
+ DllMgr_call32(proc.proc, address(stack), stack.size())));
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ for (USHORT i = 1; i < (arguments == 0 ? 0 : arguments->Count()); ++i) {
+ arguments->Get(i)->ResetFlag(SBX_REFERENCE);
+ //TODO: skipped for errors?!?
+ }
+ for (std::vector< UnmarshalData >::iterator i(data.unmarshal.begin());
+ i != data.unmarshal.end(); ++i)
+ {
+ unmarshal(i->variable, i->buffer);
+ }
+ for (std::vector< StringData >::iterator i(data.unmarshalStrings.begin());
+ i != data.unmarshalStrings.end(); ++i)
+ {
+ SbError e = unmarshalString(*i, result);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ }
+ return ERRCODE_NONE;
+}
+
+SbError getProcData(HMODULE handle, rtl::OUString const & name, ProcData * proc)
+{
+ OSL_ASSERT(proc != 0);
+ if (name.getLength() != 0 && name[0] == '@') { //TODO: "@" vs. "#"???
+ sal_Int32 n = name.copy(1).toInt32(); //TODO: handle bad input
+ if (n <= 0 || n > 0xFFFF) {
+ return ERRCODE_BASIC_BAD_ARGUMENT; //TODO: more specific errcode?
+ }
+ FARPROC p = GetProcAddress(handle, reinterpret_cast< LPCSTR >(n));
+ if (p != 0) {
+ proc->name = rtl::OString(RTL_CONSTASCII_STRINGPARAM("#")) +
+ rtl::OString::valueOf(n);
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ } else {
+ rtl::OString name8;
+ SbError e = convert(name, &name8);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ FARPROC p = GetProcAddress(handle, name8.getStr());
+ if (p != 0) {
+ proc->name = name8;
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ sal_Int32 i = name8.indexOf('#');
+ if (i != -1) {
+ name8 = name8.copy(0, i);
+ p = GetProcAddress(handle, name8.getStr());
+ if (p != 0) {
+ proc->name = name8;
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ }
+ rtl::OString real(
+ rtl::OString(RTL_CONSTASCII_STRINGPARAM("_")) + name8);
+ p = GetProcAddress(handle, real.getStr());
+ if (p != 0) {
+ proc->name = real;
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ real = name8 + rtl::OString(RTL_CONSTASCII_STRINGPARAM("A"));
+ p = GetProcAddress(handle, real.getStr());
+ if (p != 0) {
+ proc->name = real;
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ }
+ return ERRCODE_BASIC_PROC_UNDEFINED;
+}
+
+struct Dll: public salhelper::SimpleReferenceObject {
+private:
+ typedef std::map< rtl::OUString, ProcData > Procs;
+
+ virtual ~Dll();
+
+public:
+ Dll(): handle(0) {}
+
+ SbError getProc(rtl::OUString const & name, ProcData * proc);
+
+ HMODULE handle;
+ Procs procs;
+};
+
+Dll::~Dll() {
+ if (handle != 0 && !FreeLibrary(handle)) {
+ OSL_TRACE("FreeLibrary(%p) failed with %u", handle, GetLastError());
+ }
+}
+
+SbError Dll::getProc(rtl::OUString const & name, ProcData * proc) {
+ Procs::iterator i(procs.find(name));
+ if (i != procs.end()) {
+ *proc = i->second;
+ return ERRCODE_NONE;
+ }
+ SbError e = getProcData(handle, name, proc);
+ if (e == ERRCODE_NONE) {
+ procs.insert(Procs::value_type(name, *proc));
+ }
+ return e;
+}
+
+rtl::OUString fullDllName(rtl::OUString const & name) {
+ rtl::OUString full(name);
+ if (full.indexOf('.') == -1) {
+ full += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".DLL"));
+ }
+ return full;
+}
+
+}
+
+struct SbiDllMgr::Impl: private boost::noncopyable {
+private:
+ typedef std::map< rtl::OUString, rtl::Reference< Dll > > Dlls;
+
+public:
+ Dll * getDll(rtl::OUString const & name);
+
+ Dlls dlls;
+};
+
+Dll * SbiDllMgr::Impl::getDll(rtl::OUString const & name) {
+ Dlls::iterator i(dlls.find(name));
+ if (i == dlls.end()) {
+ i = dlls.insert(Dlls::value_type(name, new Dll)).first;
+ HMODULE h = LoadLibraryW(reinterpret_cast<LPCWSTR>(name.getStr()));
+ if (h == 0) {
+ dlls.erase(i);
+ return 0;
+ }
+ i->second->handle = h;
+ }
+ return i->second.get();
+}
+
+SbError SbiDllMgr::Call(
+ rtl::OUString const & function, rtl::OUString const & library,
+ SbxArray * arguments, SbxVariable & result, bool cdeclConvention)
+{
+ if (cdeclConvention) {
+ return ERRCODE_BASIC_NOT_IMPLEMENTED;
+ }
+ rtl::OUString dllName(fullDllName(library));
+ Dll * dll = impl_->getDll(dllName);
+ if (dll == 0) {
+ return ERRCODE_BASIC_BAD_DLL_LOAD;
+ }
+ ProcData proc;
+ SbError e = dll->getProc(function, &proc);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ return call(dllName, proc, arguments, result);
+}
+
+void SbiDllMgr::FreeDll(rtl::OUString const & library) {
+ impl_->dlls.erase(library);
+}
+
+#else
+
+struct SbiDllMgr::Impl {};
+
+SbError SbiDllMgr::Call(
+ rtl::OUString const &, rtl::OUString const &, SbxArray *, SbxVariable &,
+ bool)
+{
+ return ERRCODE_BASIC_NOT_IMPLEMENTED;
+}
+
+void SbiDllMgr::FreeDll(rtl::OUString const &) {}
+
+#endif
+
+SbiDllMgr::SbiDllMgr(): impl_(new Impl) {}
+
+SbiDllMgr::~SbiDllMgr() {}
diff --git a/basic/source/runtime/dllmgr.hxx b/basic/source/runtime/dllmgr.hxx
new file mode 100644
index 000000000000..fdff8c2849be
--- /dev/null
+++ b/basic/source/runtime/dllmgr.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASIC_SOURCE_RUNTIME_DLLMGR_HXX
+#define INCLUDED_BASIC_SOURCE_RUNTIME_DLLMGR_HXX
+
+#include "sal/config.h"
+
+#include <memory>
+
+#include "basic/sberrors.hxx"
+#include "boost/noncopyable.hpp"
+
+namespace rtl { class OUString; }
+class SbxArray;
+class SbxVariable;
+
+class SbiDllMgr: private boost::noncopyable {
+public:
+ SbiDllMgr();
+
+ ~SbiDllMgr();
+
+ SbError Call(
+ rtl::OUString const & function, rtl::OUString const & library,
+ SbxArray * arguments, SbxVariable & result, bool cdeclConvention);
+
+ void FreeDll(rtl::OUString const & library);
+
+private:
+ struct Impl;
+
+ std::auto_ptr< Impl > impl_;
+};
+
+#endif
diff --git a/basic/source/runtime/inputbox.cxx b/basic/source/runtime/inputbox.cxx
new file mode 100644
index 000000000000..17b98ad7addd
--- /dev/null
+++ b/basic/source/runtime/inputbox.cxx
@@ -0,0 +1,197 @@
+/*************************************************************************
+ *
+ * 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"
+
+#ifndef _SV_BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+#include <vcl/fixed.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/svapp.hxx>
+#include "runtime.hxx"
+#include "stdobj.hxx"
+#include "rtlproto.hxx"
+
+class SvRTLInputBox : public ModalDialog
+{
+ Edit aEdit;
+ OKButton aOk;
+ CancelButton aCancel;
+ FixedText aPromptText;
+ String aText;
+
+ void PositionDialog( long nXTwips, long nYTwips, const Size& rDlgSize );
+ void InitButtons( const Size& rDlgSize );
+ void PositionEdit( const Size& rDlgSize );
+ void PositionPrompt( const String& rPrompt, const Size& rDlgSize );
+ DECL_LINK( OkHdl, Button * );
+ DECL_LINK( CancelHdl, Button * );
+
+public:
+ SvRTLInputBox( Window* pParent, const String& rPrompt, const String& rTitle,
+ const String& rDefault, long nXTwips = -1, long nYTwips = -1 );
+ String GetText() const { return aText; }
+};
+
+SvRTLInputBox::SvRTLInputBox( Window* pParent, const String& rPrompt,
+ const String& rTitle, const String& rDefault,
+ long nXTwips, long nYTwips ) :
+ ModalDialog( pParent,WB_3DLOOK | WB_MOVEABLE | WB_CLOSEABLE ),
+ aEdit( this, WB_LEFT | WB_BORDER ),
+ aOk( this ), aCancel( this ), aPromptText( this, WB_WORDBREAK )
+{
+ SetMapMode( MapMode( MAP_APPFONT ) );
+ Size aDlgSizeApp( 280, 80 );
+ PositionDialog( nXTwips, nYTwips, aDlgSizeApp );
+ InitButtons( aDlgSizeApp );
+ PositionEdit( aDlgSizeApp );
+ PositionPrompt( rPrompt, aDlgSizeApp );
+ aOk.Show();
+ aCancel.Show();
+ aEdit.Show();
+ aPromptText.Show();
+ SetText( rTitle );
+ Font aFont( GetFont());
+ Color aColor( GetBackground().GetColor() );
+ aFont.SetFillColor( aColor );
+ aEdit.SetFont( aFont );
+ aEdit.SetText( rDefault );
+ aEdit.SetSelection( Selection( SELECTION_MIN, SELECTION_MAX ) );
+}
+
+void SvRTLInputBox::InitButtons( const Size& rDlgSize )
+{
+ aOk.SetSizePixel( LogicToPixel( Size( 45, 15) ));
+ aCancel.SetSizePixel( LogicToPixel( Size( 45, 15) ));
+ Point aPos( rDlgSize.Width()-45-10, 5 );
+ aOk.SetPosPixel( LogicToPixel( Point(aPos) ));
+ aPos.Y() += 16;
+ aCancel.SetPosPixel( LogicToPixel( Point(aPos) ));
+ aOk.SetClickHdl(LINK(this,SvRTLInputBox, OkHdl));
+ aCancel.SetClickHdl(LINK(this,SvRTLInputBox,CancelHdl));
+}
+
+void SvRTLInputBox::PositionDialog(long nXTwips, long nYTwips, const Size& rDlgSize)
+{
+ SetSizePixel( LogicToPixel(rDlgSize) );
+ if( nXTwips != -1 && nYTwips != -1 )
+ {
+ Point aDlgPosApp( nXTwips, nYTwips );
+ SetPosPixel( LogicToPixel( aDlgPosApp, MAP_TWIP ) );
+ }
+}
+
+void SvRTLInputBox::PositionEdit( const Size& rDlgSize )
+{
+ aEdit.SetPosPixel( LogicToPixel( Point( 5,rDlgSize.Height()-35)));
+ aEdit.SetSizePixel( LogicToPixel( Size(rDlgSize.Width()-15,12)));
+}
+
+
+void SvRTLInputBox::PositionPrompt(const String& rPrompt,const Size& rDlgSize)
+{
+ if ( rPrompt.Len() == 0 )
+ return;
+ String aText_( rPrompt );
+ aText_.ConvertLineEnd( LINEEND_CR );
+ aPromptText.SetPosPixel( LogicToPixel(Point(5,5)));
+ aPromptText.SetText( aText_ );
+ Size aSize( rDlgSize );
+ aSize.Width() -= 70;
+ aSize.Height() -= 50;
+ aPromptText.SetSizePixel( LogicToPixel(aSize));
+}
+
+
+IMPL_LINK_INLINE_START( SvRTLInputBox, OkHdl, Button *, pButton )
+{
+ (void)pButton;
+
+ aText = aEdit.GetText();
+ EndDialog( 1 );
+ return 0;
+}
+IMPL_LINK_INLINE_END( SvRTLInputBox, OkHdl, Button *, pButton )
+
+IMPL_LINK_INLINE_START( SvRTLInputBox, CancelHdl, Button *, pButton )
+{
+ (void)pButton;
+
+ aText.Erase();
+ EndDialog( 0 );
+ return 0;
+}
+IMPL_LINK_INLINE_END( SvRTLInputBox, CancelHdl, Button *, pButton )
+
+
+// *********************************************************************
+// *********************************************************************
+// *********************************************************************
+
+// Syntax: String InputBox( Prompt, [Title], [Default] [, nXpos, nYpos ] )
+
+RTLFUNC(InputBox)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count();
+ if ( nArgCount < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aTitle;
+ String aDefault;
+ INT32 nX = -1, nY = -1; // zentrieren
+ const String& rPrompt = rPar.Get(1)->GetString();
+ if ( nArgCount > 2 && !rPar.Get(2)->IsErr() )
+ aTitle = rPar.Get(2)->GetString();
+ if ( nArgCount > 3 && !rPar.Get(3)->IsErr() )
+ aDefault = rPar.Get(3)->GetString();
+ if ( nArgCount > 4 )
+ {
+ if ( nArgCount != 6 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ nX = rPar.Get(4)->GetLong();
+ nY = rPar.Get(5)->GetLong();
+ }
+ SvRTLInputBox *pDlg=new SvRTLInputBox(GetpApp()->GetDefDialogParent(),
+ rPrompt,aTitle,aDefault,nX,nY);
+ pDlg->Execute();
+ rPar.Get(0)->PutString( pDlg->GetText() );
+ delete pDlg;
+ }
+}
+
+
+
diff --git a/basic/source/runtime/iosys.cxx b/basic/source/runtime/iosys.cxx
new file mode 100644
index 000000000000..9940890286b4
--- /dev/null
+++ b/basic/source/runtime/iosys.cxx
@@ -0,0 +1,1048 @@
+/*************************************************************************
+ *
+ * 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 <vcl/dialog.hxx>
+#include <vcl/edit.hxx>
+#ifndef _SV_BUTTON_HXX //autogen
+#include <vcl/button.hxx>
+#endif
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/security.h>
+#include <osl/file.hxx>
+#include <tools/urlobj.hxx>
+#include <vos/mutex.hxx>
+
+#include "runtime.hxx"
+
+#ifdef _USE_UNO
+
+// <-- encoding
+#include <sal/alloca.h>
+
+#include <ctype.h>
+#include <rtl/byteseq.hxx>
+#include <rtl/textenc.h>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/textenc.h>
+#include <rtl/ustrbuf.hxx>
+// encoding -->
+#include <comphelper/processfactory.hxx>
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#include <com/sun/star/ucb/XContentProviderManager.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/bridge/XBridge.hpp>
+#include <com/sun/star/bridge/XBridgeFactory.hpp>
+
+using namespace comphelper;
+using namespace osl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::io;
+using namespace com::sun::star::bridge;
+
+#endif /* _USE_UNO */
+
+#include "iosys.hxx"
+#include "sbintern.hxx"
+
+// Der Input-Dialog:
+
+class SbiInputDialog : public ModalDialog {
+ Edit aInput;
+ OKButton aOk;
+ CancelButton aCancel;
+ String aText;
+ DECL_LINK( Ok, Window * );
+ DECL_LINK( Cancel, Window * );
+public:
+ SbiInputDialog( Window*, const String& );
+ const String& GetInput() { return aText; }
+};
+
+SbiInputDialog::SbiInputDialog( Window* pParent, const String& rPrompt )
+ :ModalDialog( pParent, WB_3DLOOK | WB_MOVEABLE | WB_CLOSEABLE ),
+ aInput( this, WB_3DLOOK | WB_LEFT | WB_BORDER ),
+ aOk( this ), aCancel( this )
+{
+ SetText( rPrompt );
+ aOk.SetClickHdl( LINK( this, SbiInputDialog, Ok ) );
+ aCancel.SetClickHdl( LINK( this, SbiInputDialog, Cancel ) );
+ SetMapMode( MapMode( MAP_APPFONT ) );
+
+ Point aPt = LogicToPixel( Point( 50, 50 ) );
+ Size aSz = LogicToPixel( Size( 145, 65 ) );
+ SetPosSizePixel( aPt, aSz );
+ aPt = LogicToPixel( Point( 10, 10 ) );
+ aSz = LogicToPixel( Size( 120, 12 ) );
+ aInput.SetPosSizePixel( aPt, aSz );
+ aPt = LogicToPixel( Point( 15, 30 ) );
+ aSz = LogicToPixel( Size( 45, 15) );
+ aOk.SetPosSizePixel( aPt, aSz );
+ aPt = LogicToPixel( Point( 80, 30 ) );
+ aSz = LogicToPixel( Size( 45, 15) );
+ aCancel.SetPosSizePixel( aPt, aSz );
+
+ aInput.Show();
+ aOk.Show();
+ aCancel.Show();
+}
+
+IMPL_LINK_INLINE_START( SbiInputDialog, Ok, Window *, pWindow )
+{
+ (void)pWindow;
+
+ aText = aInput.GetText();
+ EndDialog( 1 );
+ return 0;
+}
+IMPL_LINK_INLINE_END( SbiInputDialog, Ok, Window *, pWindow )
+
+IMPL_LINK_INLINE_START( SbiInputDialog, Cancel, Window *, pWindow )
+{
+ (void)pWindow;
+
+ EndDialog( 0 );
+ return 0;
+}
+IMPL_LINK_INLINE_END( SbiInputDialog, Cancel, Window *, pWindow )
+
+//////////////////////////////////////////////////////////////////////////
+
+SbiStream::SbiStream()
+ : pStrm( 0 )
+{
+}
+
+SbiStream::~SbiStream()
+{
+ delete pStrm;
+}
+
+// Ummappen eines SvStream-Fehlers auf einen StarBASIC-Code
+
+void SbiStream::MapError()
+{
+ if( pStrm )
+ switch( pStrm->GetError() )
+ {
+ case SVSTREAM_OK:
+ nError = 0; break;
+ case SVSTREAM_FILE_NOT_FOUND:
+ nError = SbERR_FILE_NOT_FOUND; break;
+ case SVSTREAM_PATH_NOT_FOUND:
+ nError = SbERR_PATH_NOT_FOUND; break;
+ case SVSTREAM_TOO_MANY_OPEN_FILES:
+ nError = SbERR_TOO_MANY_FILES; break;
+ case SVSTREAM_ACCESS_DENIED:
+ nError = SbERR_ACCESS_DENIED; break;
+ case SVSTREAM_INVALID_PARAMETER:
+ nError = SbERR_BAD_ARGUMENT; break;
+ case SVSTREAM_OUTOFMEMORY:
+ nError = SbERR_NO_MEMORY; break;
+ default:
+ nError = SbERR_IO_ERROR; break;
+ }
+}
+
+#ifdef _USE_UNO
+
+// TODO: Code is copied from daemons2/source/uno/asciiEncoder.cxx
+
+::rtl::OUString findUserInDescription( const ::rtl::OUString& aDescription )
+{
+ ::rtl::OUString user;
+
+ sal_Int32 index;
+ sal_Int32 lastIndex = 0;
+
+ do
+ {
+ index = aDescription.indexOf((sal_Unicode) ',', lastIndex);
+ ::rtl::OUString token = (index == -1) ? aDescription.copy(lastIndex) : aDescription.copy(lastIndex, index - lastIndex);
+
+ lastIndex = index + 1;
+
+ sal_Int32 eindex = token.indexOf((sal_Unicode)'=');
+ ::rtl::OUString left = token.copy(0, eindex).toAsciiLowerCase().trim();
+ ::rtl::OUString right = INetURLObject::decode( token.copy(eindex + 1).trim(), '%',
+ INetURLObject::DECODE_WITH_CHARSET );
+
+ if(left.equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("user"))))
+ {
+ user = right;
+ break;
+ }
+ }
+ while(index != -1);
+
+ return user;
+}
+
+#endif
+
+
+// Hack for #83750
+BOOL runsInSetup( void );
+
+BOOL needSecurityRestrictions( void )
+{
+#ifdef _USE_UNO
+ static BOOL bNeedInit = TRUE;
+ static BOOL bRetVal = TRUE;
+
+ if( bNeedInit )
+ {
+ // Hack for #83750, use internal flag until
+ // setup provides own service manager
+ if( runsInSetup() )
+ {
+ // Setup is not critical
+ bRetVal = FALSE;
+ return bRetVal;
+ }
+
+ bNeedInit = FALSE;
+
+ // Get system user to compare to portal user
+ oslSecurity aSecurity = osl_getCurrentSecurity();
+ ::rtl::OUString aSystemUser;
+ sal_Bool bRet = osl_getUserName( aSecurity, &aSystemUser.pData );
+ if( !bRet )
+ {
+ // No valid security! -> Secure mode!
+ return TRUE;
+ }
+
+ Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
+ if( !xSMgr.is() )
+ return TRUE;
+ Reference< XBridgeFactory > xBridgeFac( xSMgr->createInstance
+ ( ::rtl::OUString::createFromAscii( "com.sun.star.bridge.BridgeFactory" ) ), UNO_QUERY );
+
+ Sequence< Reference< XBridge > > aBridgeSeq;
+ sal_Int32 nBridgeCount = 0;
+ if( xBridgeFac.is() )
+ {
+ aBridgeSeq = xBridgeFac->getExistingBridges();
+ nBridgeCount = aBridgeSeq.getLength();
+ }
+
+ if( nBridgeCount == 0 )
+ {
+ // No bridges -> local
+ bRetVal = FALSE;
+ return bRetVal;
+ }
+
+ // Iterate through all bridges to find (portal) user property
+ const Reference< XBridge >* pBridges = aBridgeSeq.getConstArray();
+ bRetVal = FALSE; // Now only TRUE if user different from portal user is found
+ sal_Int32 i;
+ for( i = 0 ; i < nBridgeCount ; i++ )
+ {
+ const Reference< XBridge >& rxBridge = pBridges[ i ];
+ ::rtl::OUString aDescription = rxBridge->getDescription();
+ ::rtl::OUString aPortalUser = findUserInDescription( aDescription );
+ if( aPortalUser.getLength() > 0 )
+ {
+ // User Found, compare to system user
+ if( aPortalUser == aSystemUser )
+ {
+ // Same user -> system security is ok, bRetVal stays FALSE
+ break;
+ }
+ else
+ {
+ // Different user -> Secure mode!
+ bRetVal = TRUE;
+ break;
+ }
+ }
+ }
+ // No user found or PortalUser != SystemUser -> Secure mode! (Keep default value)
+ }
+
+ return bRetVal;
+#else
+ return FALSE;
+#endif
+}
+
+// Returns TRUE if UNO is available, otherwise the old file
+// system implementation has to be used
+// #89378 New semantic: Don't just ask for UNO but for UCB
+BOOL hasUno( void )
+{
+#ifdef _USE_UNO
+ static BOOL bNeedInit = TRUE;
+ static BOOL bRetVal = TRUE;
+
+ if( bNeedInit )
+ {
+ bNeedInit = FALSE;
+ Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
+ if( !xSMgr.is() )
+ {
+ // No service manager at all
+ bRetVal = FALSE;
+ }
+ else
+ {
+ Reference< XContentProviderManager > xManager( xSMgr->createInstance( ::rtl::OUString::createFromAscii
+ ( "com.sun.star.ucb.UniversalContentBroker" ) ), UNO_QUERY );
+
+ if ( !( xManager.is() && xManager->queryContentProvider( ::rtl::OUString::createFromAscii( "file:///" ) ).is() ) )
+ {
+ // No UCB
+ bRetVal = FALSE;
+ }
+ }
+ }
+ return bRetVal;
+#else
+ return FALSE;
+#endif
+}
+
+
+
+#ifndef _OLD_FILE_IMPL
+
+class OslStream : public SvStream
+{
+ File maFile;
+ short mnStrmMode;
+
+public:
+ OslStream( const String& rName, short nStrmMode );
+ ~OslStream();
+ virtual ULONG GetData( void* pData, ULONG nSize );
+ virtual ULONG PutData( const void* pData, ULONG nSize );
+ virtual ULONG SeekPos( ULONG nPos );
+ virtual void FlushData();
+ virtual void SetSize( ULONG nSize );
+};
+
+OslStream::OslStream( const String& rName, short nStrmMode )
+ : maFile( rName )
+ , mnStrmMode( nStrmMode )
+{
+ sal_uInt32 nFlags;
+
+ if( (nStrmMode & (STREAM_READ | STREAM_WRITE)) == (STREAM_READ | STREAM_WRITE) )
+ {
+ nFlags = OpenFlag_Read | OpenFlag_Write;
+ }
+ else if( nStrmMode & STREAM_WRITE )
+ {
+ nFlags = OpenFlag_Write;
+ }
+ else //if( nStrmMode & STREAM_READ )
+ {
+ nFlags = OpenFlag_Read;
+ }
+
+ FileBase::RC nRet = maFile.open( nFlags );
+ if( nRet == FileBase::E_NOENT && nFlags != OpenFlag_Read )
+ {
+ nFlags |= OpenFlag_Create;
+ nRet = maFile.open( nFlags );
+ }
+
+ if( nRet != FileBase::E_None )
+ {
+ SetError( ERRCODE_IO_GENERAL );
+ }
+}
+
+
+OslStream::~OslStream()
+{
+ maFile.close();
+}
+
+ULONG OslStream::GetData( void* pData, ULONG nSize )
+{
+ sal_uInt64 nBytesRead = nSize;
+ FileBase::RC nRet = FileBase::E_None;
+ nRet = maFile.read( pData, nBytesRead, nBytesRead );
+ return (ULONG)nBytesRead;
+}
+
+ULONG OslStream::PutData( const void* pData, ULONG nSize )
+{
+ sal_uInt64 nBytesWritten;
+ FileBase::RC nRet = FileBase::E_None;
+ nRet = maFile.write( pData, (sal_uInt64)nSize, nBytesWritten );
+ return (ULONG)nBytesWritten;
+}
+
+ULONG OslStream::SeekPos( ULONG nPos )
+{
+ FileBase::RC nRet;
+ if( nPos == STREAM_SEEK_TO_END )
+ {
+ nRet = maFile.setPos( Pos_End, 0 );
+ }
+ else
+ {
+ nRet = maFile.setPos( Pos_Absolut, (sal_uInt64)nPos );
+ }
+ sal_uInt64 nRealPos;
+ nRet = maFile.getPos( nRealPos );
+ return sal::static_int_cast<ULONG>(nRealPos);
+}
+
+void OslStream::FlushData()
+{
+}
+
+void OslStream::SetSize( ULONG nSize )
+{
+ FileBase::RC nRet = FileBase::E_None;
+ nRet = maFile.setSize( (sal_uInt64)nSize );
+}
+
+#endif
+
+
+#ifdef _USE_UNO
+
+class UCBStream : public SvStream
+{
+ Reference< XInputStream > xIS;
+ Reference< XOutputStream > xOS;
+ Reference< XStream > xS;
+ Reference< XSeekable > xSeek;
+public:
+ UCBStream( Reference< XInputStream > & xIS );
+ UCBStream( Reference< XOutputStream > & xOS );
+ UCBStream( Reference< XStream > & xS );
+ ~UCBStream();
+ virtual ULONG GetData( void* pData, ULONG nSize );
+ virtual ULONG PutData( const void* pData, ULONG nSize );
+ virtual ULONG SeekPos( ULONG nPos );
+ virtual void FlushData();
+ virtual void SetSize( ULONG nSize );
+};
+
+/*
+ULONG UCBErrorToSvStramError( ucb::IOErrorCode nError )
+{
+ ULONG eReturn = ERRCODE_IO_GENERAL;
+ switch( nError )
+ {
+ case ucb::IOErrorCode_ABORT: eReturn = SVSTREAM_GENERALERROR; break;
+ case ucb::IOErrorCode_NOT_EXISTING: eReturn = SVSTREAM_FILE_NOT_FOUND; break;
+ case ucb::IOErrorCode_NOT_EXISTING_PATH: eReturn = SVSTREAM_PATH_NOT_FOUND; break;
+ case ucb::IOErrorCode_OUT_OF_FILE_HANDLES: eReturn = SVSTREAM_TOO_MANY_OPEN_FILES; break;
+ case ucb::IOErrorCode_ACCESS_DENIED: eReturn = SVSTREAM_ACCESS_DENIED; break;
+ case ucb::IOErrorCode_LOCKING_VIOLATION: eReturn = SVSTREAM_SHARING_VIOLATION; break;
+
+ case ucb::IOErrorCode_INVALID_ACCESS: eReturn = SVSTREAM_INVALID_ACCESS; break;
+ case ucb::IOErrorCode_CANT_CREATE: eReturn = SVSTREAM_CANNOT_MAKE; break;
+ case ucb::IOErrorCode_INVALID_PARAMETER: eReturn = SVSTREAM_INVALID_PARAMETER; break;
+
+ case ucb::IOErrorCode_CANT_READ: eReturn = SVSTREAM_READ_ERROR; break;
+ case ucb::IOErrorCode_CANT_WRITE: eReturn = SVSTREAM_WRITE_ERROR; break;
+ case ucb::IOErrorCode_CANT_SEEK: eReturn = SVSTREAM_SEEK_ERROR; break;
+ case ucb::IOErrorCode_CANT_TELL: eReturn = SVSTREAM_TELL_ERROR; break;
+
+ case ucb::IOErrorCode_OUT_OF_MEMORY: eReturn = SVSTREAM_OUTOFMEMORY; break;
+
+ case SVSTREAM_FILEFORMAT_ERROR: eReturn = SVSTREAM_FILEFORMAT_ERROR; break;
+ case ucb::IOErrorCode_WRONG_VERSION: eReturn = SVSTREAM_WRONGVERSION;
+ case ucb::IOErrorCode_OUT_OF_DISK_SPACE: eReturn = SVSTREAM_DISK_FULL; break;
+
+ case ucb::IOErrorCode_BAD_CRC: eReturn = ERRCODE_IO_BADCRC; break;
+ }
+ return eReturn;
+}
+*/
+
+UCBStream::UCBStream( Reference< XInputStream > & rStm )
+ : xIS( rStm )
+ , xSeek( rStm, UNO_QUERY )
+{
+}
+
+UCBStream::UCBStream( Reference< XOutputStream > & rStm )
+ : xOS( rStm )
+ , xSeek( rStm, UNO_QUERY )
+{
+}
+
+UCBStream::UCBStream( Reference< XStream > & rStm )
+ : xS( rStm )
+ , xSeek( rStm, UNO_QUERY )
+{
+}
+
+
+UCBStream::~UCBStream()
+{
+ try
+ {
+ if( xIS.is() )
+ xIS->closeInput();
+ else if( xOS.is() )
+ xOS->closeOutput();
+ else if( xS.is() )
+ {
+ Reference< XInputStream > xIS_ = xS->getInputStream();
+ if( xIS_.is() )
+ xIS_->closeInput();
+ }
+ }
+ catch( Exception & )
+ {
+ SetError( ERRCODE_IO_GENERAL );
+ }
+}
+
+ULONG UCBStream::GetData( void* pData, ULONG nSize )
+{
+ try
+ {
+ Reference< XInputStream > xISFromS;
+ if( xIS.is() )
+ {
+ Sequence<sal_Int8> aData;
+ nSize = xIS->readBytes( aData, nSize );
+ rtl_copyMemory( pData, aData.getConstArray(), nSize );
+ return nSize;
+ }
+ else if( xS.is() && (xISFromS = xS->getInputStream()).is() )
+ {
+ Sequence<sal_Int8> aData;
+ nSize = xISFromS->readBytes( aData, nSize );
+ rtl_copyMemory( pData, aData.getConstArray(), nSize );
+ return nSize;
+ }
+ else
+ SetError( ERRCODE_IO_GENERAL );
+ }
+ catch( Exception & )
+ {
+ SetError( ERRCODE_IO_GENERAL );
+ }
+ return 0;
+}
+
+ULONG UCBStream::PutData( const void* pData, ULONG nSize )
+{
+ try
+ {
+ Reference< XOutputStream > xOSFromS;
+ if( xOS.is() )
+ {
+ Sequence<sal_Int8> aData( (const sal_Int8 *)pData, nSize );
+ xOS->writeBytes( aData );
+ return nSize;
+ }
+ else if( xS.is() && (xOSFromS = xS->getOutputStream()).is() )
+ {
+ Sequence<sal_Int8> aData( (const sal_Int8 *)pData, nSize );
+ xOSFromS->writeBytes( aData );
+ return nSize;
+ }
+ else
+ SetError( ERRCODE_IO_GENERAL );
+ }
+ catch( Exception & )
+ {
+ SetError( ERRCODE_IO_GENERAL );
+ }
+ return 0;
+}
+
+ULONG UCBStream::SeekPos( ULONG nPos )
+{
+ try
+ {
+ if( xSeek.is() )
+ {
+ ULONG nLen = sal::static_int_cast<ULONG>( xSeek->getLength() );
+ if( nPos > nLen )
+ nPos = nLen;
+ xSeek->seek( nPos );
+ return nPos;
+ }
+ else
+ SetError( ERRCODE_IO_GENERAL );
+ }
+ catch( Exception & )
+ {
+ SetError( ERRCODE_IO_GENERAL );
+ }
+ return 0;
+}
+
+void UCBStream::FlushData()
+{
+ try
+ {
+ Reference< XOutputStream > xOSFromS;
+ if( xOS.is() )
+ xOS->flush();
+ else if( xS.is() && (xOSFromS = xS->getOutputStream()).is() )
+ xOSFromS->flush();
+ else
+ SetError( ERRCODE_IO_GENERAL );
+ }
+ catch( Exception & )
+ {
+ SetError( ERRCODE_IO_GENERAL );
+ }
+}
+
+void UCBStream::SetSize( ULONG nSize )
+{
+ (void)nSize;
+
+ DBG_ERROR( "not allowed to call from basic" );
+ SetError( ERRCODE_IO_GENERAL );
+}
+
+#endif
+
+// Oeffnen eines Streams
+SbError SbiStream::Open
+( short nCh, const ByteString& rName, short nStrmMode, short nFlags, short nL )
+{
+ nMode = nFlags;
+ nLen = nL;
+ nChan = nCh;
+ nLine = 0;
+ nExpandOnWriteTo = 0;
+ if( ( nStrmMode & ( STREAM_READ|STREAM_WRITE ) ) == STREAM_READ )
+ nStrmMode |= STREAM_NOCREATE;
+ String aStr( rName, gsl_getSystemTextEncoding() );
+ String aNameStr = getFullPath( aStr );
+
+#ifdef _USE_UNO
+ if( hasUno() )
+ {
+ Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
+ if( xSMgr.is() )
+ {
+ Reference< XSimpleFileAccess >
+ xSFI( xSMgr->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
+ if( xSFI.is() )
+ {
+ try
+ {
+
+ // #??? For write access delete file if it already exists (not for appending)
+ if( (nStrmMode & STREAM_WRITE) != 0 && !IsAppend() && !IsBinary() &&
+ xSFI->exists( aNameStr ) && !xSFI->isFolder( aNameStr ) )
+ {
+ xSFI->kill( aNameStr );
+ }
+
+ if( (nStrmMode & (STREAM_READ | STREAM_WRITE)) == (STREAM_READ | STREAM_WRITE) )
+ {
+ Reference< XStream > xIS = xSFI->openFileReadWrite( aNameStr );
+ pStrm = new UCBStream( xIS );
+ }
+ else if( nStrmMode & STREAM_WRITE )
+ {
+ Reference< XStream > xIS = xSFI->openFileReadWrite( aNameStr );
+ pStrm = new UCBStream( xIS );
+ // Open for writing is not implemented in ucb yet!!!
+ //Reference< XOutputStream > xIS = xSFI->openFileWrite( aNameStr );
+ //pStrm = new UCBStream( xIS );
+ }
+ else //if( nStrmMode & STREAM_READ )
+ {
+ Reference< XInputStream > xIS = xSFI->openFileRead( aNameStr );
+ pStrm = new UCBStream( xIS );
+ }
+
+ }
+ catch( Exception & )
+ {
+ nError = ERRCODE_IO_GENERAL;
+ }
+ }
+ }
+ }
+
+#endif
+ if( !pStrm )
+ {
+#ifdef _OLD_FILE_IMPL
+ pStrm = new SvFileStream( aNameStr, nStrmMode );
+#else
+ pStrm = new OslStream( aNameStr, nStrmMode );
+#endif
+ }
+ if( IsAppend() )
+ pStrm->Seek( STREAM_SEEK_TO_END );
+ MapError();
+ if( nError )
+ delete pStrm, pStrm = NULL;
+ return nError;
+}
+
+SbError SbiStream::Close()
+{
+ if( pStrm )
+ {
+ if( !hasUno() )
+ {
+#ifdef _OLD_FILE_IMPL
+ ((SvFileStream *)pStrm)->Close();
+#endif
+ }
+ MapError();
+ delete pStrm;
+ pStrm = NULL;
+ }
+ nChan = 0;
+ return nError;
+}
+
+SbError SbiStream::Read( ByteString& rBuf, USHORT n, bool bForceReadingPerByte )
+{
+ nExpandOnWriteTo = 0;
+ if( !bForceReadingPerByte && IsText() )
+ {
+ pStrm->ReadLine( rBuf );
+ nLine++;
+ }
+ else
+ {
+ if( !n ) n = nLen;
+ if( !n )
+ return nError = SbERR_BAD_RECORD_LENGTH;
+ rBuf.Fill( n, ' ' );
+ pStrm->Read( (void*)rBuf.GetBuffer(), n );
+ }
+ MapError();
+ if( !nError && pStrm->IsEof() )
+ nError = SbERR_READ_PAST_EOF;
+ return nError;
+}
+
+SbError SbiStream::Read( char& ch )
+{
+ nExpandOnWriteTo = 0;
+ if( !aLine.Len() )
+ {
+ Read( aLine, 0 );
+ aLine += '\n';
+ }
+ ch = aLine.GetBuffer()[0];
+ aLine.Erase( 0, 1 );
+ return nError;
+}
+
+void SbiStream::ExpandFile()
+{
+ if ( nExpandOnWriteTo )
+ {
+ ULONG nCur = pStrm->Seek(STREAM_SEEK_TO_END);
+ if( nCur < nExpandOnWriteTo )
+ {
+ ULONG nDiff = nExpandOnWriteTo - nCur;
+ char c = 0;
+ while( nDiff-- )
+ *pStrm << c;
+ }
+ else
+ {
+ pStrm->Seek( nExpandOnWriteTo );
+ }
+ nExpandOnWriteTo = 0;
+ }
+}
+
+SbError SbiStream::Write( const ByteString& rBuf, USHORT n )
+{
+ ExpandFile();
+ if( IsAppend() )
+ pStrm->Seek( STREAM_SEEK_TO_END );
+
+ if( IsText() )
+ {
+ aLine += rBuf;
+ // Raus damit, wenn das Ende ein LF ist, aber CRLF vorher
+ // strippen, da der SvStrm ein CRLF anfuegt!
+ USHORT nLineLen = aLine.Len();
+ if( nLineLen && aLine.GetBuffer()[ --nLineLen ] == 0x0A )
+ {
+ aLine.Erase( nLineLen );
+ if( nLineLen && aLine.GetBuffer()[ --nLineLen ] == 0x0D )
+ aLine.Erase( nLineLen );
+ pStrm->WriteLines( aLine );
+ aLine.Erase();
+ }
+ }
+ else
+ {
+ if( !n ) n = nLen;
+ if( !n )
+ return nError = SbERR_BAD_RECORD_LENGTH;
+ pStrm->Write( rBuf.GetBuffer(), n );
+ MapError();
+ }
+ return nError;
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+// Zugriff auf das aktuelle I/O-System:
+
+SbiIoSystem* SbGetIoSystem()
+{
+ SbiInstance* pInst = pINST;
+ return pInst ? pInst->GetIoSystem() : NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+SbiIoSystem::SbiIoSystem()
+{
+ for( short i = 0; i < CHANNELS; i++ )
+ pChan[ i ] = NULL;
+ nChan = 0;
+ nError = 0;
+}
+
+SbiIoSystem::~SbiIoSystem()
+{
+ Shutdown();
+}
+
+SbError SbiIoSystem::GetError()
+{
+ SbError n = nError; nError = 0;
+ return n;
+}
+
+void SbiIoSystem::Open
+ ( short nCh, const ByteString& rName, short nMode, short nFlags, short nLen )
+{
+ nError = 0;
+ if( nCh >= CHANNELS || !nCh )
+ nError = SbERR_BAD_CHANNEL;
+ else if( pChan[ nCh ] )
+ nError = SbERR_FILE_ALREADY_OPEN;
+ else
+ {
+ pChan[ nCh ] = new SbiStream;
+ nError = pChan[ nCh ]->Open( nCh, rName, nMode, nFlags, nLen );
+ if( nError )
+ delete pChan[ nCh ], pChan[ nCh ] = NULL;
+ }
+ nChan = 0;
+}
+
+// Aktuellen Kanal schliessen
+
+void SbiIoSystem::Close()
+{
+ if( !nChan )
+ nError = SbERR_BAD_CHANNEL;
+ else if( !pChan[ nChan ] )
+ nError = SbERR_BAD_CHANNEL;
+ else
+ {
+ nError = pChan[ nChan ]->Close();
+ delete pChan[ nChan ];
+ pChan[ nChan ] = NULL;
+ }
+ nChan = 0;
+}
+
+// Shutdown nach Programmlauf
+
+void SbiIoSystem::Shutdown()
+{
+ for( short i = 1; i < CHANNELS; i++ )
+ {
+ if( pChan[ i ] )
+ {
+ SbError n = pChan[ i ]->Close();
+ delete pChan[ i ];
+ pChan[ i ] = NULL;
+ if( n && !nError )
+ nError = n;
+ }
+ }
+ nChan = 0;
+ // Noch was zu PRINTen?
+ if( aOut.Len() )
+ {
+ String aOutStr( aOut, gsl_getSystemTextEncoding() );
+#if defined GCC
+ Window* pParent = Application::GetDefDialogParent();
+ MessBox( pParent, WinBits( WB_OK ), String(), aOutStr ).Execute();
+#else
+ MessBox( GetpApp()->GetDefDialogParent(), WinBits( WB_OK ), String(), aOutStr ).Execute();
+#endif
+ }
+ aOut.Erase();
+}
+
+// Aus aktuellem Kanal lesen
+
+void SbiIoSystem::Read( ByteString& rBuf, short n )
+{
+ if( !nChan )
+ ReadCon( rBuf );
+ else if( !pChan[ nChan ] )
+ nError = SbERR_BAD_CHANNEL;
+ else
+ nError = pChan[ nChan ]->Read( rBuf, n );
+}
+
+char SbiIoSystem::Read()
+{
+ char ch = ' ';
+ if( !nChan )
+ {
+ if( !aIn.Len() )
+ {
+ ReadCon( aIn );
+ aIn += '\n';
+ }
+ ch = aIn.GetBuffer()[0];
+ aIn.Erase( 0, 1 );
+ }
+ else if( !pChan[ nChan ] )
+ nError = SbERR_BAD_CHANNEL;
+ else
+ nError = pChan[ nChan ]->Read( ch );
+ return ch;
+}
+
+void SbiIoSystem::Write( const ByteString& rBuf, short n )
+{
+ if( !nChan )
+ WriteCon( rBuf );
+ else if( !pChan[ nChan ] )
+ nError = SbERR_BAD_CHANNEL;
+ else
+ nError = pChan[ nChan ]->Write( rBuf, n );
+}
+
+short SbiIoSystem::NextChannel()
+{
+ for( short i = 1; i < CHANNELS; i++ )
+ {
+ if( !pChan[ i ] )
+ return i;
+ }
+ nError = SbERR_TOO_MANY_FILES;
+ return CHANNELS;
+}
+
+// nChannel == 0..CHANNELS-1
+
+SbiStream* SbiIoSystem::GetStream( short nChannel ) const
+{
+ SbiStream* pRet = 0;
+ if( nChannel >= 0 && nChannel < CHANNELS )
+ pRet = pChan[ nChannel ];
+ return pRet;
+}
+
+void SbiIoSystem::CloseAll(void)
+{
+ for( short i = 1; i < CHANNELS; i++ )
+ {
+ if( pChan[ i ] )
+ {
+ SbError n = pChan[ i ]->Close();
+ delete pChan[ i ];
+ pChan[ i ] = NULL;
+ if( n && !nError )
+ nError = n;
+ }
+ }
+}
+
+/***************************************************************************
+*
+* Console Support
+*
+***************************************************************************/
+
+// Einlesen einer Zeile von der Console
+
+void SbiIoSystem::ReadCon( ByteString& rIn )
+{
+ String aPromptStr( aPrompt, gsl_getSystemTextEncoding() );
+ SbiInputDialog aDlg( NULL, aPromptStr );
+ if( aDlg.Execute() )
+ rIn = ByteString( aDlg.GetInput(), gsl_getSystemTextEncoding() );
+ else
+ nError = SbERR_USER_ABORT;
+ aPrompt.Erase();
+}
+
+// Ausgabe einer MessageBox, wenn im Console-Puffer ein CR ist
+
+void SbiIoSystem::WriteCon( const ByteString& rText )
+{
+ aOut += rText;
+ USHORT n1 = aOut.Search( '\n' );
+ USHORT n2 = aOut.Search( '\r' );
+ if( n1 != STRING_NOTFOUND || n2 != STRING_NOTFOUND )
+ {
+ if( n1 == STRING_NOTFOUND ) n1 = n2;
+ else
+ if( n2 == STRING_NOTFOUND ) n2 = n1;
+ if( n1 > n2 ) n1 = n2;
+ ByteString s( aOut.Copy( 0, n1 ) );
+ aOut.Erase( 0, n1 );
+ while( aOut.GetBuffer()[0] == '\n' || aOut.GetBuffer()[0] == '\r' )
+ aOut.Erase( 0, 1 );
+ String aStr( s, gsl_getSystemTextEncoding() );
+ {
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ if( !MessBox( GetpApp()->GetDefDialogParent(),
+ WinBits( WB_OK_CANCEL | WB_DEF_OK ),
+ String(), aStr ).Execute() )
+ nError = SbERR_USER_ABORT;
+ }
+ }
+}
+
diff --git a/basic/source/runtime/makefile.mk b/basic/source/runtime/makefile.mk
new file mode 100644
index 000000000000..f2ed11196b28
--- /dev/null
+++ b/basic/source/runtime/makefile.mk
@@ -0,0 +1,71 @@
+#*************************************************************************
+#
+# 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=runtime
+
+ENABLE_EXCEPTIONS = TRUE
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+
+# --- Allgemein -----------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/basrdll.obj \
+ $(SLO)$/inputbox.obj \
+ $(SLO)$/runtime.obj \
+ $(SLO)$/step0.obj \
+ $(SLO)$/step1.obj \
+ $(SLO)$/step2.obj \
+ $(SLO)$/iosys.obj \
+ $(SLO)$/stdobj.obj \
+ $(SLO)$/stdobj1.obj \
+ $(SLO)$/methods.obj \
+ $(SLO)$/methods1.obj \
+ $(SLO)$/props.obj \
+ $(SLO)$/ddectrl.obj \
+ $(SLO)$/dllmgr.obj
+
+.IF "$(GUI)$(COM)$(CPU)" == "WNTMSCI"
+SLOFILES+= $(SLO)$/wnt.obj
+.ELIF "$(GUI)$(COM)$(CPU)" == "WNTGCCI"
+SLOFILES+= $(SLO)$/wnt-mingw.obj
+.ENDIF
+
+# --- Targets -------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+#kendy: Cut'n'paste from bridges/source/cpp_uno/mingw_intel/makefile.mk
+ $(CC) -c -o $(SLO)$/$(@:b).obj $<
+ touch $@
diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx
new file mode 100644
index 000000000000..1a60a5d79a45
--- /dev/null
+++ b/basic/source/runtime/methods.cxx
@@ -0,0 +1,4583 @@
+/*************************************************************************
+ *
+ * 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/date.hxx>
+#include <basic/sbxvar.hxx>
+#ifndef _VOS_PROCESS_HXX
+#include <vos/process.hxx>
+#endif
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/sound.hxx>
+#include <vcl/wintypes.hxx>
+#include <vcl/msgbox.hxx>
+#include <basic/sbx.hxx>
+#include <svl/zforlist.hxx>
+#include <rtl/math.hxx>
+#include <tools/urlobj.hxx>
+#include <osl/time.h>
+#include <unotools/charclass.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <tools/wldcrd.hxx>
+#include <i18npool/lang.h>
+
+#include "runtime.hxx"
+#include "sbunoobj.hxx"
+#ifdef WNT
+#include <tools/prewin.h>
+#include "winbase.h"
+#include <tools/postwin.h>
+#ifndef _FSYS_HXX //autogen
+#include <tools/fsys.hxx>
+#endif
+#else
+#include <osl/file.hxx>
+#endif
+#include "errobject.hxx"
+
+#ifdef _USE_UNO
+#include <comphelper/processfactory.hxx>
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+
+using namespace comphelper;
+using namespace osl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::io;
+
+#endif /* _USE_UNO */
+
+//#define _ENABLE_CUR_DIR
+
+#include "stdobj.hxx"
+#include <basic/sbstdobj.hxx>
+#include "rtlproto.hxx"
+#include "basrid.hxx"
+#include "image.hxx"
+#include "sb.hrc"
+#include "iosys.hxx"
+#include "ddectrl.hxx"
+#include <sbintern.hxx>
+
+#include <list>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#if defined (WIN) || defined (WNT) || defined (OS2)
+#include <direct.h> // _getdcwd get current work directory, _chdrive
+#endif
+
+#ifdef WIN
+#include <dos.h> // _dos_getfileattr
+#include <errno.h>
+#endif
+
+#ifdef UNX
+#include <errno.h>
+#include <unistd.h>
+#endif
+
+#ifdef WNT
+#include <io.h>
+#endif
+
+#include <basic/sbobjmod.hxx>
+
+static void FilterWhiteSpace( String& rStr )
+{
+ rStr.EraseAllChars( ' ' );
+ rStr.EraseAllChars( '\t' );
+ rStr.EraseAllChars( '\n' );
+ rStr.EraseAllChars( '\r' );
+}
+
+static long GetDayDiff( const Date& rDate )
+{
+ Date aRefDate( 1,1,1900 );
+ long nDiffDays;
+ if ( aRefDate > rDate )
+ {
+ nDiffDays = (long)(aRefDate - rDate);
+ nDiffDays *= -1;
+ }
+ else
+ nDiffDays = (long)(rDate - aRefDate);
+ nDiffDays += 2; // Anpassung VisualBasic: 1.Jan.1900 == 2
+ return nDiffDays;
+}
+
+static CharClass& GetCharClass( void )
+{
+ static sal_Bool bNeedsInit = sal_True;
+ static ::com::sun::star::lang::Locale aLocale;
+ if( bNeedsInit )
+ {
+ bNeedsInit = sal_False;
+ aLocale = Application::GetSettings().GetLocale();
+ }
+ static CharClass aCharClass( aLocale );
+ return aCharClass;
+}
+
+static inline BOOL isFolder( FileStatus::Type aType )
+{
+ return ( aType == FileStatus::Directory || aType == FileStatus::Volume );
+}
+
+
+//*** UCB file access ***
+
+// Converts possibly relative paths to absolute paths
+// according to the setting done by ChDir/ChDrive
+String getFullPath( const String& aRelPath )
+{
+ ::rtl::OUString aFileURL;
+
+ // #80204 Try first if it already is a valid URL
+ INetURLObject aURLObj( aRelPath );
+ aFileURL = aURLObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if( !aFileURL.getLength() )
+ {
+ File::getFileURLFromSystemPath( aRelPath, aFileURL );
+ }
+
+ return aFileURL;
+}
+
+// Sets (virtual) current path for UCB file access
+void implChDir( const String& aDir )
+{
+ (void)aDir;
+ // TODO
+}
+
+// Sets (virtual) current drive for UCB file access
+void implChDrive( const String& aDrive )
+{
+ (void)aDrive;
+ // TODO
+}
+
+// Returns (virtual) current path for UCB file access
+String implGetCurDir( void )
+{
+ String aRetStr;
+
+ return aRetStr;
+}
+
+// TODO: -> SbiGlobals
+static com::sun::star::uno::Reference< XSimpleFileAccess3 > getFileAccess( void )
+{
+ static com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI;
+ if( !xSFI.is() )
+ {
+ com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
+ if( xSMgr.is() )
+ {
+ xSFI = com::sun::star::uno::Reference< XSimpleFileAccess3 >( xSMgr->createInstance
+ ( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
+ }
+ }
+ return xSFI;
+}
+
+
+
+// Properties und Methoden legen beim Get (bPut = FALSE) den Returnwert
+// im Element 0 des Argv ab; beim Put (bPut = TRUE) wird der Wert aus
+// Element 0 gespeichert.
+
+// CreateObject( class )
+
+RTLFUNC(CreateObject)
+{
+ (void)bWrite;
+
+ String aClass( rPar.Get( 1 )->GetString() );
+ SbxObjectRef p = SbxBase::CreateObject( aClass );
+ if( !p )
+ StarBASIC::Error( SbERR_CANNOT_LOAD );
+ else
+ {
+ // Convenience: BASIC als Parent eintragen
+ p->SetParent( pBasic );
+ rPar.Get( 0 )->PutObject( p );
+ }
+}
+
+// Error( n )
+
+RTLFUNC(Error)
+{
+ (void)bWrite;
+
+ if( !pBasic )
+ StarBASIC::Error( SbERR_INTERNAL_ERROR );
+ else
+ {
+ String aErrorMsg;
+ SbError nErr = 0L;
+ INT32 nCode = 0;
+ if( rPar.Count() == 1 )
+ {
+ nErr = StarBASIC::GetErrBasic();
+ aErrorMsg = StarBASIC::GetErrorMsg();
+ }
+ else
+ {
+ nCode = rPar.Get( 1 )->GetLong();
+ if( nCode > 65535L )
+ StarBASIC::Error( SbERR_CONVERSION );
+ else
+ nErr = StarBASIC::GetSfxFromVBError( (USHORT)nCode );
+ }
+
+ bool bVBA = SbiRuntime::isVBAEnabled();
+ String tmpErrMsg;
+ if( bVBA && aErrorMsg.Len() > 0 )
+ {
+ tmpErrMsg = aErrorMsg;
+ }
+ else
+ {
+ pBasic->MakeErrorText( nErr, aErrorMsg );
+ tmpErrMsg = pBasic->GetErrorText();
+ }
+ // If this rtlfunc 'Error' passed a errcode the same as the active Err Objects's
+ // current err then return the description for the error message if it is set
+ // ( complicated isn't it ? )
+ if ( bVBA && rPar.Count() > 1 )
+ {
+ com::sun::star::uno::Reference< ooo::vba::XErrObject > xErrObj( SbxErrObject::getUnoErrObject() );
+ if ( xErrObj.is() && xErrObj->getNumber() == nCode && xErrObj->getDescription().getLength() )
+ tmpErrMsg = xErrObj->getDescription();
+ }
+ rPar.Get( 0 )->PutString( tmpErrMsg );
+ }
+}
+
+// Sinus
+
+RTLFUNC(Sin)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ rPar.Get( 0 )->PutDouble( sin( pArg->GetDouble() ) );
+ }
+}
+
+// Cosinus
+
+RTLFUNC(Cos)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ rPar.Get( 0 )->PutDouble( cos( pArg->GetDouble() ) );
+ }
+}
+
+// Atn
+
+RTLFUNC(Atn)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ rPar.Get( 0 )->PutDouble( atan( pArg->GetDouble() ) );
+ }
+}
+
+
+
+RTLFUNC(Abs)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ rPar.Get( 0 )->PutDouble( fabs( pArg->GetDouble() ) );
+ }
+}
+
+
+RTLFUNC(Asc)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ String aStr( pArg->GetString() );
+ if ( aStr.Len() == 0 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ rPar.Get(0)->PutEmpty();
+ }
+ else
+ {
+ sal_Unicode aCh = aStr.GetBuffer()[0];
+ rPar.Get(0)->PutLong( aCh );
+ }
+ }
+}
+
+RTLFUNC(Chr)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ sal_Unicode aCh = (sal_Unicode)pArg->GetUShort();
+ String aStr( aCh );
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+
+#ifdef UNX
+#define _MAX_PATH 260
+#define _PATH_INCR 250
+#endif
+
+RTLFUNC(CurDir)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // #57064 Obwohl diese Funktion nicht mit DirEntry arbeitet, ist sie von
+ // der Anpassung an virtuelle URLs nich betroffen, da bei Nutzung der
+ // DirEntry-Funktionalitaet keine Moeglichkeit besteht, das aktuelle so
+ // zu ermitteln, dass eine virtuelle URL geliefert werden koennte.
+
+// rPar.Get(0)->PutEmpty();
+#if defined (WIN) || defined (WNT) || defined (OS2)
+ int nCurDir = 0; // Current dir // JSM
+ if ( rPar.Count() == 2 )
+ {
+ String aDrive = rPar.Get(1)->GetString();
+ if ( aDrive.Len() != 1 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ else
+ {
+ nCurDir = (int)aDrive.GetBuffer()[0];
+ if ( !isalpha( nCurDir ) )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ else
+ nCurDir -= ( 'A' - 1 );
+ }
+ }
+ char* pBuffer = new char[ _MAX_PATH ];
+#ifdef OS2
+ if( !nCurDir )
+ nCurDir = _getdrive();
+#endif
+ if ( _getdcwd( nCurDir, pBuffer, _MAX_PATH ) != 0 )
+ rPar.Get(0)->PutString( String::CreateFromAscii( pBuffer ) );
+ else
+ StarBASIC::Error( SbERR_NO_DEVICE );
+ delete [] pBuffer;
+
+#elif defined( UNX )
+
+ int nSize = _PATH_INCR;
+ char* pMem;
+ while( TRUE )
+ {
+ pMem = new char[nSize];
+ if( !pMem )
+ {
+ StarBASIC::Error( SbERR_NO_MEMORY );
+ return;
+ }
+ if( getcwd( pMem, nSize-1 ) != NULL )
+ {
+ rPar.Get(0)->PutString( String::CreateFromAscii(pMem) );
+ delete [] pMem;
+ return;
+ }
+ if( errno != ERANGE )
+ {
+ StarBASIC::Error( SbERR_INTERNAL_ERROR );
+ delete [] pMem;
+ return;
+ }
+ delete [] pMem;
+ nSize += _PATH_INCR;
+ };
+
+#endif
+}
+
+RTLFUNC(ChDir) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutEmpty();
+ if (rPar.Count() == 2)
+ {
+#ifdef _ENABLE_CUR_DIR
+ String aPath = rPar.Get(1)->GetString();
+ BOOL bError = FALSE;
+#ifdef WNT
+ // #55997 Laut MI hilft es bei File-URLs einen DirEntry zwischenzuschalten
+ // #40996 Harmoniert bei Verwendung der WIN32-Funktion nicht mit getdir
+ DirEntry aEntry( aPath );
+ ByteString aFullPath( aEntry.GetFull(), gsl_getSystemTextEncoding() );
+ if( chdir( aFullPath.GetBuffer()) )
+ bError = TRUE;
+#else
+ if (!DirEntry(aPath).SetCWD())
+ bError = TRUE;
+#endif
+ if( bError )
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+#endif
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(ChDrive) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutEmpty();
+ if (rPar.Count() == 2)
+ {
+#ifdef _ENABLE_CUR_DIR
+ // Keine Laufwerke in Unix
+#ifndef UNX
+ String aPar1 = rPar.Get(1)->GetString();
+
+#if defined (WIN) || defined (WNT) || defined (OS2)
+ if (aPar1.Len() > 0)
+ {
+ int nCurDrive = (int)aPar1.GetBuffer()[0]; ;
+ if ( !isalpha( nCurDrive ) )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ else
+ nCurDrive -= ( 'A' - 1 );
+ if (_chdrive(nCurDrive))
+ StarBASIC::Error( SbERR_NO_DEVICE );
+ }
+#endif
+
+#endif
+ // #ifndef UNX
+#endif
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+
+// Implementation of StepRENAME with UCB
+void implStepRenameUCB( const String& aSource, const String& aDest )
+{
+ com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ String aSourceFullPath = getFullPath( aSource );
+ if( !xSFI->exists( aSourceFullPath ) )
+ {
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ return;
+ }
+
+ String aDestFullPath = getFullPath( aDest );
+ if( xSFI->exists( aDestFullPath ) )
+ StarBASIC::Error( SbERR_FILE_EXISTS );
+ else
+ xSFI->move( aSourceFullPath, aDestFullPath );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ }
+ }
+}
+
+// Implementation of StepRENAME with OSL
+void implStepRenameOSL( const String& aSource, const String& aDest )
+{
+ FileBase::RC nRet = File::move( getFullPathUNC( aSource ), getFullPathUNC( aDest ) );
+ if( nRet != FileBase::E_None )
+ {
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+ }
+}
+
+RTLFUNC(FileCopy) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutEmpty();
+ if (rPar.Count() == 3)
+ {
+ String aSource = rPar.Get(1)->GetString();
+ String aDest = rPar.Get(2)->GetString();
+ // <-- UCB
+ if( hasUno() )
+ {
+ com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ xSFI->copy( getFullPath( aSource ), getFullPath( aDest ) );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+#ifdef _OLD_FILE_IMPL
+ DirEntry aSourceDirEntry(aSource);
+ if (aSourceDirEntry.Exists())
+ {
+ if (aSourceDirEntry.CopyTo(DirEntry(aDest),FSYS_ACTION_COPYFILE) != FSYS_ERR_OK)
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+ }
+ else
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+#else
+ FileBase::RC nRet = File::copy( getFullPathUNC( aSource ), getFullPathUNC( aDest ) );
+ if( nRet != FileBase::E_None )
+ {
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+ }
+#endif
+ }
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(Kill) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutEmpty();
+ if (rPar.Count() == 2)
+ {
+ String aFileSpec = rPar.Get(1)->GetString();
+
+ // <-- UCB
+ if( hasUno() )
+ {
+ com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ String aFullPath = getFullPath( aFileSpec );
+ if( !xSFI->exists( aFullPath ) || xSFI->isFolder( aFullPath ) )
+ {
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ return;
+ }
+ try
+ {
+ xSFI->kill( aFullPath );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+#ifdef _OLD_FILE_IMPL
+ if(DirEntry(aFileSpec).Kill() != FSYS_ERR_OK)
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+#else
+ File::remove( getFullPathUNC( aFileSpec ) );
+#endif
+ }
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(MkDir) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutEmpty();
+ if (rPar.Count() == 2)
+ {
+ String aPath = rPar.Get(1)->GetString();
+
+ // <-- UCB
+ if( hasUno() )
+ {
+ com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ xSFI->createFolder( getFullPath( aPath ) );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+#ifdef _OLD_FILE_IMPL
+ if (!DirEntry(aPath).MakeDir())
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+#else
+ Directory::create( getFullPathUNC( aPath ) );
+#endif
+ }
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+
+#ifndef _OLD_FILE_IMPL
+
+// In OSL only empty directories can be deleted
+// so we have to delete all files recursively
+void implRemoveDirRecursive( const String& aDirPath )
+{
+ DirectoryItem aItem;
+ FileBase::RC nRet = DirectoryItem::get( aDirPath, aItem );
+ sal_Bool bExists = (nRet == FileBase::E_None);
+
+ FileStatus aFileStatus( FileStatusMask_Type );
+ nRet = aItem.getFileStatus( aFileStatus );
+ FileStatus::Type aType = aFileStatus.getFileType();
+ sal_Bool bFolder = isFolder( aType );
+
+ if( !bExists || !bFolder )
+ {
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+ return;
+ }
+
+ Directory aDir( aDirPath );
+ nRet = aDir.open();
+ if( nRet != FileBase::E_None )
+ {
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+ return;
+ }
+
+ for( ;; )
+ {
+ DirectoryItem aItem2;
+ nRet = aDir.getNextItem( aItem2 );
+ if( nRet != FileBase::E_None )
+ break;
+
+ // Handle flags
+ FileStatus aFileStatus2( FileStatusMask_Type | FileStatusMask_FileURL );
+ nRet = aItem2.getFileStatus( aFileStatus2 );
+ ::rtl::OUString aPath = aFileStatus2.getFileURL();
+
+ // Directory?
+ FileStatus::Type aType2 = aFileStatus2.getFileType();
+ sal_Bool bFolder2 = isFolder( aType2 );
+ if( bFolder2 )
+ {
+ implRemoveDirRecursive( aPath );
+ }
+ else
+ {
+ File::remove( aPath );
+ }
+ }
+ nRet = aDir.close();
+
+ nRet = Directory::remove( aDirPath );
+}
+#endif
+
+
+RTLFUNC(RmDir) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutEmpty();
+ if (rPar.Count() == 2)
+ {
+ String aPath = rPar.Get(1)->GetString();
+ // <-- UCB
+ if( hasUno() )
+ {
+ com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ if( !xSFI->isFolder( aPath ) )
+ {
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+ return;
+ }
+ SbiInstance* pInst = pINST;
+ bool bCompatibility = ( pInst && pInst->IsCompatibility() );
+ if( bCompatibility )
+ {
+ Sequence< ::rtl::OUString > aContent = xSFI->getFolderContents( aPath, true );
+ sal_Int32 nCount = aContent.getLength();
+ if( nCount > 0 )
+ {
+ StarBASIC::Error( SbERR_ACCESS_ERROR );
+ return;
+ }
+ }
+
+ xSFI->kill( getFullPath( aPath ) );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+#ifdef _OLD_FILE_IMPL
+ DirEntry aDirEntry(aPath);
+ if (aDirEntry.Kill() != FSYS_ERR_OK)
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+#else
+ implRemoveDirRecursive( getFullPathUNC( aPath ) );
+#endif
+ }
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(SendKeys) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutEmpty();
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+}
+
+RTLFUNC(Exp)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double aDouble = rPar.Get( 1 )->GetDouble();
+ aDouble = exp( aDouble );
+ checkArithmeticOverflow( aDouble );
+ rPar.Get( 0 )->PutDouble( aDouble );
+ }
+}
+
+RTLFUNC(FileLen)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ String aStr( pArg->GetString() );
+ INT32 nLen = 0;
+ // <-- UCB
+ if( hasUno() )
+ {
+ com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ nLen = xSFI->getSize( getFullPath( aStr ) );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+#ifdef _OLD_FILE_IMPL
+ FileStat aStat = DirEntry( aStr );
+ nLen = aStat.GetSize();
+#else
+ DirectoryItem aItem;
+ FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aStr ), aItem );
+ FileStatus aFileStatus( FileStatusMask_FileSize );
+ nRet = aItem.getFileStatus( aFileStatus );
+ nLen = (INT32)aFileStatus.getFileSize();
+#endif
+ }
+ rPar.Get(0)->PutLong( (long)nLen );
+ }
+}
+
+
+RTLFUNC(Hex)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ char aBuffer[16];
+ SbxVariableRef pArg = rPar.Get( 1 );
+ if ( pArg->IsInteger() )
+ snprintf( aBuffer, sizeof(aBuffer), "%X", pArg->GetInteger() );
+ else
+ snprintf( aBuffer, sizeof(aBuffer), "%lX", static_cast<long unsigned int>(pArg->GetLong()) );
+ rPar.Get(0)->PutString( String::CreateFromAscii( aBuffer ) );
+ }
+}
+
+// InStr( [start],string,string,[compare] )
+
+RTLFUNC(InStr)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+ if ( nArgCount < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ USHORT nStartPos = 1;
+
+ USHORT nFirstStringPos = 1;
+ if ( nArgCount >= 3 )
+ {
+ INT32 lStartPos = rPar.Get(1)->GetLong();
+ if( lStartPos <= 0 || lStartPos > 0xffff )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ lStartPos = 1;
+ }
+ nStartPos = (USHORT)lStartPos;
+ nFirstStringPos++;
+ }
+
+ SbiInstance* pInst = pINST;
+ int bTextMode;
+ bool bCompatibility = ( pInst && pInst->IsCompatibility() );
+ if( bCompatibility )
+ {
+ SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
+ bTextMode = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : FALSE;
+ }
+ else
+ {
+ bTextMode = 1;;
+ }
+ if ( nArgCount == 4 )
+ bTextMode = rPar.Get(4)->GetInteger();
+
+ USHORT nPos;
+ const String& rToken = rPar.Get(nFirstStringPos+1)->GetString();
+
+ // #97545 Always find empty string
+ if( !rToken.Len() )
+ {
+ nPos = nStartPos;
+ }
+ else
+ {
+ if( !bTextMode )
+ {
+ const String& rStr1 = rPar.Get(nFirstStringPos)->GetString();
+
+ nPos = rStr1.Search( rToken, nStartPos-1 );
+ if ( nPos == STRING_NOTFOUND )
+ nPos = 0;
+ else
+ nPos++;
+ }
+ else
+ {
+ String aStr1 = rPar.Get(nFirstStringPos)->GetString();
+ String aToken = rToken;
+
+ aStr1.ToUpperAscii();
+ aToken.ToUpperAscii();
+
+ nPos = aStr1.Search( aToken, nStartPos-1 );
+ if ( nPos == STRING_NOTFOUND )
+ nPos = 0;
+ else
+ nPos++;
+ }
+ }
+ rPar.Get(0)->PutLong( nPos );
+ }
+}
+
+
+// InstrRev(string1, string2[, start[, compare]])
+
+RTLFUNC(InStrRev)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+ if ( nArgCount < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr1 = rPar.Get(1)->GetString();
+ String aToken = rPar.Get(2)->GetString();
+
+ INT32 lStartPos = -1;
+ if ( nArgCount >= 3 )
+ {
+ lStartPos = rPar.Get(3)->GetLong();
+ if( (lStartPos <= 0 && lStartPos != -1) || lStartPos > 0xffff )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ lStartPos = -1;
+ }
+ }
+
+ SbiInstance* pInst = pINST;
+ int bTextMode;
+ bool bCompatibility = ( pInst && pInst->IsCompatibility() );
+ if( bCompatibility )
+ {
+ SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
+ bTextMode = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : FALSE;
+ }
+ else
+ {
+ bTextMode = 1;;
+ }
+ if ( nArgCount == 4 )
+ bTextMode = rPar.Get(4)->GetInteger();
+
+ USHORT nStrLen = aStr1.Len();
+ USHORT nStartPos = lStartPos == -1 ? nStrLen : (USHORT)lStartPos;
+
+ USHORT nPos = 0;
+ if( nStartPos <= nStrLen )
+ {
+ USHORT nTokenLen = aToken.Len();
+ if( !nTokenLen )
+ {
+ // Always find empty string
+ nPos = nStartPos;
+ }
+ else if( nStrLen > 0 )
+ {
+ if( !bTextMode )
+ {
+ ::rtl::OUString aOUStr1 ( aStr1 );
+ ::rtl::OUString aOUToken( aToken );
+ sal_Int32 nRet = aOUStr1.lastIndexOf( aOUToken, nStartPos );
+ if( nRet == -1 )
+ nPos = 0;
+ else
+ nPos = (USHORT)nRet + 1;
+ }
+ else
+ {
+ aStr1.ToUpperAscii();
+ aToken.ToUpperAscii();
+
+ ::rtl::OUString aOUStr1 ( aStr1 );
+ ::rtl::OUString aOUToken( aToken );
+ sal_Int32 nRet = aOUStr1.lastIndexOf( aOUToken, nStartPos );
+
+ if( nRet == -1 )
+ nPos = 0;
+ else
+ nPos = (USHORT)nRet + 1;
+ }
+ }
+ }
+ rPar.Get(0)->PutLong( nPos );
+ }
+}
+
+
+/*
+ Int( 2.8 ) = 2.0
+ Int( -2.8 ) = -3.0
+ Fix( 2.8 ) = 2.0
+ Fix( -2.8 ) = -2.0 <- !!
+*/
+
+RTLFUNC(Int)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ double aDouble= pArg->GetDouble();
+ /*
+ floor( 2.8 ) = 2.0
+ floor( -2.8 ) = -3.0
+ */
+ aDouble = floor( aDouble );
+ rPar.Get(0)->PutDouble( aDouble );
+ }
+}
+
+
+
+RTLFUNC(Fix)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ double aDouble = pArg->GetDouble();
+ if ( aDouble >= 0.0 )
+ aDouble = floor( aDouble );
+ else
+ aDouble = ceil( aDouble );
+ rPar.Get(0)->PutDouble( aDouble );
+ }
+}
+
+
+RTLFUNC(LCase)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ CharClass& rCharClass = GetCharClass();
+ String aStr( rPar.Get(1)->GetString() );
+ rCharClass.toLower( aStr );
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+RTLFUNC(Left)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 3 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr( rPar.Get(1)->GetString() );
+ INT32 lResultLen = rPar.Get(2)->GetLong();
+ if( lResultLen > 0xffff )
+ {
+ lResultLen = 0xffff;
+ }
+ else if( lResultLen < 0 )
+ {
+ lResultLen = 0;
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ }
+ aStr.Erase( (USHORT)lResultLen );
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+RTLFUNC(Log)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double aArg = rPar.Get(1)->GetDouble();
+ if ( aArg > 0 )
+ {
+ double d = log( aArg );
+ checkArithmeticOverflow( d );
+ rPar.Get( 0 )->PutDouble( d );
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ }
+}
+
+RTLFUNC(LTrim)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr( rPar.Get(1)->GetString() );
+ aStr.EraseLeadingChars();
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+
+// Mid( String, nStart, nLength )
+
+RTLFUNC(Mid)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+ if ( nArgCount < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ // #23178: Funktionalitaet von Mid$ als Anweisung nachbilden, indem
+ // als weiterer (4.) Parameter ein Ersetzungsstring aufgenommen wird.
+ // Anders als im Original kann in dieser Variante der 3. Parameter
+ // nLength nicht weggelassen werden. Ist ueber bWrite schon vorgesehen.
+ if( nArgCount == 4 )
+ bWrite = TRUE;
+
+ String aArgStr = rPar.Get(1)->GetString();
+ USHORT nStartPos = (USHORT)(rPar.Get(2)->GetLong() );
+ if ( nStartPos == 0 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ nStartPos--;
+ USHORT nLen = 0xffff;
+ bool bWriteNoLenParam = false;
+ if ( nArgCount == 3 || bWrite )
+ {
+ INT32 n = rPar.Get(3)->GetLong();
+ if( bWrite && n == -1 )
+ bWriteNoLenParam = true;
+ nLen = (USHORT)n;
+ }
+ String aResultStr;
+ if ( bWrite )
+ {
+ SbiInstance* pInst = pINST;
+ bool bCompatibility = ( pInst && pInst->IsCompatibility() );
+ if( bCompatibility )
+ {
+ USHORT nArgLen = aArgStr.Len();
+ if( nStartPos + 1 > nArgLen )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ String aReplaceStr = rPar.Get(4)->GetString();
+ USHORT nReplaceStrLen = aReplaceStr.Len();
+ USHORT nReplaceLen;
+ if( bWriteNoLenParam )
+ {
+ nReplaceLen = nReplaceStrLen;
+ }
+ else
+ {
+ nReplaceLen = nLen;
+ if( nReplaceLen > nReplaceStrLen )
+ nReplaceLen = nReplaceStrLen;
+ }
+
+ USHORT nReplaceEndPos = nStartPos + nReplaceLen;
+ if( nReplaceEndPos > nArgLen )
+ nReplaceLen -= (nReplaceEndPos - nArgLen);
+
+ aResultStr = aArgStr;
+ USHORT nErase = nReplaceLen;
+ aResultStr.Erase( nStartPos, nErase );
+ aResultStr.Insert( aReplaceStr, 0, nReplaceLen, nStartPos );
+ }
+ else
+ {
+ aResultStr = aArgStr;
+ aResultStr.Erase( nStartPos, nLen );
+ aResultStr.Insert(rPar.Get(4)->GetString(),0,nLen,nStartPos);
+ }
+
+ rPar.Get(1)->PutString( aResultStr );
+ }
+ else
+ {
+ aResultStr = aArgStr.Copy( nStartPos, nLen );
+ rPar.Get(0)->PutString( aResultStr );
+ }
+ }
+ }
+}
+
+RTLFUNC(Oct)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ char aBuffer[16];
+ SbxVariableRef pArg = rPar.Get( 1 );
+ if ( pArg->IsInteger() )
+ snprintf( aBuffer, sizeof(aBuffer), "%o", pArg->GetInteger() );
+ else
+ snprintf( aBuffer, sizeof(aBuffer), "%lo", static_cast<long unsigned int>(pArg->GetLong()) );
+ rPar.Get(0)->PutString( String::CreateFromAscii( aBuffer ) );
+ }
+}
+
+// Replace(expression, find, replace[, start[, count[, compare]]])
+
+RTLFUNC(Replace)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+ if ( nArgCount < 3 || nArgCount > 6 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aExpStr = rPar.Get(1)->GetString();
+ String aFindStr = rPar.Get(2)->GetString();
+ String aReplaceStr = rPar.Get(3)->GetString();
+
+ INT32 lStartPos = 1;
+ if ( nArgCount >= 4 )
+ {
+ if( rPar.Get(4)->GetType() != SbxEMPTY )
+ lStartPos = rPar.Get(4)->GetLong();
+ if( lStartPos < 1 || lStartPos > 0xffff )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ lStartPos = 1;
+ }
+ }
+
+ INT32 lCount = -1;
+ if( nArgCount >=5 )
+ {
+ if( rPar.Get(5)->GetType() != SbxEMPTY )
+ lCount = rPar.Get(5)->GetLong();
+ if( lCount < -1 || lCount > 0xffff )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ lCount = -1;
+ }
+ }
+
+ SbiInstance* pInst = pINST;
+ int bTextMode;
+ bool bCompatibility = ( pInst && pInst->IsCompatibility() );
+ if( bCompatibility )
+ {
+ SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
+ bTextMode = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : FALSE;
+ }
+ else
+ {
+ bTextMode = 1;
+ }
+ if ( nArgCount == 6 )
+ bTextMode = rPar.Get(6)->GetInteger();
+
+ USHORT nExpStrLen = aExpStr.Len();
+ USHORT nFindStrLen = aFindStr.Len();
+ USHORT nReplaceStrLen = aReplaceStr.Len();
+
+ if( lStartPos <= nExpStrLen )
+ {
+ USHORT nPos = static_cast<USHORT>( lStartPos - 1 );
+ USHORT nCounts = 0;
+ while( lCount == -1 || lCount > nCounts )
+ {
+ String aSrcStr( aExpStr );
+ if( bTextMode )
+ {
+ aSrcStr.ToUpperAscii();
+ aFindStr.ToUpperAscii();
+ }
+ nPos = aSrcStr.Search( aFindStr, nPos );
+ if( nPos != STRING_NOTFOUND )
+ {
+ aExpStr.Replace( nPos, nFindStrLen, aReplaceStr );
+ nPos = nPos - nFindStrLen + nReplaceStrLen + 1;
+ nCounts++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ rPar.Get(0)->PutString( aExpStr.Copy( static_cast<USHORT>(lStartPos - 1) ) );
+ }
+}
+
+RTLFUNC(Right)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 3 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ const String& rStr = rPar.Get(1)->GetString();
+ INT32 lResultLen = rPar.Get(2)->GetLong();
+ if( lResultLen > 0xffff )
+ {
+ lResultLen = 0xffff;
+ }
+ else if( lResultLen < 0 )
+ {
+ lResultLen = 0;
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ }
+ USHORT nResultLen = (USHORT)lResultLen;
+ USHORT nStrLen = rStr.Len();
+ if ( nResultLen > nStrLen )
+ nResultLen = nStrLen;
+ String aResultStr = rStr.Copy( nStrLen-nResultLen );
+ rPar.Get(0)->PutString( aResultStr );
+ }
+}
+
+RTLFUNC(RTL)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get( 0 )->PutObject( pBasic->getRTL() );
+}
+
+RTLFUNC(RTrim)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr( rPar.Get(1)->GetString() );
+ aStr.EraseTrailingChars();
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+RTLFUNC(Sgn)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double aDouble = rPar.Get(1)->GetDouble();
+ INT16 nResult = 0;
+ if ( aDouble > 0 )
+ nResult = 1;
+ else if ( aDouble < 0 )
+ nResult = -1;
+ rPar.Get(0)->PutInteger( nResult );
+ }
+}
+
+RTLFUNC(Space)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr;
+ aStr.Fill( (USHORT)(rPar.Get(1)->GetLong() ));
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+RTLFUNC(Spc)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr;
+ aStr.Fill( (USHORT)(rPar.Get(1)->GetLong() ));
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+RTLFUNC(Sqr)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double aDouble = rPar.Get(1)->GetDouble();
+ if ( aDouble >= 0 )
+ rPar.Get(0)->PutDouble( sqrt( aDouble ));
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ }
+}
+
+RTLFUNC(Str)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr;
+ SbxVariableRef pArg = rPar.Get( 1 );
+ pArg->Format( aStr );
+
+ // Numbers start with a space
+ if( pArg->IsNumericRTL() )
+ {
+ // Kommas durch Punkte ersetzen, damit es symmetrisch zu Val ist!
+ aStr.SearchAndReplace( ',', '.' );
+
+ SbiInstance* pInst = pINST;
+ bool bCompatibility = ( pInst && pInst->IsCompatibility() );
+ if( bCompatibility )
+ {
+ xub_StrLen nLen = aStr.Len();
+
+ const sal_Unicode* pBuf = aStr.GetBuffer();
+
+ bool bNeg = ( pBuf[0] == '-' );
+ USHORT iZeroSearch = 0;
+ if( bNeg )
+ iZeroSearch++;
+
+ USHORT iNext = iZeroSearch + 1;
+ if( pBuf[iZeroSearch] == '0' && nLen > iNext && pBuf[iNext] == '.' )
+ {
+ aStr.Erase( iZeroSearch, 1 );
+ pBuf = aStr.GetBuffer();
+ }
+ if( !bNeg )
+ aStr.Insert( ' ', 0 );
+ }
+ else
+ aStr.Insert( ' ', 0 );
+ }
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+RTLFUNC(StrComp)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ rPar.Get(0)->PutEmpty();
+ return;
+ }
+ const String& rStr1 = rPar.Get(1)->GetString();
+ const String& rStr2 = rPar.Get(2)->GetString();
+
+ SbiInstance* pInst = pINST;
+ INT16 nTextCompare;
+ bool bCompatibility = ( pInst && pInst->IsCompatibility() );
+ if( bCompatibility )
+ {
+ SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
+ nTextCompare = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : FALSE;
+ }
+ else
+ {
+ nTextCompare = TRUE;
+ }
+ if ( rPar.Count() == 4 )
+ nTextCompare = rPar.Get(3)->GetInteger();
+
+ if( !bCompatibility )
+ nTextCompare = !nTextCompare;
+
+ StringCompare aResult;
+ sal_Int32 nRetValue = 0;
+ if( nTextCompare )
+ {
+ ::utl::TransliterationWrapper* pTransliterationWrapper = GetSbData()->pTransliterationWrapper;
+ if( !pTransliterationWrapper )
+ {
+ com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
+ pTransliterationWrapper = GetSbData()->pTransliterationWrapper =
+ new ::utl::TransliterationWrapper( xSMgr,
+ ::com::sun::star::i18n::TransliterationModules_IGNORE_CASE |
+ ::com::sun::star::i18n::TransliterationModules_IGNORE_KANA |
+ ::com::sun::star::i18n::TransliterationModules_IGNORE_WIDTH );
+ }
+
+ LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
+ pTransliterationWrapper->loadModuleIfNeeded( eLangType );
+ nRetValue = pTransliterationWrapper->compareString( rStr1, rStr2 );
+ }
+ else
+ {
+ aResult = rStr1.CompareTo( rStr2 );
+ if ( aResult == COMPARE_LESS )
+ nRetValue = -1;
+ else if ( aResult == COMPARE_GREATER )
+ nRetValue = 1;
+ }
+
+ rPar.Get(0)->PutInteger( sal::static_int_cast< INT16 >( nRetValue ) );
+}
+
+RTLFUNC(String)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr;
+ sal_Unicode aFiller;
+ INT32 lCount = rPar.Get(1)->GetLong();
+ if( lCount < 0 || lCount > 0xffff )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ USHORT nCount = (USHORT)lCount;
+ if( rPar.Get(2)->GetType() == SbxINTEGER )
+ aFiller = (sal_Unicode)rPar.Get(2)->GetInteger();
+ else
+ {
+ const String& rStr = rPar.Get(2)->GetString();
+ aFiller = rStr.GetBuffer()[0];
+ }
+ aStr.Fill( nCount, aFiller );
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+RTLFUNC(Tan)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ rPar.Get( 0 )->PutDouble( tan( pArg->GetDouble() ) );
+ }
+}
+
+RTLFUNC(UCase)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ CharClass& rCharClass = GetCharClass();
+ String aStr( rPar.Get(1)->GetString() );
+ rCharClass.toUpper( aStr );
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+
+RTLFUNC(Val)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double nResult = 0.0;
+ char* pEndPtr;
+
+ String aStr( rPar.Get(1)->GetString() );
+// lt. Mikkysoft bei Kommas abbrechen!
+// for( USHORT n=0; n < aStr.Len(); n++ )
+// if( aStr[n] == ',' ) aStr[n] = '.';
+
+ FilterWhiteSpace( aStr );
+ if ( aStr.GetBuffer()[0] == '&' && aStr.Len() > 1 )
+ {
+ int nRadix = 10;
+ char aChar = (char)aStr.GetBuffer()[1];
+ if ( aChar == 'h' || aChar == 'H' )
+ nRadix = 16;
+ else if ( aChar == 'o' || aChar == 'O' )
+ nRadix = 8;
+ if ( nRadix != 10 )
+ {
+ ByteString aByteStr( aStr, gsl_getSystemTextEncoding() );
+ INT16 nlResult = (INT16)strtol( aByteStr.GetBuffer()+2, &pEndPtr, nRadix);
+ nResult = (double)nlResult;
+ }
+ }
+ else
+ {
+ // #57844 Lokalisierte Funktion benutzen
+ nResult = ::rtl::math::stringToDouble( aStr, '.', ',', NULL, NULL );
+ checkArithmeticOverflow( nResult );
+ // ATL: nResult = strtod( aStr.GetStr(), &pEndPtr );
+ }
+
+ rPar.Get(0)->PutDouble( nResult );
+ }
+}
+
+
+// Helper functions for date conversion
+INT16 implGetDateDay( double aDate )
+{
+ aDate -= 2.0; // normieren: 1.1.1900 => 0.0
+ Date aRefDate( 1, 1, 1900 );
+ if ( aDate >= 0.0 )
+ {
+ aDate = floor( aDate );
+ aRefDate += (ULONG)aDate;
+ }
+ else
+ {
+ aDate = ceil( aDate );
+ aRefDate -= (ULONG)(-1.0 * aDate);
+ }
+
+ INT16 nRet = (INT16)( aRefDate.GetDay() );
+ return nRet;
+}
+
+INT16 implGetDateMonth( double aDate )
+{
+ Date aRefDate( 1,1,1900 );
+ long nDays = (long)aDate;
+ nDays -= 2; // normieren: 1.1.1900 => 0.0
+ aRefDate += nDays;
+ INT16 nRet = (INT16)( aRefDate.GetMonth() );
+ return nRet;
+}
+
+INT16 implGetDateYear( double aDate )
+{
+ Date aRefDate( 1,1,1900 );
+ long nDays = (long) aDate;
+ nDays -= 2; // normieren: 1.1.1900 => 0.0
+ aRefDate += nDays;
+ INT16 nRet = (INT16)( aRefDate.GetYear() );
+ return nRet;
+}
+
+BOOL implDateSerial( INT16 nYear, INT16 nMonth, INT16 nDay, double& rdRet )
+{
+ if ( nYear < 30 && SbiRuntime::isVBAEnabled() )
+ nYear += 2000;
+ else if ( nYear < 100 )
+ nYear += 1900;
+ Date aCurDate( nDay, nMonth, nYear );
+ if ((nYear < 100 || nYear > 9999) )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return FALSE;
+ }
+ if ( !SbiRuntime::isVBAEnabled() )
+ {
+ if ( (nMonth < 1 || nMonth > 12 )||
+ (nDay < 1 || nDay > 31 ) )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return FALSE;
+ }
+ }
+ else
+ {
+ // grab the year & month
+ aCurDate = Date( 1, (( nMonth % 12 ) > 0 ) ? ( nMonth % 12 ) : 12 + ( nMonth % 12 ), nYear );
+
+ // adjust year based on month value
+ // e.g. 2000, 0, xx = 1999, 12, xx ( or December of the previous year )
+ // 2000, 13, xx = 2001, 1, xx ( or January of the following year )
+ if( ( nMonth < 1 ) || ( nMonth > 12 ) )
+ {
+ // inacurrate around leap year, don't use days to calculate,
+ // just modify the months directory
+ INT16 nYearAdj = ( nMonth /12 ); // default to positive months inputed
+ if ( nMonth <=0 )
+ nYearAdj = ( ( nMonth -12 ) / 12 );
+ aCurDate.SetYear( aCurDate.GetYear() + nYearAdj );
+ }
+
+ // adjust day value,
+ // e.g. 2000, 2, 0 = 2000, 1, 31 or the last day of the previous month
+ // 2000, 1, 32 = 2000, 2, 1 or the first day of the following month
+ if( ( nDay < 1 ) || ( nDay > aCurDate.GetDaysInMonth() ) )
+ aCurDate += nDay - 1;
+ else
+ aCurDate.SetDay( nDay );
+ }
+
+ long nDiffDays = GetDayDiff( aCurDate );
+ rdRet = (double)nDiffDays;
+ return TRUE;
+}
+
+// Function to convert date to ISO 8601 date format
+RTLFUNC(CDateToIso)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() == 2 )
+ {
+ double aDate = rPar.Get(1)->GetDate();
+
+ char Buffer[9];
+ snprintf( Buffer, sizeof( Buffer ), "%04d%02d%02d",
+ implGetDateYear( aDate ),
+ implGetDateMonth( aDate ),
+ implGetDateDay( aDate ) );
+ String aRetStr = String::CreateFromAscii( Buffer );
+ rPar.Get(0)->PutString( aRetStr );
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+// Function to convert date from ISO 8601 date format
+RTLFUNC(CDateFromIso)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() == 2 )
+ {
+ String aStr = rPar.Get(1)->GetString();
+ INT16 iMonthStart = aStr.Len() - 4;
+ String aYearStr = aStr.Copy( 0, iMonthStart );
+ String aMonthStr = aStr.Copy( iMonthStart, 2 );
+ String aDayStr = aStr.Copy( iMonthStart+2, 2 );
+
+ double dDate;
+ if( implDateSerial( (INT16)aYearStr.ToInt32(),
+ (INT16)aMonthStr.ToInt32(), (INT16)aDayStr.ToInt32(), dDate ) )
+ {
+ rPar.Get(0)->PutDate( dDate );
+ }
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(DateSerial)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 4 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nYear = rPar.Get(1)->GetInteger();
+ INT16 nMonth = rPar.Get(2)->GetInteger();
+ INT16 nDay = rPar.Get(3)->GetInteger();
+
+ double dDate;
+ if( implDateSerial( nYear, nMonth, nDay, dDate ) )
+ rPar.Get(0)->PutDate( dDate );
+}
+
+RTLFUNC(TimeSerial)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 4 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nHour = rPar.Get(1)->GetInteger();
+ if ( nHour == 24 )
+ nHour = 0; // Wegen UNO DateTimes, die bis 24 Uhr gehen
+ INT16 nMinute = rPar.Get(2)->GetInteger();
+ INT16 nSecond = rPar.Get(3)->GetInteger();
+ if ((nHour < 0 || nHour > 23) ||
+ (nMinute < 0 || nMinute > 59 ) ||
+ (nSecond < 0 || nSecond > 59 ))
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ INT32 nSeconds = nHour;
+ nSeconds *= 3600;
+ nSeconds += nMinute * 60;
+ nSeconds += nSecond;
+ double nDays = ((double)nSeconds) / (double)(86400.0);
+ rPar.Get(0)->PutDate( nDays ); // JSM
+}
+
+RTLFUNC(DateValue)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
+ SvNumberFormatter* pFormatter = NULL;
+ if( pINST )
+ pFormatter = pINST->GetNumberFormatter();
+ else
+ {
+ sal_uInt32 n; // Dummy
+ SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n );
+ }
+
+ sal_uInt32 nIndex;
+ double fResult;
+ String aStr( rPar.Get(1)->GetString() );
+ BOOL bSuccess = pFormatter->IsNumberFormat( aStr, nIndex, fResult );
+ short nType = pFormatter->GetType( nIndex );
+
+ // DateValue("February 12, 1969") raises error if the system locale is not en_US
+ // by using SbiInstance::GetNumberFormatter.
+ // It seems that both locale number formatter and English number formatter
+ // are supported in Visual Basic.
+ LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
+ if( !bSuccess && ( eLangType != LANGUAGE_ENGLISH_US ) )
+ {
+ // Create a new SvNumberFormatter by using LANGUAGE_ENGLISH to get the date value;
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ xFactory = comphelper::getProcessServiceFactory();
+ SvNumberFormatter aFormatter( xFactory, LANGUAGE_ENGLISH_US );
+ bSuccess = aFormatter.IsNumberFormat( aStr, nIndex, fResult );
+ nType = aFormatter.GetType( nIndex );
+ }
+
+ if(bSuccess && (nType==NUMBERFORMAT_DATE || nType==NUMBERFORMAT_DATETIME))
+ {
+ if ( nType == NUMBERFORMAT_DATETIME )
+ {
+ // Zeit abschneiden
+ if ( fResult > 0.0 )
+ fResult = floor( fResult );
+ else
+ fResult = ceil( fResult );
+ }
+ // fResult += 2.0; // Anpassung StarCalcFormatter
+ rPar.Get(0)->PutDate( fResult ); // JSM
+ }
+ else
+ StarBASIC::Error( SbERR_CONVERSION );
+
+ // #39629 pFormatter kann selbst angefordert sein
+ if( !pINST )
+ delete pFormatter;
+ }
+}
+
+RTLFUNC(TimeValue)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
+ SvNumberFormatter* pFormatter = NULL;
+ if( pINST )
+ pFormatter = pINST->GetNumberFormatter();
+ else
+ {
+ sal_uInt32 n; // Dummy
+ SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n );
+ }
+
+ sal_uInt32 nIndex;
+ double fResult;
+ BOOL bSuccess = pFormatter->IsNumberFormat( rPar.Get(1)->GetString(),
+ nIndex, fResult );
+ short nType = pFormatter->GetType(nIndex);
+ if(bSuccess && (nType==NUMBERFORMAT_TIME||nType==NUMBERFORMAT_DATETIME))
+ {
+ if ( nType == NUMBERFORMAT_DATETIME )
+ // Tage abschneiden
+ fResult = fmod( fResult, 1 );
+ rPar.Get(0)->PutDate( fResult ); // JSM
+ }
+ else
+ StarBASIC::Error( SbERR_CONVERSION );
+
+ // #39629 pFormatter kann selbst angefordert sein
+ if( !pINST )
+ delete pFormatter;
+ }
+}
+
+RTLFUNC(Day)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ double aDate = pArg->GetDate();
+
+ INT16 nDay = implGetDateDay( aDate );
+ rPar.Get(0)->PutInteger( nDay );
+ }
+}
+
+RTLFUNC(Year)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ INT16 nYear = implGetDateYear( rPar.Get(1)->GetDate() );
+ rPar.Get(0)->PutInteger( nYear );
+ }
+}
+
+INT16 implGetHour( double dDate )
+{
+ if( dDate < 0.0 )
+ dDate *= -1.0;
+ double nFrac = dDate - floor( dDate );
+ nFrac *= 86400.0;
+ INT32 nSeconds = (INT32)(nFrac + 0.5);
+ INT16 nHour = (INT16)(nSeconds / 3600);
+ return nHour;
+}
+
+RTLFUNC(Hour)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double nArg = rPar.Get(1)->GetDate();
+ INT16 nHour = implGetHour( nArg );
+ rPar.Get(0)->PutInteger( nHour );
+ }
+}
+
+INT16 implGetMinute( double dDate )
+{
+ if( dDate < 0.0 )
+ dDate *= -1.0;
+ double nFrac = dDate - floor( dDate );
+ nFrac *= 86400.0;
+ INT32 nSeconds = (INT32)(nFrac + 0.5);
+ INT16 nTemp = (INT16)(nSeconds % 3600);
+ INT16 nMin = nTemp / 60;
+ return nMin;
+}
+
+RTLFUNC(Minute)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double nArg = rPar.Get(1)->GetDate();
+ INT16 nMin = implGetMinute( nArg );
+ rPar.Get(0)->PutInteger( nMin );
+ }
+}
+
+RTLFUNC(Month)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ INT16 nMonth = implGetDateMonth( rPar.Get(1)->GetDate() );
+ rPar.Get(0)->PutInteger( nMonth );
+ }
+}
+
+INT16 implGetSecond( double dDate )
+{
+ if( dDate < 0.0 )
+ dDate *= -1.0;
+ double nFrac = dDate - floor( dDate );
+ nFrac *= 86400.0;
+ INT32 nSeconds = (INT32)(nFrac + 0.5);
+ INT16 nTemp = (INT16)(nSeconds / 3600);
+ nSeconds -= nTemp * 3600;
+ nTemp = (INT16)(nSeconds / 60);
+ nSeconds -= nTemp * 60;
+
+ INT16 nRet = (INT16)nSeconds;
+ return nRet;
+}
+
+RTLFUNC(Second)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double nArg = rPar.Get(1)->GetDate();
+ INT16 nSecond = implGetSecond( nArg );
+ rPar.Get(0)->PutInteger( nSecond );
+ }
+}
+
+double Now_Impl()
+{
+ Date aDate;
+ Time aTime;
+ double aSerial = (double)GetDayDiff( aDate );
+ long nSeconds = aTime.GetHour();
+ nSeconds *= 3600;
+ nSeconds += aTime.GetMin() * 60;
+ nSeconds += aTime.GetSec();
+ double nDays = ((double)nSeconds) / (double)(24.0*3600.0);
+ aSerial += nDays;
+ return aSerial;
+}
+
+// Date Now(void)
+
+RTLFUNC(Now)
+{
+ (void)pBasic;
+ (void)bWrite;
+ rPar.Get(0)->PutDate( Now_Impl() );
+}
+
+// Date Time(void)
+
+RTLFUNC(Time)
+{
+ (void)pBasic;
+
+ if ( !bWrite )
+ {
+ Time aTime;
+ SbxVariable* pMeth = rPar.Get( 0 );
+ String aRes;
+ if( pMeth->IsFixed() )
+ {
+ // Time$: hh:mm:ss
+ char buf[ 20 ];
+ snprintf( buf, sizeof(buf), "%02d:%02d:%02d",
+ aTime.GetHour(), aTime.GetMin(), aTime.GetSec() );
+ aRes = String::CreateFromAscii( buf );
+ }
+ else
+ {
+ // Time: system dependent
+ long nSeconds=aTime.GetHour();
+ nSeconds *= 3600;
+ nSeconds += aTime.GetMin() * 60;
+ nSeconds += aTime.GetSec();
+ double nDays = (double)nSeconds * ( 1.0 / (24.0*3600.0) );
+ Color* pCol;
+
+ // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
+ SvNumberFormatter* pFormatter = NULL;
+ sal_uInt32 nIndex;
+ if( pINST )
+ {
+ pFormatter = pINST->GetNumberFormatter();
+ nIndex = pINST->GetStdTimeIdx();
+ }
+ else
+ {
+ sal_uInt32 n; // Dummy
+ SbiInstance::PrepareNumberFormatter( pFormatter, n, nIndex, n );
+ }
+
+ pFormatter->GetOutputString( nDays, nIndex, aRes, &pCol );
+
+ // #39629 pFormatter kann selbst angefordert sein
+ if( !pINST )
+ delete pFormatter;
+ }
+ pMeth->PutString( aRes );
+ }
+ else
+ {
+ StarBASIC::Error( SbERR_NOT_IMPLEMENTED );
+ }
+}
+
+RTLFUNC(Timer)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ Time aTime;
+ long nSeconds = aTime.GetHour();
+ nSeconds *= 3600;
+ nSeconds += aTime.GetMin() * 60;
+ nSeconds += aTime.GetSec();
+ rPar.Get(0)->PutDate( (double)nSeconds );
+}
+
+
+RTLFUNC(Date)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( !bWrite )
+ {
+ Date aToday;
+ double nDays = (double)GetDayDiff( aToday );
+ SbxVariable* pMeth = rPar.Get( 0 );
+ if( pMeth->IsString() )
+ {
+ String aRes;
+ Color* pCol;
+
+ // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
+ SvNumberFormatter* pFormatter = NULL;
+ sal_uInt32 nIndex;
+ if( pINST )
+ {
+ pFormatter = pINST->GetNumberFormatter();
+ nIndex = pINST->GetStdDateIdx();
+ }
+ else
+ {
+ sal_uInt32 n; // Dummy
+ SbiInstance::PrepareNumberFormatter( pFormatter, nIndex, n, n );
+ }
+
+ pFormatter->GetOutputString( nDays, nIndex, aRes, &pCol );
+ pMeth->PutString( aRes );
+
+ // #39629 pFormatter kann selbst angefordert sein
+ if( !pINST )
+ delete pFormatter;
+ }
+ else
+ pMeth->PutDate( nDays );
+ }
+ else
+ {
+ StarBASIC::Error( SbERR_NOT_IMPLEMENTED );
+ }
+}
+
+RTLFUNC(IsArray)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ rPar.Get(0)->PutBool((rPar.Get(1)->GetType() & SbxARRAY) ? TRUE : FALSE );
+}
+
+RTLFUNC(IsObject)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariable* pVar = rPar.Get(1);
+ SbxBase* pObj = (SbxBase*)pVar->GetObject();
+
+ // #100385: GetObject can result in an error, so reset it
+ SbxBase::ResetError();
+
+ SbUnoClass* pUnoClass;
+ BOOL bObject;
+ if( pObj && NULL != ( pUnoClass=PTR_CAST(SbUnoClass,pObj) ) )
+ {
+ bObject = pUnoClass->getUnoClass().is();
+ }
+ else
+ {
+ bObject = pVar->IsObject();
+ }
+ rPar.Get( 0 )->PutBool( bObject );
+ }
+}
+
+RTLFUNC(IsDate)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ // #46134 Nur String wird konvertiert, andere Typen ergeben FALSE
+ SbxVariableRef xArg = rPar.Get( 1 );
+ SbxDataType eType = xArg->GetType();
+ BOOL bDate = FALSE;
+
+ if( eType == SbxDATE )
+ {
+ bDate = TRUE;
+ }
+ else if( eType == SbxSTRING )
+ {
+ // Error loeschen
+ SbxError nPrevError = SbxBase::GetError();
+ SbxBase::ResetError();
+
+ // Konvertierung des Parameters nach SbxDATE erzwingen
+ xArg->SbxValue::GetDate();
+
+ // Bei Fehler ist es kein Date
+ bDate = !SbxBase::IsError();
+
+ // Error-Situation wiederherstellen
+ SbxBase::ResetError();
+ SbxBase::SetError( nPrevError );
+ }
+ rPar.Get( 0 )->PutBool( bDate );
+ }
+}
+
+RTLFUNC(IsEmpty)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ rPar.Get( 0 )->PutBool( rPar.Get(1)->IsEmpty() );
+}
+
+RTLFUNC(IsError)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() );
+}
+
+RTLFUNC(IsNull)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ // #51475 Wegen Uno-Objekten auch true liefern,
+ // wenn der pObj-Wert NULL ist
+ SbxVariableRef pArg = rPar.Get( 1 );
+ BOOL bNull = rPar.Get(1)->IsNull();
+ if( !bNull && pArg->GetType() == SbxOBJECT )
+ {
+ SbxBase* pObj = pArg->GetObject();
+ if( !pObj )
+ bNull = TRUE;
+ }
+ rPar.Get( 0 )->PutBool( bNull );
+ }
+}
+
+RTLFUNC(IsNumeric)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ rPar.Get( 0 )->PutBool( rPar.Get( 1 )->IsNumericRTL() );
+}
+
+// Das machen wir auf die billige Tour
+
+RTLFUNC(IsMissing)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ // #57915 Missing wird durch Error angezeigt
+ rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() );
+}
+
+// Dir( [Maske] [,Attrs] )
+// ToDo: Library-globaler Datenbereich fuer Dir-Objekt und Flags
+
+
+String getDirectoryPath( String aPathStr )
+{
+ String aRetStr;
+
+ DirectoryItem aItem;
+ FileBase::RC nRet = DirectoryItem::get( aPathStr, aItem );
+ if( nRet == FileBase::E_None )
+ {
+ FileStatus aFileStatus( FileStatusMask_Type );
+ nRet = aItem.getFileStatus( aFileStatus );
+ if( nRet == FileBase::E_None )
+ {
+ FileStatus::Type aType = aFileStatus.getFileType();
+ if( isFolder( aType ) )
+ {
+ aRetStr = aPathStr;
+ }
+ else if( aType == FileStatus::Link )
+ {
+ FileStatus aFileStatus2( FileStatusMask_LinkTargetURL );
+ nRet = aItem.getFileStatus( aFileStatus2 );
+ if( nRet == FileBase::E_None )
+ aRetStr = getDirectoryPath( aFileStatus2.getLinkTargetURL() );
+ }
+ }
+ }
+ return aRetStr;
+}
+
+// Function looks for wildcards, removes them and always returns the pure path
+String implSetupWildcard( const String& rFileParam, SbiRTLData* pRTLData )
+{
+ static String aAsterisk = String::CreateFromAscii( "*" );
+ static sal_Char cDelim1 = (sal_Char)'/';
+ static sal_Char cDelim2 = (sal_Char)'\\';
+ static sal_Char cWild1 = '*';
+ static sal_Char cWild2 = '?';
+
+ delete pRTLData->pWildCard;
+ pRTLData->pWildCard = NULL;
+ pRTLData->sFullNameToBeChecked = String();
+
+ String aFileParam = rFileParam;
+ xub_StrLen nLastWild = aFileParam.SearchBackward( cWild1 );
+ if( nLastWild == STRING_NOTFOUND )
+ nLastWild = aFileParam.SearchBackward( cWild2 );
+ sal_Bool bHasWildcards = ( nLastWild != STRING_NOTFOUND );
+
+
+ xub_StrLen nLastDelim = aFileParam.SearchBackward( cDelim1 );
+ if( nLastDelim == STRING_NOTFOUND )
+ nLastDelim = aFileParam.SearchBackward( cDelim2 );
+
+ if( bHasWildcards )
+ {
+ // Wildcards in path?
+ if( nLastDelim != STRING_NOTFOUND && nLastDelim > nLastWild )
+ return aFileParam;
+ }
+ else
+ {
+ String aPathStr = getFullPath( aFileParam );
+ if( nLastDelim != aFileParam.Len() - 1 )
+ pRTLData->sFullNameToBeChecked = aPathStr;
+ return aPathStr;
+ }
+
+ String aPureFileName;
+ if( nLastDelim == STRING_NOTFOUND )
+ {
+ aPureFileName = aFileParam;
+ aFileParam = String();
+ }
+ else
+ {
+ aPureFileName = aFileParam.Copy( nLastDelim + 1 );
+ aFileParam = aFileParam.Copy( 0, nLastDelim );
+ }
+
+ // Try again to get a valid URL/UNC-path with only the path
+ String aPathStr = getFullPath( aFileParam );
+ xub_StrLen nPureLen = aPureFileName.Len();
+
+ // Is there a pure file name left? Otherwise the path is
+ // invalid anyway because it was not accepted by OSL before
+ if( nPureLen && aPureFileName != aAsterisk )
+ {
+ pRTLData->pWildCard = new WildCard( aPureFileName );
+ }
+ return aPathStr;
+}
+
+inline sal_Bool implCheckWildcard( const String& rName, SbiRTLData* pRTLData )
+{
+ sal_Bool bMatch = sal_True;
+
+ if( pRTLData->pWildCard )
+ bMatch = pRTLData->pWildCard->Matches( rName );
+ return bMatch;
+}
+
+
+bool isRootDir( String aDirURLStr )
+{
+ INetURLObject aDirURLObj( aDirURLStr );
+ BOOL bRoot = FALSE;
+
+ // Check if it's a root directory
+ sal_Int32 nCount = aDirURLObj.getSegmentCount();
+
+ // No segment means Unix root directory "file:///"
+ if( nCount == 0 )
+ {
+ bRoot = TRUE;
+ }
+ // Exactly one segment needs further checking, because it
+ // can be Unix "file:///foo/" -> no root
+ // or Windows "file:///c:/" -> root
+ else if( nCount == 1 )
+ {
+ ::rtl::OUString aSeg1 = aDirURLObj.getName( 0, TRUE,
+ INetURLObject::DECODE_WITH_CHARSET );
+ if( aSeg1.getStr()[1] == (sal_Unicode)':' )
+ {
+ bRoot = TRUE;
+ }
+ }
+ // More than one segments can never be root
+ // so bRoot remains FALSE
+
+ return bRoot;
+}
+
+RTLFUNC(Dir)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ String aPath;
+
+ USHORT nParCount = rPar.Count();
+ if( nParCount > 3 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbiRTLData* pRTLData = pINST->GetRTLData();
+
+ // #34645: Kann auch von der URL-Zeile ueber 'macro: Dir' aufgerufen werden
+ // dann existiert kein pRTLData und die Methode muss verlassen werden
+ if( !pRTLData )
+ return;
+
+ // <-- UCB
+ if( hasUno() )
+ {
+ com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ if ( nParCount >= 2 )
+ {
+ String aFileParam = rPar.Get(1)->GetString();
+
+ String aFileURLStr = implSetupWildcard( aFileParam, pRTLData );
+ if( pRTLData->sFullNameToBeChecked.Len() > 0 )
+ {
+ sal_Bool bExists = sal_False;
+ try { bExists = xSFI->exists( aFileURLStr ); }
+ catch( Exception & ) {}
+
+ String aNameOnlyStr;
+ if( bExists )
+ {
+ INetURLObject aFileURL( aFileURLStr );
+ aNameOnlyStr = aFileURL.getName( INetURLObject::LAST_SEGMENT,
+ true, INetURLObject::DECODE_WITH_CHARSET );
+ }
+ rPar.Get(0)->PutString( aNameOnlyStr );
+ return;
+ }
+
+ try
+ {
+ String aDirURLStr;
+ sal_Bool bFolder = xSFI->isFolder( aFileURLStr );
+
+ if( bFolder )
+ {
+ aDirURLStr = aFileURLStr;
+ }
+ else
+ {
+ String aEmptyStr;
+ rPar.Get(0)->PutString( aEmptyStr );
+ }
+
+ USHORT nFlags = 0;
+ if ( nParCount > 2 )
+ pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger();
+ else
+ pRTLData->nDirFlags = 0;
+
+ // Read directory
+ sal_Bool bIncludeFolders = ((nFlags & Sb_ATTR_DIRECTORY) != 0);
+ pRTLData->aDirSeq = xSFI->getFolderContents( aDirURLStr, bIncludeFolders );
+ pRTLData->nCurDirPos = 0;
+
+ // #78651 Add "." and ".." directories for VB compatibility
+ if( bIncludeFolders )
+ {
+ BOOL bRoot = isRootDir( aDirURLStr );
+
+ // If it's no root directory we flag the need for
+ // the "." and ".." directories by the value -2
+ // for the actual position. Later for -2 will be
+ // returned "." and for -1 ".."
+ if( !bRoot )
+ {
+ pRTLData->nCurDirPos = -2;
+ }
+ }
+ }
+ catch( Exception & )
+ {
+ //StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+
+
+ if( pRTLData->aDirSeq.getLength() > 0 )
+ {
+ sal_Bool bFolderFlag = ((pRTLData->nDirFlags & Sb_ATTR_DIRECTORY) != 0);
+
+ SbiInstance* pInst = pINST;
+ bool bCompatibility = ( pInst && pInst->IsCompatibility() );
+ for( ;; )
+ {
+ if( pRTLData->nCurDirPos < 0 )
+ {
+ if( pRTLData->nCurDirPos == -2 )
+ {
+ aPath = ::rtl::OUString::createFromAscii( "." );
+ }
+ else if( pRTLData->nCurDirPos == -1 )
+ {
+ aPath = ::rtl::OUString::createFromAscii( ".." );
+ }
+ pRTLData->nCurDirPos++;
+ }
+ else if( pRTLData->nCurDirPos >= pRTLData->aDirSeq.getLength() )
+ {
+ pRTLData->aDirSeq.realloc( 0 );
+ aPath.Erase();
+ break;
+ }
+ else
+ {
+ ::rtl::OUString aFile = pRTLData->aDirSeq.getConstArray()[pRTLData->nCurDirPos++];
+
+ if( bCompatibility )
+ {
+ if( !bFolderFlag )
+ {
+ sal_Bool bFolder = xSFI->isFolder( aFile );
+ if( bFolder )
+ continue;
+ }
+ }
+ else
+ {
+ // Only directories
+ if( bFolderFlag )
+ {
+ sal_Bool bFolder = xSFI->isFolder( aFile );
+ if( !bFolder )
+ continue;
+ }
+ }
+
+ INetURLObject aURL( aFile );
+ aPath = aURL.getName( INetURLObject::LAST_SEGMENT, TRUE,
+ INetURLObject::DECODE_WITH_CHARSET );
+ }
+
+ sal_Bool bMatch = implCheckWildcard( aPath, pRTLData );
+ if( !bMatch )
+ continue;
+
+ break;
+ }
+ }
+ rPar.Get(0)->PutString( aPath );
+ }
+ }
+ else
+ // --> UCB
+ {
+#ifdef _OLD_FILE_IMPL
+ if ( nParCount >= 2 )
+ {
+ delete pRTLData->pDir;
+ pRTLData->pDir = 0; // wg. Sonderbehandlung Sb_ATTR_VOLUME
+ DirEntry aEntry( rPar.Get(1)->GetString() );
+ FileStat aStat( aEntry );
+ if(!aStat.GetError() && (aStat.GetKind() & FSYS_KIND_FILE))
+ {
+ // ah ja, ist nur ein dateiname
+ // Pfad abschneiden (wg. VB4)
+ rPar.Get(0)->PutString( aEntry.GetName() );
+ return;
+ }
+ USHORT nFlags = 0;
+ if ( nParCount > 2 )
+ pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger();
+ else
+ pRTLData->nDirFlags = 0;
+ // Nur diese Bitmaske ist unter Windows erlaubt
+ #ifdef WIN
+ if( nFlags & ~0x1E )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT ), pRTLData->nDirFlags = 0;
+ #endif
+ // Sb_ATTR_VOLUME wird getrennt gehandelt
+ if( pRTLData->nDirFlags & Sb_ATTR_VOLUME )
+ aPath = aEntry.GetVolume();
+ else
+ {
+ // Die richtige Auswahl treffen
+ USHORT nMode = FSYS_KIND_FILE;
+ if( nFlags & Sb_ATTR_DIRECTORY )
+ nMode |= FSYS_KIND_DIR;
+ if( nFlags == Sb_ATTR_DIRECTORY )
+ nMode = FSYS_KIND_DIR;
+ pRTLData->pDir = new Dir( aEntry, (DirEntryKind) nMode );
+ pRTLData->nCurDirPos = 0;
+ }
+ }
+
+ if( pRTLData->pDir )
+ {
+ for( ;; )
+ {
+ if( pRTLData->nCurDirPos >= pRTLData->pDir->Count() )
+ {
+ delete pRTLData->pDir;
+ pRTLData->pDir = 0;
+ aPath.Erase();
+ break;
+ }
+ DirEntry aNextEntry=(*(pRTLData->pDir))[pRTLData->nCurDirPos++];
+ aPath = aNextEntry.GetName(); //Full();
+ #ifdef WIN
+ aNextEntry.ToAbs();
+ String sFull(aNextEntry.GetFull());
+ unsigned nFlags;
+
+ if (_dos_getfileattr( sFull.GetStr(), &nFlags ))
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ else
+ {
+ INT16 nCurFlags = pRTLData->nDirFlags;
+ if( (nCurFlags == Sb_ATTR_NORMAL)
+ && !(nFlags & ( _A_HIDDEN | _A_SYSTEM | _A_VOLID | _A_SUBDIR ) ) )
+ break;
+ else if( (nCurFlags & Sb_ATTR_HIDDEN) && (nFlags & _A_HIDDEN) )
+ break;
+ else if( (nCurFlags & Sb_ATTR_SYSTEM) && (nFlags & _A_SYSTEM) )
+ break;
+ else if( (nCurFlags & Sb_ATTR_VOLUME) && (nFlags & _A_VOLID) )
+ break;
+ else if( (nCurFlags & Sb_ATTR_DIRECTORY) && (nFlags & _A_SUBDIR) )
+ break;
+ }
+ #else
+ break;
+ #endif
+ }
+ }
+ rPar.Get(0)->PutString( aPath );
+#else
+ // TODO: OSL
+ if ( nParCount >= 2 )
+ {
+ String aFileParam = rPar.Get(1)->GetString();
+
+ String aDirURL = implSetupWildcard( aFileParam, pRTLData );
+
+ USHORT nFlags = 0;
+ if ( nParCount > 2 )
+ pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger();
+ else
+ pRTLData->nDirFlags = 0;
+
+ // Read directory
+ sal_Bool bIncludeFolders = ((nFlags & Sb_ATTR_DIRECTORY) != 0);
+ pRTLData->pDir = new Directory( aDirURL );
+ FileBase::RC nRet = pRTLData->pDir->open();
+ if( nRet != FileBase::E_None )
+ {
+ delete pRTLData->pDir;
+ pRTLData->pDir = NULL;
+ rPar.Get(0)->PutString( String() );
+ return;
+ }
+
+ // #86950 Add "." and ".." directories for VB compatibility
+ pRTLData->nCurDirPos = 0;
+ if( bIncludeFolders )
+ {
+ BOOL bRoot = isRootDir( aDirURL );
+
+ // If it's no root directory we flag the need for
+ // the "." and ".." directories by the value -2
+ // for the actual position. Later for -2 will be
+ // returned "." and for -1 ".."
+ if( !bRoot )
+ {
+ pRTLData->nCurDirPos = -2;
+ }
+ }
+
+ }
+
+ if( pRTLData->pDir )
+ {
+ sal_Bool bFolderFlag = ((pRTLData->nDirFlags & Sb_ATTR_DIRECTORY) != 0);
+ for( ;; )
+ {
+ if( pRTLData->nCurDirPos < 0 )
+ {
+ if( pRTLData->nCurDirPos == -2 )
+ {
+ aPath = ::rtl::OUString::createFromAscii( "." );
+ }
+ else if( pRTLData->nCurDirPos == -1 )
+ {
+ aPath = ::rtl::OUString::createFromAscii( ".." );
+ }
+ pRTLData->nCurDirPos++;
+ }
+ else
+ {
+ DirectoryItem aItem;
+ FileBase::RC nRet = pRTLData->pDir->getNextItem( aItem );
+ if( nRet != FileBase::E_None )
+ {
+ delete pRTLData->pDir;
+ pRTLData->pDir = NULL;
+ aPath.Erase();
+ break;
+ }
+
+ // Handle flags
+ FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileName );
+ nRet = aItem.getFileStatus( aFileStatus );
+
+ // Only directories?
+ if( bFolderFlag )
+ {
+ FileStatus::Type aType = aFileStatus.getFileType();
+ sal_Bool bFolder = isFolder( aType );
+ if( !bFolder )
+ continue;
+ }
+
+ aPath = aFileStatus.getFileName();
+ }
+
+ sal_Bool bMatch = implCheckWildcard( aPath, pRTLData );
+ if( !bMatch )
+ continue;
+
+ break;
+ }
+ }
+ rPar.Get(0)->PutString( aPath );
+#endif
+ }
+ }
+}
+
+
+RTLFUNC(GetAttr)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() == 2 )
+ {
+ INT16 nFlags = 0;
+
+ // In Windows, We want to use Windows API to get the file attributes
+ // for VBA interoperability.
+ #if defined( WNT )
+ if( SbiRuntime::isVBAEnabled() )
+ {
+ DirEntry aEntry( rPar.Get(1)->GetString() );
+ aEntry.ToAbs();
+
+ // #57064 Bei virtuellen URLs den Real-Path extrahieren
+ ByteString aByteStrFullPath( aEntry.GetFull(), gsl_getSystemTextEncoding() );
+ DWORD nRealFlags = GetFileAttributes (aByteStrFullPath.GetBuffer());
+ if (nRealFlags != 0xffffffff)
+ {
+ if (nRealFlags == FILE_ATTRIBUTE_NORMAL)
+ nRealFlags = 0;
+ nFlags = (INT16) (nRealFlags);
+ }
+ else
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+
+ rPar.Get(0)->PutInteger( nFlags );
+
+ return;
+ }
+ #endif
+
+ // <-- UCB
+ if( hasUno() )
+ {
+ com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ String aPath = getFullPath( rPar.Get(1)->GetString() );
+ sal_Bool bExists = sal_False;
+ try { bExists = xSFI->exists( aPath ); }
+ catch( Exception & ) {}
+ if( !bExists )
+ {
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ return;
+ }
+
+ sal_Bool bReadOnly = xSFI->isReadOnly( aPath );
+ sal_Bool bHidden = xSFI->isHidden( aPath );
+ sal_Bool bDirectory = xSFI->isFolder( aPath );
+ if( bReadOnly )
+ nFlags |= 0x0001; // ATTR_READONLY
+ if( bHidden )
+ nFlags |= 0x0002; // ATTR_HIDDEN
+ if( bDirectory )
+ nFlags |= 0x0010; // ATTR_DIRECTORY
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+ DirectoryItem aItem;
+ FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( rPar.Get(1)->GetString() ), aItem );
+ FileStatus aFileStatus( FileStatusMask_Attributes | FileStatusMask_Type );
+ nRet = aItem.getFileStatus( aFileStatus );
+ sal_uInt64 nAttributes = aFileStatus.getAttributes();
+ sal_Bool bReadOnly = (nAttributes & Attribute_ReadOnly) != 0;
+
+ FileStatus::Type aType = aFileStatus.getFileType();
+ sal_Bool bDirectory = isFolder( aType );
+ if( bReadOnly )
+ nFlags |= 0x0001; // ATTR_READONLY
+ if( bDirectory )
+ nFlags |= 0x0010; // ATTR_DIRECTORY
+ }
+ rPar.Get(0)->PutInteger( nFlags );
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+
+RTLFUNC(FileDateTime)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ // <-- UCB
+ String aPath = rPar.Get(1)->GetString();
+ Time aTime;
+ Date aDate;
+ if( hasUno() )
+ {
+ com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ com::sun::star::util::DateTime aUnoDT = xSFI->getDateTimeModified( aPath );
+ aTime = Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds );
+ aDate = Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+#ifdef _OLD_FILE_IMPL
+ DirEntry aEntry( aPath );
+ FileStat aStat( aEntry );
+ aTime = Time( aStat.TimeModified() );
+ aDate = Date( aStat.DateModified() );
+#else
+ DirectoryItem aItem;
+ FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aPath ), aItem );
+ FileStatus aFileStatus( FileStatusMask_ModifyTime );
+ nRet = aItem.getFileStatus( aFileStatus );
+ TimeValue aTimeVal = aFileStatus.getModifyTime();
+ oslDateTime aDT;
+ osl_getDateTimeFromTimeValue( &aTimeVal, &aDT );
+
+ aTime = Time( aDT.Hours, aDT.Minutes, aDT.Seconds, 10000000*aDT.NanoSeconds );
+ aDate = Date( aDT.Day, aDT.Month, aDT.Year );
+#endif
+ }
+
+ double fSerial = (double)GetDayDiff( aDate );
+ long nSeconds = aTime.GetHour();
+ nSeconds *= 3600;
+ nSeconds += aTime.GetMin() * 60;
+ nSeconds += aTime.GetSec();
+ double nDays = ((double)nSeconds) / (double)(24.0*3600.0);
+ fSerial += nDays;
+
+ Color* pCol;
+
+ // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
+ SvNumberFormatter* pFormatter = NULL;
+ sal_uInt32 nIndex;
+ if( pINST )
+ {
+ pFormatter = pINST->GetNumberFormatter();
+ nIndex = pINST->GetStdDateTimeIdx();
+ }
+ else
+ {
+ sal_uInt32 n; // Dummy
+ SbiInstance::PrepareNumberFormatter( pFormatter, n, n, nIndex );
+ }
+
+ String aRes;
+ pFormatter->GetOutputString( fSerial, nIndex, aRes, &pCol );
+ rPar.Get(0)->PutString( aRes );
+
+ // #39629 pFormatter kann selbst angefordert sein
+ if( !pINST )
+ delete pFormatter;
+ }
+}
+
+
+RTLFUNC(EOF)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // AB 08/16/2000: No changes for UCB
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+ // nChannel--; // macht MD beim Oeffnen auch nicht
+ SbiIoSystem* pIO = pINST->GetIoSystem();
+ SbiStream* pSbStrm = pIO->GetStream( nChannel );
+ if ( !pSbStrm )
+ {
+ StarBASIC::Error( SbERR_BAD_CHANNEL );
+ return;
+ }
+ BOOL bIsEof;
+ SvStream* pSvStrm = pSbStrm->GetStrm();
+ if ( pSbStrm->IsText() )
+ {
+ char cBla;
+ (*pSvStrm) >> cBla; // koennen wir noch ein Zeichen lesen
+ bIsEof = pSvStrm->IsEof();
+ if ( !bIsEof )
+ pSvStrm->SeekRel( -1 );
+ }
+ else
+ bIsEof = pSvStrm->IsEof(); // fuer binaerdateien!
+ rPar.Get(0)->PutBool( bIsEof );
+ }
+}
+
+RTLFUNC(FileAttr)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // AB 08/16/2000: No changes for UCB
+
+ // #57064 Obwohl diese Funktion nicht mit DirEntry arbeitet, ist sie von
+ // der Anpassung an virtuelle URLs nich betroffen, da sie nur auf bereits
+ // geoeffneten Dateien arbeitet und der Name hier keine Rolle spielt.
+
+ if ( rPar.Count() != 3 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+// nChannel--;
+ SbiIoSystem* pIO = pINST->GetIoSystem();
+ SbiStream* pSbStrm = pIO->GetStream( nChannel );
+ if ( !pSbStrm )
+ {
+ StarBASIC::Error( SbERR_BAD_CHANNEL );
+ return;
+ }
+ INT16 nRet;
+ if ( rPar.Get(2)->GetInteger() == 1 )
+ nRet = (INT16)(pSbStrm->GetMode());
+ else
+ nRet = 0; // System file handle not supported
+
+ rPar.Get(0)->PutInteger( nRet );
+ }
+}
+RTLFUNC(Loc)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // AB 08/16/2000: No changes for UCB
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+ SbiIoSystem* pIO = pINST->GetIoSystem();
+ SbiStream* pSbStrm = pIO->GetStream( nChannel );
+ if ( !pSbStrm )
+ {
+ StarBASIC::Error( SbERR_BAD_CHANNEL );
+ return;
+ }
+ SvStream* pSvStrm = pSbStrm->GetStrm();
+ ULONG nPos;
+ if( pSbStrm->IsRandom())
+ {
+ short nBlockLen = pSbStrm->GetBlockLen();
+ nPos = nBlockLen ? (pSvStrm->Tell() / nBlockLen) : 0;
+ nPos++; // Blockpositionen beginnen bei 1
+ }
+ else if ( pSbStrm->IsText() )
+ nPos = pSbStrm->GetLine();
+ else if( pSbStrm->IsBinary() )
+ nPos = pSvStrm->Tell();
+ else if ( pSbStrm->IsSeq() )
+ nPos = ( pSvStrm->Tell()+1 ) / 128;
+ else
+ nPos = pSvStrm->Tell();
+ rPar.Get(0)->PutLong( (INT32)nPos );
+ }
+}
+
+RTLFUNC(Lof)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // AB 08/16/2000: No changes for UCB
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+ SbiIoSystem* pIO = pINST->GetIoSystem();
+ SbiStream* pSbStrm = pIO->GetStream( nChannel );
+ if ( !pSbStrm )
+ {
+ StarBASIC::Error( SbERR_BAD_CHANNEL );
+ return;
+ }
+ SvStream* pSvStrm = pSbStrm->GetStrm();
+ ULONG nOldPos = pSvStrm->Tell();
+ ULONG nLen = pSvStrm->Seek( STREAM_SEEK_TO_END );
+ pSvStrm->Seek( nOldPos );
+ rPar.Get(0)->PutLong( (INT32)nLen );
+ }
+}
+
+
+RTLFUNC(Seek)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // AB 08/16/2000: No changes for UCB
+ int nArgs = (int)rPar.Count();
+ if ( nArgs < 2 || nArgs > 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+// nChannel--;
+ SbiIoSystem* pIO = pINST->GetIoSystem();
+ SbiStream* pSbStrm = pIO->GetStream( nChannel );
+ if ( !pSbStrm )
+ {
+ StarBASIC::Error( SbERR_BAD_CHANNEL );
+ return;
+ }
+ SvStream* pStrm = pSbStrm->GetStrm();
+
+ if ( nArgs == 2 ) // Seek-Function
+ {
+ ULONG nPos = pStrm->Tell();
+ if( pSbStrm->IsRandom() )
+ nPos = nPos / pSbStrm->GetBlockLen();
+ nPos++; // Basic zaehlt ab 1
+ rPar.Get(0)->PutLong( (INT32)nPos );
+ }
+ else // Seek-Statement
+ {
+ INT32 nPos = rPar.Get(2)->GetLong();
+ if ( nPos < 1 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ nPos--; // Basic zaehlt ab 1, SvStreams zaehlen ab 0
+ pSbStrm->SetExpandOnWriteTo( 0 );
+ if ( pSbStrm->IsRandom() )
+ nPos *= pSbStrm->GetBlockLen();
+ pStrm->Seek( (ULONG)nPos );
+ pSbStrm->SetExpandOnWriteTo( nPos );
+ }
+}
+
+RTLFUNC(Format)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ USHORT nArgCount = (USHORT)rPar.Count();
+ if ( nArgCount < 2 || nArgCount > 3 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aResult;
+ if( nArgCount == 2 )
+ rPar.Get(1)->Format( aResult );
+ else
+ {
+ String aFmt( rPar.Get(2)->GetString() );
+ rPar.Get(1)->Format( aResult, &aFmt );
+ }
+ rPar.Get(0)->PutString( aResult );
+ }
+}
+
+RTLFUNC(Randomize)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() > 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ INT16 nSeed;
+ if( rPar.Count() == 2 )
+ nSeed = (INT16)rPar.Get(1)->GetInteger();
+ else
+ nSeed = (INT16)rand();
+ srand( nSeed );
+}
+
+RTLFUNC(Rnd)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() > 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double nRand = (double)rand();
+ nRand = ( nRand / (double)RAND_MAX );
+ rPar.Get(0)->PutDouble( nRand );
+ }
+}
+
+
+//
+// Syntax: Shell("Path",[ Window-Style,[ "Params", [ bSync = FALSE ]]])
+//
+// WindowStyles (VBA-kompatibel):
+// 2 == Minimized
+// 3 == Maximized
+// 10 == Full-Screen (Textmodus-Anwendungen OS/2, WIN95, WNT)
+//
+// !!!HACK der WindowStyle wird im Creator an Application::StartApp
+// uebergeben. Format: "xxxx2"
+//
+
+
+RTLFUNC(Shell)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // No shell command for "virtual" portal users
+ if( needSecurityRestrictions() )
+ {
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+ return;
+ }
+
+ ULONG nArgCount = rPar.Count();
+ if ( nArgCount < 2 || nArgCount > 5 )
+ {
+ rPar.Get(0)->PutLong(0);
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ }
+ else
+ {
+ USHORT nOptions = NAMESPACE_VOS(OProcess)::TOption_SearchPath|
+ NAMESPACE_VOS(OProcess)::TOption_Detached;
+ String aCmdLine = rPar.Get(1)->GetString();
+ // Zusaetzliche Parameter anhaengen, es muss eh alles geparsed werden
+ if( nArgCount >= 4 )
+ {
+ aCmdLine.AppendAscii( " " );
+ aCmdLine += rPar.Get(3)->GetString();
+ }
+ else if( !aCmdLine.Len() )
+ {
+ // Spezial-Behandlung (leere Liste) vermeiden
+ aCmdLine.AppendAscii( " " );
+ }
+ USHORT nLen = aCmdLine.Len();
+
+ // #55735 Wenn Parameter dabei sind, muessen die abgetrennt werden
+ // #72471 Auch die einzelnen Parameter trennen
+ std::list<String> aTokenList;
+ String aToken;
+ USHORT i = 0;
+ sal_Unicode c;
+ while( i < nLen )
+ {
+ // Spaces weg
+ for ( ;; ++i )
+ {
+ c = aCmdLine.GetBuffer()[ i ];
+ if ( c != ' ' && c != '\t' )
+ break;
+ }
+
+ if( c == '\"' || c == '\'' )
+ {
+ USHORT iFoundPos = aCmdLine.Search( c, i + 1 );
+
+ // Wenn nichts gefunden wurde, Rest kopieren
+ if( iFoundPos == STRING_NOTFOUND )
+ {
+ aToken = aCmdLine.Copy( i, STRING_LEN );
+ i = nLen;
+ }
+ else
+ {
+ aToken = aCmdLine.Copy( i + 1, (iFoundPos - i - 1) );
+ i = iFoundPos + 1;
+ }
+ }
+ else
+ {
+ USHORT iFoundSpacePos = aCmdLine.Search( ' ', i );
+ USHORT iFoundTabPos = aCmdLine.Search( '\t', i );
+ USHORT iFoundPos = Min( iFoundSpacePos, iFoundTabPos );
+
+ // Wenn nichts gefunden wurde, Rest kopieren
+ if( iFoundPos == STRING_NOTFOUND )
+ {
+ aToken = aCmdLine.Copy( i, STRING_LEN );
+ i = nLen;
+ }
+ else
+ {
+ aToken = aCmdLine.Copy( i, (iFoundPos - i) );
+ i = iFoundPos;
+ }
+ }
+
+ // In die Liste uebernehmen
+ aTokenList.push_back( aToken );
+ }
+ // #55735 / #72471 Ende
+
+ INT16 nWinStyle = 0;
+ if( nArgCount >= 3 )
+ {
+ nWinStyle = rPar.Get(2)->GetInteger();
+ switch( nWinStyle )
+ {
+ case 2:
+ nOptions |= NAMESPACE_VOS(OProcess)::TOption_Minimized;
+ break;
+ case 3:
+ nOptions |= NAMESPACE_VOS(OProcess)::TOption_Maximized;
+ break;
+ case 10:
+ nOptions |= NAMESPACE_VOS(OProcess)::TOption_FullScreen;
+ break;
+ }
+
+ BOOL bSync = FALSE;
+ if( nArgCount >= 5 )
+ bSync = rPar.Get(4)->GetBool();
+ if( bSync )
+ nOptions |= NAMESPACE_VOS(OProcess)::TOption_Wait;
+ }
+ NAMESPACE_VOS(OProcess)::TProcessOption eOptions =
+ (NAMESPACE_VOS(OProcess)::TProcessOption)nOptions;
+
+
+ // #72471 Parameter aufbereiten
+ std::list<String>::const_iterator iter = aTokenList.begin();
+ const String& rStr = *iter;
+ ::rtl::OUString aOUStrProg( rStr.GetBuffer(), rStr.Len() );
+ String aOUStrProgUNC = getFullPathUNC( aOUStrProg );
+
+ iter++;
+
+ USHORT nParamCount = sal::static_int_cast< USHORT >(
+ aTokenList.size() - 1 );
+ ::rtl::OUString* pArgumentList = NULL;
+ //const char** pParamList = NULL;
+ if( nParamCount )
+ {
+ pArgumentList = new ::rtl::OUString[ nParamCount ];
+ //pParamList = new const char*[ nParamCount ];
+ USHORT iList = 0;
+ while( iter != aTokenList.end() )
+ {
+ const String& rParamStr = (*iter);
+ pArgumentList[iList++] = ::rtl::OUString( rParamStr.GetBuffer(), rParamStr.Len() );
+ //pParamList[iList++] = (*iter).GetStr();
+ iter++;
+ }
+ }
+
+ //const char* pParams = aParams.Len() ? aParams.GetStr() : 0;
+ NAMESPACE_VOS(OProcess)* pApp;
+ pApp = new NAMESPACE_VOS(OProcess)( aOUStrProgUNC );
+ BOOL bSucc;
+ if( nParamCount == 0 )
+ {
+ bSucc = pApp->execute( eOptions ) == NAMESPACE_VOS(OProcess)::E_None;
+ }
+ else
+ {
+ NAMESPACE_VOS(OArgumentList) aArgList( pArgumentList, nParamCount );
+ bSucc = pApp->execute( eOptions, aArgList ) == NAMESPACE_VOS(OProcess)::E_None;
+ }
+
+ /*
+ if( nParamCount == 0 )
+ pApp = new NAMESPACE_VOS(OProcess)( pProg );
+ else
+ pApp = new NAMESPACE_VOS(OProcess)( pProg, pParamList, nParamCount );
+ BOOL bSucc = pApp->execute( eOptions ) == NAMESPACE_VOS(OProcess)::E_None;
+ */
+
+ delete pApp;
+ delete[] pArgumentList;
+ if( !bSucc )
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ else
+ rPar.Get(0)->PutLong( 0 );
+ }
+}
+
+RTLFUNC(VarType)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxDataType eType = rPar.Get(1)->GetType();
+ rPar.Get(0)->PutInteger( (INT16)eType );
+ }
+}
+
+// Exported function
+String getBasicTypeName( SbxDataType eType )
+{
+ static const char* pTypeNames[] =
+ {
+ "Empty", // SbxEMPTY
+ "Null", // SbxNULL
+ "Integer", // SbxINTEGER
+ "Long", // SbxLONG
+ "Single", // SbxSINGLE
+ "Double", // SbxDOUBLE
+ "Currency", // SbxCURRENCY
+ "Date", // SbxDATE
+ "String", // SbxSTRING
+ "Object", // SbxOBJECT
+ "Error", // SbxERROR
+ "Boolean", // SbxBOOL
+ "Variant", // SbxVARIANT
+ "DataObject", // SbxDATAOBJECT
+ "Unknown Type", //
+ "Unknown Type", //
+ "Char", // SbxCHAR
+ "Byte", // SbxBYTE
+ "UShort", // SbxUSHORT
+ "ULong", // SbxULONG
+ "Long64", // SbxLONG64
+ "ULong64", // SbxULONG64
+ "Int", // SbxINT
+ "UInt", // SbxUINT
+ "Void", // SbxVOID
+ "HResult", // SbxHRESULT
+ "Pointer", // SbxPOINTER
+ "DimArray", // SbxDIMARRAY
+ "CArray", // SbxCARRAY
+ "Userdef", // SbxUSERDEF
+ "Lpstr", // SbxLPSTR
+ "Lpwstr", // SbxLPWSTR
+ "Unknown Type", // SbxCoreSTRING
+ "WString", // SbxWSTRING
+ "WChar", // SbxWCHAR
+ "Int64", // SbxSALINT64
+ "UInt64", // SbxSALUINT64
+ "Decimal", // SbxDECIMAL
+ };
+
+ int nPos = ((int)eType) & 0x0FFF;
+ USHORT nTypeNameCount = sizeof( pTypeNames ) / sizeof( char* );
+ if ( nPos < 0 || nPos >= nTypeNameCount )
+ nPos = nTypeNameCount - 1;
+ String aRetStr = String::CreateFromAscii( pTypeNames[nPos] );
+ return aRetStr;
+}
+
+RTLFUNC(TypeName)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxDataType eType = rPar.Get(1)->GetType();
+ BOOL bIsArray = ( ( eType & SbxARRAY ) != 0 );
+ String aRetStr = getBasicTypeName( eType );
+ if( bIsArray )
+ aRetStr.AppendAscii( "()" );
+ rPar.Get(0)->PutString( aRetStr );
+ }
+}
+
+RTLFUNC(Len)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ const String& rStr = rPar.Get(1)->GetString();
+ rPar.Get(0)->PutLong( (INT32)rStr.Len() );
+ }
+}
+
+RTLFUNC(DDEInitiate)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // No DDE for "virtual" portal users
+ if( needSecurityRestrictions() )
+ {
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+ return;
+ }
+
+ int nArgs = (int)rPar.Count();
+ if ( nArgs != 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ const String& rApp = rPar.Get(1)->GetString();
+ const String& rTopic = rPar.Get(2)->GetString();
+
+ SbiDdeControl* pDDE = pINST->GetDdeControl();
+ INT16 nChannel;
+ SbError nDdeErr = pDDE->Initiate( rApp, rTopic, nChannel );
+ if( nDdeErr )
+ StarBASIC::Error( nDdeErr );
+ else
+ rPar.Get(0)->PutInteger( nChannel );
+}
+
+RTLFUNC(DDETerminate)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // No DDE for "virtual" portal users
+ if( needSecurityRestrictions() )
+ {
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+ return;
+ }
+
+ rPar.Get(0)->PutEmpty();
+ int nArgs = (int)rPar.Count();
+ if ( nArgs != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+ SbiDdeControl* pDDE = pINST->GetDdeControl();
+ SbError nDdeErr = pDDE->Terminate( nChannel );
+ if( nDdeErr )
+ StarBASIC::Error( nDdeErr );
+}
+
+RTLFUNC(DDETerminateAll)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // No DDE for "virtual" portal users
+ if( needSecurityRestrictions() )
+ {
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+ return;
+ }
+
+ rPar.Get(0)->PutEmpty();
+ int nArgs = (int)rPar.Count();
+ if ( nArgs != 1 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ SbiDdeControl* pDDE = pINST->GetDdeControl();
+ SbError nDdeErr = pDDE->TerminateAll();
+ if( nDdeErr )
+ StarBASIC::Error( nDdeErr );
+
+}
+
+RTLFUNC(DDERequest)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // No DDE for "virtual" portal users
+ if( needSecurityRestrictions() )
+ {
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+ return;
+ }
+
+ int nArgs = (int)rPar.Count();
+ if ( nArgs != 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+ const String& rItem = rPar.Get(2)->GetString();
+ SbiDdeControl* pDDE = pINST->GetDdeControl();
+ String aResult;
+ SbError nDdeErr = pDDE->Request( nChannel, rItem, aResult );
+ if( nDdeErr )
+ StarBASIC::Error( nDdeErr );
+ else
+ rPar.Get(0)->PutString( aResult );
+}
+
+RTLFUNC(DDEExecute)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // No DDE for "virtual" portal users
+ if( needSecurityRestrictions() )
+ {
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+ return;
+ }
+
+ rPar.Get(0)->PutEmpty();
+ int nArgs = (int)rPar.Count();
+ if ( nArgs != 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+ const String& rCommand = rPar.Get(2)->GetString();
+ SbiDdeControl* pDDE = pINST->GetDdeControl();
+ SbError nDdeErr = pDDE->Execute( nChannel, rCommand );
+ if( nDdeErr )
+ StarBASIC::Error( nDdeErr );
+}
+
+RTLFUNC(DDEPoke)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // No DDE for "virtual" portal users
+ if( needSecurityRestrictions() )
+ {
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+ return;
+ }
+
+ rPar.Get(0)->PutEmpty();
+ int nArgs = (int)rPar.Count();
+ if ( nArgs != 4 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+ const String& rItem = rPar.Get(2)->GetString();
+ const String& rData = rPar.Get(3)->GetString();
+ SbiDdeControl* pDDE = pINST->GetDdeControl();
+ SbError nDdeErr = pDDE->Poke( nChannel, rItem, rData );
+ if( nDdeErr )
+ StarBASIC::Error( nDdeErr );
+}
+
+
+RTLFUNC(FreeFile)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 1 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ SbiIoSystem* pIO = pINST->GetIoSystem();
+ short nChannel = 1;
+ while( nChannel < CHANNELS )
+ {
+ SbiStream* pStrm = pIO->GetStream( nChannel );
+ if( !pStrm )
+ {
+ rPar.Get(0)->PutInteger( nChannel );
+ return;
+ }
+ nChannel++;
+ }
+ StarBASIC::Error( SbERR_TOO_MANY_FILES );
+}
+
+RTLFUNC(LBound)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ USHORT nParCount = rPar.Count();
+ if ( nParCount != 3 && nParCount != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ SbxBase* pParObj = rPar.Get(1)->GetObject();
+ SbxDimArray* pArr = PTR_CAST(SbxDimArray,pParObj);
+ if( pArr )
+ {
+ INT32 nLower, nUpper;
+ short nDim = (nParCount == 3) ? (short)rPar.Get(2)->GetInteger() : 1;
+ if( !pArr->GetDim32( nDim, nLower, nUpper ) )
+ StarBASIC::Error( SbERR_OUT_OF_RANGE );
+ else
+ rPar.Get(0)->PutLong( nLower );
+ }
+ else
+ StarBASIC::Error( SbERR_MUST_HAVE_DIMS );
+}
+
+RTLFUNC(UBound)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ USHORT nParCount = rPar.Count();
+ if ( nParCount != 3 && nParCount != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ SbxBase* pParObj = rPar.Get(1)->GetObject();
+ SbxDimArray* pArr = PTR_CAST(SbxDimArray,pParObj);
+ if( pArr )
+ {
+ INT32 nLower, nUpper;
+ short nDim = (nParCount == 3) ? (short)rPar.Get(2)->GetInteger() : 1;
+ if( !pArr->GetDim32( nDim, nLower, nUpper ) )
+ StarBASIC::Error( SbERR_OUT_OF_RANGE );
+ else
+ rPar.Get(0)->PutLong( nUpper );
+ }
+ else
+ StarBASIC::Error( SbERR_MUST_HAVE_DIMS );
+}
+
+RTLFUNC(RGB)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 4 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ ULONG nRed = rPar.Get(1)->GetInteger() & 0xFF;
+ ULONG nGreen = rPar.Get(2)->GetInteger() & 0xFF;
+ ULONG nBlue = rPar.Get(3)->GetInteger() & 0xFF;
+ ULONG nRGB;
+
+ SbiInstance* pInst = pINST;
+ bool bCompatibility = ( pInst && pInst->IsCompatibility() );
+ if( bCompatibility )
+ {
+ nRGB = (nBlue << 16) | (nGreen << 8) | nRed;
+ }
+ else
+ {
+ nRGB = (nRed << 16) | (nGreen << 8) | nBlue;
+ }
+ rPar.Get(0)->PutLong( nRGB );
+}
+
+RTLFUNC(QBColor)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ static const INT32 pRGB[] =
+ {
+ 0x000000,
+ 0x800000,
+ 0x008000,
+ 0x808000,
+ 0x000080,
+ 0x800080,
+ 0x008080,
+ 0xC0C0C0,
+ 0x808080,
+ 0xFF0000,
+ 0x00FF00,
+ 0xFFFF00,
+ 0x0000FF,
+ 0xFF00FF,
+ 0x00FFFF,
+ 0xFFFFFF,
+ };
+
+ if ( rPar.Count() != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ INT16 nCol = rPar.Get(1)->GetInteger();
+ if( nCol < 0 || nCol > 15 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT32 nRGB = pRGB[ nCol ];
+ rPar.Get(0)->PutLong( nRGB );
+}
+
+// StrConv(string, conversion, LCID)
+RTLFUNC(StrConv)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+ if( nArgCount < 2 || nArgCount > 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ String aOldStr = rPar.Get(1)->GetString();
+ INT32 nConversion = rPar.Get(2)->GetLong();
+
+ USHORT nLanguage = LANGUAGE_SYSTEM;
+ if( nArgCount == 3 )
+ {
+ // LCID not supported now
+ //nLanguage = rPar.Get(3)->GetInteger();
+ }
+
+ USHORT nOldLen = aOldStr.Len();
+ if( nOldLen == 0 )
+ {
+ // null string,return
+ rPar.Get(0)->PutString(aOldStr);
+ return;
+ }
+
+ INT32 nType = 0;
+ if ( (nConversion & 0x03) == 3 ) // vbProperCase
+ {
+ CharClass& rCharClass = GetCharClass();
+ aOldStr = rCharClass.toTitle( aOldStr.ToLowerAscii(), 0, nOldLen );
+ }
+ else if ( (nConversion & 0x01) == 1 ) // vbUpperCase
+ nType |= ::com::sun::star::i18n::TransliterationModules_LOWERCASE_UPPERCASE;
+ else if ( (nConversion & 0x02) == 2 ) // vbLowerCase
+ nType |= ::com::sun::star::i18n::TransliterationModules_UPPERCASE_LOWERCASE;
+
+ if ( (nConversion & 0x04) == 4 ) // vbWide
+ nType |= ::com::sun::star::i18n::TransliterationModules_HALFWIDTH_FULLWIDTH;
+ else if ( (nConversion & 0x08) == 8 ) // vbNarrow
+ nType |= ::com::sun::star::i18n::TransliterationModules_FULLWIDTH_HALFWIDTH;
+
+ if ( (nConversion & 0x10) == 16) // vbKatakana
+ nType |= ::com::sun::star::i18n::TransliterationModules_HIRAGANA_KATAKANA;
+ else if ( (nConversion & 0x20) == 32 ) // vbHiragana
+ nType |= ::com::sun::star::i18n::TransliterationModules_KATAKANA_HIRAGANA;
+
+ String aNewStr( aOldStr );
+ if( nType != 0 )
+ {
+ com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
+ ::utl::TransliterationWrapper aTransliterationWrapper( xSMgr,nType );
+ com::sun::star::uno::Sequence<sal_Int32> aOffsets;
+ aTransliterationWrapper.loadModuleIfNeeded( nLanguage );
+ aNewStr = aTransliterationWrapper.transliterate( aOldStr, nLanguage, 0, nOldLen, &aOffsets );
+ }
+
+ if ( (nConversion & 0x40) == 64 ) // vbUnicode
+ {
+ // convert the string to byte string, preserving unicode (2 bytes per character)
+ USHORT nSize = aNewStr.Len()*2;
+ const sal_Unicode* pSrc = aNewStr.GetBuffer();
+ sal_Char* pChar = new sal_Char[nSize+1];
+ for( USHORT i=0; i < nSize; i++ )
+ {
+ pChar[i] = static_cast< sal_Char >( i%2 ? ((*pSrc) >> 8) & 0xff : (*pSrc) & 0xff );
+ if( i%2 )
+ pSrc++;
+ }
+ pChar[nSize] = '\0';
+ ::rtl::OString aOStr(pChar);
+
+ // there is no concept about default codepage in unix. so it is incorrectly in unix
+ ::rtl::OUString aOUStr = ::rtl::OStringToOUString(aOStr, osl_getThreadTextEncoding());
+ aNewStr = String(aOUStr);
+ rPar.Get(0)->PutString( aNewStr );
+ return;
+ }
+ else if ( (nConversion & 0x80) == 128 ) // vbFromUnicode
+ {
+ ::rtl::OUString aOUStr(aNewStr);
+ // there is no concept about default codepage in unix. so it is incorrectly in unix
+ ::rtl::OString aOStr = ::rtl::OUStringToOString(aNewStr,osl_getThreadTextEncoding());
+ const sal_Char* pChar = aOStr.getStr();
+ USHORT nArraySize = static_cast< USHORT >( aOStr.getLength() );
+ SbxDimArray* pArray = new SbxDimArray(SbxBYTE);
+ bool bIncIndex = (IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
+ if(nArraySize)
+ {
+ if( bIncIndex )
+ pArray->AddDim( 1, nArraySize );
+ else
+ pArray->AddDim( 0, nArraySize-1 );
+ }
+ else
+ {
+ pArray->unoAddDim( 0, -1 );
+ }
+
+ for( USHORT i=0; i< nArraySize; i++)
+ {
+ SbxVariable* pNew = new SbxVariable( SbxBYTE );
+ pNew->PutByte(*pChar);
+ pChar++;
+ pNew->SetFlag( SBX_WRITE );
+ short index = i;
+ if( bIncIndex )
+ ++index;
+ pArray->Put( pNew, &index );
+ }
+
+ SbxVariableRef refVar = rPar.Get(0);
+ USHORT nFlags = refVar->GetFlags();
+ refVar->ResetFlag( SBX_FIXED );
+ refVar->PutObject( pArray );
+ refVar->SetFlags( nFlags );
+ refVar->SetParameters( NULL );
+ return;
+ }
+
+ rPar.Get(0)->PutString(aNewStr);
+}
+
+
+RTLFUNC(Beep)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 1 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ Sound::Beep();
+}
+
+RTLFUNC(Load)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if( rPar.Count() != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Diesen Call einfach an das Object weiterreichen
+ SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
+ if ( pObj )
+ {
+ if( pObj->IsA( TYPE( SbUserFormModule ) ) )
+ {
+ ((SbUserFormModule*)pObj)->Load();
+ }
+ else if( pObj->IsA( TYPE( SbxObject ) ) )
+ {
+ SbxVariable* pVar = ((SbxObject*)pObj)->
+ Find( String( RTL_CONSTASCII_USTRINGPARAM("Load") ), SbxCLASS_METHOD );
+ if( pVar )
+ pVar->GetInteger();
+ }
+ }
+}
+
+RTLFUNC(Unload)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutEmpty();
+ if( rPar.Count() != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Diesen Call einfach an das Object weitereichen
+ SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
+ if ( pObj )
+ {
+ if( pObj->IsA( TYPE( SbUserFormModule ) ) )
+ {
+ SbUserFormModule* pFormModule = ( SbUserFormModule* )pObj;
+ pFormModule->Unload();
+ }
+ else if( pObj->IsA( TYPE( SbxObject ) ) )
+ {
+ SbxVariable* pVar = ((SbxObject*)pObj)->
+ Find( String( RTL_CONSTASCII_USTRINGPARAM("Unload") ), SbxCLASS_METHOD );
+ if( pVar )
+ pVar->GetInteger();
+ }
+ }
+}
+
+RTLFUNC(LoadPicture)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if( rPar.Count() != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ String aFileURL = getFullPath( rPar.Get(1)->GetString() );
+ SvStream* pStream = utl::UcbStreamHelper::CreateStream( aFileURL, STREAM_READ );
+ if( pStream != NULL )
+ {
+ Bitmap aBmp;
+ *pStream >> aBmp;
+ Graphic aGraphic( aBmp );
+
+ SbxObjectRef xRef = new SbStdPicture;
+ ((SbStdPicture*)(SbxObject*)xRef)->SetGraphic( aGraphic );
+ rPar.Get(0)->PutObject( xRef );
+ }
+ delete pStream;
+}
+
+RTLFUNC(SavePicture)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutEmpty();
+ if( rPar.Count() != 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
+ if( pObj->IsA( TYPE( SbStdPicture ) ) )
+ {
+ SvFileStream aOStream( rPar.Get(2)->GetString(), STREAM_WRITE | STREAM_TRUNC );
+ Graphic aGraphic = ((SbStdPicture*)pObj)->GetGraphic();
+ aOStream << aGraphic;
+ }
+}
+
+
+//-----------------------------------------------------------------------------------------
+
+RTLFUNC(AboutStarBasic)
+{
+ (void)pBasic;
+ (void)bWrite;
+ (void)rPar;
+}
+
+RTLFUNC(MsgBox)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ static const WinBits nStyleMap[] =
+ {
+ WB_OK, // MB_OK
+ WB_OK_CANCEL, // MB_OKCANCEL
+ WB_ABORT_RETRY_IGNORE, // MB_ABORTRETRYIGNORE
+ WB_YES_NO_CANCEL, // MB_YESNOCANCEL
+ WB_YES_NO, // MB_YESNO
+ WB_RETRY_CANCEL // MB_RETRYCANCEL
+ };
+ static const INT16 nButtonMap[] =
+ {
+ 2, // #define RET_CANCEL FALSE
+ 1, // #define RET_OK TRUE
+ 6, // #define RET_YES 2
+ 7, // #define RET_NO 3
+ 4 // #define RET_RETRY 4
+ };
+
+
+ USHORT nArgCount = (USHORT)rPar.Count();
+ if( nArgCount < 2 || nArgCount > 6 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ WinBits nWinBits;
+ WinBits nType = 0; // MB_OK
+ if( nArgCount >= 3 )
+ nType = (WinBits)rPar.Get(2)->GetInteger();
+ WinBits nStyle = nType;
+ nStyle &= 15; // Bits 4-16 loeschen
+ if( nStyle > 5 )
+ nStyle = 0;
+
+ nWinBits = nStyleMap[ nStyle ];
+
+ WinBits nWinDefBits;
+ nWinDefBits = (WB_DEF_OK | WB_DEF_RETRY | WB_DEF_YES);
+ if( nType & 256 )
+ {
+ if( nStyle == 5 )
+ nWinDefBits = WB_DEF_CANCEL;
+ else if( nStyle == 2 )
+ nWinDefBits = WB_DEF_RETRY;
+ else
+ nWinDefBits = (WB_DEF_CANCEL | WB_DEF_RETRY | WB_DEF_NO);
+ }
+ else if( nType & 512 )
+ {
+ if( nStyle == 2)
+ nWinDefBits = WB_DEF_IGNORE;
+ else
+ nWinDefBits = WB_DEF_CANCEL;
+ }
+ else if( nStyle == 2)
+ nWinDefBits = WB_DEF_CANCEL;
+ nWinBits |= nWinDefBits;
+
+ String aMsg = rPar.Get(1)->GetString();
+ String aTitle;
+ if( nArgCount >= 4 )
+ aTitle = rPar.Get(3)->GetString();
+ else
+ aTitle = GetpApp()->GetAppName();
+
+ nType &= (16+32+64);
+ MessBox* pBox = 0;
+ Window* pParent = GetpApp()->GetDefDialogParent();
+ switch( nType )
+ {
+ case 16:
+ pBox = new ErrorBox( pParent, nWinBits, aMsg );
+ break;
+ case 32:
+ pBox = new QueryBox( pParent, nWinBits, aMsg );
+ break;
+ case 48:
+ pBox = new WarningBox( pParent, nWinBits, aMsg );
+ break;
+ case 64:
+ pBox = new InfoBox( pParent, aMsg );
+ break;
+ default:
+ pBox = new MessBox( pParent, nWinBits, aTitle, aMsg );
+ }
+ pBox->SetText( aTitle );
+ USHORT nRet = (USHORT)pBox->Execute();
+ if( nRet == TRUE )
+ nRet = 1;
+
+ INT16 nMappedRet;
+ if( nStyle == 2 )
+ {
+ nMappedRet = nRet;
+ if( nMappedRet == 0 )
+ nMappedRet = 3; // Abort
+ }
+ else
+ nMappedRet = nButtonMap[ nRet ];
+
+ rPar.Get(0)->PutInteger( nMappedRet );
+ delete pBox;
+}
+
+RTLFUNC(SetAttr) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutEmpty();
+ if ( rPar.Count() == 3 )
+ {
+ String aStr = rPar.Get(1)->GetString();
+ INT16 nFlags = rPar.Get(2)->GetInteger();
+
+ // <-- UCB
+ if( hasUno() )
+ {
+ com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ sal_Bool bReadOnly = (nFlags & 0x0001) != 0; // ATTR_READONLY
+ xSFI->setReadOnly( aStr, bReadOnly );
+ sal_Bool bHidden = (nFlags & 0x0002) != 0; // ATTR_HIDDEN
+ xSFI->setHidden( aStr, bHidden );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+#ifdef _OLD_FILE_IMPL
+ // #57064 Bei virtuellen URLs den Real-Path extrahieren
+ DirEntry aEntry( aStr );
+ String aFile = aEntry.GetFull();
+ #ifdef WIN
+ int nErr = _dos_setfileattr( aFile.GetStr(),(unsigned ) nFlags );
+ if ( nErr )
+ {
+ if (errno == EACCES)
+ StarBASIC::Error( SbERR_ACCESS_DENIED );
+ else
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ }
+ #endif
+ ByteString aByteFile( aFile, gsl_getSystemTextEncoding() );
+ #ifdef WNT
+ if (!SetFileAttributes (aByteFile.GetBuffer(),(DWORD)nFlags))
+ StarBASIC::Error(SbERR_FILE_NOT_FOUND);
+ #endif
+ #ifdef OS2
+ FILESTATUS3 aFileStatus;
+ APIRET rc = DosQueryPathInfo(aByteFile.GetBuffer(),1,
+ &aFileStatus,sizeof(FILESTATUS3));
+ if (!rc)
+ {
+ if (aFileStatus.attrFile != nFlags)
+ {
+ aFileStatus.attrFile = nFlags;
+ rc = DosSetPathInfo(aFile.GetStr(),1,
+ &aFileStatus,sizeof(FILESTATUS3),0);
+ if (rc)
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ }
+ }
+ else
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ #endif
+#else
+ // Not implemented
+#endif
+ }
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(Reset) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+ (void)rPar;
+
+ SbiIoSystem* pIO = pINST->GetIoSystem();
+ if (pIO)
+ pIO->CloseAll();
+}
+
+RTLFUNC(DumpAllObjects)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ USHORT nArgCount = (USHORT)rPar.Count();
+ if( nArgCount < 2 || nArgCount > 3 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else if( !pBasic )
+ StarBASIC::Error( SbERR_INTERNAL_ERROR );
+ else
+ {
+ SbxObject* p = pBasic;
+ while( p->GetParent() )
+ p = p->GetParent();
+ SvFileStream aStrm( rPar.Get( 1 )->GetString(),
+ STREAM_WRITE | STREAM_TRUNC );
+ p->Dump( aStrm, rPar.Get( 2 )->GetBool() );
+ aStrm.Close();
+ if( aStrm.GetError() != SVSTREAM_OK )
+ StarBASIC::Error( SbERR_IO_ERROR );
+ }
+}
+
+
+RTLFUNC(FileExists)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() == 2 )
+ {
+ String aStr = rPar.Get(1)->GetString();
+ BOOL bExists = FALSE;
+
+ // <-- UCB
+ if( hasUno() )
+ {
+ com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ bExists = xSFI->exists( aStr );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+#ifdef _OLD_FILE_IMPL
+ DirEntry aEntry( aStr );
+ bExists = aEntry.Exists();
+#else
+ DirectoryItem aItem;
+ FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aStr ), aItem );
+ bExists = (nRet == FileBase::E_None);
+#endif
+ }
+ rPar.Get(0)->PutBool( bExists );
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(Partition)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 5 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ INT32 nNumber = rPar.Get(1)->GetLong();
+ INT32 nStart = rPar.Get(2)->GetLong();
+ INT32 nStop = rPar.Get(3)->GetLong();
+ INT32 nInterval = rPar.Get(4)->GetLong();
+
+ if( nStart < 0 || nStop <= nStart || nInterval < 1 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // the Partition function inserts leading spaces before lowervalue and uppervalue
+ // so that they both have the same number of characters as the string
+ // representation of the value (Stop + 1). This ensures that if you use the output
+ // of the Partition function with several values of Number, the resulting text
+ // will be handled properly during any subsequent sort operation.
+
+ // calculate the maximun number of characters before lowervalue and uppervalue
+ ::rtl::OUString aBeforeStart = ::rtl::OUString::valueOf( nStart - 1 );
+ ::rtl::OUString aAfterStop = ::rtl::OUString::valueOf( nStop + 1 );
+ INT32 nLen1 = aBeforeStart.getLength();
+ INT32 nLen2 = aAfterStop.getLength();
+ INT32 nLen = nLen1 >= nLen2 ? nLen1:nLen2;
+
+ ::rtl::OUStringBuffer aRetStr( nLen * 2 + 1);
+ ::rtl::OUString aLowerValue;
+ ::rtl::OUString aUpperValue;
+ if( nNumber < nStart )
+ {
+ aUpperValue = aBeforeStart;
+ }
+ else if( nNumber > nStop )
+ {
+ aLowerValue = aAfterStop;
+ }
+ else
+ {
+ INT32 nLowerValue = nNumber;
+ INT32 nUpperValue = nLowerValue;
+ if( nInterval > 1 )
+ {
+ nLowerValue = ((( nNumber - nStart ) / nInterval ) * nInterval ) + nStart;
+ nUpperValue = nLowerValue + nInterval - 1;
+ }
+
+ aLowerValue = ::rtl::OUString::valueOf( nLowerValue );
+ aUpperValue = ::rtl::OUString::valueOf( nUpperValue );
+ }
+
+ nLen1 = aLowerValue.getLength();
+ nLen2 = aUpperValue.getLength();
+
+ if( nLen > nLen1 )
+ {
+ // appending the leading spaces for the lowervalue
+ for ( INT32 i= (nLen - nLen1) ; i > 0; --i )
+ aRetStr.appendAscii(" ");
+ }
+ aRetStr.append( aLowerValue ).appendAscii(":");
+ if( nLen > nLen2 )
+ {
+ // appending the leading spaces for the uppervalue
+ for ( INT32 i= (nLen - nLen2) ; i > 0; --i )
+ aRetStr.appendAscii(" ");
+ }
+ aRetStr.append( aUpperValue );
+ rPar.Get(0)->PutString( String(aRetStr.makeStringAndClear()) );
+}
diff --git a/basic/source/runtime/methods1.cxx b/basic/source/runtime/methods1.cxx
new file mode 100644
index 000000000000..62e9c388f5c5
--- /dev/null
+++ b/basic/source/runtime/methods1.cxx
@@ -0,0 +1,2621 @@
+/*************************************************************************
+ *
+ * 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"
+
+#if defined(WIN)
+#include <string.h>
+#else
+#include <stdlib.h> // getenv
+#endif
+#include <vcl/svapp.hxx>
+#include <vcl/mapmod.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/timer.hxx>
+#include <basic/sbxvar.hxx>
+#ifndef _SBX_HXX
+#include <basic/sbx.hxx>
+#endif
+#include <svl/zforlist.hxx>
+#include <tools/fsys.hxx>
+#include <tools/urlobj.hxx>
+#include <osl/file.hxx>
+
+#ifdef OS2
+#define INCL_DOS
+#define INCL_DOSPROCESS
+#include <svpm.h>
+#endif
+
+#if defined(WIN)
+#include <tools/svwin.h>
+#endif
+
+#ifndef CLK_TCK
+#define CLK_TCK CLOCKS_PER_SEC
+#endif
+
+#include <vcl/jobset.hxx>
+#include <basic/sbobjmod.hxx>
+
+#include "sbintern.hxx"
+#include "runtime.hxx"
+#include "stdobj.hxx"
+#include "rtlproto.hxx"
+#include "dllmgr.hxx"
+#include <iosys.hxx>
+#include "sbunoobj.hxx"
+#include "propacc.hxx"
+
+
+#include <comphelper/processfactory.hxx>
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/i18n/XCalendar.hpp>
+
+using namespace comphelper;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::i18n;
+
+
+static Reference< XCalendar > getLocaleCalendar( void )
+{
+ static Reference< XCalendar > xCalendar;
+ if( !xCalendar.is() )
+ {
+ Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
+ if( xSMgr.is() )
+ {
+ xCalendar = Reference< XCalendar >( xSMgr->createInstance
+ ( ::rtl::OUString::createFromAscii( "com.sun.star.i18n.LocaleCalendar" ) ), UNO_QUERY );
+ }
+ }
+
+ static com::sun::star::lang::Locale aLastLocale;
+ static bool bNeedsInit = true;
+
+ com::sun::star::lang::Locale aLocale = Application::GetSettings().GetLocale();
+ bool bNeedsReload = false;
+ if( bNeedsInit )
+ {
+ bNeedsInit = false;
+ bNeedsReload = true;
+ }
+ else if( aLocale.Language != aLastLocale.Language ||
+ aLocale.Country != aLastLocale.Country )
+ {
+ bNeedsReload = true;
+ }
+ if( bNeedsReload )
+ {
+ aLastLocale = aLocale;
+ xCalendar->loadDefaultCalendar( aLocale );
+ }
+ return xCalendar;
+}
+
+
+RTLFUNC(CBool) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ BOOL bVal = FALSE;
+ if ( rPar.Count() == 2 )
+ {
+ SbxVariable *pSbxVariable = rPar.Get(1);
+ bVal = pSbxVariable->GetBool();
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+
+ rPar.Get(0)->PutBool(bVal);
+}
+
+RTLFUNC(CByte) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ BYTE nByte = 0;
+ if ( rPar.Count() == 2 )
+ {
+ SbxVariable *pSbxVariable = rPar.Get(1);
+ nByte = pSbxVariable->GetByte();
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+
+ rPar.Get(0)->PutByte(nByte);
+}
+
+RTLFUNC(CCur) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ SbxINT64 nCur;
+ if ( rPar.Count() == 2 )
+ {
+ SbxVariable *pSbxVariable = rPar.Get(1);
+ nCur = pSbxVariable->GetCurrency();
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+
+ rPar.Get(0)->PutCurrency( nCur );
+}
+
+RTLFUNC(CDec) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+#ifdef WNT
+ SbxDecimal* pDec = NULL;
+ if ( rPar.Count() == 2 )
+ {
+ SbxVariable *pSbxVariable = rPar.Get(1);
+ pDec = pSbxVariable->GetDecimal();
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+
+ rPar.Get(0)->PutDecimal( pDec );
+#else
+ rPar.Get(0)->PutEmpty();
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+#endif
+}
+
+RTLFUNC(CDate) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ double nVal = 0.0;
+ if ( rPar.Count() == 2 )
+ {
+ SbxVariable *pSbxVariable = rPar.Get(1);
+ nVal = pSbxVariable->GetDate();
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+
+ rPar.Get(0)->PutDate(nVal);
+}
+
+RTLFUNC(CDbl) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ double nVal = 0.0;
+ if ( rPar.Count() == 2 )
+ {
+ SbxVariable *pSbxVariable = rPar.Get(1);
+ if( pSbxVariable->GetType() == SbxSTRING )
+ {
+ // AB #41690 , String holen
+ String aScanStr = pSbxVariable->GetString();
+ SbError Error = SbxValue::ScanNumIntnl( aScanStr, nVal );
+ if( Error != SbxERR_OK )
+ StarBASIC::Error( Error );
+ }
+ else
+ {
+ nVal = pSbxVariable->GetDouble();
+ }
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+
+ rPar.Get(0)->PutDouble(nVal);
+}
+
+RTLFUNC(CInt) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ INT16 nVal = 0;
+ if ( rPar.Count() == 2 )
+ {
+ SbxVariable *pSbxVariable = rPar.Get(1);
+ nVal = pSbxVariable->GetInteger();
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+
+ rPar.Get(0)->PutInteger(nVal);
+}
+
+RTLFUNC(CLng) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ INT32 nVal = 0;
+ if ( rPar.Count() == 2 )
+ {
+ SbxVariable *pSbxVariable = rPar.Get(1);
+ nVal = pSbxVariable->GetLong();
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+
+ rPar.Get(0)->PutLong(nVal);
+}
+
+RTLFUNC(CSng) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ float nVal = (float)0.0;
+ if ( rPar.Count() == 2 )
+ {
+ SbxVariable *pSbxVariable = rPar.Get(1);
+ if( pSbxVariable->GetType() == SbxSTRING )
+ {
+ // AB #41690 , String holen
+ double dVal = 0.0;
+ String aScanStr = pSbxVariable->GetString();
+ SbError Error = SbxValue::ScanNumIntnl( aScanStr, dVal, /*bSingle=*/TRUE );
+ if( SbxBase::GetError() == SbxERR_OK && Error != SbxERR_OK )
+ StarBASIC::Error( Error );
+ nVal = (float)dVal;
+ }
+ else
+ {
+ nVal = pSbxVariable->GetSingle();
+ }
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+
+ rPar.Get(0)->PutSingle(nVal);
+}
+
+RTLFUNC(CStr) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ String aString;
+ if ( rPar.Count() == 2 )
+ {
+ SbxVariable *pSbxVariable = rPar.Get(1);
+ aString = pSbxVariable->GetString();
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+
+ rPar.Get(0)->PutString(aString);
+}
+
+RTLFUNC(CVar) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ SbxValues aVals( SbxVARIANT );
+ if ( rPar.Count() == 2 )
+ {
+ SbxVariable *pSbxVariable = rPar.Get(1);
+ pSbxVariable->Get( aVals );
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+
+ rPar.Get(0)->Put( aVals );
+}
+
+RTLFUNC(CVErr)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ INT16 nErrCode = 0;
+ if ( rPar.Count() == 2 )
+ {
+ SbxVariable *pSbxVariable = rPar.Get(1);
+ nErrCode = pSbxVariable->GetInteger();
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+
+ rPar.Get(0)->PutErr( nErrCode );
+}
+
+RTLFUNC(Iif) // JSM
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() == 4 )
+ {
+ if (rPar.Get(1)->GetBool())
+ *rPar.Get(0) = *rPar.Get(2);
+ else
+ *rPar.Get(0) = *rPar.Get(3);
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(GetSystemType)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 1 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ // Removed for SRC595
+ rPar.Get(0)->PutInteger( -1 );
+}
+
+RTLFUNC(GetGUIType)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 1 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ // 17.7.2000 Make simple solution for testtool / fat office
+#if defined (WNT)
+ rPar.Get(0)->PutInteger( 1 );
+#elif defined OS2
+ rPar.Get(0)->PutInteger( 2 );
+#elif defined UNX
+ rPar.Get(0)->PutInteger( 4 );
+#else
+ rPar.Get(0)->PutInteger( -1 );
+#endif
+ }
+}
+
+RTLFUNC(Red)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ ULONG nRGB = (ULONG)rPar.Get(1)->GetLong();
+ nRGB &= 0x00FF0000;
+ nRGB >>= 16;
+ rPar.Get(0)->PutInteger( (INT16)nRGB );
+ }
+}
+
+RTLFUNC(Green)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ ULONG nRGB = (ULONG)rPar.Get(1)->GetLong();
+ nRGB &= 0x0000FF00;
+ nRGB >>= 8;
+ rPar.Get(0)->PutInteger( (INT16)nRGB );
+ }
+}
+
+RTLFUNC(Blue)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ ULONG nRGB = (ULONG)rPar.Get(1)->GetLong();
+ nRGB &= 0x000000FF;
+ rPar.Get(0)->PutInteger( (INT16)nRGB );
+ }
+}
+
+
+RTLFUNC(Switch)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ USHORT nCount = rPar.Count();
+ if( !(nCount & 0x0001 ))
+ // Anzahl der Argumente muss ungerade sein
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ USHORT nCurExpr = 1;
+ while( nCurExpr < (nCount-1) )
+ {
+ if( rPar.Get( nCurExpr )->GetBool())
+ {
+ (*rPar.Get(0)) = *(rPar.Get(nCurExpr+1));
+ return;
+ }
+ nCurExpr += 2;
+ }
+ rPar.Get(0)->PutNull();
+}
+
+//i#64882# Common wait impl for existing Wait and new WaitUntil
+// rtl functions
+void Wait_Impl( bool bDurationBased, SbxArray& rPar )
+{
+ if( rPar.Count() != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ long nWait = 0;
+ if ( bDurationBased )
+ {
+ double dWait = rPar.Get(1)->GetDouble();
+ double dNow = Now_Impl();
+ double dSecs = (double)( ( dWait - dNow ) * (double)( 24.0*3600.0) );
+ nWait = (long)( dSecs * 1000 ); // wait in thousands of sec
+ }
+ else
+ nWait = rPar.Get(1)->GetLong();
+ if( nWait < 0 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ Timer aTimer;
+ aTimer.SetTimeout( nWait );
+ aTimer.Start();
+ while ( aTimer.IsActive() )
+ Application::Yield();
+}
+
+//i#64882#
+RTLFUNC(Wait)
+{
+ (void)pBasic;
+ (void)bWrite;
+ Wait_Impl( false, rPar );
+}
+
+//i#64882# add new WaitUntil ( for application.wait )
+// share wait_impl with 'normal' oobasic wait
+RTLFUNC(WaitUntil)
+{
+ (void)pBasic;
+ (void)bWrite;
+ Wait_Impl( true, rPar );
+}
+
+RTLFUNC(DoEvents)
+{
+ (void)pBasic;
+ (void)bWrite;
+ (void)rPar;
+ // Dummy implementation as the following code leads
+ // to performance problems for unknown reasons
+ //Timer aTimer;
+ //aTimer.SetTimeout( 1 );
+ //aTimer.Start();
+ //while ( aTimer.IsActive() )
+ // Application::Reschedule();
+}
+
+RTLFUNC(GetGUIVersion)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 1 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ // Removed for SRC595
+ rPar.Get(0)->PutLong( -1 );
+ }
+}
+
+RTLFUNC(Choose)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ INT16 nIndex = rPar.Get(1)->GetInteger();
+ USHORT nCount = rPar.Count();
+ nCount--;
+ if( nCount == 1 || nIndex > (nCount-1) || nIndex < 1 )
+ {
+ rPar.Get(0)->PutNull();
+ return;
+ }
+ (*rPar.Get(0)) = *(rPar.Get(nIndex+1));
+}
+
+
+RTLFUNC(Trim)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr( rPar.Get(1)->GetString() );
+ aStr.EraseLeadingChars();
+ aStr.EraseTrailingChars();
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+RTLFUNC(GetSolarVersion)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutLong( (INT32)SUPD );
+}
+
+RTLFUNC(TwipsPerPixelX)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ INT32 nResult = 0;
+ Size aSize( 100,0 );
+ MapMode aMap( MAP_TWIP );
+ OutputDevice* pDevice = Application::GetDefaultDevice();
+ if( pDevice )
+ {
+ aSize = pDevice->PixelToLogic( aSize, aMap );
+ nResult = aSize.Width() / 100;
+ }
+ rPar.Get(0)->PutLong( nResult );
+}
+
+RTLFUNC(TwipsPerPixelY)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ INT32 nResult = 0;
+ Size aSize( 0,100 );
+ MapMode aMap( MAP_TWIP );
+ OutputDevice* pDevice = Application::GetDefaultDevice();
+ if( pDevice )
+ {
+ aSize = pDevice->PixelToLogic( aSize, aMap );
+ nResult = aSize.Height() / 100;
+ }
+ rPar.Get(0)->PutLong( nResult );
+}
+
+
+RTLFUNC(FreeLibrary)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ pINST->GetDllMgr()->FreeDll( rPar.Get(1)->GetString() );
+}
+bool IsBaseIndexOne()
+{
+ bool result = false;
+ if ( pINST && pINST->pRun )
+ {
+ USHORT res = pINST->pRun->GetBase();
+ if ( res )
+ result = true;
+ }
+ return result;
+}
+
+RTLFUNC(Array)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
+ USHORT nArraySize = rPar.Count() - 1;
+
+ // Option Base zunaechst ignorieren (kennt leider nur der Compiler)
+ bool bIncIndex = (IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
+ if( nArraySize )
+ {
+ if ( bIncIndex )
+ pArray->AddDim( 1, nArraySize );
+ else
+ pArray->AddDim( 0, nArraySize-1 );
+ }
+ else
+ {
+ pArray->unoAddDim( 0, -1 );
+ }
+
+ // Parameter ins Array uebernehmen
+ // ATTENTION: Using type USHORT for loop variable is
+ // mandatory to workaround a problem with the
+ // Solaris Intel compiler optimizer! See i104354
+ for( USHORT i = 0 ; i < nArraySize ; i++ )
+ {
+ SbxVariable* pVar = rPar.Get(i+1);
+ SbxVariable* pNew = new SbxVariable( *pVar );
+ pNew->SetFlag( SBX_WRITE );
+ short index = static_cast< short >(i);
+ if ( bIncIndex )
+ ++index;
+ pArray->Put( pNew, &index );
+ }
+
+ // Array zurueckliefern
+ SbxVariableRef refVar = rPar.Get(0);
+ USHORT nFlags = refVar->GetFlags();
+ refVar->ResetFlag( SBX_FIXED );
+ refVar->PutObject( pArray );
+ refVar->SetFlags( nFlags );
+ refVar->SetParameters( NULL );
+}
+
+
+// Featurewunsch #57868
+// Die Funktion liefert ein Variant-Array, wenn keine Parameter angegeben
+// werden, wird ein leeres Array erzeugt (entsprechend dim a(), entspricht
+// einer Sequence der Laenge 0 in Uno).
+// Wenn Parameter angegeben sind, wird fuer jeden eine Dimension erzeugt
+// DimArray( 2, 2, 4 ) entspricht DIM a( 2, 2, 4 )
+// Das Array ist immer vom Typ Variant
+RTLFUNC(DimArray)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ SbxDimArray * pArray = new SbxDimArray( SbxVARIANT );
+ USHORT nArrayDims = rPar.Count() - 1;
+ if( nArrayDims > 0 )
+ {
+ for( USHORT i = 0; i < nArrayDims ; i++ )
+ {
+ INT32 ub = rPar.Get(i+1)->GetLong();
+ if( ub < 0 )
+ {
+ StarBASIC::Error( SbERR_OUT_OF_RANGE );
+ ub = 0;
+ }
+ pArray->AddDim32( 0, ub );
+ }
+ }
+ else
+ pArray->unoAddDim( 0, -1 );
+
+ // Array zurueckliefern
+ SbxVariableRef refVar = rPar.Get(0);
+ USHORT nFlags = refVar->GetFlags();
+ refVar->ResetFlag( SBX_FIXED );
+ refVar->PutObject( pArray );
+ refVar->SetFlags( nFlags );
+ refVar->SetParameters( NULL );
+}
+
+/*
+ * FindObject und FindPropertyObject ermoeglichen es,
+ * Objekte und Properties vom Typ Objekt zur Laufzeit
+ * ueber ihren Namen als String-Parameter anzusprechen.
+ *
+ * Bsp.:
+ * MyObj.Prop1.Bla = 5
+ *
+ * entspricht:
+ * dim ObjVar as Object
+ * dim ObjProp as Object
+ * ObjName$ = "MyObj"
+ * ObjVar = FindObject( ObjName$ )
+ * PropName$ = "Prop1"
+ * ObjProp = FindPropertyObject( ObjVar, PropName$ )
+ * ObjProp.Bla = 5
+ *
+ * Dabei koennen die Namen zur Laufzeit dynamisch
+ * erzeugt werden und, so dass z.B. ueber Controls
+ * "TextEdit1" bis "TextEdit5" in einem Dialog in
+ * einer Schleife iteriert werden kann.
+ */
+
+// Objekt ueber den Namen ansprechen
+// 1. Parameter = Name des Objekts als String
+RTLFUNC(FindObject)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // Wir brauchen einen Parameter
+ if ( rPar.Count() < 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // 1. Parameter ist der Name
+ String aNameStr = rPar.Get(1)->GetString();
+
+ // Basic-Suchfunktion benutzen
+ SbxBase* pFind = StarBASIC::FindSBXInCurrentScope( aNameStr );
+ SbxObject* pFindObj = NULL;
+ if( pFind )
+ pFindObj = PTR_CAST(SbxObject,pFind);
+ /*
+ if( !pFindObj )
+ {
+ StarBASIC::Error( SbERR_VAR_UNDEFINED );
+ return;
+ }
+ */
+
+ // Objekt zurueckliefern
+ SbxVariableRef refVar = rPar.Get(0);
+ refVar->PutObject( pFindObj );
+}
+
+// Objekt-Property in einem Objekt ansprechen
+// 1. Parameter = Objekt
+// 2. Parameter = Name der Property als String
+RTLFUNC(FindPropertyObject)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // Wir brauchen 2 Parameter
+ if ( rPar.Count() < 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // 1. Parameter holen, muss Objekt sein
+ SbxBase* pObjVar = (SbxObject*)rPar.Get(1)->GetObject();
+ SbxObject* pObj = NULL;
+ if( pObjVar )
+ pObj = PTR_CAST(SbxObject,pObjVar);
+ if( !pObj && pObjVar && pObjVar->ISA(SbxVariable) )
+ {
+ SbxBase* pObjVarObj = ((SbxVariable*)pObjVar)->GetObject();
+ pObj = PTR_CAST(SbxObject,pObjVarObj);
+ }
+ /*
+ if( !pObj )
+ {
+ StarBASIC::Error( SbERR_VAR_UNDEFINED );
+ return;
+ }
+ */
+
+ // 2. Parameter ist der Name
+ String aNameStr = rPar.Get(2)->GetString();
+
+ // Jetzt muss ein Objekt da sein, sonst Error
+ SbxObject* pFindObj = NULL;
+ if( pObj )
+ {
+ // Im Objekt nach Objekt suchen
+ SbxVariable* pFindVar = pObj->Find( aNameStr, SbxCLASS_OBJECT );
+ pFindObj = PTR_CAST(SbxObject,pFindVar);
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_PARAMETER );
+
+ // Objekt zurueckliefern
+ SbxVariableRef refVar = rPar.Get(0);
+ refVar->PutObject( pFindObj );
+}
+
+
+
+BOOL lcl_WriteSbxVariable( const SbxVariable& rVar, SvStream* pStrm,
+ BOOL bBinary, short nBlockLen, BOOL bIsArray )
+{
+ ULONG nFPos = pStrm->Tell();
+
+ BOOL bIsVariant = !rVar.IsFixed();
+ SbxDataType eType = rVar.GetType();
+
+ switch( eType )
+ {
+ case SbxBOOL:
+ case SbxCHAR:
+ case SbxBYTE:
+ if( bIsVariant )
+ *pStrm << (USHORT)SbxBYTE; // VarType Id
+ *pStrm << rVar.GetByte();
+ break;
+
+ case SbxEMPTY:
+ case SbxNULL:
+ case SbxVOID:
+ case SbxINTEGER:
+ case SbxUSHORT:
+ case SbxINT:
+ case SbxUINT:
+ if( bIsVariant )
+ *pStrm << (USHORT)SbxINTEGER; // VarType Id
+ *pStrm << rVar.GetInteger();
+ break;
+
+ case SbxLONG:
+ case SbxULONG:
+ case SbxLONG64:
+ case SbxULONG64:
+ if( bIsVariant )
+ *pStrm << (USHORT)SbxLONG; // VarType Id
+ *pStrm << rVar.GetLong();
+ break;
+
+ case SbxSINGLE:
+ if( bIsVariant )
+ *pStrm << (USHORT)eType; // VarType Id
+ *pStrm << rVar.GetSingle();
+ break;
+
+ case SbxDOUBLE:
+ case SbxCURRENCY:
+ case SbxDATE:
+ if( bIsVariant )
+ *pStrm << (USHORT)eType; // VarType Id
+ *pStrm << rVar.GetDouble();
+ break;
+
+ case SbxSTRING:
+ case SbxLPSTR:
+ {
+ const String& rStr = rVar.GetString();
+ if( !bBinary || bIsArray )
+ {
+ if( bIsVariant )
+ *pStrm << (USHORT)SbxSTRING;
+ pStrm->WriteByteString( rStr, gsl_getSystemTextEncoding() );
+ //*pStrm << rStr;
+ }
+ else
+ {
+ // ohne Laengenangabe! ohne Endekennung!
+ // What does that mean for Unicode?! Choosing conversion to ByteString...
+ ByteString aByteStr( rStr, gsl_getSystemTextEncoding() );
+ *pStrm << (const char*)aByteStr.GetBuffer();
+ //*pStrm << (const char*)rStr.GetStr();
+ }
+ }
+ break;
+
+ default:
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return FALSE;
+ }
+
+ if( nBlockLen )
+ pStrm->Seek( nFPos + nBlockLen );
+ return pStrm->GetErrorCode() ? FALSE : TRUE;
+}
+
+BOOL lcl_ReadSbxVariable( SbxVariable& rVar, SvStream* pStrm,
+ BOOL bBinary, short nBlockLen, BOOL bIsArray )
+{
+ (void)bBinary;
+ (void)bIsArray;
+
+ double aDouble;
+
+ ULONG nFPos = pStrm->Tell();
+
+ BOOL bIsVariant = !rVar.IsFixed();
+ SbxDataType eVarType = rVar.GetType();
+
+ SbxDataType eSrcType = eVarType;
+ if( bIsVariant )
+ {
+ USHORT nTemp;
+ *pStrm >> nTemp;
+ eSrcType = (SbxDataType)nTemp;
+ }
+
+ switch( eSrcType )
+ {
+ case SbxBOOL:
+ case SbxCHAR:
+ case SbxBYTE:
+ {
+ BYTE aByte;
+ *pStrm >> aByte;
+ rVar.PutByte( aByte );
+ }
+ break;
+
+ case SbxEMPTY:
+ case SbxNULL:
+ case SbxVOID:
+ case SbxINTEGER:
+ case SbxUSHORT:
+ case SbxINT:
+ case SbxUINT:
+ {
+ INT16 aInt;
+ *pStrm >> aInt;
+ rVar.PutInteger( aInt );
+ }
+ break;
+
+ case SbxLONG:
+ case SbxULONG:
+ case SbxLONG64:
+ case SbxULONG64:
+ {
+ INT32 aInt;
+ *pStrm >> aInt;
+ rVar.PutLong( aInt );
+ }
+ break;
+
+ case SbxSINGLE:
+ {
+ float nS;
+ *pStrm >> nS;
+ rVar.PutSingle( nS );
+ }
+ break;
+
+ case SbxDOUBLE:
+ case SbxCURRENCY:
+ {
+ *pStrm >> aDouble;
+ rVar.PutDouble( aDouble );
+ }
+ break;
+
+ case SbxDATE:
+ {
+ *pStrm >> aDouble;
+ rVar.PutDate( aDouble );
+ }
+ break;
+
+ case SbxSTRING:
+ case SbxLPSTR:
+ {
+ String aStr;
+ pStrm->ReadByteString( aStr, gsl_getSystemTextEncoding() );
+ rVar.PutString( aStr );
+ }
+ break;
+
+ default:
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return FALSE;
+ }
+
+ if( nBlockLen )
+ pStrm->Seek( nFPos + nBlockLen );
+ return pStrm->GetErrorCode() ? FALSE : TRUE;
+}
+
+
+// nCurDim = 1...n
+BOOL lcl_WriteReadSbxArray( SbxDimArray& rArr, SvStream* pStrm,
+ BOOL bBinary, short nCurDim, short* pOtherDims, BOOL bWrite )
+{
+ DBG_ASSERT( nCurDim > 0,"Bad Dim");
+ short nLower, nUpper;
+ if( !rArr.GetDim( nCurDim, nLower, nUpper ) )
+ return FALSE;
+ for( short nCur = nLower; nCur <= nUpper; nCur++ )
+ {
+ pOtherDims[ nCurDim-1 ] = nCur;
+ if( nCurDim != 1 )
+ lcl_WriteReadSbxArray(rArr, pStrm, bBinary, nCurDim-1, pOtherDims, bWrite);
+ else
+ {
+ SbxVariable* pVar = rArr.Get( (const short*)pOtherDims );
+ BOOL bRet;
+ if( bWrite )
+ bRet = lcl_WriteSbxVariable(*pVar, pStrm, bBinary, 0, TRUE );
+ else
+ bRet = lcl_ReadSbxVariable(*pVar, pStrm, bBinary, 0, TRUE );
+ if( !bRet )
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void PutGet( SbxArray& rPar, BOOL bPut )
+{
+ // Wir brauchen 3 Parameter
+ if ( rPar.Count() != 4 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nFileNo = rPar.Get(1)->GetInteger();
+ SbxVariable* pVar2 = rPar.Get(2);
+ BOOL bHasRecordNo = (BOOL)(pVar2->GetType() != SbxEMPTY);
+ long nRecordNo = pVar2->GetLong();
+ if ( nFileNo < 1 || ( bHasRecordNo && nRecordNo < 1 ) )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ nRecordNo--; // wir moegen's ab 0!
+ SbiIoSystem* pIO = pINST->GetIoSystem();
+ SbiStream* pSbStrm = pIO->GetStream( nFileNo );
+ // das File muss Random (feste Record-Laenge) oder Binary sein
+ if ( !pSbStrm || !(pSbStrm->GetMode() & (SBSTRM_BINARY | SBSTRM_RANDOM)) )
+ {
+ StarBASIC::Error( SbERR_BAD_CHANNEL );
+ return;
+ }
+
+ SvStream* pStrm = pSbStrm->GetStrm();
+ BOOL bRandom = pSbStrm->IsRandom();
+ short nBlockLen = bRandom ? pSbStrm->GetBlockLen() : 0;
+
+ if( bPut )
+ {
+ // Datei aufplustern, falls jemand uebers Dateiende hinaus geseekt hat
+ pSbStrm->ExpandFile();
+ }
+
+ // auf die Startposition seeken
+ if( bHasRecordNo )
+ {
+ ULONG nFilePos = bRandom ? (ULONG)(nBlockLen*nRecordNo) : (ULONG)nRecordNo;
+ pStrm->Seek( nFilePos );
+ }
+
+ SbxDimArray* pArr = 0;
+ SbxVariable* pVar = rPar.Get(3);
+ if( pVar->GetType() & SbxARRAY )
+ {
+ SbxBase* pParObj = pVar->GetObject();
+ pArr = PTR_CAST(SbxDimArray,pParObj);
+ }
+
+ BOOL bRet;
+
+ if( pArr )
+ {
+ ULONG nFPos = pStrm->Tell();
+ short nDims = pArr->GetDims();
+ short* pDims = new short[ nDims ];
+ bRet = lcl_WriteReadSbxArray(*pArr,pStrm,!bRandom,nDims,pDims,bPut);
+ delete [] pDims;
+ if( nBlockLen )
+ pStrm->Seek( nFPos + nBlockLen );
+ }
+ else
+ {
+ if( bPut )
+ bRet = lcl_WriteSbxVariable(*pVar, pStrm, !bRandom, nBlockLen, FALSE);
+ else
+ bRet = lcl_ReadSbxVariable(*pVar, pStrm, !bRandom, nBlockLen, FALSE);
+ }
+ if( !bRet || pStrm->GetErrorCode() )
+ StarBASIC::Error( SbERR_IO_ERROR );
+}
+
+RTLFUNC(Put)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ PutGet( rPar, TRUE );
+}
+
+RTLFUNC(Get)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ PutGet( rPar, FALSE );
+}
+
+RTLFUNC(Environ)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ String aResult;
+ // sollte ANSI sein, aber unter Win16 in DLL nicht moeglich
+#if defined(WIN)
+ LPSTR lpszEnv = GetDOSEnvironment();
+ String aCompareStr( rPar.Get(1)->GetString() );
+ aCompareStr += '=';
+ const char* pCompare = aCompareStr.GetStr();
+ int nCompareLen = aCompareStr.Len();
+ while ( *lpszEnv )
+ {
+ // Es werden alle EnvString in der Form ENV=VAL 0-terminiert
+ // aneinander gehaengt.
+
+ if ( strnicmp( pCompare, lpszEnv, nCompareLen ) == 0 )
+ {
+ aResult = (const char*)(lpszEnv+nCompareLen);
+ rPar.Get(0)->PutString( aResult );
+ return;
+ }
+ lpszEnv += lstrlen( lpszEnv ) + 1; // Next Enviroment-String
+ }
+#else
+ ByteString aByteStr( rPar.Get(1)->GetString(), gsl_getSystemTextEncoding() );
+ const char* pEnvStr = getenv( aByteStr.GetBuffer() );
+ if ( pEnvStr )
+ aResult = String::CreateFromAscii( pEnvStr );
+#endif
+ rPar.Get(0)->PutString( aResult );
+}
+
+static double GetDialogZoomFactor( BOOL bX, long nValue )
+{
+ OutputDevice* pDevice = Application::GetDefaultDevice();
+ double nResult = 0;
+ if( pDevice )
+ {
+ Size aRefSize( nValue, nValue );
+#ifndef WIN
+ Fraction aFracX( 1, 26 );
+#else
+ Fraction aFracX( 1, 23 );
+#endif
+ Fraction aFracY( 1, 24 );
+ MapMode aMap( MAP_APPFONT, Point(), aFracX, aFracY );
+ Size aScaledSize = pDevice->LogicToPixel( aRefSize, aMap );
+ aRefSize = pDevice->LogicToPixel( aRefSize, MapMode(MAP_TWIP) );
+
+ double nRef, nScaled;
+ if( bX )
+ {
+ nRef = aRefSize.Width();
+ nScaled = aScaledSize.Width();
+ }
+ else
+ {
+ nRef = aRefSize.Height();
+ nScaled = aScaledSize.Height();
+ }
+ nResult = nScaled / nRef;
+ }
+ return nResult;
+}
+
+
+RTLFUNC(GetDialogZoomFactorX)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ rPar.Get(0)->PutDouble( GetDialogZoomFactor( TRUE, rPar.Get(1)->GetLong() ));
+}
+
+RTLFUNC(GetDialogZoomFactorY)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ rPar.Get(0)->PutDouble( GetDialogZoomFactor( FALSE, rPar.Get(1)->GetLong()));
+}
+
+
+RTLFUNC(EnableReschedule)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutEmpty();
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ if( pINST )
+ pINST->EnableReschedule( rPar.Get(1)->GetBool() );
+}
+
+RTLFUNC(GetSystemTicks)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 1 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ rPar.Get(0)->PutLong( Time::GetSystemTicks() );
+}
+
+RTLFUNC(GetPathSeparator)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 1 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ rPar.Get(0)->PutString( DirEntry::GetAccessDelimiter() );
+}
+
+RTLFUNC(ResolvePath)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() == 2 )
+ {
+ String aStr = rPar.Get(1)->GetString();
+ DirEntry aEntry( aStr );
+ //if( aEntry.IsVirtual() )
+ //aStr = aEntry.GetRealPathFromVirtualURL();
+ rPar.Get(0)->PutString( aStr );
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(TypeLen)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxDataType eType = rPar.Get(1)->GetType();
+ INT16 nLen = 0;
+ switch( eType )
+ {
+ case SbxEMPTY:
+ case SbxNULL:
+ case SbxVECTOR:
+ case SbxARRAY:
+ case SbxBYREF:
+ case SbxVOID:
+ case SbxHRESULT:
+ case SbxPOINTER:
+ case SbxDIMARRAY:
+ case SbxCARRAY:
+ case SbxUSERDEF:
+ nLen = 0;
+ break;
+
+ case SbxINTEGER:
+ case SbxERROR:
+ case SbxUSHORT:
+ case SbxINT:
+ case SbxUINT:
+ nLen = 2;
+ break;
+
+ case SbxLONG:
+ case SbxSINGLE:
+ case SbxULONG:
+ nLen = 4;
+ break;
+
+ case SbxDOUBLE:
+ case SbxCURRENCY:
+ case SbxDATE:
+ case SbxLONG64:
+ case SbxULONG64:
+ nLen = 8;
+ break;
+
+ case SbxOBJECT:
+ case SbxVARIANT:
+ case SbxDATAOBJECT:
+ nLen = 0;
+ break;
+
+ case SbxCHAR:
+ case SbxBYTE:
+ case SbxBOOL:
+ nLen = 1;
+ break;
+
+ case SbxLPSTR:
+ case SbxLPWSTR:
+ case SbxCoreSTRING:
+ case SbxSTRING:
+ nLen = (INT16)rPar.Get(1)->GetString().Len();
+ break;
+
+ default:
+ nLen = 0;
+ }
+ rPar.Get(0)->PutInteger( nLen );
+ }
+}
+
+
+// Uno-Struct eines beliebigen Typs erzeugen
+// 1. Parameter == Klassename, weitere Parameter zur Initialisierung
+RTLFUNC(CreateUnoStruct)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ RTL_Impl_CreateUnoStruct( pBasic, rPar, bWrite );
+}
+
+// Uno-Service erzeugen
+// 1. Parameter == Service-Name
+RTLFUNC(CreateUnoService)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ RTL_Impl_CreateUnoService( pBasic, rPar, bWrite );
+}
+
+RTLFUNC(CreateUnoServiceWithArguments)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ RTL_Impl_CreateUnoServiceWithArguments( pBasic, rPar, bWrite );
+}
+
+
+RTLFUNC(CreateUnoValue)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ RTL_Impl_CreateUnoValue( pBasic, rPar, bWrite );
+}
+
+
+// ServiceManager liefern (keine Parameter)
+RTLFUNC(GetProcessServiceManager)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ RTL_Impl_GetProcessServiceManager( pBasic, rPar, bWrite );
+}
+
+// PropertySet erzeugen
+// 1. Parameter == Sequence<PropertyValue>
+RTLFUNC(CreatePropertySet)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ RTL_Impl_CreatePropertySet( pBasic, rPar, bWrite );
+}
+
+// Abfragen, ob ein Interface unterstuetzt wird
+// Mehrere Interface-Namen als Parameter
+RTLFUNC(HasUnoInterfaces)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ RTL_Impl_HasInterfaces( pBasic, rPar, bWrite );
+}
+
+// Abfragen, ob ein Basic-Objekt ein Uno-Struct repraesentiert
+RTLFUNC(IsUnoStruct)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ RTL_Impl_IsUnoStruct( pBasic, rPar, bWrite );
+}
+
+// Abfragen, ob zwei Uno-Objekte identisch sind
+RTLFUNC(EqualUnoObjects)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ RTL_Impl_EqualUnoObjects( pBasic, rPar, bWrite );
+}
+
+// Instanciate "com.sun.star.awt.UnoControlDialog" on basis
+// of a DialogLibrary entry: Convert from XML-ByteSequence
+// and attach events. Implemented in classes\eventatt.cxx
+void RTL_Impl_CreateUnoDialog( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite );
+
+RTLFUNC(CreateUnoDialog)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ RTL_Impl_CreateUnoDialog( pBasic, rPar, bWrite );
+}
+
+// Return the application standard lib as root scope
+RTLFUNC(GlobalScope)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ SbxObject* p = pBasic;
+ while( p->GetParent() )
+ p = p->GetParent();
+
+ SbxVariableRef refVar = rPar.Get(0);
+ refVar->PutObject( p );
+}
+
+// Helper functions to convert Url from/to system paths
+RTLFUNC(ConvertToUrl)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() == 2 )
+ {
+ String aStr = rPar.Get(1)->GetString();
+ INetURLObject aURLObj( aStr, INET_PROT_FILE );
+ ::rtl::OUString aFileURL = aURLObj.GetMainURL( INetURLObject::NO_DECODE );
+ if( !aFileURL.getLength() )
+ ::osl::File::getFileURLFromSystemPath( aFileURL, aFileURL );
+ if( !aFileURL.getLength() )
+ aFileURL = aStr;
+ rPar.Get(0)->PutString( String(aFileURL) );
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(ConvertFromUrl)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() == 2 )
+ {
+ String aStr = rPar.Get(1)->GetString();
+ ::rtl::OUString aSysPath;
+ ::osl::File::getSystemPathFromFileURL( aStr, aSysPath );
+ if( !aSysPath.getLength() )
+ aSysPath = aStr;
+ rPar.Get(0)->PutString( String(aSysPath) );
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+
+// Provide DefaultContext
+RTLFUNC(GetDefaultContext)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ RTL_Impl_GetDefaultContext( pBasic, rPar, bWrite );
+}
+
+
+RTLFUNC(Join)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ USHORT nParCount = rPar.Count();
+ if ( nParCount != 3 && nParCount != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ SbxBase* pParObj = rPar.Get(1)->GetObject();
+ SbxDimArray* pArr = PTR_CAST(SbxDimArray,pParObj);
+ if( pArr )
+ {
+ if( pArr->GetDims() != 1 )
+ StarBASIC::Error( SbERR_WRONG_DIMS ); // Syntax Error?!
+
+ String aDelim;
+ if( nParCount == 3 )
+ aDelim = rPar.Get(2)->GetString();
+ else
+ aDelim = String::CreateFromAscii( " " );
+
+ String aRetStr;
+ short nLower, nUpper;
+ pArr->GetDim( 1, nLower, nUpper );
+ for( short i = nLower ; i <= nUpper ; ++i )
+ {
+ String aStr = pArr->Get( &i )->GetString();
+ aRetStr += aStr;
+ if( i != nUpper )
+ aRetStr += aDelim;
+ }
+ rPar.Get(0)->PutString( aRetStr );
+ }
+ else
+ StarBASIC::Error( SbERR_MUST_HAVE_DIMS );
+}
+
+
+RTLFUNC(Split)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ USHORT nParCount = rPar.Count();
+ if ( nParCount < 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ String aExpression = rPar.Get(1)->GetString();
+ short nArraySize = 0;
+ StringVector vRet;
+ if( aExpression.Len() )
+ {
+ String aDelim;
+ if( nParCount >= 3 )
+ aDelim = rPar.Get(2)->GetString();
+ else
+ aDelim = String::CreateFromAscii( " " );
+
+ INT32 nCount = -1;
+ if( nParCount == 4 )
+ nCount = rPar.Get(3)->GetLong();
+
+ xub_StrLen nDelimLen = aDelim.Len();
+ if( nDelimLen )
+ {
+ xub_StrLen iSearch = STRING_NOTFOUND;
+ xub_StrLen iStart = 0;
+ do
+ {
+ bool bBreak = false;
+ if( nCount >= 0 && nArraySize == nCount - 1 )
+ bBreak = true;
+
+ iSearch = aExpression.Search( aDelim, iStart );
+ String aSubStr;
+ if( iSearch != STRING_NOTFOUND && !bBreak )
+ {
+ aSubStr = aExpression.Copy( iStart, iSearch - iStart );
+ iStart = iSearch + nDelimLen;
+ }
+ else
+ {
+ aSubStr = aExpression.Copy( iStart );
+ }
+ vRet.push_back( aSubStr );
+ nArraySize++;
+
+ if( bBreak )
+ break;
+ }
+ while( iSearch != STRING_NOTFOUND );
+ }
+ else
+ {
+ vRet.push_back( aExpression );
+ nArraySize = 1;
+ }
+ }
+
+ SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
+ pArray->unoAddDim( 0, nArraySize-1 );
+
+ // Parameter ins Array uebernehmen
+ for( short i = 0 ; i < nArraySize ; i++ )
+ {
+ SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
+ xVar->PutString( vRet[i] );
+ pArray->Put( (SbxVariable*)xVar, &i );
+ }
+
+ // Array zurueckliefern
+ SbxVariableRef refVar = rPar.Get(0);
+ USHORT nFlags = refVar->GetFlags();
+ refVar->ResetFlag( SBX_FIXED );
+ refVar->PutObject( pArray );
+ refVar->SetFlags( nFlags );
+ refVar->SetParameters( NULL );
+}
+
+// MonthName(month[, abbreviate])
+RTLFUNC(MonthName)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ USHORT nParCount = rPar.Count();
+ if( nParCount != 2 && nParCount != 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ Reference< XCalendar > xCalendar = getLocaleCalendar();
+ if( !xCalendar.is() )
+ {
+ StarBASIC::Error( SbERR_INTERNAL_ERROR );
+ return;
+ }
+ Sequence< CalendarItem > aMonthSeq = xCalendar->getMonths();
+ sal_Int32 nMonthCount = aMonthSeq.getLength();
+
+ INT16 nVal = rPar.Get(1)->GetInteger();
+ if( nVal < 1 || nVal > nMonthCount )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ BOOL bAbbreviate = false;
+ if( nParCount == 3 )
+ bAbbreviate = rPar.Get(2)->GetBool();
+
+ const CalendarItem* pCalendarItems = aMonthSeq.getConstArray();
+ const CalendarItem& rItem = pCalendarItems[nVal - 1];
+
+ ::rtl::OUString aRetStr = ( bAbbreviate ? rItem.AbbrevName : rItem.FullName );
+ rPar.Get(0)->PutString( String(aRetStr) );
+}
+
+// WeekdayName(weekday, abbreviate, firstdayofweek)
+RTLFUNC(WeekdayName)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ USHORT nParCount = rPar.Count();
+ if( nParCount < 2 || nParCount > 4 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ Reference< XCalendar > xCalendar = getLocaleCalendar();
+ if( !xCalendar.is() )
+ {
+ StarBASIC::Error( SbERR_INTERNAL_ERROR );
+ return;
+ }
+
+ Sequence< CalendarItem > aDaySeq = xCalendar->getDays();
+ INT16 nDayCount = (INT16)aDaySeq.getLength();
+ INT16 nDay = rPar.Get(1)->GetInteger();
+ INT16 nFirstDay = 0;
+ if( nParCount == 4 )
+ {
+ nFirstDay = rPar.Get(3)->GetInteger();
+ if( nFirstDay < 0 || nFirstDay > 7 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ }
+ if( nFirstDay == 0 )
+ nFirstDay = INT16( xCalendar->getFirstDayOfWeek() + 1 );
+
+ nDay = 1 + (nDay + nDayCount + nFirstDay - 2) % nDayCount;
+ if( nDay < 1 || nDay > nDayCount )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ BOOL bAbbreviate = false;
+ if( nParCount >= 3 )
+ {
+ SbxVariable* pPar2 = rPar.Get(2);
+ if( !pPar2->IsErr() )
+ bAbbreviate = pPar2->GetBool();
+ }
+
+ const CalendarItem* pCalendarItems = aDaySeq.getConstArray();
+ const CalendarItem& rItem = pCalendarItems[nDay - 1];
+
+ ::rtl::OUString aRetStr = ( bAbbreviate ? rItem.AbbrevName : rItem.FullName );
+ rPar.Get(0)->PutString( String(aRetStr) );
+}
+
+INT16 implGetWeekDay( double aDate, bool bFirstDayParam = false, INT16 nFirstDay = 0 )
+{
+ Date aRefDate( 1,1,1900 );
+ long nDays = (long) aDate;
+ nDays -= 2; // normieren: 1.1.1900 => 0
+ aRefDate += nDays;
+ DayOfWeek aDay = aRefDate.GetDayOfWeek();
+ INT16 nDay;
+ if ( aDay != SUNDAY )
+ nDay = (INT16)aDay + 2;
+ else
+ nDay = 1; // 1==Sonntag
+
+ // #117253 Optional 2. parameter "firstdayofweek"
+ if( bFirstDayParam )
+ {
+ if( nFirstDay < 0 || nFirstDay > 7 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return 0;
+ }
+ if( nFirstDay == 0 )
+ {
+ Reference< XCalendar > xCalendar = getLocaleCalendar();
+ if( !xCalendar.is() )
+ {
+ StarBASIC::Error( SbERR_INTERNAL_ERROR );
+ return 0;
+ }
+ nFirstDay = INT16( xCalendar->getFirstDayOfWeek() + 1 );
+ }
+ nDay = 1 + (nDay + 7 - nFirstDay) % 7;
+ }
+ return nDay;
+}
+
+RTLFUNC(Weekday)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ USHORT nParCount = rPar.Count();
+ if ( nParCount < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double aDate = rPar.Get(1)->GetDate();
+
+ bool bFirstDay = false;
+ INT16 nFirstDay = 0;
+ if ( nParCount > 2 )
+ {
+ nFirstDay = rPar.Get(2)->GetInteger();
+ bFirstDay = true;
+ }
+ INT16 nDay = implGetWeekDay( aDate, bFirstDay, nFirstDay );
+ rPar.Get(0)->PutInteger( nDay );
+ }
+}
+
+
+enum Interval
+{
+ INTERVAL_NONE,
+ INTERVAL_YYYY,
+ INTERVAL_Q,
+ INTERVAL_M,
+ INTERVAL_Y,
+ INTERVAL_D,
+ INTERVAL_W,
+ INTERVAL_WW,
+ INTERVAL_H,
+ INTERVAL_N,
+ INTERVAL_S
+};
+
+struct IntervalInfo
+{
+ Interval meInterval;
+ const char* mpStringCode;
+ double mdValue;
+ bool mbSimple;
+
+ IntervalInfo( Interval eInterval, const char* pStringCode, double dValue, bool bSimple )
+ : meInterval( eInterval )
+ , mpStringCode( pStringCode )
+ , mdValue( dValue )
+ , mbSimple( bSimple )
+ {}
+};
+
+static IntervalInfo pIntervalTable[] =
+{
+ IntervalInfo( INTERVAL_YYYY, "yyyy", 0.0, false ), // Year
+ IntervalInfo( INTERVAL_Q, "q", 0.0, false ), // Quarter
+ IntervalInfo( INTERVAL_M, "m", 0.0, false ), // Month
+ IntervalInfo( INTERVAL_Y, "y", 1.0, true ), // Day of year
+ IntervalInfo( INTERVAL_D, "d", 1.0, true ), // Day
+ IntervalInfo( INTERVAL_W, "w", 1.0, true ), // Weekday
+ IntervalInfo( INTERVAL_WW, "ww", 7.0, true ), // Week
+ IntervalInfo( INTERVAL_H, "h", (1.0 / 24.0), true ), // Hour
+ IntervalInfo( INTERVAL_N, "n", (1.0 / 1440.0), true), // Minute
+ IntervalInfo( INTERVAL_S, "s", (1.0 / 86400.0), true ), // Second
+ IntervalInfo( INTERVAL_NONE, NULL, 0.0, false )
+};
+
+IntervalInfo* getIntervalInfo( const String& rStringCode )
+{
+ IntervalInfo* pInfo = NULL;
+ INT16 i = 0;
+ while( (pInfo = pIntervalTable + i)->mpStringCode != NULL )
+ {
+ if( rStringCode.EqualsIgnoreCaseAscii( pInfo->mpStringCode ) )
+ break;
+ i++;
+ }
+ return pInfo;
+}
+
+// From methods.cxx
+BOOL implDateSerial( INT16 nYear, INT16 nMonth, INT16 nDay, double& rdRet );
+INT16 implGetDateDay( double aDate );
+INT16 implGetDateMonth( double aDate );
+INT16 implGetDateYear( double aDate );
+
+INT16 implGetHour( double dDate );
+INT16 implGetMinute( double dDate );
+INT16 implGetSecond( double dDate );
+
+
+inline void implGetDayMonthYear( INT16& rnYear, INT16& rnMonth, INT16& rnDay, double dDate )
+{
+ rnDay = implGetDateDay( dDate );
+ rnMonth = implGetDateMonth( dDate );
+ rnYear = implGetDateYear( dDate );
+}
+
+inline INT16 limitToINT16( INT32 n32 )
+{
+ if( n32 > 32767 )
+ n32 = 32767;
+ else if( n32 < -32768 )
+ n32 = -32768;
+ return (INT16)n32;
+}
+
+RTLFUNC(DateAdd)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ USHORT nParCount = rPar.Count();
+ if( nParCount != 4 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ String aStringCode = rPar.Get(1)->GetString();
+ IntervalInfo* pInfo = getIntervalInfo( aStringCode );
+ if( !pInfo )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ INT32 lNumber = rPar.Get(2)->GetLong();
+ double dDate = rPar.Get(3)->GetDate();
+ double dNewDate = 0;
+ if( pInfo->mbSimple )
+ {
+ double dAdd = pInfo->mdValue * lNumber;
+ dNewDate = dDate + dAdd;
+ }
+ else
+ {
+ // Keep hours, minutes, seconds
+ double dHoursMinutesSeconds = dDate - floor( dDate );
+
+ BOOL bOk = TRUE;
+ INT16 nYear, nMonth, nDay;
+ INT16 nTargetYear16 = 0, nTargetMonth = 0;
+ implGetDayMonthYear( nYear, nMonth, nDay, dDate );
+ switch( pInfo->meInterval )
+ {
+ case INTERVAL_YYYY:
+ {
+ INT32 nTargetYear = lNumber + nYear;
+ nTargetYear16 = limitToINT16( nTargetYear );
+ nTargetMonth = nMonth;
+ bOk = implDateSerial( nTargetYear16, nTargetMonth, nDay, dNewDate );
+ break;
+ }
+ case INTERVAL_Q:
+ case INTERVAL_M:
+ {
+ bool bNeg = (lNumber < 0);
+ if( bNeg )
+ lNumber = -lNumber;
+ INT32 nYearsAdd;
+ INT16 nMonthAdd;
+ if( pInfo->meInterval == INTERVAL_Q )
+ {
+ nYearsAdd = lNumber / 4;
+ nMonthAdd = (INT16)( 3 * (lNumber % 4) );
+ }
+ else
+ {
+ nYearsAdd = lNumber / 12;
+ nMonthAdd = (INT16)( lNumber % 12 );
+ }
+
+ INT32 nTargetYear;
+ if( bNeg )
+ {
+ nTargetMonth = nMonth - nMonthAdd;
+ if( nTargetMonth <= 0 )
+ {
+ nTargetMonth += 12;
+ nYearsAdd++;
+ }
+ nTargetYear = (INT32)nYear - nYearsAdd;
+ }
+ else
+ {
+ nTargetMonth = nMonth + nMonthAdd;
+ if( nTargetMonth > 12 )
+ {
+ nTargetMonth -= 12;
+ nYearsAdd++;
+ }
+ nTargetYear = (INT32)nYear + nYearsAdd;
+ }
+ nTargetYear16 = limitToINT16( nTargetYear );
+ bOk = implDateSerial( nTargetYear16, nTargetMonth, nDay, dNewDate );
+ break;
+ }
+ default: break;
+ }
+
+ if( bOk )
+ {
+ // Overflow?
+ INT16 nNewYear, nNewMonth, nNewDay;
+ implGetDayMonthYear( nNewYear, nNewMonth, nNewDay, dNewDate );
+ if( nNewYear > 9999 || nNewYear < 100 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nCorrectionDay = nDay;
+ while( nNewMonth > nTargetMonth )
+ {
+ nCorrectionDay--;
+ implDateSerial( nTargetYear16, nTargetMonth, nCorrectionDay, dNewDate );
+ implGetDayMonthYear( nNewYear, nNewMonth, nNewDay, dNewDate );
+ }
+ dNewDate += dHoursMinutesSeconds;
+ }
+ }
+
+ rPar.Get(0)->PutDate( dNewDate );
+}
+
+inline double RoundImpl( double d )
+{
+ return ( d >= 0 ) ? floor( d + 0.5 ) : -floor( -d + 0.5 );
+}
+
+RTLFUNC(DateDiff)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // DateDiff(interval, date1, date2[, firstdayofweek[, firstweekofyear]])
+
+ USHORT nParCount = rPar.Count();
+ if( nParCount < 4 || nParCount > 6 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ String aStringCode = rPar.Get(1)->GetString();
+ IntervalInfo* pInfo = getIntervalInfo( aStringCode );
+ if( !pInfo )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ double dDate1 = rPar.Get(2)->GetDate();
+ double dDate2 = rPar.Get(3)->GetDate();
+
+ double dRet = 0.0;
+ switch( pInfo->meInterval )
+ {
+ case INTERVAL_YYYY:
+ {
+ INT16 nYear1 = implGetDateYear( dDate1 );
+ INT16 nYear2 = implGetDateYear( dDate2 );
+ dRet = nYear2 - nYear1;
+ break;
+ }
+ case INTERVAL_Q:
+ {
+ INT16 nYear1 = implGetDateYear( dDate1 );
+ INT16 nYear2 = implGetDateYear( dDate2 );
+ INT16 nQ1 = 1 + (implGetDateMonth( dDate1 ) - 1) / 3;
+ INT16 nQ2 = 1 + (implGetDateMonth( dDate2 ) - 1) / 3;
+ INT16 nQGes1 = 4 * nYear1 + nQ1;
+ INT16 nQGes2 = 4 * nYear2 + nQ2;
+ dRet = nQGes2 - nQGes1;
+ break;
+ }
+ case INTERVAL_M:
+ {
+ INT16 nYear1 = implGetDateYear( dDate1 );
+ INT16 nYear2 = implGetDateYear( dDate2 );
+ INT16 nMonth1 = implGetDateMonth( dDate1 );
+ INT16 nMonth2 = implGetDateMonth( dDate2 );
+ INT16 nMonthGes1 = 12 * nYear1 + nMonth1;
+ INT16 nMonthGes2 = 12 * nYear2 + nMonth2;
+ dRet = nMonthGes2 - nMonthGes1;
+ break;
+ }
+ case INTERVAL_Y:
+ case INTERVAL_D:
+ {
+ double dDays1 = floor( dDate1 );
+ double dDays2 = floor( dDate2 );
+ dRet = dDays2 - dDays1;
+ break;
+ }
+ case INTERVAL_W:
+ case INTERVAL_WW:
+ {
+ double dDays1 = floor( dDate1 );
+ double dDays2 = floor( dDate2 );
+ if( pInfo->meInterval == INTERVAL_WW )
+ {
+ INT16 nFirstDay = 1; // Default
+ if( nParCount >= 5 )
+ {
+ nFirstDay = rPar.Get(4)->GetInteger();
+ if( nFirstDay < 0 || nFirstDay > 7 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ if( nFirstDay == 0 )
+ {
+ Reference< XCalendar > xCalendar = getLocaleCalendar();
+ if( !xCalendar.is() )
+ {
+ StarBASIC::Error( SbERR_INTERNAL_ERROR );
+ return;
+ }
+ nFirstDay = INT16( xCalendar->getFirstDayOfWeek() + 1 );
+ }
+ }
+ INT16 nDay1 = implGetWeekDay( dDate1 );
+ INT16 nDay1_Diff = nDay1 - nFirstDay;
+ if( nDay1_Diff < 0 )
+ nDay1_Diff += 7;
+ dDays1 -= nDay1_Diff;
+
+ INT16 nDay2 = implGetWeekDay( dDate2 );
+ INT16 nDay2_Diff = nDay2 - nFirstDay;
+ if( nDay2_Diff < 0 )
+ nDay2_Diff += 7;
+ dDays2 -= nDay2_Diff;
+ }
+
+ double dDiff = dDays2 - dDays1;
+ dRet = ( dDiff >= 0 ) ? floor( dDiff / 7.0 ) : -floor( -dDiff / 7.0 );
+ break;
+ }
+ case INTERVAL_H:
+ {
+ double dFactor = 24.0;
+ dRet = RoundImpl( dFactor * (dDate2 - dDate1) );
+ break;
+ }
+ case INTERVAL_N:
+ {
+ double dFactor =1440.0;
+ dRet = RoundImpl( dFactor * (dDate2 - dDate1) );
+ break;
+ }
+ case INTERVAL_S:
+ {
+ double dFactor = 86400.0;
+ dRet = RoundImpl( dFactor * (dDate2 - dDate1) );
+ break;
+ }
+ case INTERVAL_NONE:
+ break;
+ }
+ rPar.Get(0)->PutDouble( dRet );
+}
+
+double implGetDateOfFirstDayInFirstWeek
+ ( INT16 nYear, INT16& nFirstDay, INT16& nFirstWeek, bool* pbError = NULL )
+{
+ SbError nError = 0;
+ if( nFirstDay < 0 || nFirstDay > 7 )
+ nError = SbERR_BAD_ARGUMENT;
+
+ if( nFirstWeek < 0 || nFirstWeek > 3 )
+ nError = SbERR_BAD_ARGUMENT;
+
+ Reference< XCalendar > xCalendar;
+ if( nFirstDay == 0 || nFirstWeek == 0 )
+ {
+ xCalendar = getLocaleCalendar();
+ if( !xCalendar.is() )
+ nError = SbERR_BAD_ARGUMENT;
+ }
+
+ if( nError != 0 )
+ {
+ StarBASIC::Error( nError );
+ if( pbError )
+ *pbError = true;
+ return 0.0;
+ }
+
+ if( nFirstDay == 0 )
+ nFirstDay = INT16( xCalendar->getFirstDayOfWeek() + 1 );
+
+ INT16 nFirstWeekMinDays = 0; // Not used for vbFirstJan1 = default
+ if( nFirstWeek == 0 )
+ {
+ nFirstWeekMinDays = xCalendar->getMinimumNumberOfDaysForFirstWeek();
+ if( nFirstWeekMinDays == 1 )
+ {
+ nFirstWeekMinDays = 0;
+ nFirstWeek = 1;
+ }
+ else if( nFirstWeekMinDays == 4 )
+ nFirstWeek = 2;
+ else if( nFirstWeekMinDays == 7 )
+ nFirstWeek = 3;
+ }
+ else if( nFirstWeek == 2 )
+ nFirstWeekMinDays = 4; // vbFirstFourDays
+ else if( nFirstWeek == 3 )
+ nFirstWeekMinDays = 7; // vbFirstFourDays
+
+ double dBaseDate;
+ implDateSerial( nYear, 1, 1, dBaseDate );
+ double dRetDate = dBaseDate;
+
+ INT16 nWeekDay0101 = implGetWeekDay( dBaseDate );
+ INT16 nDayDiff = nWeekDay0101 - nFirstDay;
+ if( nDayDiff < 0 )
+ nDayDiff += 7;
+
+ if( nFirstWeekMinDays )
+ {
+ INT16 nThisWeeksDaysInYearCount = 7 - nDayDiff;
+ if( nThisWeeksDaysInYearCount < nFirstWeekMinDays )
+ nDayDiff -= 7;
+ }
+ dRetDate = dBaseDate - nDayDiff;
+ return dRetDate;
+}
+
+RTLFUNC(DatePart)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // DatePart(interval, date[,firstdayofweek[, firstweekofyear]])
+
+ USHORT nParCount = rPar.Count();
+ if( nParCount < 3 || nParCount > 5 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ String aStringCode = rPar.Get(1)->GetString();
+ IntervalInfo* pInfo = getIntervalInfo( aStringCode );
+ if( !pInfo )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ double dDate = rPar.Get(2)->GetDate();
+
+ INT32 nRet = 0;
+ switch( pInfo->meInterval )
+ {
+ case INTERVAL_YYYY:
+ {
+ nRet = implGetDateYear( dDate );
+ break;
+ }
+ case INTERVAL_Q:
+ {
+ nRet = 1 + (implGetDateMonth( dDate ) - 1) / 3;
+ break;
+ }
+ case INTERVAL_M:
+ {
+ nRet = implGetDateMonth( dDate );
+ break;
+ }
+ case INTERVAL_Y:
+ {
+ INT16 nYear = implGetDateYear( dDate );
+ double dBaseDate;
+ implDateSerial( nYear, 1, 1, dBaseDate );
+ nRet = 1 + INT32( dDate - dBaseDate );
+ break;
+ }
+ case INTERVAL_D:
+ {
+ nRet = implGetDateDay( dDate );
+ break;
+ }
+ case INTERVAL_W:
+ {
+ bool bFirstDay = false;
+ INT16 nFirstDay = 1; // Default
+ if( nParCount >= 4 )
+ {
+ nFirstDay = rPar.Get(3)->GetInteger();
+ bFirstDay = true;
+ }
+ nRet = implGetWeekDay( dDate, bFirstDay, nFirstDay );
+ break;
+ }
+ case INTERVAL_WW:
+ {
+ INT16 nFirstDay = 1; // Default
+ if( nParCount >= 4 )
+ nFirstDay = rPar.Get(3)->GetInteger();
+
+ INT16 nFirstWeek = 1; // Default
+ if( nParCount == 5 )
+ nFirstWeek = rPar.Get(4)->GetInteger();
+
+ INT16 nYear = implGetDateYear( dDate );
+ bool bError = false;
+ double dYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear, nFirstDay, nFirstWeek, &bError );
+ if( !bError )
+ {
+ if( dYearFirstDay > dDate )
+ {
+ // Date belongs to last year's week
+ dYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear - 1, nFirstDay, nFirstWeek );
+ }
+ else if( nFirstWeek != 1 )
+ {
+ // Check if date belongs to next year
+ double dNextYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear + 1, nFirstDay, nFirstWeek );
+ if( dDate >= dNextYearFirstDay )
+ dYearFirstDay = dNextYearFirstDay;
+ }
+
+ // Calculate week
+ double dDiff = dDate - dYearFirstDay;
+ nRet = 1 + INT32( dDiff / 7 );
+ }
+ break;
+ }
+ case INTERVAL_H:
+ {
+ nRet = implGetHour( dDate );
+ break;
+ }
+ case INTERVAL_N:
+ {
+ nRet = implGetMinute( dDate );
+ break;
+ }
+ case INTERVAL_S:
+ {
+ nRet = implGetSecond( dDate );
+ break;
+ }
+ case INTERVAL_NONE:
+ break;
+ }
+ rPar.Get(0)->PutLong( nRet );
+}
+
+// FormatDateTime(Date[,NamedFormat])
+RTLFUNC(FormatDateTime)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ USHORT nParCount = rPar.Count();
+ if( nParCount < 2 || nParCount > 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ double dDate = rPar.Get(1)->GetDate();
+ INT16 nNamedFormat = 0;
+ if( nParCount > 2 )
+ {
+ nNamedFormat = rPar.Get(2)->GetInteger();
+ if( nNamedFormat < 0 || nNamedFormat > 4 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ }
+
+ Reference< XCalendar > xCalendar = getLocaleCalendar();
+ if( !xCalendar.is() )
+ {
+ StarBASIC::Error( SbERR_INTERNAL_ERROR );
+ return;
+ }
+
+ String aRetStr;
+ SbxVariableRef pSbxVar = new SbxVariable( SbxSTRING );
+ switch( nNamedFormat )
+ {
+ // GeneralDate:
+ // Display a date and/or time. If there is a date part,
+ // display it as a short date. If there is a time part,
+ // display it as a long time. If present, both parts are displayed.
+
+ // 12/21/2004 11:24:50 AM
+ // 21.12.2004 12:13:51
+ case 0:
+ pSbxVar->PutDate( dDate );
+ aRetStr = pSbxVar->GetString();
+ break;
+
+ // LongDate: Display a date using the long date format specified
+ // in your computer's regional settings.
+ // Tuesday, December 21, 2004
+ // Dienstag, 21. December 2004
+ case 1:
+ {
+ SvNumberFormatter* pFormatter = NULL;
+ if( pINST )
+ pFormatter = pINST->GetNumberFormatter();
+ else
+ {
+ sal_uInt32 n; // Dummy
+ SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n );
+ }
+
+ LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
+ ULONG nIndex = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_LONG, eLangType );
+ Color* pCol;
+ pFormatter->GetOutputString( dDate, nIndex, aRetStr, &pCol );
+
+ if( !pINST )
+ delete pFormatter;
+
+ break;
+ }
+
+ // ShortDate: Display a date using the short date format specified
+ // in your computer's regional settings.
+ // 12/21/2004
+ // 21.12.2004
+ case 2:
+ pSbxVar->PutDate( floor(dDate) );
+ aRetStr = pSbxVar->GetString();
+ break;
+
+ // LongTime: Display a time using the time format specified
+ // in your computer's regional settings.
+ // 11:24:50 AM
+ // 12:13:51
+ case 3:
+ // ShortTime: Display a time using the 24-hour format (hh:mm).
+ // 11:24
+ case 4:
+ double n;
+ double dTime = modf( dDate, &n );
+ pSbxVar->PutDate( dTime );
+ if( nNamedFormat == 3 )
+ aRetStr = pSbxVar->GetString();
+ else
+ aRetStr = pSbxVar->GetString().Copy( 0, 5 );
+ break;
+ }
+
+ rPar.Get(0)->PutString( aRetStr );
+}
+
+RTLFUNC(Round)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ USHORT nParCount = rPar.Count();
+ if( nParCount != 2 && nParCount != 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ SbxVariable *pSbxVariable = rPar.Get(1);
+ double dVal = pSbxVariable->GetDouble();
+ double dRes = 0.0;
+ if( dVal != 0.0 )
+ {
+ bool bNeg = false;
+ if( dVal < 0.0 )
+ {
+ bNeg = true;
+ dVal = -dVal;
+ }
+
+ INT16 numdecimalplaces = 0;
+ if( nParCount == 3 )
+ {
+ numdecimalplaces = rPar.Get(2)->GetInteger();
+ if( numdecimalplaces < 0 || numdecimalplaces > 22 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ }
+
+ if( numdecimalplaces == 0 )
+ {
+ dRes = floor( dVal + 0.5 );
+ }
+ else
+ {
+ double dFactor = pow( 10.0, numdecimalplaces );
+ dVal *= dFactor;
+ dRes = floor( dVal + 0.5 );
+ dRes /= dFactor;
+ }
+
+ if( bNeg )
+ dRes = -dRes;
+ }
+ rPar.Get(0)->PutDouble( dRes );
+}
+
+RTLFUNC(StrReverse)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if ( rPar.Count() != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ SbxVariable *pSbxVariable = rPar.Get(1);
+ if( pSbxVariable->IsNull() )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ String aStr = pSbxVariable->GetString();
+ aStr.Reverse();
+ rPar.Get(0)->PutString( aStr );
+}
+
+RTLFUNC(CompatibilityMode)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ bool bEnabled = false;
+ USHORT nCount = rPar.Count();
+ if ( nCount != 1 && nCount != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+
+ SbiInstance* pInst = pINST;
+ if( pInst )
+ {
+ if ( nCount == 2 )
+ pInst->EnableCompatibility( rPar.Get(1)->GetBool() );
+
+ bEnabled = pInst->IsCompatibility();
+ }
+ rPar.Get(0)->PutBool( bEnabled );
+}
+
+RTLFUNC(Input)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // 2 parameters needed
+ if ( rPar.Count() < 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ USHORT nByteCount = rPar.Get(1)->GetUShort();
+ INT16 nFileNumber = rPar.Get(2)->GetInteger();
+
+ SbiIoSystem* pIosys = pINST->GetIoSystem();
+ SbiStream* pSbStrm = pIosys->GetStream( nFileNumber );
+ if ( !pSbStrm || !(pSbStrm->GetMode() & (SBSTRM_BINARY | SBSTRM_INPUT)) )
+ {
+ StarBASIC::Error( SbERR_BAD_CHANNEL );
+ return;
+ }
+
+ ByteString aByteBuffer;
+ SbError err = pSbStrm->Read( aByteBuffer, nByteCount, true );
+ if( !err )
+ err = pIosys->GetError();
+
+ if( err )
+ {
+ StarBASIC::Error( err );
+ return;
+ }
+ rPar.Get(0)->PutString( String( aByteBuffer, gsl_getSystemTextEncoding() ) );
+}
+
+// #115824
+RTLFUNC(Me)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ SbModule* pActiveModule = pINST->GetActiveModule();
+ SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pActiveModule);
+ SbxVariableRef refVar = rPar.Get(0);
+ if( pClassModuleObject == NULL )
+ {
+ SbObjModule* pMod = PTR_CAST(SbObjModule,pActiveModule);
+ if ( pMod )
+ refVar->PutObject( pMod );
+ else
+ StarBASIC::Error( SbERR_INVALID_USAGE_OBJECT );
+ }
+ else
+ refVar->PutObject( pClassModuleObject );
+}
+
diff --git a/basic/source/runtime/props.cxx b/basic/source/runtime/props.cxx
new file mode 100644
index 000000000000..663d12fbcd72
--- /dev/null
+++ b/basic/source/runtime/props.cxx
@@ -0,0 +1,776 @@
+/*************************************************************************
+ *
+ * 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 "runtime.hxx"
+#include "stdobj.hxx"
+#include "rtlproto.hxx"
+#include "errobject.hxx"
+
+
+// Properties und Methoden legen beim Get (bWrite = FALSE) den Returnwert
+// im Element 0 des Argv ab; beim Put (bWrite = TRUE) wird der Wert aus
+// Element 0 gespeichert.
+
+RTLFUNC(Erl)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get( 0 )->PutLong( StarBASIC::GetErl() );
+}
+
+RTLFUNC(Err)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ if( SbiRuntime::isVBAEnabled() )
+ {
+ rPar.Get( 0 )->PutObject( SbxErrObject::getErrObject() );
+ }
+ else
+ {
+ if( bWrite )
+ {
+ INT32 nVal = rPar.Get( 0 )->GetLong();
+ if( nVal <= 65535L )
+ StarBASIC::Error( StarBASIC::GetSfxFromVBError( (USHORT) nVal ) );
+ }
+ else
+ rPar.Get( 0 )->PutLong( StarBASIC::GetVBErrorCode( StarBASIC::GetErrBasic() ) );
+ }
+}
+
+RTLFUNC(False)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutBool( FALSE );
+}
+
+RTLFUNC(Empty)
+{
+ (void)pBasic;
+ (void)bWrite;
+ (void)rPar;
+}
+
+RTLFUNC(Nothing)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // liefert eine leere Objekt-Variable.
+ rPar.Get( 0 )->PutObject( NULL );
+}
+
+RTLFUNC(Null)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ // liefert eine leere Objekt-Variable.
+ rPar.Get( 0 )->PutNull();
+}
+
+RTLFUNC(PI)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get( 0 )->PutDouble( F_PI );
+}
+
+RTLFUNC(True)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get( 0 )->PutBool( TRUE );
+}
+
+RTLFUNC(ATTR_NORMAL)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(0);
+}
+RTLFUNC(ATTR_READONLY)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(1);
+}
+RTLFUNC(ATTR_HIDDEN)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(2);
+}
+RTLFUNC(ATTR_SYSTEM)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(4);
+}
+RTLFUNC(ATTR_VOLUME)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(8);
+}
+RTLFUNC(ATTR_DIRECTORY)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(16);
+}
+RTLFUNC(ATTR_ARCHIVE)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(32);
+}
+
+RTLFUNC(V_EMPTY)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(0);
+}
+RTLFUNC(V_NULL)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(1);
+}
+RTLFUNC(V_INTEGER)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(2);
+}
+RTLFUNC(V_LONG)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(3);
+}
+RTLFUNC(V_SINGLE)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(4);
+}
+RTLFUNC(V_DOUBLE)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(5);
+}
+RTLFUNC(V_CURRENCY)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(6);
+}
+RTLFUNC(V_DATE)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(7);
+}
+RTLFUNC(V_STRING)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(8);
+}
+
+RTLFUNC(MB_OK)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(0);
+}
+RTLFUNC(MB_OKCANCEL)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(1);
+}
+RTLFUNC(MB_ABORTRETRYIGNORE)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(2);
+}
+RTLFUNC(MB_YESNOCANCEL)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(3);
+}
+RTLFUNC(MB_YESNO)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(4);
+}
+RTLFUNC(MB_RETRYCANCEL)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(5);
+}
+RTLFUNC(MB_ICONSTOP)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(16);
+}
+RTLFUNC(MB_ICONQUESTION)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(32);
+}
+RTLFUNC(MB_ICONEXCLAMATION)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(48);
+}
+RTLFUNC(MB_ICONINFORMATION)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(64);
+}
+RTLFUNC(MB_DEFBUTTON1)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(0);
+}
+RTLFUNC(MB_DEFBUTTON2)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(256);
+}
+RTLFUNC(MB_DEFBUTTON3)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(512);
+}
+RTLFUNC(MB_APPLMODAL)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(0);
+}
+RTLFUNC(MB_SYSTEMMODAL)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(4096);
+}
+
+RTLFUNC(IDOK)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(1);
+}
+
+RTLFUNC(IDCANCEL)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(2);
+}
+RTLFUNC(IDABORT)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(3);
+}
+RTLFUNC(IDRETRY)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(4);
+}
+RTLFUNC(IDYES)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(6);
+}
+RTLFUNC(IDNO)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(7);
+}
+
+RTLFUNC(CF_TEXT)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(1);
+}
+RTLFUNC(CF_BITMAP)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(2);
+}
+RTLFUNC(CF_METAFILEPICT)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(3);
+}
+
+RTLFUNC(TYP_AUTHORFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(7);
+}
+RTLFUNC(TYP_CHAPTERFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(4);
+}
+RTLFUNC(TYP_CONDTXTFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(27);
+}
+RTLFUNC(TYP_DATEFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(0);
+}
+RTLFUNC(TYP_DBFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(19);
+}
+RTLFUNC(TYP_DBNAMEFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(3);
+}
+RTLFUNC(TYP_DBNEXTSETFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(24);
+}
+RTLFUNC(TYP_DBNUMSETFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(25);
+}
+RTLFUNC(TYP_DBSETNUMBERFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(26);
+}
+RTLFUNC(TYP_DDEFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(14);
+}
+RTLFUNC(TYP_DOCINFOFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(18);
+}
+RTLFUNC(TYP_DOCSTATFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(6);
+}
+RTLFUNC(TYP_EXTUSERFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(30);
+}
+RTLFUNC(TYP_FILENAMEFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(2);
+}
+RTLFUNC(TYP_FIXDATEFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(31);
+}
+RTLFUNC(TYP_FIXTIMEFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(32);
+}
+RTLFUNC(TYP_FORMELFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(10);
+}
+RTLFUNC(TYP_GETFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(9);
+}
+RTLFUNC(TYP_GETREFFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(13);
+}
+RTLFUNC(TYP_HIDDENPARAFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(17);
+}
+RTLFUNC(TYP_HIDDENTXTFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(11);
+}
+RTLFUNC(TYP_INPUTFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(16);
+}
+RTLFUNC(TYP_MACROFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(15);
+}
+RTLFUNC(TYP_NEXTPAGEFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(28);
+}
+RTLFUNC(TYP_PAGENUMBERFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(5);
+}
+RTLFUNC(TYP_POSTITFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(21);
+}
+RTLFUNC(TYP_PREVPAGEFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(29);
+}
+RTLFUNC(TYP_SEQFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(23);
+}
+RTLFUNC(TYP_SETFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(8);
+}
+RTLFUNC(TYP_SETINPFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(33);
+}
+RTLFUNC(TYP_SETREFFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(12);
+}
+RTLFUNC(TYP_TEMPLNAMEFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(22);
+}
+RTLFUNC(TYP_TIMEFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(1);
+}
+RTLFUNC(TYP_USERFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(20);
+}
+RTLFUNC(TYP_USRINPFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(34);
+}
+RTLFUNC(TYP_SETREFPAGEFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(35);
+}
+RTLFUNC(TYP_GETREFPAGEFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(36);
+}
+RTLFUNC(TYP_INTERNETFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(37);
+}
+
+RTLFUNC(SET_ON)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(1);
+}
+RTLFUNC(SET_OFF)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(0);
+}
+RTLFUNC(TOGGLE)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(2);
+}
+
+RTLFUNC(FRAMEANCHORPAGE)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(1);
+}
+RTLFUNC(FRAMEANCHORPARA)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(14);
+}
+RTLFUNC(FRAMEANCHORCHAR)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(15);
+}
+
+RTLFUNC(CLEAR_ALLTABS)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(2);
+}
+RTLFUNC(CLEAR_TAB)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(1);
+}
+RTLFUNC(SET_TAB)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(0);
+}
+
+RTLFUNC(LINEPROP)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(0);
+}
+RTLFUNC(LINE_1)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(1);
+}
+RTLFUNC(LINE_15)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(2);
+}
+RTLFUNC(LINE_2)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(3);
+}
+
+RTLFUNC(TYP_JUMPEDITFLD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ rPar.Get(0)->PutInteger(38);
+}
+
+
diff --git a/basic/source/runtime/rtlproto.hxx b/basic/source/runtime/rtlproto.hxx
new file mode 100644
index 000000000000..5437654f69a0
--- /dev/null
+++ b/basic/source/runtime/rtlproto.hxx
@@ -0,0 +1,349 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include <basic/sbstar.hxx>
+
+#define RTLFUNC( name ) void SbRtl_##name( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite )
+#define RTLNAME( name ) &SbRtl_##name
+
+typedef void( *RtlCall ) ( StarBASIC* p, SbxArray& rArgs, BOOL bWrite );
+
+// Properties
+
+extern RTLFUNC(Date);
+extern RTLFUNC(Err);
+extern RTLFUNC(Erl);
+extern RTLFUNC(False);
+extern RTLFUNC(Empty);
+extern RTLFUNC(Nothing);
+extern RTLFUNC(Null);
+extern RTLFUNC(True);
+
+extern RTLFUNC(ATTR_NORMAL);
+extern RTLFUNC(ATTR_READONLY);
+extern RTLFUNC(ATTR_HIDDEN);
+extern RTLFUNC(ATTR_SYSTEM);
+extern RTLFUNC(ATTR_VOLUME);
+extern RTLFUNC(ATTR_DIRECTORY);
+extern RTLFUNC(ATTR_ARCHIVE);
+
+extern RTLFUNC(V_EMPTY);
+extern RTLFUNC(V_NULL);
+extern RTLFUNC(V_INTEGER);
+extern RTLFUNC(V_LONG);
+extern RTLFUNC(V_SINGLE);
+extern RTLFUNC(V_DOUBLE);
+extern RTLFUNC(V_CURRENCY);
+extern RTLFUNC(V_DATE);
+extern RTLFUNC(V_STRING);
+
+extern RTLFUNC(MB_OK);
+extern RTLFUNC(MB_OKCANCEL);
+extern RTLFUNC(MB_ABORTRETRYIGNORE);
+extern RTLFUNC(MB_YESNOCANCEL);
+extern RTLFUNC(MB_YESNO);
+extern RTLFUNC(MB_RETRYCANCEL);
+extern RTLFUNC(MB_ICONSTOP);
+extern RTLFUNC(MB_ICONQUESTION);
+extern RTLFUNC(MB_ICONEXCLAMATION);
+extern RTLFUNC(MB_ICONINFORMATION);
+extern RTLFUNC(MB_DEFBUTTON1);
+extern RTLFUNC(MB_DEFBUTTON2);
+extern RTLFUNC(MB_DEFBUTTON3);
+extern RTLFUNC(MB_APPLMODAL);
+extern RTLFUNC(MB_SYSTEMMODAL);
+
+extern RTLFUNC(IDOK);
+extern RTLFUNC(IDCANCEL);
+extern RTLFUNC(IDABORT);
+extern RTLFUNC(IDRETRY);
+extern RTLFUNC(IDYES);
+extern RTLFUNC(IDNO);
+
+extern RTLFUNC(CF_TEXT);
+extern RTLFUNC(CF_BITMAP);
+extern RTLFUNC(CF_METAFILEPICT);
+
+extern RTLFUNC(PI);
+
+extern RTLFUNC(SET_OFF);
+extern RTLFUNC(SET_ON);
+extern RTLFUNC(TOGGLE);
+
+extern RTLFUNC(TYP_AUTHORFLD);
+extern RTLFUNC(TYP_CHAPTERFLD);
+extern RTLFUNC(TYP_CONDTXTFLD);
+extern RTLFUNC(TYP_DATEFLD);
+extern RTLFUNC(TYP_DBFLD);
+extern RTLFUNC(TYP_DBNAMEFLD);
+extern RTLFUNC(TYP_DBNEXTSETFLD);
+extern RTLFUNC(TYP_DBNUMSETFLD);
+extern RTLFUNC(TYP_DBSETNUMBERFLD);
+extern RTLFUNC(TYP_DDEFLD);
+extern RTLFUNC(TYP_DOCINFOFLD);
+extern RTLFUNC(TYP_DOCSTATFLD);
+extern RTLFUNC(TYP_EXTUSERFLD);
+extern RTLFUNC(TYP_FILENAMEFLD);
+extern RTLFUNC(TYP_FIXDATEFLD);
+extern RTLFUNC(TYP_FIXTIMEFLD);
+extern RTLFUNC(TYP_FORMELFLD);
+extern RTLFUNC(TYP_GETFLD);
+extern RTLFUNC(TYP_GETREFFLD);
+extern RTLFUNC(TYP_HIDDENPARAFLD);
+extern RTLFUNC(TYP_HIDDENTXTFLD);
+extern RTLFUNC(TYP_INPUTFLD);
+extern RTLFUNC(TYP_MACROFLD);
+extern RTLFUNC(TYP_NEXTPAGEFLD);
+extern RTLFUNC(TYP_PAGENUMBERFLD);
+extern RTLFUNC(TYP_POSTITFLD);
+extern RTLFUNC(TYP_PREVPAGEFLD);
+extern RTLFUNC(TYP_SEQFLD);
+extern RTLFUNC(TYP_SETFLD);
+extern RTLFUNC(TYP_SETINPFLD);
+extern RTLFUNC(TYP_SETREFFLD);
+extern RTLFUNC(TYP_TEMPLNAMEFLD);
+extern RTLFUNC(TYP_TIMEFLD);
+extern RTLFUNC(TYP_USERFLD);
+extern RTLFUNC(TYP_USRINPFLD);
+extern RTLFUNC(TYP_SETREFPAGEFLD);
+extern RTLFUNC(TYP_GETREFPAGEFLD);
+extern RTLFUNC(TYP_INTERNETFLD);
+extern RTLFUNC(TYP_JUMPEDITFLD);
+
+extern RTLFUNC(FRAMEANCHORPAGE);
+extern RTLFUNC(FRAMEANCHORPARA);
+extern RTLFUNC(FRAMEANCHORCHAR);
+
+extern RTLFUNC(CLEAR_ALLTABS);
+extern RTLFUNC(CLEAR_TAB);
+extern RTLFUNC(SET_TAB);
+
+extern RTLFUNC(LINEPROP);
+extern RTLFUNC(LINE_1);
+extern RTLFUNC(LINE_15);
+extern RTLFUNC(LINE_2);
+
+// Methoden
+
+extern RTLFUNC(CreateObject);
+extern RTLFUNC(Error);
+extern RTLFUNC(Sin);
+extern RTLFUNC(Abs);
+extern RTLFUNC(Asc);
+extern RTLFUNC(Atn);
+extern RTLFUNC(Chr);
+extern RTLFUNC(Cos);
+extern RTLFUNC(CurDir);
+extern RTLFUNC(ChDir); // JSM
+extern RTLFUNC(ChDrive); // JSM
+extern RTLFUNC(FileCopy); // JSM
+extern RTLFUNC(Kill); // JSM
+extern RTLFUNC(MkDir); // JSM
+extern RTLFUNC(RmDir); // JSM
+extern RTLFUNC(SendKeys); // JSM
+extern RTLFUNC(DimArray);
+extern RTLFUNC(Dir);
+extern RTLFUNC(DoEvents);
+extern RTLFUNC(Exp);
+extern RTLFUNC(FileLen);
+extern RTLFUNC(Fix);
+extern RTLFUNC(Hex);
+extern RTLFUNC(Input);
+extern RTLFUNC(InStr);
+extern RTLFUNC(InStrRev);
+extern RTLFUNC(Int);
+extern RTLFUNC(Join);
+extern RTLFUNC(LCase);
+extern RTLFUNC(Left);
+extern RTLFUNC(Log);
+extern RTLFUNC(LTrim);
+extern RTLFUNC(Mid);
+extern RTLFUNC(Oct);
+extern RTLFUNC(Replace);
+extern RTLFUNC(Right);
+extern RTLFUNC(RTrim);
+extern RTLFUNC(RTL);
+extern RTLFUNC(Sgn);
+extern RTLFUNC(Space);
+extern RTLFUNC(Split);
+extern RTLFUNC(Sqr);
+extern RTLFUNC(Str);
+extern RTLFUNC(StrComp);
+extern RTLFUNC(String);
+extern RTLFUNC(StrReverse);
+extern RTLFUNC(Tan);
+extern RTLFUNC(UCase);
+extern RTLFUNC(Val);
+extern RTLFUNC(Len);
+extern RTLFUNC(Spc);
+extern RTLFUNC(DateSerial);
+extern RTLFUNC(TimeSerial);
+extern RTLFUNC(DateValue);
+extern RTLFUNC(TimeValue);
+extern RTLFUNC(Day);
+extern RTLFUNC(Hour);
+extern RTLFUNC(Minute);
+extern RTLFUNC(Month);
+extern RTLFUNC(MonthName);
+extern RTLFUNC(Now);
+extern RTLFUNC(Second);
+extern RTLFUNC(Time);
+extern RTLFUNC(Timer);
+extern RTLFUNC(Weekday);
+extern RTLFUNC(WeekdayName);
+extern RTLFUNC(Year);
+extern RTLFUNC(Date);
+extern RTLFUNC(InputBox);
+extern RTLFUNC(Me);
+extern RTLFUNC(MsgBox);
+extern RTLFUNC(IsArray);
+extern RTLFUNC(IsDate);
+extern RTLFUNC(IsEmpty);
+extern RTLFUNC(IsError);
+extern RTLFUNC(IsNull);
+extern RTLFUNC(IsNumeric);
+extern RTLFUNC(IsObject);
+extern RTLFUNC(IsUnoStruct);
+
+extern RTLFUNC(FileDateTime);
+extern RTLFUNC(Format);
+extern RTLFUNC(GetAttr);
+extern RTLFUNC(Randomize); // JSM
+extern RTLFUNC(Round);
+extern RTLFUNC(Rnd);
+extern RTLFUNC(Shell);
+extern RTLFUNC(VarType);
+extern RTLFUNC(TypeName);
+extern RTLFUNC(TypeLen);
+
+extern RTLFUNC(EOF);
+extern RTLFUNC(FileAttr);
+extern RTLFUNC(Loc);
+extern RTLFUNC(Lof);
+extern RTLFUNC(Seek);
+extern RTLFUNC(SetAttr); // JSM
+extern RTLFUNC(Reset); // JSM
+
+extern RTLFUNC(DDEInitiate);
+extern RTLFUNC(DDETerminate);
+extern RTLFUNC(DDETerminateAll);
+extern RTLFUNC(DDERequest);
+extern RTLFUNC(DDEExecute);
+extern RTLFUNC(DDEPoke);
+
+extern RTLFUNC(FreeFile);
+extern RTLFUNC(IsMissing);
+extern RTLFUNC(LBound);
+extern RTLFUNC(UBound);
+extern RTLFUNC(RGB);
+extern RTLFUNC(QBColor);
+extern RTLFUNC(StrConv);
+
+extern RTLFUNC(Beep);
+
+extern RTLFUNC(Load);
+extern RTLFUNC(Unload);
+extern RTLFUNC(AboutStarBasic);
+extern RTLFUNC(LoadPicture);
+extern RTLFUNC(SavePicture);
+
+extern RTLFUNC(CBool); // JSM
+extern RTLFUNC(CByte); // JSM
+extern RTLFUNC(CCur); // JSM
+extern RTLFUNC(CDate); // JSM
+extern RTLFUNC(CDbl); // JSM
+extern RTLFUNC(CInt); // JSM
+extern RTLFUNC(CLng); // JSM
+extern RTLFUNC(CSng); // JSM
+extern RTLFUNC(CStr); // JSM
+extern RTLFUNC(CVar); // JSM
+extern RTLFUNC(CVErr); // JSM
+
+extern RTLFUNC(Iif); // JSM
+
+extern RTLFUNC(DumpAllObjects);
+
+extern RTLFUNC(GetSystemType);
+extern RTLFUNC(GetGUIType);
+extern RTLFUNC(Red);
+extern RTLFUNC(Green);
+extern RTLFUNC(Blue);
+
+extern RTLFUNC(Switch);
+extern RTLFUNC(Wait);
+//i#64882# add new WaitUntil
+extern RTLFUNC(WaitUntil);
+
+extern RTLFUNC(GetGUIVersion);
+extern RTLFUNC(Choose);
+extern RTLFUNC(Trim);
+
+extern RTLFUNC(DateAdd);
+extern RTLFUNC(DateDiff);
+extern RTLFUNC(DatePart);
+extern RTLFUNC(FormatDateTime);
+extern RTLFUNC(GetSolarVersion);
+extern RTLFUNC(TwipsPerPixelX);
+extern RTLFUNC(TwipsPerPixelY);
+extern RTLFUNC(FreeLibrary);
+extern RTLFUNC(Array);
+extern RTLFUNC(FindObject);
+extern RTLFUNC(FindPropertyObject);
+extern RTLFUNC(EnableReschedule);
+
+extern RTLFUNC(Put);
+extern RTLFUNC(Get);
+extern RTLFUNC(Environ);
+extern RTLFUNC(GetDialogZoomFactorX);
+extern RTLFUNC(GetDialogZoomFactorY);
+extern RTLFUNC(GetSystemTicks);
+extern RTLFUNC(GetPathSeparator);
+extern RTLFUNC(ResolvePath);
+extern RTLFUNC(CreateUnoStruct);
+extern RTLFUNC(CreateUnoService);
+extern RTLFUNC(CreateUnoServiceWithArguments);
+extern RTLFUNC(CreateUnoValue);
+extern RTLFUNC(GetProcessServiceManager);
+extern RTLFUNC(GetDefaultContext);
+extern RTLFUNC(CreatePropertySet);
+extern RTLFUNC(CreateUnoListener);
+extern RTLFUNC(HasUnoInterfaces);
+extern RTLFUNC(EqualUnoObjects);
+extern RTLFUNC(CreateUnoDialog);
+extern RTLFUNC(GlobalScope);
+extern RTLFUNC(FileExists);
+extern RTLFUNC(ConvertToUrl);
+extern RTLFUNC(ConvertFromUrl);
+extern RTLFUNC(CDateToIso);
+extern RTLFUNC(CDateFromIso);
+extern RTLFUNC(CompatibilityMode);
+extern RTLFUNC(CDec);
+
+extern RTLFUNC(Partition); // Fong
+
+extern double Now_Impl();
+extern void Wait_Impl( bool bDurationBased, SbxArray& rPar );
diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx
new file mode 100755
index 000000000000..1bb6fb82e113
--- /dev/null
+++ b/basic/source/runtime/runtime.cxx
@@ -0,0 +1,1268 @@
+/*************************************************************************
+ *
+ * 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/fsys.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/wldcrd.hxx>
+#include <svl/zforlist.hxx>
+#include <unotools/syslocale.hxx>
+#include "runtime.hxx"
+#include "sbintern.hxx"
+#include "opcodes.hxx"
+#include "codegen.hxx"
+#include "iosys.hxx"
+#include "image.hxx"
+#include "ddectrl.hxx"
+#include "dllmgr.hxx"
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include "sbunoobj.hxx"
+#include "errobject.hxx"
+#include "sbtrace.hxx"
+
+using namespace ::com::sun::star;
+
+bool SbiRuntime::isVBAEnabled()
+{
+ bool result = false;
+ SbiInstance* pInst = pINST;
+ if ( pInst && pINST->pRun )
+ result = pInst->pRun->bVBAEnabled;
+ return result;
+}
+
+// #91147 Global reschedule flag
+static BOOL bStaticGlobalEnableReschedule = TRUE;
+
+void StarBASIC::StaticEnableReschedule( BOOL bReschedule )
+{
+ bStaticGlobalEnableReschedule = bReschedule;
+}
+void StarBASIC::SetVBAEnabled( BOOL bEnabled )
+{
+ if ( bDocBasic )
+ {
+ bVBAEnabled = bEnabled;
+ }
+}
+
+BOOL StarBASIC::isVBAEnabled()
+{
+ if ( bDocBasic )
+ {
+ if( SbiRuntime::isVBAEnabled() )
+ return TRUE;
+ return bVBAEnabled;
+ }
+ return FALSE;
+}
+
+
+struct SbiArgvStack { // Argv stack:
+ SbiArgvStack* pNext; // Stack Chain
+ SbxArrayRef refArgv; // Argv
+ short nArgc; // Argc
+};
+
+SbiRuntime::pStep0 SbiRuntime::aStep0[] = { // Alle Opcodes ohne Operanden
+ &SbiRuntime::StepNOP,
+ &SbiRuntime::StepEXP,
+ &SbiRuntime::StepMUL,
+ &SbiRuntime::StepDIV,
+ &SbiRuntime::StepMOD,
+ &SbiRuntime::StepPLUS,
+ &SbiRuntime::StepMINUS,
+ &SbiRuntime::StepNEG,
+ &SbiRuntime::StepEQ,
+ &SbiRuntime::StepNE,
+ &SbiRuntime::StepLT,
+ &SbiRuntime::StepGT,
+ &SbiRuntime::StepLE,
+ &SbiRuntime::StepGE,
+ &SbiRuntime::StepIDIV,
+ &SbiRuntime::StepAND,
+ &SbiRuntime::StepOR,
+ &SbiRuntime::StepXOR,
+ &SbiRuntime::StepEQV,
+ &SbiRuntime::StepIMP,
+ &SbiRuntime::StepNOT,
+ &SbiRuntime::StepCAT,
+
+ &SbiRuntime::StepLIKE,
+ &SbiRuntime::StepIS,
+ // Laden/speichern
+ &SbiRuntime::StepARGC, // neuen Argv einrichten
+ &SbiRuntime::StepARGV, // TOS ==> aktueller Argv
+ &SbiRuntime::StepINPUT, // Input ==> TOS
+ &SbiRuntime::StepLINPUT, // Line Input ==> TOS
+ &SbiRuntime::StepGET, // TOS anfassen
+ &SbiRuntime::StepSET, // Speichern Objekt TOS ==> TOS-1
+ &SbiRuntime::StepPUT, // TOS ==> TOS-1
+ &SbiRuntime::StepPUTC, // TOS ==> TOS-1, dann ReadOnly
+ &SbiRuntime::StepDIM, // DIM
+ &SbiRuntime::StepREDIM, // REDIM
+ &SbiRuntime::StepREDIMP, // REDIM PRESERVE
+ &SbiRuntime::StepERASE, // TOS loeschen
+ // Verzweigen
+ &SbiRuntime::StepSTOP, // Programmende
+ &SbiRuntime::StepINITFOR, // FOR-Variable initialisieren
+ &SbiRuntime::StepNEXT, // FOR-Variable inkrementieren
+ &SbiRuntime::StepCASE, // Anfang CASE
+ &SbiRuntime::StepENDCASE, // Ende CASE
+ &SbiRuntime::StepSTDERROR, // Standard-Fehlerbehandlung
+ &SbiRuntime::StepNOERROR, // keine Fehlerbehandlung
+ &SbiRuntime::StepLEAVE, // UP verlassen
+ // E/A
+ &SbiRuntime::StepCHANNEL, // TOS = Kanalnummer
+ &SbiRuntime::StepPRINT, // print TOS
+ &SbiRuntime::StepPRINTF, // print TOS in field
+ &SbiRuntime::StepWRITE, // write TOS
+ &SbiRuntime::StepRENAME, // Rename Tos+1 to Tos
+ &SbiRuntime::StepPROMPT, // Input Prompt aus TOS definieren
+ &SbiRuntime::StepRESTART, // Set restart point
+ &SbiRuntime::StepCHANNEL0, // E/A-Kanal 0 einstellen
+ &SbiRuntime::StepEMPTY, // Leeren Ausdruck auf Stack
+ &SbiRuntime::StepERROR, // TOS = Fehlercode
+ &SbiRuntime::StepLSET, // Speichern Objekt TOS ==> TOS-1
+ &SbiRuntime::StepRSET, // Speichern Objekt TOS ==> TOS-1
+ &SbiRuntime::StepREDIMP_ERASE,// Copy array object for REDIMP
+ &SbiRuntime::StepINITFOREACH,// Init for each loop
+ &SbiRuntime::StepVBASET,// vba-like set statement
+ &SbiRuntime::StepERASE_CLEAR,// vba-like set statement
+ &SbiRuntime::StepARRAYACCESS,// access TOS as array
+ &SbiRuntime::StepBYVAL, // access TOS as array
+};
+
+SbiRuntime::pStep1 SbiRuntime::aStep1[] = { // Alle Opcodes mit einem Operanden
+ &SbiRuntime::StepLOADNC, // Laden einer numerischen Konstanten (+ID)
+ &SbiRuntime::StepLOADSC, // Laden einer Stringkonstanten (+ID)
+ &SbiRuntime::StepLOADI, // Immediate Load (+Wert)
+ &SbiRuntime::StepARGN, // Speichern eines named Args in Argv (+StringID)
+ &SbiRuntime::StepPAD, // String auf feste Laenge bringen (+Laenge)
+ // Verzweigungen
+ &SbiRuntime::StepJUMP, // Sprung (+Target)
+ &SbiRuntime::StepJUMPT, // TOS auswerten), bedingter Sprung (+Target)
+ &SbiRuntime::StepJUMPF, // TOS auswerten), bedingter Sprung (+Target)
+ &SbiRuntime::StepONJUMP, // TOS auswerten), Sprung in JUMP-Tabelle (+MaxVal)
+ &SbiRuntime::StepGOSUB, // UP-Aufruf (+Target)
+ &SbiRuntime::StepRETURN, // UP-Return (+0 oder Target)
+ &SbiRuntime::StepTESTFOR, // FOR-Variable testen), inkrementieren (+Endlabel)
+ &SbiRuntime::StepCASETO, // Tos+1 <= Case <= Tos), 2xremove (+Target)
+ &SbiRuntime::StepERRHDL, // Fehler-Handler (+Offset)
+ &SbiRuntime::StepRESUME, // Resume nach Fehlern (+0 or 1 or Label)
+ // E/A
+ &SbiRuntime::StepCLOSE, // (+Kanal/0)
+ &SbiRuntime::StepPRCHAR, // (+char)
+ // Verwaltung
+ &SbiRuntime::StepSETCLASS, // Set + Klassennamen testen (+StringId)
+ &SbiRuntime::StepTESTCLASS, // Check TOS class (+StringId)
+ &SbiRuntime::StepLIB, // Lib fuer Declare-Call (+StringId)
+ &SbiRuntime::StepBASED, // TOS wird um BASE erhoeht, BASE davor gepusht
+ &SbiRuntime::StepARGTYP, // Letzten Parameter in Argv konvertieren (+Typ)
+ &SbiRuntime::StepVBASETCLASS,// vba-like set statement
+};
+
+SbiRuntime::pStep2 SbiRuntime::aStep2[] = {// Alle Opcodes mit zwei Operanden
+ &SbiRuntime::StepRTL, // Laden aus RTL (+StringID+Typ)
+ &SbiRuntime::StepFIND, // Laden (+StringID+Typ)
+ &SbiRuntime::StepELEM, // Laden Element (+StringID+Typ)
+ &SbiRuntime::StepPARAM, // Parameter (+Offset+Typ)
+ // Verzweigen
+ &SbiRuntime::StepCALL, // Declare-Call (+StringID+Typ)
+ &SbiRuntime::StepCALLC, // CDecl-Declare-Call (+StringID+Typ)
+ &SbiRuntime::StepCASEIS, // Case-Test (+Test-Opcode+False-Target)
+ // Verwaltung
+ &SbiRuntime::StepSTMNT, // Beginn eines Statements (+Line+Col)
+ // E/A
+ &SbiRuntime::StepOPEN, // (+SvStreamFlags+Flags)
+ // Objekte
+ &SbiRuntime::StepLOCAL, // Lokale Variable definieren (+StringId+Typ)
+ &SbiRuntime::StepPUBLIC, // Modulglobale Variable (+StringID+Typ)
+ &SbiRuntime::StepGLOBAL, // Globale Variable definieren (+StringID+Typ)
+ &SbiRuntime::StepCREATE, // Objekt kreieren (+StringId+StringId)
+ &SbiRuntime::StepSTATIC, // Statische Variable (+StringId+StringId)
+ &SbiRuntime::StepTCREATE, // User Defined Objekte (+StringId+StringId)
+ &SbiRuntime::StepDCREATE, // Objekt-Array kreieren (+StringID+StringID)
+ &SbiRuntime::StepGLOBAL_P, // Globale Variable definieren, die beim Neustart
+ // von Basic nicht ueberschrieben wird (+StringID+Typ)
+ &SbiRuntime::StepFIND_G, // Sucht globale Variable mit Spezialbehandlung wegen _GLOBAL_P
+ &SbiRuntime::StepDCREATE_REDIMP, // Objekt-Array redimensionieren (+StringID+StringID)
+ &SbiRuntime::StepFIND_CM, // Search inside a class module (CM) to enable global search in time
+ &SbiRuntime::StepPUBLIC_P, // Search inside a class module (CM) to enable global search in time
+ &SbiRuntime::StepFIND_STATIC, // Search inside a class module (CM) to enable global search in time
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+// SbiRTLData //
+//////////////////////////////////////////////////////////////////////////
+
+SbiRTLData::SbiRTLData()
+{
+ pDir = 0;
+ nDirFlags = 0;
+ nCurDirPos = 0;
+ pWildCard = NULL;
+}
+
+SbiRTLData::~SbiRTLData()
+{
+ delete pDir;
+ pDir = 0;
+ delete pWildCard;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// SbiInstance //
+//////////////////////////////////////////////////////////////////////////
+
+// 16.10.96: #31460 Neues Konzept fuer StepInto/Over/Out
+// Die Entscheidung, ob StepPoint aufgerufen werden soll, wird anhand des
+// CallLevels getroffen. Angehalten wird, wenn der aktuelle CallLevel <=
+// nBreakCallLvl ist. Der aktuelle CallLevel kann niemals kleiner als 1
+// sein, da er beim Aufruf einer Methode (auch main) inkrementiert wird.
+// Daher bedeutet ein BreakCallLvl von 0, dass das Programm gar nicht
+// angehalten wird.
+// (siehe auch step2.cxx, SbiRuntime::StepSTMNT() )
+
+// Hilfsfunktion, um den BreakCallLevel gemaess der der Debug-Flags zu ermitteln
+void SbiInstance::CalcBreakCallLevel( USHORT nFlags )
+{
+ // Break-Flag wegfiltern
+ nFlags &= ~((USHORT)SbDEBUG_BREAK);
+
+ USHORT nRet;
+ switch( nFlags )
+ {
+ case SbDEBUG_STEPINTO:
+ nRet = nCallLvl + 1; // CallLevel+1 wird auch angehalten
+ break;
+ case SbDEBUG_STEPOVER | SbDEBUG_STEPINTO:
+ nRet = nCallLvl; // Aktueller CallLevel wird angehalten
+ break;
+ case SbDEBUG_STEPOUT:
+ nRet = nCallLvl - 1; // Kleinerer CallLevel wird angehalten
+ break;
+ case SbDEBUG_CONTINUE:
+ // Basic-IDE liefert 0 statt SbDEBUG_CONTINUE, also auch default=continue
+ default:
+ nRet = 0; // CallLevel ist immer >0 -> kein StepPoint
+ }
+ nBreakCallLvl = nRet; // Ergebnis uebernehmen
+}
+
+SbiInstance::SbiInstance( StarBASIC* p )
+{
+ pBasic = p;
+ pNext = NULL;
+ pRun = NULL;
+ pIosys = new SbiIoSystem;
+ pDdeCtrl = new SbiDdeControl;
+ pDllMgr = 0; // on demand
+ pNumberFormatter = 0; // on demand
+ nCallLvl = 0;
+ nBreakCallLvl = 0;
+ nErr =
+ nErl = 0;
+ bReschedule = TRUE;
+ bCompatibility = FALSE;
+}
+
+SbiInstance::~SbiInstance()
+{
+ while( pRun )
+ {
+ SbiRuntime* p = pRun->pNext;
+ delete pRun;
+ pRun = p;
+ }
+ delete pIosys;
+ delete pDdeCtrl;
+ delete pDllMgr;
+ delete pNumberFormatter;
+
+ try
+ {
+ int nSize = ComponentVector.size();
+ if( nSize )
+ {
+ for( int i = nSize - 1 ; i >= 0 ; --i )
+ {
+ Reference< XComponent > xDlgComponent = ComponentVector[i];
+ if( xDlgComponent.is() )
+ xDlgComponent->dispose();
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_ERROR( "SbiInstance::~SbiInstance: caught an exception while disposing the components!" );
+ }
+
+ ComponentVector.clear();
+}
+
+SbiDllMgr* SbiInstance::GetDllMgr()
+{
+ if( !pDllMgr )
+ pDllMgr = new SbiDllMgr;
+ return pDllMgr;
+}
+
+// #39629 NumberFormatter jetzt ueber statische Methode anlegen
+SvNumberFormatter* SbiInstance::GetNumberFormatter()
+{
+ LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
+ SvtSysLocale aSysLocale;
+ DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
+ if( pNumberFormatter )
+ {
+ if( eLangType != meFormatterLangType ||
+ eDate != meFormatterDateFormat )
+ {
+ delete pNumberFormatter;
+ pNumberFormatter = NULL;
+ }
+ }
+ meFormatterLangType = eLangType;
+ meFormatterDateFormat = eDate;
+ if( !pNumberFormatter )
+ PrepareNumberFormatter( pNumberFormatter, nStdDateIdx, nStdTimeIdx, nStdDateTimeIdx,
+ &meFormatterLangType, &meFormatterDateFormat );
+ return pNumberFormatter;
+}
+
+// #39629 NumberFormatter auch statisch anbieten
+void SbiInstance::PrepareNumberFormatter( SvNumberFormatter*& rpNumberFormatter,
+ sal_uInt32 &rnStdDateIdx, sal_uInt32 &rnStdTimeIdx, sal_uInt32 &rnStdDateTimeIdx,
+ LanguageType* peFormatterLangType, DateFormat* peFormatterDateFormat )
+{
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ xFactory = comphelper::getProcessServiceFactory();
+
+ LanguageType eLangType;
+ if( peFormatterLangType )
+ eLangType = *peFormatterLangType;
+ else
+ eLangType = GetpApp()->GetSettings().GetLanguage();
+
+ DateFormat eDate;
+ if( peFormatterDateFormat )
+ eDate = *peFormatterDateFormat;
+ else
+ {
+ SvtSysLocale aSysLocale;
+ eDate = aSysLocale.GetLocaleData().getDateFormat();
+ }
+
+ rpNumberFormatter = new SvNumberFormatter( xFactory, eLangType );
+
+ xub_StrLen nCheckPos = 0; short nType;
+ rnStdTimeIdx = rpNumberFormatter->GetStandardFormat( NUMBERFORMAT_TIME, eLangType );
+
+ // Standard-Vorlagen des Formatters haben nur zweistellige
+ // Jahreszahl. Deshalb eigenes Format registrieren
+
+ // HACK, da der Numberformatter in PutandConvertEntry die Platzhalter
+ // fuer Monat, Tag, Jahr nicht entsprechend der Systemeinstellung
+ // austauscht. Problem: Print Year(Date) unter engl. BS
+ // siehe auch svtools\source\sbx\sbxdate.cxx
+
+ String aDateStr;
+ switch( eDate )
+ {
+ case MDY: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("MM.TT.JJJJ") ); break;
+ case DMY: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("TT.MM.JJJJ") ); break;
+ case YMD: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("JJJJ.MM.TT") ); break;
+ default: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("MM.TT.JJJJ") );
+ }
+ String aStr( aDateStr );
+ rpNumberFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
+ rnStdDateIdx, LANGUAGE_GERMAN, eLangType );
+ nCheckPos = 0;
+ String aStrHHMMSS( RTL_CONSTASCII_USTRINGPARAM(" HH:MM:SS") );
+ aStr = aDateStr;
+ aStr += aStrHHMMSS;
+ rpNumberFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
+ rnStdDateTimeIdx, LANGUAGE_GERMAN, eLangType );
+}
+
+
+
+// Engine laufenlassen. Falls Flags == SbDEBUG_CONTINUE, Flags uebernehmen
+
+void SbiInstance::Stop()
+{
+ for( SbiRuntime* p = pRun; p; p = p->pNext )
+ p->Stop();
+}
+
+// Allows Basic IDE to set watch mode to suppress errors
+static bool bWatchMode = false;
+
+void setBasicWatchMode( bool bOn )
+{
+ bWatchMode = bOn;
+}
+
+void SbiInstance::Error( SbError n )
+{
+ Error( n, String() );
+}
+
+void SbiInstance::Error( SbError n, const String& rMsg )
+{
+ if( !bWatchMode )
+ {
+ aErrorMsg = rMsg;
+ pRun->Error( n );
+ }
+}
+
+void SbiInstance::ErrorVB( sal_Int32 nVBNumber, const String& rMsg )
+{
+ if( !bWatchMode )
+ {
+ SbError n = StarBASIC::GetSfxFromVBError( static_cast< USHORT >( nVBNumber ) );
+ if ( !n )
+ n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors
+
+ aErrorMsg = rMsg;
+ SbiRuntime::translateErrorToVba( n, aErrorMsg );
+
+ bool bVBATranslationAlreadyDone = true;
+ pRun->Error( SbERR_BASIC_COMPAT, bVBATranslationAlreadyDone );
+ }
+}
+
+void SbiInstance::setErrorVB( sal_Int32 nVBNumber, const String& rMsg )
+{
+ SbError n = StarBASIC::GetSfxFromVBError( static_cast< USHORT >( nVBNumber ) );
+ if( !n )
+ n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors
+
+ aErrorMsg = rMsg;
+ SbiRuntime::translateErrorToVba( n, aErrorMsg );
+
+ nErr = n;
+}
+
+
+void SbiInstance::FatalError( SbError n )
+{
+ pRun->FatalError( n );
+}
+
+void SbiInstance::FatalError( SbError _errCode, const String& _details )
+{
+ pRun->FatalError( _errCode, _details );
+}
+
+void SbiInstance::Abort()
+{
+ // Basic suchen, in dem der Fehler auftrat
+ StarBASIC* pErrBasic = GetCurrentBasic( pBasic );
+ pErrBasic->RTError( nErr, aErrorMsg, pRun->nLine, pRun->nCol1, pRun->nCol2 );
+ pBasic->Stop();
+}
+
+// Hilfsfunktion, um aktives Basic zu finden, kann ungleich pRTBasic sein
+StarBASIC* GetCurrentBasic( StarBASIC* pRTBasic )
+{
+ StarBASIC* pCurBasic = pRTBasic;
+ SbModule* pActiveModule = pRTBasic->GetActiveModule();
+ if( pActiveModule )
+ {
+ SbxObject* pParent = pActiveModule->GetParent();
+ if( pParent && pParent->ISA(StarBASIC) )
+ pCurBasic = (StarBASIC*)pParent;
+ }
+ return pCurBasic;
+}
+
+SbModule* SbiInstance::GetActiveModule()
+{
+ if( pRun )
+ return pRun->GetModule();
+ else
+ return NULL;
+}
+
+SbMethod* SbiInstance::GetCaller( USHORT nLevel )
+{
+ SbiRuntime* p = pRun;
+ while( nLevel-- && p )
+ p = p->pNext;
+ if( p )
+ return p->GetCaller();
+ else
+ return NULL;
+}
+
+SbxArray* SbiInstance::GetLocals( SbMethod* pMeth )
+{
+ SbiRuntime* p = pRun;
+ while( p && p->GetMethod() != pMeth )
+ p = p->pNext;
+ if( p )
+ return p->GetLocals();
+ else
+ return NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// SbiInstance //
+//////////////////////////////////////////////////////////////////////////
+
+// Achtung: pMeth kann auch NULL sein (beim Aufruf des Init-Codes)
+
+SbiRuntime::SbiRuntime( SbModule* pm, SbMethod* pe, UINT32 nStart )
+ : rBasic( *(StarBASIC*)pm->pParent ), pInst( pINST ),
+ pMod( pm ), pMeth( pe ), pImg( pMod->pImage ), m_nLastTime(0)
+{
+ nFlags = pe ? pe->GetDebugFlags() : 0;
+ pIosys = pInst->pIosys;
+ pArgvStk = NULL;
+ pGosubStk = NULL;
+ pForStk = NULL;
+ pError = NULL;
+ pErrCode =
+ pErrStmnt =
+ pRestart = NULL;
+ pNext = NULL;
+ pCode =
+ pStmnt = (const BYTE* ) pImg->GetCode() + nStart;
+ bRun =
+ bError = TRUE;
+ bInError = FALSE;
+ bBlocked = FALSE;
+ nLine = 0;
+ nCol1 = 0;
+ nCol2 = 0;
+ nExprLvl = 0;
+ nArgc = 0;
+ nError = 0;
+ nGosubLvl = 0;
+ nForLvl = 0;
+ nOps = 0;
+ refExprStk = new SbxArray;
+ SetVBAEnabled( pMod->IsVBACompat() );
+#if defined GCC
+ SetParameters( pe ? pe->GetParameters() : (class SbxArray *)NULL );
+#else
+ SetParameters( pe ? pe->GetParameters() : NULL );
+#endif
+ pRefSaveList = NULL;
+ pItemStoreList = NULL;
+}
+
+SbiRuntime::~SbiRuntime()
+{
+ ClearGosubStack();
+ ClearArgvStack();
+ ClearForStack();
+
+ // #74254 Items zum Sichern temporaere Referenzen freigeben
+ ClearRefs();
+ while( pItemStoreList )
+ {
+ RefSaveItem* pToDeleteItem = pItemStoreList;
+ pItemStoreList = pToDeleteItem->pNext;
+ delete pToDeleteItem;
+ }
+}
+
+void SbiRuntime::SetVBAEnabled(bool bEnabled )
+{
+ bVBAEnabled = bEnabled;
+}
+
+// Aufbau der Parameterliste. Alle ByRef-Parameter werden direkt
+// uebernommen; von ByVal-Parametern werden Kopien angelegt. Falls
+// ein bestimmter Datentyp verlangt wird, wird konvertiert.
+
+void SbiRuntime::SetParameters( SbxArray* pParams )
+{
+ refParams = new SbxArray;
+ // fuer den Returnwert
+ refParams->Put( pMeth, 0 );
+
+ SbxInfo* pInfo = pMeth ? pMeth->GetInfo() : NULL;
+ USHORT nParamCount = pParams ? pParams->Count() : 1;
+ if( nParamCount > 1 )
+ {
+ for( USHORT i = 1 ; i < nParamCount ; i++ )
+ {
+ const SbxParamInfo* p = pInfo ? pInfo->GetParam( i ) : NULL;
+
+ // #111897 ParamArray
+ if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 )
+ {
+ SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
+ USHORT nParamArrayParamCount = nParamCount - i;
+ pArray->unoAddDim( 0, nParamArrayParamCount - 1 );
+ for( USHORT j = i ; j < nParamCount ; j++ )
+ {
+ SbxVariable* v = pParams->Get( j );
+ short nDimIndex = j - i;
+ pArray->Put( v, &nDimIndex );
+ }
+ SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT );
+ pArrayVar->SetFlag( SBX_READWRITE );
+ pArrayVar->PutObject( pArray );
+ refParams->Put( pArrayVar, i );
+
+ // Block ParamArray for missing parameter
+ pInfo = NULL;
+ break;
+ }
+
+ SbxVariable* v = pParams->Get( i );
+ // Methoden sind immer byval!
+ BOOL bByVal = v->IsA( TYPE(SbxMethod) );
+ SbxDataType t = v->GetType();
+ if( p )
+ {
+ bByVal |= BOOL( ( p->eType & SbxBYREF ) == 0 );
+ t = (SbxDataType) ( p->eType & 0x0FFF );
+
+ if( !bByVal && t != SbxVARIANT &&
+ (!v->IsFixed() || (SbxDataType)(v->GetType() & 0x0FFF ) != t) )
+ bByVal = TRUE;
+ }
+ if( bByVal )
+ {
+ SbxVariable* v2 = new SbxVariable( t );
+ v2->SetFlag( SBX_READWRITE );
+ *v2 = *v;
+ refParams->Put( v2, i );
+ }
+ else
+ {
+ if( t != SbxVARIANT && t != ( v->GetType() & 0x0FFF ) )
+ {
+ // Array konvertieren??
+ if( p && (p->eType & SbxARRAY) )
+ Error( SbERR_CONVERSION );
+ else
+ v->Convert( t );
+ }
+ refParams->Put( v, i );
+ }
+ if( p )
+ refParams->PutAlias( p->aName, i );
+ }
+ }
+
+ // ParamArray for missing parameter
+ if( pInfo )
+ {
+ // #111897 Check first missing parameter for ParamArray
+ const SbxParamInfo* p = pInfo->GetParam( nParamCount );
+ if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 )
+ {
+ SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
+ pArray->unoAddDim( 0, -1 );
+ SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT );
+ pArrayVar->SetFlag( SBX_READWRITE );
+ pArrayVar->PutObject( pArray );
+ refParams->Put( pArrayVar, nParamCount );
+ }
+ }
+}
+
+
+// Einen P-Code ausfuehren
+
+BOOL SbiRuntime::Step()
+{
+ if( bRun )
+ {
+ // Unbedingt gelegentlich die Kontrolle abgeben!
+ if( !( ++nOps & 0xF ) && pInst->IsReschedule() && bStaticGlobalEnableReschedule )
+ {
+ sal_uInt32 nTime = osl_getGlobalTimer();
+ if (nTime - m_nLastTime > 5 ) // 20 ms
+ {
+ Application::Reschedule();
+ m_nLastTime = nTime;
+ }
+ }
+
+ // #i48868 blocked by next call level?
+ while( bBlocked )
+ {
+ if( pInst->IsReschedule() && bStaticGlobalEnableReschedule )
+ Application::Reschedule();
+ }
+
+#ifdef DBG_TRACE_BASIC
+ UINT32 nPC = ( pCode - (const BYTE* )pImg->GetCode() );
+ dbg_traceStep( pMod, nPC, pINST->nCallLvl );
+#endif
+
+ SbiOpcode eOp = (SbiOpcode ) ( *pCode++ );
+ UINT32 nOp1, nOp2;
+ if( eOp <= SbOP0_END )
+ {
+ (this->*( aStep0[ eOp ] ) )();
+ }
+ else if( eOp >= SbOP1_START && eOp <= SbOP1_END )
+ {
+ nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24;
+
+ (this->*( aStep1[ eOp - SbOP1_START ] ) )( nOp1 );
+ }
+ else if( eOp >= SbOP2_START && eOp <= SbOP2_END )
+ {
+ nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24;
+ nOp2 = *pCode++; nOp2 |= *pCode++ << 8; nOp2 |= *pCode++ << 16; nOp2 |= *pCode++ << 24;
+ (this->*( aStep2[ eOp - SbOP2_START ] ) )( nOp1, nOp2 );
+ }
+ else
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+
+ // SBX-Fehler aufgetreten?
+ SbError nSbError = SbxBase::GetError();
+ Error( ERRCODE_TOERROR(nSbError) ); // Warnings rausfiltern
+
+ // AB 13.2.1997, neues Error-Handling:
+ // ACHTUNG: Hier kann nError auch dann gesetzt sein, wenn !nSbError,
+ // da nError jetzt auch von anderen RT-Instanzen gesetzt werden kann
+
+ if( nError )
+ SbxBase::ResetError();
+
+ // AB,15.3.96: Fehler nur anzeigen, wenn BASIC noch aktiv
+ // (insbesondere nicht nach Compiler-Fehlern zur Laufzeit)
+ if( nError && bRun )
+ {
+#ifdef DBG_TRACE_BASIC
+ SbError nTraceErr = nError;
+ String aTraceErrMsg = GetSbData()->aErrMsg;
+ bool bTraceErrHandled = true;
+#endif
+ SbError err = nError;
+ ClearExprStack();
+ nError = 0;
+ pInst->nErr = err;
+ pInst->nErl = nLine;
+ pErrCode = pCode;
+ pErrStmnt = pStmnt;
+ // An error occured in an error handler
+ // force parent handler ( if there is one )
+ // to handle the error
+ bool bLetParentHandleThis = false;
+
+ // Im Error Handler? Dann Std-Error
+ if ( !bInError )
+ {
+ bInError = TRUE;
+
+ if( !bError ) // On Error Resume Next
+ StepRESUME( 1 );
+ else if( pError ) // On Error Goto ...
+ pCode = pError;
+ else
+ bLetParentHandleThis = true;
+ }
+ else
+ {
+ bLetParentHandleThis = true;
+ pError = NULL; //terminate the handler
+ }
+ if ( bLetParentHandleThis )
+ {
+ // AB 13.2.1997, neues Error-Handling:
+ // Uebergeordnete Error-Handler beruecksichtigen
+
+ // Wir haben keinen Error-Handler -> weiter oben suchen
+ SbiRuntime* pRtErrHdl = NULL;
+ SbiRuntime* pRt = this;
+ while( NULL != (pRt = pRt->pNext) )
+ {
+ // Gibt es einen Error-Handler?
+ if( pRt->bError == FALSE || pRt->pError != NULL )
+ {
+ pRtErrHdl = pRt;
+ break;
+ }
+ }
+
+ // Error-Hdl gefunden?
+ if( pRtErrHdl )
+ {
+ // (Neuen) Error-Stack anlegen
+ SbErrorStack*& rErrStack = GetSbData()->pErrStack;
+ if( rErrStack )
+ delete rErrStack;
+ rErrStack = new SbErrorStack();
+
+ // Alle im Call-Stack darunter stehenden RTs manipulieren
+ pRt = this;
+ do
+ {
+ // Fehler setzen
+ pRt->nError = err;
+ if( pRt != pRtErrHdl )
+ pRt->bRun = FALSE;
+
+ // In Error-Stack eintragen
+ SbErrorStackEntry *pEntry = new SbErrorStackEntry
+ ( pRt->pMeth, pRt->nLine, pRt->nCol1, pRt->nCol2 );
+ rErrStack->C40_INSERT(SbErrorStackEntry, pEntry, rErrStack->Count() );
+
+ // Nach RT mit Error-Handler aufhoeren
+ if( pRt == pRtErrHdl )
+ break;
+ pRt = pRt->pNext;
+ }
+ while( pRt );
+ }
+ // Kein Error-Hdl gefunden -> altes Vorgehen
+ else
+ {
+#ifdef DBG_TRACE_BASIC
+ bTraceErrHandled = false;
+#endif
+ pInst->Abort();
+ }
+
+ // ALT: Nur
+ // pInst->Abort();
+ }
+
+#ifdef DBG_TRACE_BASIC
+ dbg_traceNotifyError( nTraceErr, aTraceErrMsg, bTraceErrHandled, pINST->nCallLvl );
+#endif
+ }
+ }
+ return bRun;
+}
+
+void SbiRuntime::Error( SbError n, bool bVBATranslationAlreadyDone )
+{
+ if( n )
+ {
+ nError = n;
+ if( isVBAEnabled() && !bVBATranslationAlreadyDone )
+ {
+ String aMsg = pInst->GetErrorMsg();
+ sal_Int32 nVBAErrorNumber = translateErrorToVba( nError, aMsg );
+ SbxVariable* pSbxErrObjVar = SbxErrObject::getErrObject();
+ SbxErrObject* pGlobErr = static_cast< SbxErrObject* >( pSbxErrObjVar );
+ if( pGlobErr != NULL )
+ pGlobErr->setNumberAndDescription( nVBAErrorNumber, aMsg );
+
+ pInst->aErrorMsg = aMsg;
+ nError = SbERR_BASIC_COMPAT;
+ }
+ }
+}
+
+void SbiRuntime::Error( SbError _errCode, const String& _details )
+{
+ if ( _errCode )
+ {
+ OSL_ENSURE( pInst->pRun == this, "SbiRuntime::Error: can't propagate the error message details!" );
+ if ( pInst->pRun == this )
+ {
+ pInst->Error( _errCode, _details );
+ OSL_POSTCOND( nError == _errCode, "SbiRuntime::Error: the instance is expecte to propagate the error code back to me!" );
+ }
+ else
+ {
+ nError = _errCode;
+ }
+ }
+}
+
+void SbiRuntime::FatalError( SbError n )
+{
+ StepSTDERROR();
+ Error( n );
+}
+
+void SbiRuntime::FatalError( SbError _errCode, const String& _details )
+{
+ StepSTDERROR();
+ Error( _errCode, _details );
+}
+
+sal_Int32 SbiRuntime::translateErrorToVba( SbError nError, String& rMsg )
+{
+ // If a message is defined use that ( in preference to
+ // the defined one for the error ) NB #TODO
+ // if there is an error defined it more than likely
+ // is not the one you want ( some are the same though )
+ // we really need a new vba compatible error list
+ if ( !rMsg.Len() )
+ {
+ // TEST, has to be vb here always
+#ifdef DBG_UTIL
+ SbError nTmp = StarBASIC::GetSfxFromVBError( (USHORT)nError );
+ DBG_ASSERT( nTmp, "No VB error!" );
+#endif
+
+ StarBASIC::MakeErrorText( nError, rMsg );
+ rMsg = StarBASIC::GetErrorText();
+ if ( !rMsg.Len() ) // no message for err no, need localized resource here
+ rMsg = String( RTL_CONSTASCII_USTRINGPARAM("Internal Object Error:") );
+ }
+ // no num? most likely then it *is* really a vba err
+ USHORT nVBErrorCode = StarBASIC::GetVBErrorCode( nError );
+ sal_Int32 nVBAErrorNumber = ( nVBErrorCode == 0 ) ? nError : nVBErrorCode;
+ return nVBAErrorNumber;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//
+// Parameter, Locals, Caller
+//
+//////////////////////////////////////////////////////////////////////////
+
+SbMethod* SbiRuntime::GetCaller()
+{
+ return pMeth;
+}
+
+SbxArray* SbiRuntime::GetLocals()
+{
+ return refLocals;
+}
+
+SbxArray* SbiRuntime::GetParams()
+{
+ return refParams;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//
+// Stacks
+//
+//////////////////////////////////////////////////////////////////////////
+
+// Der Expression-Stack steht fuer die laufende Auswertung von Expressions
+// zur Verfuegung.
+
+void SbiRuntime::PushVar( SbxVariable* pVar )
+{
+ if( pVar )
+ refExprStk->Put( pVar, nExprLvl++ );
+}
+
+SbxVariableRef SbiRuntime::PopVar()
+{
+#ifdef DBG_UTIL
+ if( !nExprLvl )
+ {
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ return new SbxVariable;
+ }
+#endif
+ SbxVariableRef xVar = refExprStk->Get( --nExprLvl );
+#ifdef DBG_UTIL
+ if ( xVar->GetName().EqualsAscii( "Cells" ) )
+ DBG_TRACE( "" );
+#endif
+ // Methods halten im 0.Parameter sich selbst, also weghauen
+ if( xVar->IsA( TYPE(SbxMethod) ) )
+ xVar->SetParameters(0);
+ return xVar;
+}
+
+BOOL SbiRuntime::ClearExprStack()
+{
+ // Achtung: Clear() reicht nicht, da Methods geloescht werden muessen
+ while ( nExprLvl )
+ {
+ PopVar();
+ }
+ refExprStk->Clear();
+ return FALSE;
+}
+
+// Variable auf dem Expression-Stack holen, ohne sie zu entfernen
+// n zaehlt ab 0.
+
+SbxVariable* SbiRuntime::GetTOS( short n )
+{
+ n = nExprLvl - n - 1;
+#ifdef DBG_UTIL
+ if( n < 0 )
+ {
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ return new SbxVariable;
+ }
+#endif
+ return refExprStk->Get( (USHORT) n );
+}
+
+// Sicherstellen, dass TOS eine temporaere Variable ist
+
+void SbiRuntime::TOSMakeTemp()
+{
+ SbxVariable* p = refExprStk->Get( nExprLvl - 1 );
+ if( p->GetRefCount() != 1 )
+ {
+ SbxVariable* pNew = new SbxVariable( *p );
+ pNew->SetFlag( SBX_READWRITE );
+ refExprStk->Put( pNew, nExprLvl - 1 );
+ }
+}
+
+// Der GOSUB-Stack nimmt Returnadressen fuer GOSUBs auf
+
+void SbiRuntime::PushGosub( const BYTE* pc )
+{
+ if( ++nGosubLvl > MAXRECURSION )
+ StarBASIC::FatalError( SbERR_STACK_OVERFLOW );
+ SbiGosubStack* p = new SbiGosubStack;
+ p->pCode = pc;
+ p->pNext = pGosubStk;
+ p->nStartForLvl = nForLvl;
+ pGosubStk = p;
+}
+
+void SbiRuntime::PopGosub()
+{
+ if( !pGosubStk )
+ Error( SbERR_NO_GOSUB );
+ else
+ {
+ SbiGosubStack* p = pGosubStk;
+ pCode = p->pCode;
+ pGosubStk = p->pNext;
+ delete p;
+ nGosubLvl--;
+ }
+}
+
+// Entleeren des GOSUB-Stacks
+
+void SbiRuntime::ClearGosubStack()
+{
+ SbiGosubStack* p;
+ while(( p = pGosubStk ) != NULL )
+ pGosubStk = p->pNext, delete p;
+ nGosubLvl = 0;
+}
+
+// Der Argv-Stack nimmt aktuelle Argument-Vektoren auf
+
+void SbiRuntime::PushArgv()
+{
+ SbiArgvStack* p = new SbiArgvStack;
+ p->refArgv = refArgv;
+ p->nArgc = nArgc;
+ nArgc = 1;
+ refArgv.Clear();
+ p->pNext = pArgvStk;
+ pArgvStk = p;
+}
+
+void SbiRuntime::PopArgv()
+{
+ if( pArgvStk )
+ {
+ SbiArgvStack* p = pArgvStk;
+ pArgvStk = p->pNext;
+ refArgv = p->refArgv;
+ nArgc = p->nArgc;
+ delete p;
+ }
+}
+
+// Entleeren des Argv-Stacks
+
+void SbiRuntime::ClearArgvStack()
+{
+ while( pArgvStk )
+ PopArgv();
+}
+
+// Push des For-Stacks. Der Stack hat Inkrement, Ende, Beginn und Variable.
+// Nach Aufbau des Stack-Elements ist der Stack leer.
+
+void SbiRuntime::PushFor()
+{
+ SbiForStack* p = new SbiForStack;
+ p->eForType = FOR_TO;
+ p->pNext = pForStk;
+ pForStk = p;
+ // Der Stack ist wie folgt aufgebaut:
+ p->refInc = PopVar();
+ p->refEnd = PopVar();
+ SbxVariableRef xBgn = PopVar();
+ p->refVar = PopVar();
+ *(p->refVar) = *xBgn;
+ nForLvl++;
+}
+
+void SbiRuntime::PushForEach()
+{
+ SbiForStack* p = new SbiForStack;
+ p->pNext = pForStk;
+ pForStk = p;
+
+ SbxVariableRef xObjVar = PopVar();
+ SbxBase* pObj = xObjVar.Is() ? xObjVar->GetObject() : NULL;
+ if( pObj == NULL )
+ {
+ Error( SbERR_NO_OBJECT );
+ return;
+ }
+
+ bool bError_ = false;
+ BasicCollection* pCollection;
+ SbxDimArray* pArray;
+ SbUnoObject* pUnoObj;
+ if( (pArray = PTR_CAST(SbxDimArray,pObj)) != NULL )
+ {
+ p->eForType = FOR_EACH_ARRAY;
+ p->refEnd = (SbxVariable*)pArray;
+
+ short nDims = pArray->GetDims();
+ p->pArrayLowerBounds = new sal_Int32[nDims];
+ p->pArrayUpperBounds = new sal_Int32[nDims];
+ p->pArrayCurIndices = new sal_Int32[nDims];
+ sal_Int32 lBound, uBound;
+ for( short i = 0 ; i < nDims ; i++ )
+ {
+ pArray->GetDim32( i+1, lBound, uBound );
+ p->pArrayCurIndices[i] = p->pArrayLowerBounds[i] = lBound;
+ p->pArrayUpperBounds[i] = uBound;
+ }
+ }
+ else if( (pCollection = PTR_CAST(BasicCollection,pObj)) != NULL )
+ {
+ p->eForType = FOR_EACH_COLLECTION;
+ p->refEnd = pCollection;
+ p->nCurCollectionIndex = 0;
+ }
+ else if( (pUnoObj = PTR_CAST(SbUnoObject,pObj)) != NULL )
+ {
+ // XEnumerationAccess?
+ Any aAny = pUnoObj->getUnoAny();
+ Reference< XEnumerationAccess > xEnumerationAccess;
+ if( (aAny >>= xEnumerationAccess) )
+ {
+ p->xEnumeration = xEnumerationAccess->createEnumeration();
+ p->eForType = FOR_EACH_XENUMERATION;
+ }
+ else
+ {
+ bError_ = true;
+ }
+ }
+ else
+ {
+ bError_ = true;
+ }
+
+ if( bError_ )
+ {
+ Error( SbERR_CONVERSION );
+ return;
+ }
+
+ // Container variable
+ p->refVar = PopVar();
+ nForLvl++;
+}
+
+// Poppen des FOR-Stacks
+
+void SbiRuntime::PopFor()
+{
+ if( pForStk )
+ {
+ SbiForStack* p = pForStk;
+ pForStk = p->pNext;
+ delete p;
+ nForLvl--;
+ }
+}
+
+// Entleeren des FOR-Stacks
+
+void SbiRuntime::ClearForStack()
+{
+ while( pForStk )
+ PopFor();
+}
+
+//////////////////////////////////////////////////////////////////////////
+//
+// DLL-Aufrufe
+//
+//////////////////////////////////////////////////////////////////////////
+
+void SbiRuntime::DllCall
+ ( const String& aFuncName, // Funktionsname
+ const String& aDLLName, // Name der DLL
+ SbxArray* pArgs, // Parameter (ab Index 1, kann NULL sein)
+ SbxDataType eResType, // Returnwert
+ BOOL bCDecl ) // TRUE: nach C-Konventionen
+{
+ // No DllCall for "virtual" portal users
+ if( needSecurityRestrictions() )
+ {
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+ return;
+ }
+
+ // MUSS NOCH IMPLEMENTIERT WERDEN
+ /*
+ String aMsg;
+ aMsg = "FUNC=";
+ aMsg += pFunc;
+ aMsg += " DLL=";
+ aMsg += pDLL;
+ MessBox( NULL, WB_OK, String( "DLL-CALL" ), aMsg ).Execute();
+ Error( SbERR_NOT_IMPLEMENTED );
+ */
+
+ SbxVariable* pRes = new SbxVariable( eResType );
+ SbiDllMgr* pDllMgr = pInst->GetDllMgr();
+ SbError nErr = pDllMgr->Call( aFuncName, aDLLName, pArgs, *pRes, bCDecl );
+ if( nErr )
+ Error( nErr );
+ PushVar( pRes );
+}
+USHORT
+SbiRuntime::GetImageFlag( USHORT n ) const
+{
+ return pImg->GetFlag( n );
+}
+USHORT
+SbiRuntime::GetBase()
+{
+ return pImg->GetBase();
+}
diff --git a/basic/source/runtime/stdobj.cxx b/basic/source/runtime/stdobj.cxx
new file mode 100644
index 000000000000..4455901bfeba
--- /dev/null
+++ b/basic/source/runtime/stdobj.cxx
@@ -0,0 +1,788 @@
+/*************************************************************************
+ *
+ * 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 "runtime.hxx"
+#include "stdobj.hxx"
+#include <basic/sbstdobj.hxx>
+#include "rtlproto.hxx"
+#include "sbintern.hxx"
+
+// Das nArgs-Feld eines Tabelleneintrags ist wie folgt verschluesselt:
+// Zur Zeit wird davon ausgegangen, dass Properties keine Parameter
+// benoetigen!
+
+#define _ARGSMASK 0x007F // Bis zu 127 Argumente
+#define _COMPTMASK 0x0080 // Only valid in compatibility mode
+#define _RWMASK 0x0F00 // Maske fuer R/W-Bits
+#define _TYPEMASK 0xF000 // Maske fuer den Typ des Eintrags
+
+#define _READ 0x0100 // kann gelesen werden
+#define _BWRITE 0x0200 // kann as Lvalue verwendet werden
+#define _LVALUE _BWRITE // kann as Lvalue verwendet werden
+#define _READWRITE 0x0300 // beides
+#define _OPT 0x0400 // Parameter ist optional
+#define _CONST 0x0800 // Property ist const
+#define _METHOD 0x3000 // Masken-Bits fuer eine Methode
+#define _PROPERTY 0x4000 // Masken-Bit fuer eine Property
+#define _OBJECT 0x8000 // Masken-Bit fuer ein Objekt
+ // Kombination von oberen Bits:
+#define _FUNCTION 0x1100 // Maske fuer Function
+#define _LFUNCTION 0x1300 // Maske fuer Function, die auch als Lvalue geht
+#define _SUB 0x2100 // Maske fuer Sub
+#define _ROPROP 0x4100 // Maske Read Only-Property
+#define _WOPROP 0x4200 // Maske Write Only-Property
+#define _RWPROP 0x4300 // Maske Read/Write-Property
+#define _CPROP 0x4900 // Maske fuer Konstante
+
+struct Methods {
+ const char* pName; // Name des Eintrags
+ SbxDataType eType; // Datentyp
+ short nArgs; // Argumente und Flags
+ RtlCall pFunc; // Function Pointer
+ USHORT nHash; // Hashcode
+};
+
+static Methods aMethods[] = {
+
+{ "AboutStarBasic", SbxNULL, 1 | _FUNCTION, RTLNAME(AboutStarBasic),0 },
+ { "Name", SbxSTRING, 0,NULL,0 },
+{ "Abs", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Abs),0 },
+ { "number", SbxDOUBLE, 0,NULL,0 },
+{ "Array", SbxOBJECT, _FUNCTION, RTLNAME(Array),0 },
+{ "Asc", SbxLONG, 1 | _FUNCTION, RTLNAME(Asc),0 },
+ { "string", SbxSTRING, 0,NULL,0 },
+{ "AscW", SbxLONG, 1 | _FUNCTION | _COMPTMASK, RTLNAME(Asc),0},
+ { "string", SbxSTRING, 0,NULL,0 },
+{ "Atn", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Atn),0 },
+ { "number", SbxDOUBLE, 0,NULL,0 },
+{ "ATTR_ARCHIVE", SbxINTEGER, _CPROP, RTLNAME(ATTR_ARCHIVE),0 },
+{ "ATTR_DIRECTORY", SbxINTEGER, _CPROP, RTLNAME(ATTR_DIRECTORY),0 },
+{ "ATTR_HIDDEN", SbxINTEGER, _CPROP, RTLNAME(ATTR_HIDDEN),0 },
+{ "ATTR_NORMAL", SbxINTEGER, _CPROP, RTLNAME(ATTR_NORMAL),0 },
+{ "ATTR_READONLY", SbxINTEGER, _CPROP, RTLNAME(ATTR_READONLY),0 },
+{ "ATTR_SYSTEM", SbxINTEGER, _CPROP, RTLNAME(ATTR_SYSTEM),0 },
+{ "ATTR_VOLUME", SbxINTEGER, _CPROP, RTLNAME(ATTR_VOLUME),0 },
+
+{ "Beep", SbxNULL, _FUNCTION, RTLNAME(Beep),0 },
+{ "Blue", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Blue),0 },
+ { "RGB-Value", SbxLONG, 0,NULL,0 },
+
+{ "CBool", SbxBOOL, 1 | _FUNCTION, RTLNAME(CBool),0 },
+ { "expression", SbxVARIANT, 0,NULL,0 },
+{ "CByte", SbxBYTE, 1 | _FUNCTION, RTLNAME(CByte),0 },
+ { "expression", SbxVARIANT, 0,NULL,0 },
+{ "CCur", SbxCURRENCY, 1 | _FUNCTION, RTLNAME(CCur),0 },
+ { "expression", SbxVARIANT, 0,NULL,0 },
+{ "CDate", SbxDATE, 1 | _FUNCTION, RTLNAME(CDate),0 },
+ { "expression", SbxVARIANT, 0,NULL,0 },
+{ "CDateFromIso", SbxDATE, 1 | _FUNCTION, RTLNAME(CDateFromIso),0 },
+ { "IsoDate", SbxSTRING, 0,NULL,0 },
+{ "CDateToIso", SbxSTRING, 1 | _FUNCTION, RTLNAME(CDateToIso),0 },
+ { "Date", SbxDATE, 0,NULL,0 },
+{ "CDec", SbxDECIMAL, 1 | _FUNCTION, RTLNAME(CDec),0 },
+ { "expression", SbxVARIANT, 0,NULL,0 },
+{ "CDbl", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(CDbl),0 },
+ { "expression", SbxVARIANT, 0,NULL,0 },
+{ "CF_BITMAP", SbxINTEGER, _CPROP, RTLNAME(CF_BITMAP),0 },
+{ "CF_METAFILEPICT",SbxINTEGER, _CPROP, RTLNAME(CF_METAFILEPICT),0 },
+{ "CF_TEXT", SbxINTEGER, _CPROP, RTLNAME(CF_TEXT),0 },
+{ "ChDir", SbxNULL, 1 | _FUNCTION, RTLNAME(ChDir),0 },
+ { "string", SbxSTRING, 0,NULL,0 },
+{ "ChDrive", SbxNULL, 1 | _FUNCTION, RTLNAME(ChDrive),0 },
+ { "string", SbxSTRING, 0,NULL,0 },
+
+{ "Choose", SbxVARIANT, 2 | _FUNCTION, RTLNAME(Choose),0 },
+ { "Index", SbxINTEGER, 0,NULL,0 },
+ { "Expression", SbxVARIANT, 0,NULL,0 },
+
+{ "Chr", SbxSTRING, 1 | _FUNCTION, RTLNAME(Chr),0 },
+ { "string", SbxINTEGER, 0,NULL,0 },
+{ "ChrW", SbxSTRING, 1 | _FUNCTION | _COMPTMASK, RTLNAME(Chr),0},
+ { "string", SbxINTEGER, 0,NULL,0 },
+
+{ "CInt", SbxINTEGER, 1 | _FUNCTION, RTLNAME(CInt),0 },
+ { "expression", SbxVARIANT, 0,NULL,0 },
+{ "CLEAR_ALLTABS", SbxINTEGER, _CPROP, RTLNAME(CLEAR_ALLTABS),0 },
+{ "CLEAR_TAB", SbxINTEGER, _CPROP, RTLNAME(CLEAR_TAB),0 },
+{ "CLng", SbxLONG, 1 | _FUNCTION, RTLNAME(CLng),0 },
+ { "expression", SbxVARIANT, 0,NULL,0 },
+{ "CompatibilityMode", SbxBOOL, 1 | _FUNCTION, RTLNAME(CompatibilityMode),0},
+ { "bEnable", SbxBOOL, 0,NULL,0 },
+{ "ConvertFromUrl", SbxSTRING, 1 | _FUNCTION, RTLNAME(ConvertFromUrl),0 },
+ { "Url", SbxSTRING, 0,NULL,0 },
+{ "ConvertToUrl", SbxSTRING, 1 | _FUNCTION, RTLNAME(ConvertToUrl),0 },
+ { "SystemPath", SbxSTRING, 0,NULL,0 },
+{ "Cos", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Cos),0 },
+ { "number", SbxDOUBLE, 0,NULL,0 },
+{ "CreateObject", SbxOBJECT, 1 | _FUNCTION, RTLNAME( CreateObject ),0 },
+ { "class", SbxSTRING, 0,NULL,0 },
+{ "CreateUnoListener",SbxOBJECT, 1 | _FUNCTION, RTLNAME( CreateUnoListener ),0 },
+ { "prefix", SbxSTRING, 0,NULL,0 },
+ { "typename", SbxSTRING, 0,NULL,0 },
+{ "CreateUnoDialog",SbxOBJECT, 2 | _FUNCTION, RTLNAME( CreateUnoDialog ),0 },
+ { "dialoglibrary",SbxOBJECT, 0,NULL,0 },
+ { "dialogname", SbxSTRING, 0,NULL,0 },
+{ "CreateUnoService",SbxOBJECT, 1 | _FUNCTION, RTLNAME( CreateUnoService ),0 },
+ { "servicename", SbxSTRING, 0,NULL,0 },
+{ "CreateUnoServiceWithArguments",SbxOBJECT, 2 | _FUNCTION, RTLNAME( CreateUnoServiceWithArguments ),0 },
+ { "servicename", SbxSTRING, 0,NULL,0 },
+ { "arguments", SbxARRAY, 0,NULL,0 },
+{ "CreateUnoStruct",SbxOBJECT, 1 | _FUNCTION, RTLNAME( CreateUnoStruct ),0 },
+ { "classname", SbxSTRING, 0,NULL,0 },
+{ "CreateUnoValue", SbxOBJECT, 2 | _FUNCTION, RTLNAME( CreateUnoValue ),0 },
+ { "type", SbxSTRING, 0,NULL,0 },
+ { "value", SbxVARIANT, 0,NULL,0 },
+{ "CreatePropertySet",SbxOBJECT, 1 | _FUNCTION, RTLNAME( CreatePropertySet ),0 },
+ { "values", SbxARRAY, 0,NULL,0 },
+{ "CSng", SbxSINGLE, 1 | _FUNCTION, RTLNAME(CSng),0 },
+ { "expression", SbxVARIANT, 0,NULL,0 },
+{ "CStr", SbxSTRING, 1 | _FUNCTION, RTLNAME(CStr),0 },
+ { "expression", SbxVARIANT, 0,NULL,0 },
+{ "CurDir", SbxSTRING, 1 | _FUNCTION, RTLNAME(CurDir),0 },
+ { "string", SbxSTRING, 0,NULL,0 },
+{ "CVar", SbxVARIANT, 1 | _FUNCTION, RTLNAME(CVar),0 },
+ { "expression", SbxVARIANT, 0,NULL,0 },
+{ "CVErr", SbxVARIANT, 1 | _FUNCTION, RTLNAME(CVErr),0 },
+ { "expression", SbxVARIANT, 0,NULL,0 },
+
+{ "Date", SbxDATE, _LFUNCTION,RTLNAME(Date),0 },
+{ "DateAdd", SbxDATE, 3 | _FUNCTION, RTLNAME(DateAdd),0 },
+ { "Interval", SbxSTRING, 0,NULL,0 },
+ { "Number", SbxLONG, 0,NULL,0 },
+ { "Date", SbxDATE, 0,NULL,0 },
+{ "DateDiff", SbxDOUBLE, 5 | _FUNCTION, RTLNAME(DateDiff),0 },
+ { "Interval", SbxSTRING, 0,NULL,0 },
+ { "Date1", SbxDATE, 0,NULL,0 },
+ { "Date2", SbxDATE, 0,NULL,0 },
+ { "Firstdayofweek" , SbxINTEGER, _OPT,NULL,0 },
+ { "Firstweekofyear", SbxINTEGER, _OPT,NULL,0 },
+{ "DatePart", SbxLONG, 4 | _FUNCTION, RTLNAME(DatePart),0 },
+ { "Interval", SbxSTRING, 0,NULL,0 },
+ { "Date", SbxDATE, 0,NULL,0 },
+ { "Firstdayofweek" , SbxINTEGER, _OPT, NULL,0 },
+ { "Firstweekofyear", SbxINTEGER, _OPT, NULL,0 },
+{ "DateSerial", SbxDATE, 3 | _FUNCTION, RTLNAME(DateSerial),0 },
+ { "Year", SbxINTEGER, 0,NULL,0 },
+ { "Month", SbxINTEGER, 0,NULL,0 },
+ { "Day", SbxINTEGER, 0,NULL,0 },
+{ "DateValue", SbxDATE, 1 | _FUNCTION, RTLNAME(DateValue),0 },
+ { "String", SbxSTRING, 0,NULL,0 },
+{ "Day", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Day),0 },
+ { "Date", SbxDATE, 0,NULL,0 },
+{ "Ddeexecute", SbxNULL, 2 | _FUNCTION, RTLNAME(DDEExecute),0 },
+ { "Channel", SbxLONG, 0,NULL,0 },
+ { "Command", SbxSTRING, 0,NULL,0 },
+{ "Ddeinitiate", SbxINTEGER, 2 | _FUNCTION, RTLNAME(DDEInitiate),0 },
+ { "Application", SbxSTRING, 0,NULL,0 },
+ { "Topic", SbxSTRING, 0,NULL,0 },
+{ "Ddepoke", SbxNULL, 3 | _FUNCTION, RTLNAME(DDEPoke),0 },
+ { "Channel", SbxLONG, 0,NULL,0 },
+ { "Item", SbxSTRING, 0,NULL,0 },
+ { "Data", SbxSTRING, 0,NULL,0 },
+{ "Dderequest", SbxSTRING, 2 | _FUNCTION, RTLNAME(DDERequest),0 },
+ { "Channel", SbxLONG, 0,NULL,0 },
+ { "Item", SbxSTRING, 0,NULL,0 },
+{ "Ddeterminate", SbxNULL, 1 | _FUNCTION, RTLNAME(DDETerminate),0 },
+ { "Channel", SbxLONG, 0,NULL,0 },
+{ "Ddeterminateall", SbxNULL, _FUNCTION, RTLNAME(DDETerminateAll),0 },
+{ "DimArray", SbxOBJECT, _FUNCTION, RTLNAME(DimArray),0 },
+{ "Dir", SbxSTRING, 2 | _FUNCTION, RTLNAME(Dir),0 },
+ { "FileSpec", SbxSTRING, _OPT, NULL,0 },
+ { "attrmask", SbxINTEGER, _OPT, NULL,0 },
+{ "DoEvents", SbxEMPTY, _FUNCTION, RTLNAME(DoEvents),0 },
+{ "DumpAllObjects", SbxEMPTY, 2 | _SUB, RTLNAME(DumpAllObjects),0 },
+ { "FileSpec", SbxSTRING, 0,NULL,0 },
+ { "DumpAll", SbxINTEGER, _OPT, NULL,0 },
+
+{ "Empty", SbxVARIANT, _CPROP, RTLNAME(Empty),0 },
+{ "EqualUnoObjects",SbxBOOL, 2 | _FUNCTION, RTLNAME(EqualUnoObjects),0 },
+ { "Variant", SbxVARIANT, 0,NULL,0 },
+ { "Variant", SbxVARIANT, 0,NULL,0 },
+{ "EnableReschedule", SbxNULL, 1 | _FUNCTION, RTLNAME(EnableReschedule),0},
+ { "bEnable", SbxBOOL, 0,NULL,0 },
+{ "Environ", SbxSTRING, 1 | _FUNCTION, RTLNAME(Environ),0 },
+ { "Environmentstring",SbxSTRING, 0,NULL,0 },
+{ "EOF", SbxBOOL, 1 | _FUNCTION, RTLNAME(EOF),0 },
+ { "Channel", SbxINTEGER, 0,NULL,0 },
+{ "Erl", SbxLONG, _ROPROP, RTLNAME( Erl ),0 },
+{ "Err", SbxVARIANT, _RWPROP, RTLNAME( Err ),0 },
+{ "Error", SbxSTRING, 1 | _FUNCTION, RTLNAME( Error ),0 },
+ { "code", SbxLONG, 0,NULL,0 },
+{ "Exp", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Exp),0 },
+ { "number", SbxDOUBLE, 0,NULL,0 },
+
+{ "False", SbxBOOL, _CPROP, RTLNAME(False),0 },
+{ "FileAttr", SbxINTEGER, 2 | _FUNCTION, RTLNAME(FileAttr),0 },
+ { "Channel", SbxINTEGER, 0,NULL,0 },
+ { "Attributes", SbxINTEGER, 0,NULL,0 },
+{ "FileCopy", SbxNULL, 2 | _FUNCTION, RTLNAME(FileCopy),0 },
+ { "Source", SbxSTRING, 0,NULL,0 },
+ { "Destination", SbxSTRING, 0,NULL,0 },
+{ "FileDateTime", SbxSTRING, 1 | _FUNCTION, RTLNAME(FileDateTime),0 },
+ { "filename", SbxSTRING, 0,NULL,0 },
+{ "FileExists", SbxBOOL, 1 | _FUNCTION, RTLNAME(FileExists),0 },
+ { "filename", SbxSTRING, 0,NULL,0 },
+{ "FileLen", SbxLONG, 1 | _FUNCTION, RTLNAME(FileLen),0 },
+ { "filename", SbxSTRING, 0,NULL,0 },
+{ "FindObject", SbxOBJECT, 1 | _FUNCTION, RTLNAME(FindObject),0 },
+ { "Name", SbxSTRING, 0,NULL,0 },
+{ "FindPropertyObject", SbxOBJECT, 2 | _FUNCTION, RTLNAME(FindPropertyObject),0 },
+ { "Object", SbxOBJECT, 0,NULL,0 },
+ { "Name", SbxSTRING, 0,NULL,0 },
+{ "Fix", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Fix),0 },
+ { "number", SbxDOUBLE, 0,NULL,0 },
+{ "Format", SbxSTRING, 2 | _FUNCTION, RTLNAME(Format),0 },
+ { "expression", SbxVARIANT, 0,NULL,0 },
+ { "format", SbxSTRING, _OPT, NULL,0 },
+{ "FormatDateTime", SbxSTRING, 2 | _FUNCTION | _COMPTMASK, RTLNAME(FormatDateTime),0 },
+ { "Date", SbxDATE, 0,NULL,0 },
+ { "NamedFormat", SbxINTEGER, _OPT, NULL,0 },
+{ "FRAMEANCHORCHAR", SbxINTEGER, _CPROP, RTLNAME(FRAMEANCHORCHAR),0 },
+{ "FRAMEANCHORPAGE", SbxINTEGER, _CPROP, RTLNAME(FRAMEANCHORPAGE),0 },
+{ "FRAMEANCHORPARA", SbxINTEGER, _CPROP, RTLNAME(FRAMEANCHORPARA),0 },
+{ "FreeFile", SbxINTEGER, _FUNCTION, RTLNAME(FreeFile),0 },
+{ "FreeLibrary", SbxNULL, 1 | _FUNCTION, RTLNAME(FreeLibrary),0 },
+ { "Modulename", SbxSTRING, 0,NULL,0 },
+
+{ "Get", SbxNULL, 3 | _FUNCTION, RTLNAME(Get),0 },
+ { "filenumber", SbxINTEGER, 0,NULL,0 },
+ { "recordnumber", SbxLONG, 0,NULL,0 },
+ { "variablename", SbxVARIANT, 0,NULL,0 },
+{ "GetAttr", SbxINTEGER, 1 | _FUNCTION, RTLNAME(GetAttr),0 },
+ { "filename", SbxSTRING, 0,NULL,0 },
+{ "GetDefaultContext", SbxOBJECT, 0 | _FUNCTION, RTLNAME(GetDefaultContext),0 },
+{ "GetDialogZoomFactorX", SbxDOUBLE, _FUNCTION,RTLNAME(GetDialogZoomFactorX),0 },
+{ "GetDialogZoomFactorY", SbxDOUBLE, _FUNCTION,RTLNAME(GetDialogZoomFactorY),0 },
+{ "GetGUIType", SbxINTEGER, _FUNCTION,RTLNAME(GetGUIType),0 },
+{ "GetGUIVersion", SbxLONG, _FUNCTION,RTLNAME(GetGUIVersion),0 },
+{ "GetPathSeparator", SbxSTRING, _FUNCTION,RTLNAME(GetPathSeparator),0 },
+{ "GetProcessServiceManager", SbxOBJECT, 0 | _FUNCTION, RTLNAME(GetProcessServiceManager),0 },
+{ "GetSolarVersion", SbxLONG, _FUNCTION,RTLNAME(GetSolarVersion),0 },
+{ "GetSystemTicks", SbxLONG, _FUNCTION,RTLNAME(GetSystemTicks),0 },
+{ "GetSystemType", SbxINTEGER, _FUNCTION,RTLNAME(GetSystemType),0 },
+{ "GlobalScope", SbxOBJECT, _FUNCTION,RTLNAME(GlobalScope),0 },
+{ "Green", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Green),0 },
+ { "RGB-Value", SbxLONG, 0,NULL,0 },
+
+{ "HasUnoInterfaces", SbxBOOL, 1 | _FUNCTION, RTLNAME(HasUnoInterfaces),0},
+ { "InterfaceName",SbxSTRING, 0,NULL,0 },
+{ "Hex", SbxSTRING, 1 | _FUNCTION, RTLNAME(Hex),0 },
+ { "number", SbxLONG, 0,NULL,0 },
+{ "Hour", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Hour),0 },
+ { "Date", SbxDATE, 0,NULL,0 },
+
+{ "IDABORT", SbxINTEGER, _CPROP, RTLNAME(IDABORT),0 },
+{ "IDCANCEL", SbxINTEGER, _CPROP, RTLNAME(IDCANCEL),0 },
+{ "IDNO", SbxINTEGER, _CPROP, RTLNAME(IDNO),0 },
+{ "IDOK", SbxINTEGER, _CPROP, RTLNAME(IDOK),0 },
+{ "IDRETRY", SbxINTEGER, _CPROP, RTLNAME(IDRETRY),0 },
+{ "IDYES", SbxINTEGER, _CPROP, RTLNAME(IDYES),0 },
+
+{ "Iif", SbxVARIANT, 3 | _FUNCTION, RTLNAME(Iif),0 },
+ { "Bool", SbxBOOL, 0,NULL,0 },
+ { "Variant1", SbxVARIANT, 0,NULL,0 },
+ { "Variant2", SbxVARIANT, 0,NULL,0 },
+
+{ "Input", SbxSTRING, 2 | _FUNCTION | _COMPTMASK, RTLNAME(Input),0},
+ { "Number", SbxLONG, 0,NULL,0 },
+ { "FileNumber", SbxLONG, 0,NULL,0 },
+{ "InputBox", SbxSTRING, 5 | _FUNCTION, RTLNAME(InputBox),0 },
+ { "Prompt", SbxSTRING, 0,NULL,0 },
+ { "Title", SbxSTRING, _OPT, NULL,0 },
+ { "Default", SbxSTRING, _OPT, NULL,0 },
+ { "XPosTwips", SbxLONG, _OPT, NULL,0 },
+ { "YPosTwips", SbxLONG, _OPT, NULL,0 },
+{ "InStr", SbxLONG, 4 | _FUNCTION, RTLNAME(InStr),0 },
+ { "Start", SbxSTRING, _OPT, NULL,0 },
+ { "String1", SbxSTRING, 0,NULL,0 },
+ { "String2", SbxSTRING, 0,NULL,0 },
+ { "Compare", SbxINTEGER, _OPT, NULL,0 },
+{ "InStrRev", SbxLONG, 4 | _FUNCTION | _COMPTMASK, RTLNAME(InStrRev),0},
+ { "String1", SbxSTRING, 0,NULL,0 },
+ { "String2", SbxSTRING, 0,NULL,0 },
+ { "Start", SbxSTRING, _OPT, NULL,0 },
+ { "Compare", SbxINTEGER, _OPT, NULL,0 },
+{ "Int", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Int),0 },
+ { "number", SbxDOUBLE, 0,NULL,0 },
+{ "IsArray", SbxBOOL, 1 | _FUNCTION, RTLNAME(IsArray),0 },
+ { "Variant", SbxVARIANT, 0,NULL,0 },
+{ "IsDate", SbxBOOL, 1 | _FUNCTION, RTLNAME(IsDate),0 },
+ { "Variant", SbxVARIANT, 0,NULL,0 },
+{ "IsEmpty", SbxBOOL, 1 | _FUNCTION, RTLNAME(IsEmpty),0 },
+ { "Variant", SbxVARIANT, 0,NULL,0 },
+{ "IsError", SbxBOOL, 1 | _FUNCTION, RTLNAME(IsError),0 },
+ { "Variant", SbxVARIANT, 0,NULL,0 },
+{ "IsMissing", SbxBOOL, 1 | _FUNCTION, RTLNAME(IsMissing),0 },
+ { "Variant", SbxVARIANT, 0,NULL,0 },
+{ "IsNull", SbxBOOL, 1 | _FUNCTION, RTLNAME(IsNull),0 },
+ { "Variant", SbxVARIANT, 0,NULL,0 },
+{ "IsNumeric", SbxBOOL, 1 | _FUNCTION, RTLNAME(IsNumeric),0 },
+ { "Variant", SbxVARIANT, 0,NULL,0 },
+{ "IsObject", SbxBOOL, 1 | _FUNCTION, RTLNAME(IsObject),0 },
+ { "Variant", SbxVARIANT, 0,NULL,0 },
+{ "IsUnoStruct", SbxBOOL, 1 | _FUNCTION, RTLNAME(IsUnoStruct),0 },
+ { "Variant", SbxVARIANT, 0,NULL,0 },
+{ "Join", SbxSTRING, 2 | _FUNCTION, RTLNAME(Join),0 },
+ { "list", SbxOBJECT, 0,NULL,0 },
+ { "delimiter", SbxSTRING, 0,NULL,0 },
+{ "Kill", SbxNULL, 1 | _FUNCTION, RTLNAME(Kill),0 },
+ { "filespec", SbxSTRING, 0,NULL,0 },
+{ "LBound", SbxLONG, 1 | _FUNCTION, RTLNAME(LBound),0 },
+ { "Variant", SbxVARIANT, 0,NULL,0 },
+{ "LCase", SbxSTRING, 1 | _FUNCTION, RTLNAME(LCase),0 },
+ { "string", SbxSTRING, 0,NULL,0 },
+{ "Left", SbxSTRING, 2 | _FUNCTION, RTLNAME(Left),0 },
+ { "String", SbxSTRING, 0,NULL,0 },
+ { "Count", SbxLONG, 0,NULL,0 },
+{ "Len", SbxLONG, 1 | _FUNCTION, RTLNAME(Len),0 },
+ { "StringOrVariant", SbxVARIANT, 0,NULL,0 },
+{ "LenB", SbxLONG, 1 | _FUNCTION, RTLNAME(Len),0 },
+ { "StringOrVariant", SbxVARIANT, 0,NULL,0 },
+{ "Load", SbxNULL, 1 | _FUNCTION, RTLNAME(Load),0 },
+ { "object", SbxOBJECT, 0,NULL,0 },
+{ "LoadPicture", SbxOBJECT, 1 | _FUNCTION, RTLNAME(LoadPicture),0 },
+ { "string", SbxSTRING, 0,NULL,0 },
+{ "Loc", SbxLONG, 1 | _FUNCTION, RTLNAME(Loc),0 },
+ { "Channel", SbxINTEGER, 0,NULL,0 },
+{ "Lof", SbxLONG, 1 | _FUNCTION, RTLNAME(Lof),0 },
+ { "Channel", SbxINTEGER, 0,NULL,0 },
+{ "Log", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Log),0 },
+ { "number", SbxDOUBLE, 0,NULL,0 },
+{ "LTrim", SbxSTRING, 1 | _FUNCTION, RTLNAME(LTrim),0 },
+ { "string", SbxSTRING, 0,NULL,0 },
+
+{ "MB_ABORTRETRYIGNORE", SbxINTEGER, _CPROP, RTLNAME(MB_ABORTRETRYIGNORE),0},
+{ "MB_APPLMODAL", SbxINTEGER, _CPROP, RTLNAME(MB_APPLMODAL),0 },
+{ "MB_DEFBUTTON1", SbxINTEGER, _CPROP, RTLNAME(MB_DEFBUTTON1),0 },
+{ "MB_DEFBUTTON2", SbxINTEGER, _CPROP, RTLNAME(MB_DEFBUTTON2),0 },
+{ "MB_DEFBUTTON3", SbxINTEGER, _CPROP, RTLNAME(MB_DEFBUTTON3),0 },
+{ "MB_ICONEXCLAMATION", SbxINTEGER, _CPROP, RTLNAME(MB_ICONEXCLAMATION),0},
+{ "MB_ICONINFORMATION", SbxINTEGER, _CPROP, RTLNAME(MB_ICONINFORMATION),0},
+{ "MB_ICONQUESTION",SbxINTEGER, _CPROP, RTLNAME(MB_ICONQUESTION),0 },
+{ "MB_ICONSTOP", SbxINTEGER, _CPROP, RTLNAME(MB_ICONSTOP),0 },
+{ "MB_OK", SbxINTEGER, _CPROP, RTLNAME(MB_OK),0 },
+{ "MB_OKCANCEL", SbxINTEGER, _CPROP, RTLNAME(MB_OKCANCEL),0 },
+{ "MB_RETRYCANCEL", SbxINTEGER, _CPROP, RTLNAME(MB_RETRYCANCEL),0 },
+{ "MB_SYSTEMMODAL", SbxINTEGER, _CPROP, RTLNAME(MB_SYSTEMMODAL),0 },
+{ "MB_YESNO", SbxINTEGER, _CPROP, RTLNAME(MB_YESNO),0 },
+{ "MB_YESNOCANCEL", SbxINTEGER, _CPROP, RTLNAME(MB_YESNOCANCEL),0 },
+
+{ "Me", SbxOBJECT, 0 | _FUNCTION | _COMPTMASK, RTLNAME(Me),0 },
+{ "Mid", SbxSTRING, 3 | _LFUNCTION,RTLNAME(Mid),0 },
+ { "String", SbxSTRING, 0,NULL,0 },
+ { "StartPos", SbxLONG, 0,NULL,0 },
+ { "Length", SbxLONG, _OPT, NULL,0 },
+{ "Minute", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Minute),0 },
+ { "Date", SbxDATE, 0,NULL,0 },
+{ "MkDir", SbxNULL, 1 | _FUNCTION, RTLNAME(MkDir),0 },
+ { "pathname", SbxSTRING, 0,NULL,0 },
+{ "Month", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Month),0 },
+ { "Date", SbxDATE, 0,NULL,0 },
+{ "MonthName", SbxSTRING, 2 | _FUNCTION | _COMPTMASK, RTLNAME(MonthName),0 },
+ { "Month", SbxINTEGER, 0,NULL,0 },
+ { "Abbreviate", SbxBOOL, _OPT, NULL,0 },
+{ "MsgBox", SbxINTEGER, 5 | _FUNCTION, RTLNAME(MsgBox),0 },
+ { "Prompt", SbxSTRING, 0,NULL,0 },
+ { "Buttons", SbxINTEGER, _OPT, NULL,0 },
+ { "Title", SbxSTRING, _OPT, NULL,0 },
+ { "Helpfile", SbxSTRING, _OPT, NULL,0 },
+ { "Context", SbxINTEGER, _OPT, NULL,0 },
+
+{ "Nothing", SbxOBJECT, _CPROP, RTLNAME(Nothing),0 },
+{ "Now", SbxDATE, _FUNCTION, RTLNAME(Now),0 },
+{ "Null", SbxNULL, _CPROP, RTLNAME(Null),0 },
+
+{ "Oct", SbxSTRING, 1 | _FUNCTION, RTLNAME(Oct),0 },
+ { "number", SbxLONG, 0,NULL,0 },
+
+{ "Partition", SbxSTRING, 4 | _FUNCTION, RTLNAME(Partition),0 },
+ { "number", SbxLONG, 0,NULL,0 },
+ { "start", SbxLONG, 0,NULL,0 },
+ { "stop", SbxLONG, 0,NULL,0 },
+ { "interval", SbxLONG, 0,NULL,0 },
+{ "Pi", SbxDOUBLE, _CPROP, RTLNAME(PI),0 },
+{ "Put", SbxNULL, 3 | _FUNCTION, RTLNAME(Put),0 },
+ { "filenumber", SbxINTEGER, 0,NULL,0 },
+ { "recordnumber", SbxLONG, 0,NULL,0 },
+ { "variablename", SbxVARIANT, 0,NULL,0 },
+
+{ "QBColor", SbxLONG, 1 | _FUNCTION, RTLNAME(QBColor),0 },
+ { "number", SbxINTEGER, 0,NULL,0 },
+
+{ "Randomize", SbxNULL, 1 | _FUNCTION, RTLNAME(Randomize),0 },
+ { "Number", SbxDOUBLE, _OPT, NULL,0 },
+{ "Red", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Red),0 },
+ { "RGB-Value", SbxLONG, 0,NULL,0 },
+{ "Reset", SbxNULL, 0 | _FUNCTION, RTLNAME(Reset),0 },
+{ "ResolvePath", SbxSTRING, 1 | _FUNCTION, RTLNAME(ResolvePath),0 },
+ { "Path", SbxSTRING, 0,NULL,0 },
+{ "RGB", SbxLONG, 3 | _FUNCTION, RTLNAME(RGB),0 },
+ { "Red", SbxINTEGER, 0,NULL,0 },
+ { "Green", SbxINTEGER, 0,NULL,0 },
+ { "Blue", SbxINTEGER, 0,NULL,0 },
+{ "Replace", SbxSTRING, 6 | _FUNCTION, RTLNAME(Replace),0 },
+ { "Expression", SbxSTRING, 0,NULL,0 },
+ { "Find", SbxSTRING, 0,NULL,0 },
+ { "Replace", SbxSTRING, 0,NULL,0 },
+ { "Start", SbxINTEGER, _OPT, NULL,0 },
+ { "Count", SbxINTEGER, _OPT, NULL,0 },
+ { "Compare", SbxINTEGER, _OPT, NULL,0 },
+{ "Right", SbxSTRING, 2 | _FUNCTION, RTLNAME(Right),0 },
+ { "String", SbxSTRING, 0,NULL,0 },
+ { "Count", SbxLONG, 0,NULL,0 },
+{ "RmDir", SbxNULL, 1 | _FUNCTION, RTLNAME(RmDir),0 },
+ { "pathname", SbxSTRING, 0,NULL,0 },
+{ "Round", SbxDOUBLE, 2 | _FUNCTION | _COMPTMASK, RTLNAME(Round),0},
+ { "Expression", SbxDOUBLE, 0,NULL,0 },
+ { "Numdecimalplaces", SbxINTEGER, _OPT, NULL,0 },
+{ "Rnd", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Rnd),0 },
+ { "Number", SbxDOUBLE, _OPT, NULL,0 },
+{ "RTL", SbxOBJECT, 0 | _FUNCTION | _COMPTMASK, RTLNAME(RTL),0},
+{ "RTrim", SbxSTRING, 1 | _FUNCTION, RTLNAME(RTrim),0 },
+ { "string", SbxSTRING, 0,NULL,0 },
+
+{ "SavePicture", SbxNULL, 2 | _FUNCTION, RTLNAME(SavePicture),0 },
+ { "object", SbxOBJECT, 0,NULL,0 },
+ { "string", SbxSTRING, 0,NULL,0 },
+{ "Second", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Second),0 },
+ { "Date", SbxDATE, 0,NULL,0 },
+{ "Seek", SbxLONG, 1 | _FUNCTION, RTLNAME(Seek),0 },
+ { "Channel", SbxINTEGER, 0,NULL,0 },
+{ "SendKeys", SbxNULL, 2 | _FUNCTION, RTLNAME(SendKeys),0 },
+ { "String", SbxSTRING, 0,NULL,0 },
+ { "Wait", SbxBOOL, _OPT, NULL,0 },
+{ "SetAttr", SbxNULL, 2 | _FUNCTION, RTLNAME(SetAttr),0 },
+ { "File" , SbxSTRING, 0,NULL,0 },
+ { "Attributes", SbxINTEGER, 0,NULL,0 },
+{ "SET_OFF", SbxINTEGER, _CPROP, RTLNAME(SET_OFF),0 },
+{ "SET_ON", SbxINTEGER, _CPROP, RTLNAME(SET_ON),0 },
+{ "SET_TAB", SbxINTEGER, _CPROP, RTLNAME(SET_TAB),0 },
+{ "Sgn", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Sgn),0 },
+ { "number", SbxDOUBLE, 0,NULL,0 },
+{ "Shell", SbxLONG, 2 | _FUNCTION, RTLNAME(Shell),0 },
+ { "Commandstring",SbxSTRING, 0,NULL,0 },
+ { "WindowStyle", SbxINTEGER, _OPT, NULL,0 },
+{ "Sin", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Sin),0 },
+ { "number", SbxDOUBLE, 0,NULL,0 },
+{ "Space", SbxSTRING, 1 | _FUNCTION, RTLNAME(Space),0 },
+ { "string", SbxLONG, 0,NULL,0 },
+{ "Spc", SbxSTRING, 1 | _FUNCTION, RTLNAME(Spc),0 },
+ { "Count", SbxLONG, 0,NULL,0 },
+{ "Split", SbxOBJECT, 3 | _FUNCTION, RTLNAME(Split),0 },
+ { "expression", SbxSTRING, 0,NULL,0 },
+ { "delimiter", SbxSTRING, 0,NULL,0 },
+ { "count", SbxLONG, 0,NULL,0 },
+{ "Sqr", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Sqr),0 },
+ { "number", SbxDOUBLE, 0,NULL,0 },
+{ "Str", SbxSTRING, 1 | _FUNCTION, RTLNAME(Str),0 },
+ { "number", SbxDOUBLE, 0,NULL,0 },
+{ "StrComp", SbxINTEGER, 3 | _FUNCTION, RTLNAME(StrComp),0 },
+ { "String1", SbxSTRING, 0,NULL,0 },
+ { "String2", SbxSTRING, 0,NULL,0 },
+ { "Compare", SbxINTEGER, _OPT, NULL,0 },
+{ "StrConv", SbxOBJECT, 3 | _FUNCTION, RTLNAME(StrConv),0 },
+ { "String", SbxSTRING, 0,NULL,0 },
+ { "Conversion", SbxSTRING, 0,NULL,0 },
+ { "LCID", SbxINTEGER, _OPT,NULL,0 },
+{ "String", SbxSTRING, 2 | _FUNCTION, RTLNAME(String),0 },
+ { "Count", SbxLONG, 0,NULL,0 },
+ { "Filler", SbxVARIANT, 0,NULL,0 },
+{ "StrReverse", SbxSTRING, 1 | _FUNCTION | _COMPTMASK, RTLNAME(StrReverse),0 },
+ { "String1", SbxSTRING, 0,NULL,0 },
+{ "Switch", SbxVARIANT, 2 | _FUNCTION, RTLNAME(Switch),0 },
+ { "Expression", SbxVARIANT, 0,NULL,0 },
+ { "Value", SbxVARIANT, 0,NULL,0 },
+
+{ "Tan", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Tan),0 },
+ { "number", SbxDOUBLE, 0,NULL,0 },
+{ "Time", SbxVARIANT, _LFUNCTION,RTLNAME(Time),0 },
+{ "Timer", SbxDATE, _FUNCTION, RTLNAME(Timer),0 },
+{ "TimeSerial", SbxDATE, 3 | _FUNCTION, RTLNAME(TimeSerial),0 },
+ { "Hour", SbxLONG, 0,NULL,0 },
+ { "Minute", SbxLONG, 0,NULL,0 },
+ { "Second", SbxLONG, 0,NULL,0 },
+{ "TimeValue", SbxDATE, 1 | _FUNCTION, RTLNAME(TimeValue),0 },
+ { "String", SbxSTRING, 0,NULL,0 },
+{ "TOGGLE", SbxINTEGER, _CPROP, RTLNAME(TOGGLE),0 },
+{ "Trim", SbxSTRING, 1 | _FUNCTION, RTLNAME(Trim),0 },
+ { "String", SbxSTRING, 0,NULL,0 },
+{ "True", SbxBOOL, _CPROP, RTLNAME(True),0 },
+{ "TwipsPerPixelX", SbxLONG, _FUNCTION, RTLNAME(TwipsPerPixelX),0 },
+{ "TwipsPerPixelY", SbxLONG, _FUNCTION, RTLNAME(TwipsPerPixelY),0 },
+
+{ "TYP_AUTHORFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_AUTHORFLD),0 },
+{ "TYP_CHAPTERFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_CHAPTERFLD),0 },
+{ "TYP_CONDTXTFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_CONDTXTFLD),0 },
+{ "TYP_DATEFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_DATEFLD),0 },
+{ "TYP_DBFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_DBFLD),0 },
+{ "TYP_DBNAMEFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_DBNAMEFLD),0 },
+{ "TYP_DBNEXTSETFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_DBNEXTSETFLD),0 },
+{ "TYP_DBNUMSETFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_DBNUMSETFLD),0 },
+{ "TYP_DBSETNUMBERFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_DBSETNUMBERFLD),0 },
+{ "TYP_DDEFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_DDEFLD),0 },
+{ "TYP_DOCINFOFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_DOCINFOFLD),0 },
+{ "TYP_DOCSTATFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_DOCSTATFLD),0 },
+{ "TYP_EXTUSERFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_EXTUSERFLD),0 },
+{ "TYP_FILENAMEFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_FILENAMEFLD),0 },
+{ "TYP_FIXDATEFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_FIXDATEFLD),0 },
+{ "TYP_FIXTIMEFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_FIXTIMEFLD),0 },
+{ "TYP_FORMELFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_FORMELFLD),0 },
+{ "TYP_GETFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_GETFLD),0 },
+{ "TYP_GETREFFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_GETREFFLD),0 },
+{ "TYP_GETREFPAGEFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_GETREFPAGEFLD),0 },
+{ "TYP_HIDDENPARAFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_HIDDENPARAFLD),0 },
+{ "TYP_HIDDENTXTFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_HIDDENTXTFLD),0 },
+{ "TYP_INPUTFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_INPUTFLD),0 },
+{ "TYP_INTERNETFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_INTERNETFLD),0 },
+{ "TYP_JUMPEDITFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_JUMPEDITFLD),0 },
+{ "TYP_MACROFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_MACROFLD),0 },
+{ "TYP_NEXTPAGEFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_NEXTPAGEFLD),0 },
+{ "TYP_PAGENUMBERFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_PAGENUMBERFLD),0 },
+{ "TYP_POSTITFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_POSTITFLD),0 },
+{ "TYP_PREVPAGEFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_PREVPAGEFLD),0 },
+{ "TYP_SEQFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_SEQFLD),0 },
+{ "TYP_SETFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_SETFLD),0 },
+{ "TYP_SETINPFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_SETINPFLD),0 },
+{ "TYP_SETREFFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_SETREFFLD),0 },
+{ "TYP_SETREFPAGEFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_SETREFPAGEFLD),0 },
+{ "TYP_TEMPLNAMEFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_TEMPLNAMEFLD),0},
+{ "TYP_TIMEFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_TIMEFLD),0 },
+{ "TYP_USERFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_USERFLD),0 },
+{ "TYP_USRINPFLD", SbxINTEGER, _CPROP, RTLNAME(TYP_USRINPFLD),0 },
+
+{ "TypeLen", SbxINTEGER, 1 | _FUNCTION, RTLNAME(TypeLen),0 },
+ { "Var", SbxVARIANT, 0,NULL,0 },
+{ "TypeName", SbxSTRING, 1 | _FUNCTION, RTLNAME(TypeName),0 },
+ { "Var", SbxVARIANT, 0,NULL,0 },
+
+{ "UBound", SbxLONG, 1 | _FUNCTION, RTLNAME(UBound),0 },
+ { "Var", SbxVARIANT, 0,NULL,0 },
+{ "UCase", SbxSTRING, 1 | _FUNCTION, RTLNAME(UCase),0 },
+ { "String", SbxSTRING, 0,NULL,0 },
+{ "Unload", SbxNULL, 1 | _FUNCTION, RTLNAME(Unload),0 },
+ { "Dialog", SbxOBJECT, 0,NULL,0 },
+
+{ "Val", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Val),0 },
+ { "String", SbxSTRING, 0,NULL,0 },
+{ "VarType", SbxINTEGER, 1 | _FUNCTION, RTLNAME(VarType),0 },
+ { "Var", SbxVARIANT, 0,NULL,0 },
+{ "V_EMPTY", SbxINTEGER, _CPROP, RTLNAME(V_EMPTY),0 },
+{ "V_NULL", SbxINTEGER, _CPROP, RTLNAME(V_NULL),0 },
+{ "V_INTEGER", SbxINTEGER, _CPROP, RTLNAME(V_INTEGER),0 },
+{ "V_LONG", SbxINTEGER, _CPROP, RTLNAME(V_LONG),0 },
+{ "V_SINGLE", SbxINTEGER, _CPROP, RTLNAME(V_SINGLE),0 },
+{ "V_DOUBLE", SbxINTEGER, _CPROP, RTLNAME(V_DOUBLE),0 },
+{ "V_CURRENCY", SbxINTEGER, _CPROP, RTLNAME(V_CURRENCY),0 },
+{ "V_DATE", SbxINTEGER, _CPROP, RTLNAME(V_DATE),0 },
+{ "V_STRING", SbxINTEGER, _CPROP, RTLNAME(V_STRING),0 },
+
+{ "Wait", SbxNULL, 1 | _FUNCTION, RTLNAME(Wait),0 },
+ { "Milliseconds", SbxLONG, 0,NULL,0 },
+//#i64882#
+{ "WaitUntil", SbxNULL, 1 | _FUNCTION, RTLNAME(WaitUntil),0 },
+ { "Date", SbxDOUBLE, 0,NULL,0 },
+{ "Weekday", SbxINTEGER, 2 | _FUNCTION, RTLNAME(Weekday),0 },
+ { "Date", SbxDATE, 0,NULL,0 },
+ { "Firstdayofweek", SbxINTEGER, _OPT, NULL,0 },
+{ "WeekdayName", SbxSTRING, 3 | _FUNCTION | _COMPTMASK, RTLNAME(WeekdayName),0 },
+ { "Weekday", SbxINTEGER, 0,NULL,0 },
+ { "Abbreviate", SbxBOOL, _OPT, NULL,0 },
+ { "Firstdayofweek", SbxINTEGER, _OPT, NULL,0 },
+{ "Year", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Year),0 },
+ { "Date", SbxDATE, 0,NULL,0 },
+
+{ NULL, SbxNULL, -1,NULL,0 }}; // Tabellenende
+
+SbiStdObject::SbiStdObject( const String& r, StarBASIC* pb ) : SbxObject( r )
+{
+ // Muessen wir die Hashcodes initialisieren?
+ Methods* p = aMethods;
+ if( !p->nHash )
+ while( p->nArgs != -1 )
+ {
+ String aName_ = String::CreateFromAscii( p->pName );
+ p->nHash = SbxVariable::MakeHashCode( aName_ );
+ p += ( p->nArgs & _ARGSMASK ) + 1;
+ }
+
+ // #i92642: Remove default properties
+ Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_DONTCARE );
+ Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Parent") ), SbxCLASS_DONTCARE );
+
+ SetParent( pb );
+
+ pStdFactory = new SbStdFactory;
+ SbxBase::AddFactory( pStdFactory );
+
+ Insert( new SbStdClipboard );
+}
+
+SbiStdObject::~SbiStdObject()
+{
+ SbxBase::RemoveFactory( pStdFactory );
+ delete pStdFactory;
+}
+
+// Suche nach einem Element:
+// Hier wird linear durch die Methodentabelle gegangen, bis eine
+// passende Methode gefunden wurde. Auf Grund der Bits im nArgs-Feld
+// wird dann die passende Instanz eines SbxObjElement generiert.
+// Wenn die Methode/Property nicht gefunden wurde, nur NULL ohne
+// Fehlercode zurueckliefern, da so auch eine ganze Chain von
+// Objekten nach der Methode/Property befragt werden kann.
+
+SbxVariable* SbiStdObject::Find( const String& rName, SbxClassType t )
+{
+ // Bereits eingetragen?
+ SbxVariable* pVar = SbxObject::Find( rName, t );
+ if( !pVar )
+ {
+ // sonst suchen
+ USHORT nHash_ = SbxVariable::MakeHashCode( rName );
+ Methods* p = aMethods;
+ BOOL bFound = FALSE;
+ short nIndex = 0;
+ USHORT nSrchMask = _TYPEMASK;
+ switch( t )
+ {
+ case SbxCLASS_METHOD: nSrchMask = _METHOD; break;
+ case SbxCLASS_PROPERTY: nSrchMask = _PROPERTY; break;
+ case SbxCLASS_OBJECT: nSrchMask = _OBJECT; break;
+ default: break;
+ }
+ while( p->nArgs != -1 )
+ {
+ if( ( p->nArgs & nSrchMask )
+ && ( p->nHash == nHash_ )
+ && ( rName.EqualsIgnoreCaseAscii( p->pName ) ) )
+ {
+ bFound = TRUE;
+ if( p->nArgs & _COMPTMASK )
+ {
+ SbiInstance* pInst = pINST;
+ if( !pInst || !pInst->IsCompatibility() )
+ bFound = FALSE;
+ }
+ break;
+ }
+ nIndex += ( p->nArgs & _ARGSMASK ) + 1;
+ p = aMethods + nIndex;
+ }
+
+ if( bFound )
+ {
+ // Args-Felder isolieren:
+ short nAccess = ( p->nArgs & _RWMASK ) >> 8;
+ short nType = ( p->nArgs & _TYPEMASK );
+ if( p->nArgs & _CONST )
+ nAccess |= SBX_CONST;
+ String aName_ = String::CreateFromAscii( p->pName );
+ SbxClassType eCT = SbxCLASS_OBJECT;
+ if( nType & _PROPERTY )
+ eCT = SbxCLASS_PROPERTY;
+ else if( nType & _METHOD )
+ eCT = SbxCLASS_METHOD;
+ pVar = Make( aName_, eCT, p->eType );
+ pVar->SetUserData( nIndex + 1 );
+ pVar->SetFlags( nAccess );
+ }
+ }
+ return pVar;
+}
+
+// SetModified muß bei der RTL abgklemmt werden
+void SbiStdObject::SetModified( BOOL )
+{
+}
+
+// Aufruf einer Property oder Methode.
+
+void SbiStdObject::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* pPar_ = pVar->GetParameters();
+ ULONG t = pHint->GetId();
+ USHORT nCallId = (USHORT) pVar->GetUserData();
+ if( nCallId )
+ {
+ if( t == SBX_HINT_INFOWANTED )
+ pVar->SetInfo( GetInfo( (short) pVar->GetUserData() ) );
+ else
+ {
+ BOOL bWrite = FALSE;
+ if( t == SBX_HINT_DATACHANGED )
+ bWrite = TRUE;
+ if( t == SBX_HINT_DATAWANTED || bWrite )
+ {
+ RtlCall p = (RtlCall) aMethods[ nCallId-1 ].pFunc;
+ SbxArrayRef rPar( pPar_ );
+ if( !pPar_ )
+ {
+ rPar = pPar_ = new SbxArray;
+ pPar_->Put( pVar, 0 );
+ }
+ p( (StarBASIC*) GetParent(), *pPar_, bWrite );
+ return;
+ }
+ }
+ }
+ SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+ }
+}
+
+// Zusammenbau der Infostruktur fuer einzelne Elemente
+// Falls nIdx = 0, nix erzeugen (sind Std-Props!)
+
+SbxInfo* SbiStdObject::GetInfo( short nIdx )
+{
+ if( !nIdx )
+ return NULL;
+ Methods* p = &aMethods[ --nIdx ];
+ // Wenn mal eine Hilfedatei zur Verfuegung steht:
+ // SbxInfo* pInfo_ = new SbxInfo( Hilfedateiname, p->nHelpId );
+ SbxInfo* pInfo_ = new SbxInfo;
+ short nPar = p->nArgs & _ARGSMASK;
+ for( short i = 0; i < nPar; i++ )
+ {
+ p++;
+ String aName_ = String::CreateFromAscii( p->pName );
+ USHORT nFlags_ = ( p->nArgs >> 8 ) & 0x03;
+ if( p->nArgs & _OPT )
+ nFlags_ |= SBX_OPTIONAL;
+ pInfo_->AddParam( aName_, p->eType, nFlags_ );
+ }
+ return pInfo_;
+}
+
diff --git a/basic/source/runtime/stdobj1.cxx b/basic/source/runtime/stdobj1.cxx
new file mode 100644
index 000000000000..94b7973c7e77
--- /dev/null
+++ b/basic/source/runtime/stdobj1.cxx
@@ -0,0 +1,551 @@
+/*************************************************************************
+ *
+ * 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 <vcl/wrkwin.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/transfer.hxx>
+#include "runtime.hxx"
+#include <basic/sbstdobj.hxx>
+
+#define ATTR_IMP_TYPE 1
+#define ATTR_IMP_WIDTH 2
+#define ATTR_IMP_HEIGHT 3
+#define ATTR_IMP_BOLD 4
+#define ATTR_IMP_ITALIC 5
+#define ATTR_IMP_STRIKETHROUGH 6
+#define ATTR_IMP_UNDERLINE 7
+#define ATTR_IMP_WEIGHT 8
+#define ATTR_IMP_SIZE 9
+#define ATTR_IMP_NAME 10
+
+#define METH_CLEAR 20
+#define METH_GETDATA 21
+#define METH_GETFORMAT 22
+#define METH_GETTEXT 23
+#define METH_SETDATA 24
+#define METH_SETTEXT 25
+
+//------------------------------------------------------------------------------
+SbStdFactory::SbStdFactory()
+{
+}
+
+SbxObject* SbStdFactory::CreateObject( const String& rClassName )
+{
+ if( rClassName.EqualsIgnoreCaseAscii( String( RTL_CONSTASCII_USTRINGPARAM("Picture") ) ) )
+ return new SbStdPicture;
+ else
+ if( rClassName.EqualsIgnoreCaseAscii( String( RTL_CONSTASCII_USTRINGPARAM("Font") ) ) )
+ return new SbStdFont;
+ else
+ return NULL;
+}
+
+//------------------------------------------------------------------------------
+
+
+
+void SbStdPicture::PropType( SbxVariable* pVar, SbxArray*, BOOL bWrite )
+{
+ if( bWrite )
+ {
+ StarBASIC::Error( SbERR_PROP_READONLY );
+ return;
+ }
+
+ GraphicType eType = aGraphic.GetType();
+ INT16 nType = 0;
+
+ if( eType == GRAPHIC_BITMAP )
+ nType = 1;
+ else
+ if( eType != GRAPHIC_NONE )
+ nType = 2;
+
+ pVar->PutInteger( nType );
+}
+
+
+void SbStdPicture::PropWidth( SbxVariable* pVar, SbxArray*, BOOL bWrite )
+{
+ if( bWrite )
+ {
+ StarBASIC::Error( SbERR_PROP_READONLY );
+ return;
+ }
+
+ Size aSize = aGraphic.GetPrefSize();
+ aSize = GetpApp()->GetAppWindow()->LogicToPixel( aSize, aGraphic.GetPrefMapMode() );
+ aSize = GetpApp()->GetAppWindow()->PixelToLogic( aSize, MapMode( MAP_TWIP ) );
+
+ pVar->PutInteger( (INT16)aSize.Width() );
+}
+
+void SbStdPicture::PropHeight( SbxVariable* pVar, SbxArray*, BOOL bWrite )
+{
+ if( bWrite )
+ {
+ StarBASIC::Error( SbERR_PROP_READONLY );
+ return;
+ }
+
+ Size aSize = aGraphic.GetPrefSize();
+ aSize = GetpApp()->GetAppWindow()->LogicToPixel( aSize, aGraphic.GetPrefMapMode() );
+ aSize = GetpApp()->GetAppWindow()->PixelToLogic( aSize, MapMode( MAP_TWIP ) );
+
+ pVar->PutInteger( (INT16)aSize.Height() );
+}
+
+
+TYPEINIT1( SbStdPicture, SbxObject );
+
+SbStdPicture::SbStdPicture() :
+ SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("Picture") ) )
+{
+ // Properties
+ SbxVariable* p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Type") ), SbxCLASS_PROPERTY, SbxVARIANT );
+ p->SetFlags( SBX_READ | SBX_DONTSTORE );
+ p->SetUserData( ATTR_IMP_TYPE );
+ p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Width") ), SbxCLASS_PROPERTY, SbxVARIANT );
+ p->SetFlags( SBX_READ | SBX_DONTSTORE );
+ p->SetUserData( ATTR_IMP_WIDTH );
+ p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Height") ), SbxCLASS_PROPERTY, SbxVARIANT );
+ p->SetFlags( SBX_READ | SBX_DONTSTORE );
+ p->SetUserData( ATTR_IMP_HEIGHT );
+}
+
+SbStdPicture::~SbStdPicture()
+{
+}
+
+
+SbxVariable* SbStdPicture::Find( const String& rName, SbxClassType t )
+{
+ // Bereits eingetragen?
+ return SbxObject::Find( rName, t );
+}
+
+
+
+void SbStdPicture::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType )
+
+{
+ const SbxHint* pHint = PTR_CAST( SbxHint, &rHint );
+
+ if( pHint )
+ {
+ if( pHint->GetId() == SBX_HINT_INFOWANTED )
+ {
+ SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+ return;
+ }
+
+ SbxVariable* pVar = pHint->GetVar();
+ SbxArray* pPar_ = pVar->GetParameters();
+ USHORT nWhich = (USHORT)pVar->GetUserData();
+ BOOL bWrite = pHint->GetId() == SBX_HINT_DATACHANGED;
+
+ // Propteries
+ switch( nWhich )
+ {
+ case ATTR_IMP_TYPE: PropType( pVar, pPar_, bWrite ); return;
+ case ATTR_IMP_WIDTH: PropWidth( pVar, pPar_, bWrite ); return;
+ case ATTR_IMP_HEIGHT: PropHeight( pVar, pPar_, bWrite ); return;
+ }
+
+ SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void SbStdFont::PropBold( SbxVariable* pVar, SbxArray*, BOOL bWrite )
+{
+ if( bWrite )
+ SetBold( pVar->GetBool() );
+ else
+ pVar->PutBool( IsBold() );
+}
+
+void SbStdFont::PropItalic( SbxVariable* pVar, SbxArray*, BOOL bWrite )
+{
+ if( bWrite )
+ SetItalic( pVar->GetBool() );
+ else
+ pVar->PutBool( IsItalic() );
+}
+
+void SbStdFont::PropStrikeThrough( SbxVariable* pVar, SbxArray*, BOOL bWrite )
+{
+ if( bWrite )
+ SetStrikeThrough( pVar->GetBool() );
+ else
+ pVar->PutBool( IsStrikeThrough() );
+}
+
+void SbStdFont::PropUnderline( SbxVariable* pVar, SbxArray*, BOOL bWrite )
+{
+ if( bWrite )
+ SetUnderline( pVar->GetBool() );
+ else
+ pVar->PutBool( IsUnderline() );
+}
+
+void SbStdFont::PropSize( SbxVariable* pVar, SbxArray*, BOOL bWrite )
+{
+ if( bWrite )
+ SetSize( (USHORT)pVar->GetInteger() );
+ else
+ pVar->PutInteger( (INT16)GetSize() );
+}
+
+void SbStdFont::PropName( SbxVariable* pVar, SbxArray*, BOOL bWrite )
+{
+ if( bWrite )
+ SetFontName( pVar->GetString() );
+ else
+ pVar->PutString( GetFontName() );
+}
+
+
+TYPEINIT1( SbStdFont, SbxObject );
+
+SbStdFont::SbStdFont() :
+ SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("Font") ) )
+{
+ // Properties
+ SbxVariable* p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Bold") ), SbxCLASS_PROPERTY, SbxVARIANT );
+ p->SetFlags( SBX_READWRITE | SBX_DONTSTORE );
+ p->SetUserData( ATTR_IMP_BOLD );
+ p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Italic") ), SbxCLASS_PROPERTY, SbxVARIANT );
+ p->SetFlags( SBX_READWRITE | SBX_DONTSTORE );
+ p->SetUserData( ATTR_IMP_ITALIC );
+ p = Make( String( RTL_CONSTASCII_USTRINGPARAM("StrikeThrough") ), SbxCLASS_PROPERTY, SbxVARIANT );
+ p->SetFlags( SBX_READWRITE | SBX_DONTSTORE );
+ p->SetUserData( ATTR_IMP_STRIKETHROUGH );
+ p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Underline") ), SbxCLASS_PROPERTY, SbxVARIANT );
+ p->SetFlags( SBX_READWRITE | SBX_DONTSTORE );
+ p->SetUserData( ATTR_IMP_UNDERLINE );
+ p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Size") ), SbxCLASS_PROPERTY, SbxVARIANT );
+ p->SetFlags( SBX_READWRITE | SBX_DONTSTORE );
+ p->SetUserData( ATTR_IMP_SIZE );
+
+ // Name Property selbst verarbeiten
+ p = Find( String( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_PROPERTY );
+ DBG_ASSERT( p, "Keine Name Property" );
+ p->SetUserData( ATTR_IMP_NAME );
+}
+
+SbStdFont::~SbStdFont()
+{
+}
+
+
+SbxVariable* SbStdFont::Find( const String& rName, SbxClassType t )
+{
+ // Bereits eingetragen?
+ return SbxObject::Find( rName, t );
+}
+
+
+
+void SbStdFont::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType )
+{
+ const SbxHint* pHint = PTR_CAST( SbxHint, &rHint );
+
+ if( pHint )
+ {
+ if( pHint->GetId() == SBX_HINT_INFOWANTED )
+ {
+ SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+ return;
+ }
+
+ SbxVariable* pVar = pHint->GetVar();
+ SbxArray* pPar_ = pVar->GetParameters();
+ USHORT nWhich = (USHORT)pVar->GetUserData();
+ BOOL bWrite = pHint->GetId() == SBX_HINT_DATACHANGED;
+
+ // Propteries
+ switch( nWhich )
+ {
+ case ATTR_IMP_BOLD: PropBold( pVar, pPar_, bWrite ); return;
+ case ATTR_IMP_ITALIC: PropItalic( pVar, pPar_, bWrite ); return;
+ case ATTR_IMP_STRIKETHROUGH:PropStrikeThrough( pVar, pPar_, bWrite ); return;
+ case ATTR_IMP_UNDERLINE: PropUnderline( pVar, pPar_, bWrite ); return;
+ case ATTR_IMP_SIZE: PropSize( pVar, pPar_, bWrite ); return;
+ case ATTR_IMP_NAME: PropName( pVar, pPar_, bWrite ); return;
+ }
+
+ SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+
+/*
+class TransferableHelperImpl : public TransferableHelper
+{
+ SotFormatStringId mFormat;
+ String mString;
+ Graphic mGraphic;
+
+ virtual void AddSupportedFormats();
+ virtual sal_Bool GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor );
+
+public:
+ TransferableHelperImpl( void ) { mFormat = 0; }
+ TransferableHelperImpl( const String& rStr )
+ mFormat( FORMAT_STRING ), mString( rStr ) {}
+ TransferableHelperImpl( const Graphic& rGraphic );
+ mFormat( FORMAT_BITMAP ), mGraphic( rGraphic ) {}
+
+};
+
+void TransferableHelperImpl::AddSupportedFormats()
+{
+}
+
+sal_Bool TransferableHelperImpl::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
+{
+ sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
+ if( nFormat == FORMAT_STRING )
+ {
+ }
+ else if( nFormat == FORMAT_BITMAP ||
+ nFormat == FORMAT_GDIMETAFILE )
+ {
+ }
+}
+*/
+
+void SbStdClipboard::MethClear( SbxVariable*, SbxArray* pPar_, BOOL )
+{
+ if( pPar_ && (pPar_->Count() > 1) )
+ {
+ StarBASIC::Error( SbERR_BAD_NUMBER_OF_ARGS );
+ return;
+ }
+
+ //Clipboard::Clear();
+}
+
+void SbStdClipboard::MethGetData( SbxVariable* pVar, SbxArray* pPar_, BOOL )
+{
+ (void)pVar;
+
+ if( !pPar_ || (pPar_->Count() != 2) )
+ {
+ StarBASIC::Error( SbERR_BAD_NUMBER_OF_ARGS );
+ return;
+ }
+
+ USHORT nFormat = pPar_->Get(1)->GetInteger();
+ if( !nFormat || nFormat > 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ /*
+ if( nFormat == FORMAT_STRING )
+ pVar->PutString( Clipboard::PasteString() );
+ else
+ if( (nFormat == FORMAT_BITMAP) ||
+ (nFormat == FORMAT_GDIMETAFILE ) )
+ {
+ SbxObjectRef xPic = new SbStdPicture;
+ Graphic aGraph;
+ aGraph.Paste();
+ ((SbStdPicture*)(SbxObject*)xPic)->SetGraphic( aGraph );
+ pVar->PutObject( xPic );
+ }
+ */
+}
+
+void SbStdClipboard::MethGetFormat( SbxVariable* pVar, SbxArray* pPar_, BOOL )
+{
+ if( !pPar_ || (pPar_->Count() != 2) )
+ {
+ StarBASIC::Error( SbERR_BAD_NUMBER_OF_ARGS );
+ return;
+ }
+
+ USHORT nFormat = pPar_->Get(1)->GetInteger();
+ if( !nFormat || nFormat > 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ pVar->PutBool( FALSE );
+ //pVar->PutBool( Clipboard::HasFormat( nFormat ) );
+}
+
+void SbStdClipboard::MethGetText( SbxVariable* pVar, SbxArray* pPar_, BOOL )
+{
+ if( pPar_ && (pPar_->Count() > 1) )
+ {
+ StarBASIC::Error( SbERR_BAD_NUMBER_OF_ARGS );
+ return;
+ }
+
+ pVar->PutString( String() );
+ //pVar->PutString( Clipboard::PasteString() );
+}
+
+void SbStdClipboard::MethSetData( SbxVariable* pVar, SbxArray* pPar_, BOOL )
+{
+ (void)pVar;
+
+ if( !pPar_ || (pPar_->Count() != 3) )
+ {
+ StarBASIC::Error( SbERR_BAD_NUMBER_OF_ARGS );
+ return;
+ }
+
+ USHORT nFormat = pPar_->Get(2)->GetInteger();
+ if( !nFormat || nFormat > 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ /*
+ if( nFormat == FORMAT_STRING )
+ {
+ Clipboard::CopyString( pPar_->Get(1)->GetString() );
+ }
+ else
+ if( (nFormat == FORMAT_BITMAP) ||
+ (nFormat == FORMAT_GDIMETAFILE) )
+ {
+ SbxObject* pObj = (SbxObject*)pPar_->Get(1)->GetObject();
+
+ if( pObj && pObj->IsA( TYPE( SbStdPicture ) ) )
+ ((SbStdPicture*)(SbxObject*)pObj)->GetGraphic().Copy();
+ }
+ */
+}
+
+void SbStdClipboard::MethSetText( SbxVariable* pVar, SbxArray* pPar_, BOOL )
+{
+ (void)pVar;
+
+ if( !pPar_ || (pPar_->Count() != 2) )
+ {
+ StarBASIC::Error( SbERR_BAD_NUMBER_OF_ARGS );
+ return;
+ }
+
+ // Clipboard::CopyString( pPar_->Get(1)->GetString() );
+}
+
+
+TYPEINIT1( SbStdClipboard, SbxObject );
+
+SbStdClipboard::SbStdClipboard() :
+ SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("Clipboard") ) )
+{
+ // Name Property selbst verarbeiten
+ SbxVariable* p = Find( String( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_PROPERTY );
+ DBG_ASSERT( p, "Keine Name Property" );
+ p->SetUserData( ATTR_IMP_NAME );
+
+ //Methoden registrieren
+ p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Clear") ), SbxCLASS_METHOD, SbxEMPTY );
+ p->SetFlag( SBX_DONTSTORE );
+ p->SetUserData( METH_CLEAR );
+ p = Make( String( RTL_CONSTASCII_USTRINGPARAM("GetData") ), SbxCLASS_METHOD, SbxEMPTY );
+ p->SetFlag( SBX_DONTSTORE );
+ p->SetUserData( METH_GETDATA );
+ p = Make( String( RTL_CONSTASCII_USTRINGPARAM("GetFormat") ), SbxCLASS_METHOD, SbxEMPTY );
+ p->SetFlag( SBX_DONTSTORE );
+ p->SetUserData( METH_GETFORMAT );
+ p = Make( String( RTL_CONSTASCII_USTRINGPARAM("GetText") ), SbxCLASS_METHOD, SbxEMPTY );
+ p->SetFlag( SBX_DONTSTORE );
+ p->SetUserData( METH_GETTEXT );
+ p = Make( String( RTL_CONSTASCII_USTRINGPARAM("SetData") ), SbxCLASS_METHOD, SbxEMPTY );
+ p->SetFlag( SBX_DONTSTORE );
+ p->SetUserData( METH_SETDATA );
+ p = Make( String( RTL_CONSTASCII_USTRINGPARAM("SetText") ), SbxCLASS_METHOD, SbxEMPTY );
+ p->SetFlag( SBX_DONTSTORE );
+ p->SetUserData( METH_SETTEXT );
+}
+
+SbStdClipboard::~SbStdClipboard()
+{
+}
+
+
+SbxVariable* SbStdClipboard::Find( const String& rName, SbxClassType t )
+{
+ // Bereits eingetragen?
+ return SbxObject::Find( rName, t );
+}
+
+
+
+void SbStdClipboard::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType )
+{
+ const SbxHint* pHint = PTR_CAST( SbxHint, &rHint );
+
+ if( pHint )
+ {
+ if( pHint->GetId() == SBX_HINT_INFOWANTED )
+ {
+ SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+ return;
+ }
+
+ SbxVariable* pVar = pHint->GetVar();
+ SbxArray* pPar_ = pVar->GetParameters();
+ USHORT nWhich = (USHORT)pVar->GetUserData();
+ BOOL bWrite = pHint->GetId() == SBX_HINT_DATACHANGED;
+
+ // Methods
+ switch( nWhich )
+ {
+ case METH_CLEAR: MethClear( pVar, pPar_, bWrite ); return;
+ case METH_GETDATA: MethGetData( pVar, pPar_, bWrite ); return;
+ case METH_GETFORMAT: MethGetFormat( pVar, pPar_, bWrite ); return;
+ case METH_GETTEXT: MethGetText( pVar, pPar_, bWrite ); return;
+ case METH_SETDATA: MethSetData( pVar, pPar_, bWrite ); return;
+ case METH_SETTEXT: MethSetText( pVar, pPar_, bWrite ); return;
+ }
+
+ SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+ }
+}
+
+
diff --git a/basic/source/runtime/step0.cxx b/basic/source/runtime/step0.cxx
new file mode 100644
index 000000000000..06a8bb19af00
--- /dev/null
+++ b/basic/source/runtime/step0.cxx
@@ -0,0 +1,1332 @@
+/*************************************************************************
+ *
+ * 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 <vcl/msgbox.hxx>
+#include <tools/fsys.hxx>
+
+#include "errobject.hxx"
+#include "runtime.hxx"
+#include "sbintern.hxx"
+#include "iosys.hxx"
+#include <sb.hrc>
+#include <basrid.hxx>
+#include "sbunoobj.hxx"
+#include "image.hxx"
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/util/SearchOptions.hdl>
+#include <vcl/svapp.hxx>
+#include <unotools/textsearch.hxx>
+
+Reference< XInterface > createComListener( const Any& aControlAny, const ::rtl::OUString& aVBAType,
+ const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj );
+
+#include <algorithm>
+
+SbxVariable* getDefaultProp( SbxVariable* pRef );
+
+void SbiRuntime::StepNOP()
+{}
+
+void SbiRuntime::StepArith( SbxOperator eOp )
+{
+ SbxVariableRef p1 = PopVar();
+ TOSMakeTemp();
+ SbxVariable* p2 = GetTOS();
+
+
+ // This could & should be moved to the MakeTempTOS() method in runtime.cxx
+ // In the code which this is cut'npaste from there is a check for a ref
+ // count != 1 based on which the copy of the SbxVariable is done.
+ // see orig code in MakeTempTOS ( and I'm not sure what the significance,
+ // of that is )
+ // here we alway seem to have a refcount of 1. Also it seems that
+ // MakeTempTOS is called for other operation, so I hold off for now
+ // until I have a better idea
+ if ( bVBAEnabled
+ && ( p2->GetType() == SbxOBJECT || p2->GetType() == SbxVARIANT )
+ )
+ {
+ SbxVariable* pDflt = getDefaultProp( p2 );
+ if ( pDflt )
+ {
+ pDflt->Broadcast( SBX_HINT_DATAWANTED );
+ // replacing new p2 on stack causes object pointed by
+ // pDft->pParent to be deleted, when p2->Compute() is
+ // called below pParent is accessed ( but its deleted )
+ // so set it to NULL now
+ pDflt->SetParent( NULL );
+ p2 = new SbxVariable( *pDflt );
+ p2->SetFlag( SBX_READWRITE );
+ refExprStk->Put( p2, nExprLvl - 1 );
+ }
+ }
+
+ p2->ResetFlag( SBX_FIXED );
+ p2->Compute( eOp, *p1 );
+
+ checkArithmeticOverflow( p2 );
+}
+
+void SbiRuntime::StepUnary( SbxOperator eOp )
+{
+ TOSMakeTemp();
+ SbxVariable* p = GetTOS();
+ p->Compute( eOp, *p );
+}
+
+void SbiRuntime::StepCompare( SbxOperator eOp )
+{
+ SbxVariableRef p1 = PopVar();
+ SbxVariableRef p2 = PopVar();
+
+ // Make sure objects with default params have
+ // values ( and type ) set as appropriate
+ SbxDataType p1Type = p1->GetType();
+ SbxDataType p2Type = p2->GetType();
+ if ( p1Type == p2Type )
+ {
+ if ( p1Type == SbxEMPTY )
+ {
+ p1->Broadcast( SBX_HINT_DATAWANTED );
+ p2->Broadcast( SBX_HINT_DATAWANTED );
+ }
+ // if both sides are an object and have default props
+ // then we need to use the default props
+ // we don't need to worry if only one side ( lhs, rhs ) is an
+ // object ( object side will get coerced to correct type in
+ // Compare )
+ else if ( p1Type == SbxOBJECT )
+ {
+ SbxVariable* pDflt = getDefaultProp( p1 );
+ if ( pDflt )
+ {
+ p1 = pDflt;
+ p1->Broadcast( SBX_HINT_DATAWANTED );
+ }
+ pDflt = getDefaultProp( p2 );
+ if ( pDflt )
+ {
+ p2 = pDflt;
+ p2->Broadcast( SBX_HINT_DATAWANTED );
+ }
+ }
+
+ }
+#ifndef WIN
+ static SbxVariable* pTRUE = NULL;
+ static SbxVariable* pFALSE = NULL;
+
+ if( p2->Compare( eOp, *p1 ) )
+ {
+ if( !pTRUE )
+ {
+ pTRUE = new SbxVariable;
+ pTRUE->PutBool( TRUE );
+ pTRUE->AddRef();
+ }
+ PushVar( pTRUE );
+ }
+ else
+ {
+ if( !pFALSE )
+ {
+ pFALSE = new SbxVariable;
+ pFALSE->PutBool( FALSE );
+ pFALSE->AddRef();
+ }
+ PushVar( pFALSE );
+ }
+#else
+ BOOL bRes = p2->Compare( eOp, *p1 );
+ SbxVariable* pRes = new SbxVariable;
+ pRes->PutBool( bRes );
+ PushVar( pRes );
+#endif
+}
+
+void SbiRuntime::StepEXP() { StepArith( SbxEXP ); }
+void SbiRuntime::StepMUL() { StepArith( SbxMUL ); }
+void SbiRuntime::StepDIV() { StepArith( SbxDIV ); }
+void SbiRuntime::StepIDIV() { StepArith( SbxIDIV ); }
+void SbiRuntime::StepMOD() { StepArith( SbxMOD ); }
+void SbiRuntime::StepPLUS() { StepArith( SbxPLUS ); }
+void SbiRuntime::StepMINUS() { StepArith( SbxMINUS ); }
+void SbiRuntime::StepCAT() { StepArith( SbxCAT ); }
+void SbiRuntime::StepAND() { StepArith( SbxAND ); }
+void SbiRuntime::StepOR() { StepArith( SbxOR ); }
+void SbiRuntime::StepXOR() { StepArith( SbxXOR ); }
+void SbiRuntime::StepEQV() { StepArith( SbxEQV ); }
+void SbiRuntime::StepIMP() { StepArith( SbxIMP ); }
+
+void SbiRuntime::StepNEG() { StepUnary( SbxNEG ); }
+void SbiRuntime::StepNOT() { StepUnary( SbxNOT ); }
+
+void SbiRuntime::StepEQ() { StepCompare( SbxEQ ); }
+void SbiRuntime::StepNE() { StepCompare( SbxNE ); }
+void SbiRuntime::StepLT() { StepCompare( SbxLT ); }
+void SbiRuntime::StepGT() { StepCompare( SbxGT ); }
+void SbiRuntime::StepLE() { StepCompare( SbxLE ); }
+void SbiRuntime::StepGE() { StepCompare( SbxGE ); }
+
+namespace
+{
+ bool NeedEsc(sal_Unicode cCode)
+ {
+ String sEsc(RTL_CONSTASCII_USTRINGPARAM(".^$+\\|{}()"));
+ return (STRING_NOTFOUND != sEsc.Search(cCode));
+ }
+
+ String VBALikeToRegexp(const String &rIn)
+ {
+ String sResult;
+ const sal_Unicode *start = rIn.GetBuffer();
+ const sal_Unicode *end = start + rIn.Len();
+
+ int seenright = 0;
+
+ sResult.Append('^');
+
+ while (start < end)
+ {
+ switch (*start)
+ {
+ case '?':
+ sResult.Append('.');
+ start++;
+ break;
+ case '*':
+ sResult.Append(String(RTL_CONSTASCII_USTRINGPARAM(".*")));
+ start++;
+ break;
+ case '#':
+ sResult.Append(String(RTL_CONSTASCII_USTRINGPARAM("[0-9]")));
+ start++;
+ break;
+ case ']':
+ sResult.Append('\\');
+ sResult.Append(*start++);
+ break;
+ case '[':
+ sResult.Append(*start++);
+ seenright = 0;
+ while (start < end && !seenright)
+ {
+ switch (*start)
+ {
+ case '[':
+ case '?':
+ case '*':
+ sResult.Append('\\');
+ sResult.Append(*start);
+ break;
+ case ']':
+ sResult.Append(*start);
+ seenright = 1;
+ break;
+ case '!':
+ sResult.Append('^');
+ break;
+ default:
+ if (NeedEsc(*start))
+ sResult.Append('\\');
+ sResult.Append(*start);
+ break;
+ }
+ start++;
+ }
+ break;
+ default:
+ if (NeedEsc(*start))
+ sResult.Append('\\');
+ sResult.Append(*start++);
+ }
+ }
+
+ sResult.Append('$');
+
+ return sResult;
+ }
+}
+
+void SbiRuntime::StepLIKE()
+{
+ SbxVariableRef refVar1 = PopVar();
+ SbxVariableRef refVar2 = PopVar();
+
+ String pattern = VBALikeToRegexp(refVar1->GetString());
+ String value = refVar2->GetString();
+
+ com::sun::star::util::SearchOptions aSearchOpt;
+
+ aSearchOpt.algorithmType = com::sun::star::util::SearchAlgorithms_REGEXP;
+
+ aSearchOpt.Locale = Application::GetSettings().GetLocale();
+ aSearchOpt.searchString = pattern;
+
+ int bTextMode(1);
+ bool bCompatibility = ( pINST && pINST->IsCompatibility() );
+ if( bCompatibility )
+ bTextMode = GetImageFlag( SBIMG_COMPARETEXT );
+
+ if( bTextMode )
+ aSearchOpt.transliterateFlags |= com::sun::star::i18n::TransliterationModules_IGNORE_CASE;
+
+ SbxVariable* pRes = new SbxVariable;
+ utl::TextSearch aSearch(aSearchOpt);
+ xub_StrLen nStart=0, nEnd=value.Len();
+ int bRes = aSearch.SearchFrwrd(value, &nStart, &nEnd);
+ pRes->PutBool( bRes != 0 );
+
+ PushVar( pRes );
+}
+
+// TOS und TOS-1 sind beides Objektvariable und enthalten den selben Pointer
+
+void SbiRuntime::StepIS()
+{
+ SbxVariableRef refVar1 = PopVar();
+ SbxVariableRef refVar2 = PopVar();
+
+ SbxDataType eType1 = refVar1->GetType();
+ SbxDataType eType2 = refVar2->GetType();
+ if ( eType1 == SbxEMPTY )
+ {
+ refVar1->Broadcast( SBX_HINT_DATAWANTED );
+ eType1 = refVar1->GetType();
+ }
+ if ( eType2 == SbxEMPTY )
+ {
+ refVar2->Broadcast( SBX_HINT_DATAWANTED );
+ eType2 = refVar2->GetType();
+ }
+
+ BOOL bRes = BOOL( eType1 == SbxOBJECT && eType2 == SbxOBJECT );
+ if ( bVBAEnabled && !bRes )
+ Error( SbERR_INVALID_USAGE_OBJECT );
+ bRes = ( bRes && refVar1->GetObject() == refVar2->GetObject() );
+ SbxVariable* pRes = new SbxVariable;
+ pRes->PutBool( bRes );
+ PushVar( pRes );
+}
+
+// Aktualisieren des Wertes von TOS
+
+void SbiRuntime::StepGET()
+{
+ SbxVariable* p = GetTOS();
+ p->Broadcast( SBX_HINT_DATAWANTED );
+}
+
+// #67607 Uno-Structs kopieren
+inline void checkUnoStructCopy( SbxVariableRef& refVal, SbxVariableRef& refVar )
+{
+ SbxDataType eVarType = refVar->GetType();
+ if( eVarType != SbxOBJECT )
+ return;
+
+ SbxObjectRef xValObj = (SbxObject*)refVal->GetObject();
+ if( !xValObj.Is() || xValObj->ISA(SbUnoAnyObject) )
+ return;
+
+ // #115826: Exclude ProcedureProperties to avoid call to Property Get procedure
+ if( refVar->ISA(SbProcedureProperty) )
+ return;
+
+ SbxObjectRef xVarObj = (SbxObject*)refVar->GetObject();
+ SbxDataType eValType = refVal->GetType();
+ if( eValType == SbxOBJECT && xVarObj == xValObj )
+ {
+ SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,(SbxObject*)xVarObj);
+ if( pUnoObj )
+ {
+ Any aAny = pUnoObj->getUnoAny();
+ if( aAny.getValueType().getTypeClass() == TypeClass_STRUCT )
+ {
+ SbUnoObject* pNewUnoObj = new SbUnoObject( pUnoObj->GetName(), aAny );
+ // #70324: ClassName uebernehmen
+ pNewUnoObj->SetClassName( pUnoObj->GetClassName() );
+ refVar->PutObject( pNewUnoObj );
+ }
+ }
+ }
+}
+
+
+// Ablage von TOS in TOS-1
+
+void SbiRuntime::StepPUT()
+{
+ SbxVariableRef refVal = PopVar();
+ SbxVariableRef refVar = PopVar();
+ // Store auf die eigene Methode (innerhalb einer Function)?
+ BOOL bFlagsChanged = FALSE;
+ USHORT n = 0;
+ if( (SbxVariable*) refVar == (SbxVariable*) pMeth )
+ {
+ bFlagsChanged = TRUE;
+ n = refVar->GetFlags();
+ refVar->SetFlag( SBX_WRITE );
+ }
+
+ // if left side arg is an object or variant and right handside isn't
+ // either an object or a variant then try and see if a default
+ // property exists.
+ // to use e.g. Range{"A1") = 34
+ // could equate to Range("A1").Value = 34
+ if ( bVBAEnabled )
+ {
+ if ( refVar->GetType() == SbxOBJECT )
+ {
+ SbxVariable* pDflt = getDefaultProp( refVar );
+ if ( pDflt )
+ refVar = pDflt;
+ }
+ if ( refVal->GetType() == SbxOBJECT )
+ {
+ SbxVariable* pDflt = getDefaultProp( refVal );
+ if ( pDflt )
+ refVal = pDflt;
+ }
+ }
+
+ *refVar = *refVal;
+ // lhs is a property who's value is currently null
+ if ( !bVBAEnabled || ( bVBAEnabled && refVar->GetType() != SbxEMPTY ) )
+ // #67607 Uno-Structs kopieren
+ checkUnoStructCopy( refVal, refVar );
+ if( bFlagsChanged )
+ refVar->SetFlags( n );
+}
+
+
+// Speichern Objektvariable
+// Nicht-Objekt-Variable fuehren zu Fehlern
+
+void SbiRuntime::StepSET_Impl( SbxVariableRef& refVal, SbxVariableRef& refVar, bool bHandleDefaultProp )
+{
+ // #67733 Typen mit Array-Flag sind auch ok
+
+ // Check var, !object is no error for sure if, only if type is fixed
+ SbxDataType eVarType = refVar->GetType();
+ if( !bHandleDefaultProp && eVarType != SbxOBJECT && !(eVarType & SbxARRAY) && refVar->IsFixed() )
+ {
+ Error( SbERR_INVALID_USAGE_OBJECT );
+ return;
+ }
+
+ // Check value, !object is no error for sure if, only if type is fixed
+ SbxDataType eValType = refVal->GetType();
+// bool bGetValObject = false;
+ if( !bHandleDefaultProp && eValType != SbxOBJECT && !(eValType & SbxARRAY) && refVal->IsFixed() )
+ {
+ Error( SbERR_INVALID_USAGE_OBJECT );
+ return;
+ }
+
+ // Getting in here causes problems with objects with default properties
+ // if they are SbxEMPTY I guess
+ if ( !bHandleDefaultProp || ( bHandleDefaultProp && eValType == SbxOBJECT ) )
+ {
+ // Auf refVal GetObject fuer Collections ausloesen
+ SbxBase* pObjVarObj = refVal->GetObject();
+ if( pObjVarObj )
+ {
+ SbxVariableRef refObjVal = PTR_CAST(SbxObject,pObjVarObj);
+
+ // #67733 Typen mit Array-Flag sind auch ok
+ if( refObjVal )
+ refVal = refObjVal;
+ else if( !(eValType & SbxARRAY) )
+ refVal = NULL;
+ }
+ }
+
+ // #52896 Wenn Uno-Sequences bzw. allgemein Arrays einer als
+ // Object deklarierten Variable zugewiesen werden, kann hier
+ // refVal ungueltig sein!
+ if( !refVal )
+ {
+ Error( SbERR_INVALID_USAGE_OBJECT );
+ }
+ else
+ {
+ // Store auf die eigene Methode (innerhalb einer Function)?
+ BOOL bFlagsChanged = FALSE;
+ USHORT n = 0;
+ if( (SbxVariable*) refVar == (SbxVariable*) pMeth )
+ {
+ bFlagsChanged = TRUE;
+ n = refVar->GetFlags();
+ refVar->SetFlag( SBX_WRITE );
+ }
+ SbProcedureProperty* pProcProperty = PTR_CAST(SbProcedureProperty,(SbxVariable*)refVar);
+ if( pProcProperty )
+ pProcProperty->setSet( true );
+
+ if ( bHandleDefaultProp )
+ {
+ // get default properties for lhs & rhs where necessary
+ // SbxVariable* defaultProp = NULL; unused variable
+ bool bLHSHasDefaultProp = false;
+ // LHS try determine if a default prop exists
+ if ( refVar->GetType() == SbxOBJECT )
+ {
+ SbxVariable* pDflt = getDefaultProp( refVar );
+ if ( pDflt )
+ {
+ refVar = pDflt;
+ bLHSHasDefaultProp = true;
+ }
+ }
+ // RHS only get a default prop is the rhs has one
+ if ( refVal->GetType() == SbxOBJECT )
+ {
+ // check if lhs is a null object
+ // if it is then use the object not the default property
+ SbxObject* pObj = NULL;
+
+
+ pObj = PTR_CAST(SbxObject,(SbxVariable*)refVar);
+
+ // calling GetObject on a SbxEMPTY variable raises
+ // object not set errors, make sure its an Object
+ if ( !pObj && refVar->GetType() == SbxOBJECT )
+ {
+ SbxBase* pObjVarObj = refVar->GetObject();
+ pObj = PTR_CAST(SbxObject,pObjVarObj);
+ }
+ SbxVariable* pDflt = NULL;
+ if ( pObj || bLHSHasDefaultProp )
+ // lhs is either a valid object || or has a defaultProp
+ pDflt = getDefaultProp( refVal );
+ if ( pDflt )
+ refVal = pDflt;
+ }
+ }
+
+ // Handle withevents
+ BOOL bWithEvents = refVar->IsSet( SBX_WITH_EVENTS );
+ if ( bWithEvents )
+ {
+ Reference< XInterface > xComListener;
+
+ SbxBase* pObj = refVal->GetObject();
+ SbUnoObject* pUnoObj = (pObj != NULL) ? PTR_CAST(SbUnoObject,pObj) : NULL;
+ if( pUnoObj != NULL )
+ {
+ Any aControlAny = pUnoObj->getUnoAny();
+ String aDeclareClassName = refVar->GetDeclareClassName();
+ ::rtl::OUString aVBAType = aDeclareClassName;
+ ::rtl::OUString aPrefix = refVar->GetName();
+ SbxObjectRef xScopeObj = refVar->GetParent();
+ xComListener = createComListener( aControlAny, aVBAType, aPrefix, xScopeObj );
+
+ refVal->SetDeclareClassName( aDeclareClassName );
+ refVal->SetComListener( xComListener ); // Hold reference
+ }
+
+ *refVar = *refVal;
+ }
+ else
+ {
+ *refVar = *refVal;
+ }
+
+ // lhs is a property who's value is currently (Empty e.g. no broadcast yet)
+ // in this case if there is a default prop involved the value of the
+ // default property may infact be void so the type will also be SbxEMPTY
+ // in this case we do not want to call checkUnoStructCopy 'cause that will
+ // cause an error also
+ if ( !bHandleDefaultProp || ( bHandleDefaultProp && ( refVar->GetType() != SbxEMPTY ) ) )
+ // #67607 Uno-Structs kopieren
+ checkUnoStructCopy( refVal, refVar );
+ if( bFlagsChanged )
+ refVar->SetFlags( n );
+ }
+}
+
+void SbiRuntime::StepSET()
+{
+ SbxVariableRef refVal = PopVar();
+ SbxVariableRef refVar = PopVar();
+ StepSET_Impl( refVal, refVar, bVBAEnabled ); // this is really assigment
+}
+
+void SbiRuntime::StepVBASET()
+{
+ SbxVariableRef refVal = PopVar();
+ SbxVariableRef refVar = PopVar();
+ // don't handle default property
+ StepSET_Impl( refVal, refVar, false ); // set obj = something
+}
+
+
+// JSM 07.10.95
+void SbiRuntime::StepLSET()
+{
+ SbxVariableRef refVal = PopVar();
+ SbxVariableRef refVar = PopVar();
+ if( refVar->GetType() != SbxSTRING
+ || refVal->GetType() != SbxSTRING )
+ Error( SbERR_INVALID_USAGE_OBJECT );
+ else
+ {
+ // Store auf die eigene Methode (innerhalb einer Function)?
+ USHORT n = refVar->GetFlags();
+ if( (SbxVariable*) refVar == (SbxVariable*) pMeth )
+ refVar->SetFlag( SBX_WRITE );
+ String aRefVarString = refVar->GetString();
+ String aRefValString = refVal->GetString();
+
+ USHORT nVarStrLen = aRefVarString.Len();
+ USHORT nValStrLen = aRefValString.Len();
+ String aNewStr;
+ if( nVarStrLen > nValStrLen )
+ {
+ aRefVarString.Fill(nVarStrLen,' ');
+ aNewStr = aRefValString.Copy( 0, nValStrLen );
+ aNewStr += aRefVarString.Copy( nValStrLen, nVarStrLen - nValStrLen );
+ }
+ else
+ {
+ aNewStr = aRefValString.Copy( 0, nVarStrLen );
+ }
+
+ refVar->PutString( aNewStr );
+ refVar->SetFlags( n );
+ }
+}
+
+// JSM 07.10.95
+void SbiRuntime::StepRSET()
+{
+ SbxVariableRef refVal = PopVar();
+ SbxVariableRef refVar = PopVar();
+ if( refVar->GetType() != SbxSTRING
+ || refVal->GetType() != SbxSTRING )
+ Error( SbERR_INVALID_USAGE_OBJECT );
+ else
+ {
+ // Store auf die eigene Methode (innerhalb einer Function)?
+ USHORT n = refVar->GetFlags();
+ if( (SbxVariable*) refVar == (SbxVariable*) pMeth )
+ refVar->SetFlag( SBX_WRITE );
+ String aRefVarString = refVar->GetString();
+ String aRefValString = refVal->GetString();
+
+ USHORT nPos = 0;
+ USHORT nVarStrLen = aRefVarString.Len();
+ if( nVarStrLen > aRefValString.Len() )
+ {
+ aRefVarString.Fill(nVarStrLen,' ');
+ nPos = nVarStrLen - aRefValString.Len();
+ }
+ aRefVarString = aRefVarString.Copy( 0, nPos );
+ aRefVarString += aRefValString.Copy( 0, nVarStrLen - nPos );
+ refVar->PutString(aRefVarString);
+
+ refVar->SetFlags( n );
+ }
+}
+
+// Ablage von TOS in TOS-1, dann ReadOnly-Bit setzen
+
+void SbiRuntime::StepPUTC()
+{
+ SbxVariableRef refVal = PopVar();
+ SbxVariableRef refVar = PopVar();
+ refVar->SetFlag( SBX_WRITE );
+ *refVar = *refVal;
+ refVar->ResetFlag( SBX_WRITE );
+ refVar->SetFlag( SBX_CONST );
+}
+
+// DIM
+// TOS = Variable fuer das Array mit Dimensionsangaben als Parameter
+
+void SbiRuntime::StepDIM()
+{
+ SbxVariableRef refVar = PopVar();
+ DimImpl( refVar );
+}
+
+// #56204 DIM-Funktionalitaet in Hilfsmethode auslagern (step0.cxx)
+void SbiRuntime::DimImpl( SbxVariableRef refVar )
+{
+ SbxArray* pDims = refVar->GetParameters();
+ // Muss eine gerade Anzahl Argumente haben
+ // Man denke daran, dass Arg[0] nicht zaehlt!
+ if( pDims && !( pDims->Count() & 1 ) )
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ else
+ {
+ SbxDataType eType = refVar->IsFixed() ? refVar->GetType() : SbxVARIANT;
+ SbxDimArray* pArray = new SbxDimArray( eType );
+ // AB 2.4.1996, auch Arrays ohne Dimensionsangaben zulassen (VB-komp.)
+ if( pDims )
+ {
+ for( USHORT i = 1; i < pDims->Count(); )
+ {
+ INT32 lb = pDims->Get( i++ )->GetLong();
+ INT32 ub = pDims->Get( i++ )->GetLong();
+ if( ub < lb )
+ Error( SbERR_OUT_OF_RANGE ), ub = lb;
+ pArray->AddDim32( lb, ub );
+ if ( lb != ub )
+ pArray->setHasFixedSize( true );
+ }
+ }
+ else
+ {
+ // #62867 Beim Anlegen eines Arrays der Laenge 0 wie bei
+ // Uno-Sequences der Laenge 0 eine Dimension anlegen
+ pArray->unoAddDim( 0, -1 );
+ }
+ USHORT nSavFlags = refVar->GetFlags();
+ refVar->ResetFlag( SBX_FIXED );
+ refVar->PutObject( pArray );
+ refVar->SetFlags( nSavFlags );
+ refVar->SetParameters( NULL );
+ }
+}
+
+// REDIM
+// TOS = Variable fuer das Array
+// argv = Dimensionsangaben
+
+void SbiRuntime::StepREDIM()
+{
+ // Im Moment ist es nichts anderes als Dim, da doppeltes Dim
+ // bereits vom Compiler erkannt wird.
+ StepDIM();
+}
+
+
+// Helper function for StepREDIMP
+void implCopyDimArray( SbxDimArray* pNewArray, SbxDimArray* pOldArray, short nMaxDimIndex,
+ short nActualDim, sal_Int32* pActualIndices, sal_Int32* pLowerBounds, sal_Int32* pUpperBounds )
+{
+ sal_Int32& ri = pActualIndices[nActualDim];
+ for( ri = pLowerBounds[nActualDim] ; ri <= pUpperBounds[nActualDim] ; ri++ )
+ {
+ if( nActualDim < nMaxDimIndex )
+ {
+ implCopyDimArray( pNewArray, pOldArray, nMaxDimIndex, nActualDim + 1,
+ pActualIndices, pLowerBounds, pUpperBounds );
+ }
+ else
+ {
+ SbxVariable* pSource = pOldArray->Get32( pActualIndices );
+ SbxVariable* pDest = pNewArray->Get32( pActualIndices );
+ if( pSource && pDest )
+ *pDest = *pSource;
+ }
+ }
+}
+
+// REDIM PRESERVE
+// TOS = Variable fuer das Array
+// argv = Dimensionsangaben
+
+void SbiRuntime::StepREDIMP()
+{
+ SbxVariableRef refVar = PopVar();
+ DimImpl( refVar );
+
+ // Now check, if we can copy from the old array
+ if( refRedimpArray.Is() )
+ {
+ SbxBase* pElemObj = refVar->GetObject();
+ SbxDimArray* pNewArray = PTR_CAST(SbxDimArray,pElemObj);
+ SbxDimArray* pOldArray = (SbxDimArray*)(SbxArray*)refRedimpArray;
+ if( pNewArray )
+ {
+ short nDimsNew = pNewArray->GetDims();
+ short nDimsOld = pOldArray->GetDims();
+ short nDims = nDimsNew;
+ BOOL bRangeError = FALSE;
+
+ // Store dims to use them for copying later
+ sal_Int32* pLowerBounds = new sal_Int32[nDims];
+ sal_Int32* pUpperBounds = new sal_Int32[nDims];
+ sal_Int32* pActualIndices = new sal_Int32[nDims];
+
+ if( nDimsOld != nDimsNew )
+ {
+ bRangeError = TRUE;
+ }
+ else
+ {
+ // Compare bounds
+ for( short i = 1 ; i <= nDims ; i++ )
+ {
+ sal_Int32 lBoundNew, uBoundNew;
+ sal_Int32 lBoundOld, uBoundOld;
+ pNewArray->GetDim32( i, lBoundNew, uBoundNew );
+ pOldArray->GetDim32( i, lBoundOld, uBoundOld );
+
+ /* #69094 Allow all dimensions to be changed
+ although Visual Basic is not able to do so.
+ // All bounds but the last have to be the same
+ if( i < nDims && ( lBoundNew != lBoundOld || uBoundNew != uBoundOld ) )
+ {
+ bRangeError = TRUE;
+ break;
+ }
+ else
+ */
+ {
+ // #69094: if( i == nDims )
+ {
+ lBoundNew = std::max( lBoundNew, lBoundOld );
+ uBoundNew = std::min( uBoundNew, uBoundOld );
+ }
+ short j = i - 1;
+ pActualIndices[j] = pLowerBounds[j] = lBoundNew;
+ pUpperBounds[j] = uBoundNew;
+ }
+ }
+ }
+
+ if( bRangeError )
+ {
+ StarBASIC::Error( SbERR_OUT_OF_RANGE );
+ }
+ else
+ {
+ // Copy data from old array by going recursively through all dimensions
+ // (It would be faster to work on the flat internal data array of an
+ // SbyArray but this solution is clearer and easier)
+ implCopyDimArray( pNewArray, pOldArray, nDims - 1,
+ 0, pActualIndices, pLowerBounds, pUpperBounds );
+ }
+
+ delete[] pUpperBounds;
+ delete[] pLowerBounds;
+ delete[] pActualIndices;
+ refRedimpArray = NULL;
+ }
+ }
+
+ //StarBASIC::FatalError( SbERR_NOT_IMPLEMENTED );
+}
+
+// REDIM_COPY
+// TOS = Array-Variable, Reference to array is copied
+// Variable is cleared as in ERASE
+
+void SbiRuntime::StepREDIMP_ERASE()
+{
+ SbxVariableRef refVar = PopVar();
+ SbxDataType eType = refVar->GetType();
+ if( eType & SbxARRAY )
+ {
+ SbxBase* pElemObj = refVar->GetObject();
+ SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj);
+ if( pDimArray )
+ {
+ refRedimpArray = pDimArray;
+ }
+
+ // As in ERASE
+ USHORT nSavFlags = refVar->GetFlags();
+ refVar->ResetFlag( SBX_FIXED );
+ refVar->SetType( SbxDataType(eType & 0x0FFF) );
+ refVar->SetFlags( nSavFlags );
+ refVar->Clear();
+ }
+ else
+ if( refVar->IsFixed() )
+ refVar->Clear();
+ else
+ refVar->SetType( SbxEMPTY );
+}
+
+void lcl_clearImpl( SbxVariableRef& refVar, SbxDataType& eType )
+{
+ USHORT nSavFlags = refVar->GetFlags();
+ refVar->ResetFlag( SBX_FIXED );
+ refVar->SetType( SbxDataType(eType & 0x0FFF) );
+ refVar->SetFlags( nSavFlags );
+ refVar->Clear();
+}
+
+void lcl_eraseImpl( SbxVariableRef& refVar, bool bVBAEnabled )
+{
+ SbxDataType eType = refVar->GetType();
+ if( eType & SbxARRAY )
+ {
+ if ( bVBAEnabled )
+ {
+ SbxBase* pElemObj = refVar->GetObject();
+ SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj);
+ bool bClearValues = true;
+ if( pDimArray )
+ {
+ if ( pDimArray->hasFixedSize() )
+ {
+ // Clear all Value(s)
+ pDimArray->SbxArray::Clear();
+ bClearValues = false;
+ }
+ else
+ pDimArray->Clear(); // clear Dims
+ }
+ if ( bClearValues )
+ {
+ SbxArray* pArray = PTR_CAST(SbxArray,pElemObj);
+ if ( pArray )
+ pArray->Clear();
+ }
+ }
+ else
+ // AB 2.4.1996
+ // Arrays haben bei Erase nach VB ein recht komplexes Verhalten. Hier
+ // werden zunaechst nur die Typ-Probleme bei REDIM (#26295) beseitigt:
+ // Typ hart auf den Array-Typ setzen, da eine Variable mit Array
+ // SbxOBJECT ist. Bei REDIM entsteht dann ein SbxOBJECT-Array und
+ // der ursruengliche Typ geht verloren -> Laufzeitfehler
+ lcl_clearImpl( refVar, eType );
+ }
+ else
+ if( refVar->IsFixed() )
+ refVar->Clear();
+ else
+ refVar->SetType( SbxEMPTY );
+}
+
+// Variable loeschen
+// TOS = Variable
+
+void SbiRuntime::StepERASE()
+{
+ SbxVariableRef refVar = PopVar();
+ lcl_eraseImpl( refVar, bVBAEnabled );
+}
+
+void SbiRuntime::StepERASE_CLEAR()
+{
+ SbxVariableRef refVar = PopVar();
+ lcl_eraseImpl( refVar, bVBAEnabled );
+ SbxDataType eType = refVar->GetType();
+ lcl_clearImpl( refVar, eType );
+}
+
+void SbiRuntime::StepARRAYACCESS()
+{
+ if( !refArgv )
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ SbxVariableRef refVar = PopVar();
+ refVar->SetParameters( refArgv );
+ PopArgv();
+ PushVar( CheckArray( refVar ) );
+}
+
+void SbiRuntime::StepBYVAL()
+{
+ // Copy variable on stack to break call by reference
+ SbxVariableRef pVar = PopVar();
+ SbxDataType t = pVar->GetType();
+
+ SbxVariable* pCopyVar = new SbxVariable( t );
+ pCopyVar->SetFlag( SBX_READWRITE );
+ *pCopyVar = *pVar;
+
+ PushVar( pCopyVar );
+}
+
+// Einrichten eines Argvs
+// nOp1 bleibt so -> 1. Element ist Returnwert
+
+void SbiRuntime::StepARGC()
+{
+ PushArgv();
+ refArgv = new SbxArray;
+ nArgc = 1;
+}
+
+// Speichern eines Arguments in Argv
+
+void SbiRuntime::StepARGV()
+{
+ if( !refArgv )
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ else
+ {
+ SbxVariableRef pVal = PopVar();
+
+ // Before fix of #94916:
+ // if( pVal->ISA(SbxMethod) || pVal->ISA(SbxProperty) )
+ if( pVal->ISA(SbxMethod) || pVal->ISA(SbUnoProperty) || pVal->ISA(SbProcedureProperty) )
+ {
+ // Methoden und Properties evaluieren!
+ SbxVariable* pRes = new SbxVariable( *pVal );
+ pVal = pRes;
+ }
+ refArgv->Put( pVal, nArgc++ );
+ }
+}
+
+// Input to Variable. Die Variable ist auf TOS und wird
+// anschliessend entfernt.
+
+void SbiRuntime::StepINPUT()
+{
+ String s;
+ char ch = 0;
+ SbError err;
+ // Skip whitespace
+ while( ( err = pIosys->GetError() ) == 0 )
+ {
+ ch = pIosys->Read();
+ if( ch != ' ' && ch != '\t' && ch != '\n' )
+ break;
+ }
+ if( !err )
+ {
+ // Scan until comma or whitespace
+ char sep = ( ch == '"' ) ? ch : 0;
+ if( sep ) ch = pIosys->Read();
+ while( ( err = pIosys->GetError() ) == 0 )
+ {
+ if( ch == sep )
+ {
+ ch = pIosys->Read();
+ if( ch != sep )
+ break;
+ }
+ else if( !sep && (ch == ',' || ch == '\n') )
+ break;
+ s += ch;
+ ch = pIosys->Read();
+ }
+ // skip whitespace
+ if( ch == ' ' || ch == '\t' )
+ while( ( err = pIosys->GetError() ) == 0 )
+ {
+ if( ch != ' ' && ch != '\t' && ch != '\n' )
+ break;
+ ch = pIosys->Read();
+ }
+ }
+ if( !err )
+ {
+ SbxVariableRef pVar = GetTOS();
+ // Zuerst versuchen, die Variable mit einem numerischen Wert
+ // zu fuellen, dann mit einem Stringwert
+ if( !pVar->IsFixed() || pVar->IsNumeric() )
+ {
+ USHORT nLen = 0;
+ if( !pVar->Scan( s, &nLen ) )
+ {
+ err = SbxBase::GetError();
+ SbxBase::ResetError();
+ }
+ // Der Wert muss komplett eingescant werden
+ else if( nLen != s.Len() && !pVar->PutString( s ) )
+ {
+ err = SbxBase::GetError();
+ SbxBase::ResetError();
+ }
+ else if( nLen != s.Len() && pVar->IsNumeric() )
+ {
+ err = SbxBase::GetError();
+ SbxBase::ResetError();
+ if( !err )
+ err = SbERR_CONVERSION;
+ }
+ }
+ else
+ {
+ pVar->PutString( s );
+ err = SbxBase::GetError();
+ SbxBase::ResetError();
+ }
+ }
+ if( err == SbERR_USER_ABORT )
+ Error( err );
+ else if( err )
+ {
+ if( pRestart && !pIosys->GetChannel() )
+ {
+ BasResId aId( IDS_SBERR_START + 4 );
+ String aMsg( aId );
+
+ //****** DONT CHECK IN, TEST ONLY *******
+ //****** DONT CHECK IN, TEST ONLY *******
+ // ErrorBox( NULL, WB_OK, aMsg ).Execute();
+ //****** DONT CHECK IN, TEST ONLY *******
+ //****** DONT CHECK IN, TEST ONLY *******
+
+ pCode = pRestart;
+ }
+ else
+ Error( err );
+ }
+ else
+ {
+ // pIosys->ResetChannel();
+ PopVar();
+ }
+}
+
+// Line Input to Variable. Die Variable ist auf TOS und wird
+// anschliessend entfernt.
+
+void SbiRuntime::StepLINPUT()
+{
+ ByteString aInput;
+ pIosys->Read( aInput );
+ Error( pIosys->GetError() );
+ SbxVariableRef p = PopVar();
+ p->PutString( String( aInput, gsl_getSystemTextEncoding() ) );
+ // pIosys->ResetChannel();
+}
+
+// Programmende
+
+void SbiRuntime::StepSTOP()
+{
+ pInst->Stop();
+}
+
+// FOR-Variable initialisieren
+
+void SbiRuntime::StepINITFOR()
+{
+ PushFor();
+}
+
+void SbiRuntime::StepINITFOREACH()
+{
+ PushForEach();
+}
+
+// FOR-Variable inkrementieren
+
+void SbiRuntime::StepNEXT()
+{
+ if( !pForStk )
+ {
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ return;
+ }
+ if( pForStk->eForType == FOR_TO )
+ pForStk->refVar->Compute( SbxPLUS, *pForStk->refInc );
+}
+
+// Anfang CASE: TOS in CASE-Stack
+
+void SbiRuntime::StepCASE()
+{
+ if( !refCaseStk.Is() )
+ refCaseStk = new SbxArray;
+ SbxVariableRef xVar = PopVar();
+ refCaseStk->Put( xVar, refCaseStk->Count() );
+}
+
+// Ende CASE: Variable freigeben
+
+void SbiRuntime::StepENDCASE()
+{
+ if( !refCaseStk || !refCaseStk->Count() )
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ else
+ refCaseStk->Remove( refCaseStk->Count() - 1 );
+}
+
+// Standard-Fehlerbehandlung
+
+void SbiRuntime::StepSTDERROR()
+{
+ pError = NULL; bError = TRUE;
+ pInst->aErrorMsg = String();
+ pInst->nErr = 0L;
+ pInst->nErl = 0;
+ nError = 0L;
+ SbxErrObject::getUnoErrObject()->Clear();
+}
+
+void SbiRuntime::StepNOERROR()
+{
+ pInst->aErrorMsg = String();
+ pInst->nErr = 0L;
+ pInst->nErl = 0;
+ nError = 0L;
+ SbxErrObject::getUnoErrObject()->Clear();
+ bError = FALSE;
+}
+
+// UP verlassen
+
+void SbiRuntime::StepLEAVE()
+{
+ bRun = FALSE;
+ // If VBA and we are leaving an ErrorHandler then clear the error ( it's been processed )
+ if ( bInError && pError )
+ SbxErrObject::getUnoErrObject()->Clear();
+}
+
+void SbiRuntime::StepCHANNEL() // TOS = Kanalnummer
+{
+ SbxVariableRef pChan = PopVar();
+ short nChan = pChan->GetInteger();
+ pIosys->SetChannel( nChan );
+ Error( pIosys->GetError() );
+}
+
+void SbiRuntime::StepCHANNEL0()
+{
+ pIosys->ResetChannel();
+}
+
+void SbiRuntime::StepPRINT() // print TOS
+{
+ SbxVariableRef p = PopVar();
+ String s1 = p->GetString();
+ String s;
+ if( p->GetType() >= SbxINTEGER && p->GetType() <= SbxDOUBLE )
+ s = ' '; // ein Blank davor
+ s += s1;
+ ByteString aByteStr( s, gsl_getSystemTextEncoding() );
+ pIosys->Write( aByteStr );
+ Error( pIosys->GetError() );
+}
+
+void SbiRuntime::StepPRINTF() // print TOS in field
+{
+ SbxVariableRef p = PopVar();
+ String s1 = p->GetString();
+ String s;
+ if( p->GetType() >= SbxINTEGER && p->GetType() <= SbxDOUBLE )
+ s = ' '; // ein Blank davor
+ s += s1;
+ s.Expand( 14, ' ' );
+ ByteString aByteStr( s, gsl_getSystemTextEncoding() );
+ pIosys->Write( aByteStr );
+ Error( pIosys->GetError() );
+}
+
+void SbiRuntime::StepWRITE() // write TOS
+{
+ SbxVariableRef p = PopVar();
+ // Muss der String gekapselt werden?
+ char ch = 0;
+ switch (p->GetType() )
+ {
+ case SbxSTRING: ch = '"'; break;
+ case SbxCURRENCY:
+ case SbxBOOL:
+ case SbxDATE: ch = '#'; break;
+ default: break;
+ }
+ String s;
+ if( ch )
+ s += ch;
+ s += p->GetString();
+ if( ch )
+ s += ch;
+ ByteString aByteStr( s, gsl_getSystemTextEncoding() );
+ pIosys->Write( aByteStr );
+ Error( pIosys->GetError() );
+}
+
+void SbiRuntime::StepRENAME() // Rename Tos+1 to Tos
+{
+ SbxVariableRef pTos1 = PopVar();
+ SbxVariableRef pTos = PopVar();
+ String aDest = pTos1->GetString();
+ String aSource = pTos->GetString();
+
+ // <-- UCB
+ if( hasUno() )
+ {
+ implStepRenameUCB( aSource, aDest );
+ }
+ else
+ // --> UCB
+ {
+#ifdef _OLD_FILE_IMPL
+ DirEntry aSourceDirEntry( aSource );
+ if( aSourceDirEntry.Exists() )
+ {
+ if( aSourceDirEntry.MoveTo( DirEntry(aDest) ) != FSYS_ERR_OK )
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+ }
+ else
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+#else
+ implStepRenameOSL( aSource, aDest );
+#endif
+ }
+}
+
+// TOS = Prompt
+
+void SbiRuntime::StepPROMPT()
+{
+ SbxVariableRef p = PopVar();
+ ByteString aStr( p->GetString(), gsl_getSystemTextEncoding() );
+ pIosys->SetPrompt( aStr );
+}
+
+// Set Restart point
+
+void SbiRuntime::StepRESTART()
+{
+ pRestart = pCode;
+}
+
+// Leerer Ausdruck auf Stack fuer fehlenden Parameter
+
+void SbiRuntime::StepEMPTY()
+{
+ // #57915 Die Semantik von StepEMPTY() ist die Repraesentation eines fehlenden
+ // Arguments. Dies wird in VB durch ein durch den Wert 448 (SbERR_NAMED_NOT_FOUND)
+ // vom Typ Error repraesentiert. StepEmpty jetzt muesste besser StepMISSING()
+ // heissen, aber der Name wird der Einfachkeit halber beibehalten.
+ SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
+ xVar->PutErr( 448 );
+ PushVar( xVar );
+ // ALT: PushVar( new SbxVariable( SbxEMPTY ) );
+}
+
+// TOS = Fehlercode
+
+void SbiRuntime::StepERROR()
+{
+ SbxVariableRef refCode = PopVar();
+ USHORT n = refCode->GetUShort();
+ SbError error = StarBASIC::GetSfxFromVBError( n );
+ if ( bVBAEnabled )
+ pInst->Error( error );
+ else
+ Error( error );
+}
+
diff --git a/basic/source/runtime/step1.cxx b/basic/source/runtime/step1.cxx
new file mode 100644
index 000000000000..e23ef864218e
--- /dev/null
+++ b/basic/source/runtime/step1.cxx
@@ -0,0 +1,574 @@
+/*************************************************************************
+ *
+ * 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 <stdlib.h>
+#include <rtl/math.hxx>
+#include <basic/sbuno.hxx>
+#include "runtime.hxx"
+#include "sbintern.hxx"
+#include "iosys.hxx"
+#include "image.hxx"
+#include "sbunoobj.hxx"
+#include "errobject.hxx"
+
+bool checkUnoObjectType( SbUnoObject* refVal,
+ const String& aClass );
+
+// Laden einer numerischen Konstanten (+ID)
+
+void SbiRuntime::StepLOADNC( UINT32 nOp1 )
+{
+ SbxVariable* p = new SbxVariable( SbxDOUBLE );
+
+ // #57844 Lokalisierte Funktion benutzen
+ String aStr = pImg->GetString( static_cast<short>( nOp1 ) );
+ // Auch , zulassen !!!
+ USHORT iComma = aStr.Search( ',' );
+ if( iComma != STRING_NOTFOUND )
+ {
+ String aStr1 = aStr.Copy( 0, iComma );
+ String aStr2 = aStr.Copy( iComma + 1 );
+ aStr = aStr1;
+ aStr += '.';
+ aStr += aStr2;
+ }
+ double n = ::rtl::math::stringToDouble( aStr, '.', ',', NULL, NULL );
+
+ p->PutDouble( n );
+ PushVar( p );
+}
+
+// Laden einer Stringkonstanten (+ID)
+
+void SbiRuntime::StepLOADSC( UINT32 nOp1 )
+{
+ SbxVariable* p = new SbxVariable;
+ p->PutString( pImg->GetString( static_cast<short>( nOp1 ) ) );
+ PushVar( p );
+}
+
+// Immediate Load (+Wert)
+
+void SbiRuntime::StepLOADI( UINT32 nOp1 )
+{
+ SbxVariable* p = new SbxVariable;
+ p->PutInteger( static_cast<INT16>( nOp1 ) );
+ PushVar( p );
+}
+
+// Speichern eines named Arguments in Argv (+Arg-Nr ab 1!)
+
+void SbiRuntime::StepARGN( UINT32 nOp1 )
+{
+ if( !refArgv )
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ else
+ {
+ String aAlias( pImg->GetString( static_cast<short>( nOp1 ) ) );
+ SbxVariableRef pVal = PopVar();
+ refArgv->Put( pVal, nArgc );
+ refArgv->PutAlias( aAlias, nArgc++ );
+ }
+}
+
+// Konvertierung des Typs eines Arguments in Argv fuer DECLARE-Fkt. (+Typ)
+
+void SbiRuntime::StepARGTYP( UINT32 nOp1 )
+{
+ if( !refArgv )
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ else
+ {
+ BOOL bByVal = (nOp1 & 0x8000) != 0; // Ist BYVAL verlangt?
+ SbxDataType t = (SbxDataType) (nOp1 & 0x7FFF);
+ SbxVariable* pVar = refArgv->Get( refArgv->Count() - 1 ); // letztes Arg
+
+ // BYVAL prüfen
+ if( pVar->GetRefCount() > 2 ) // 2 ist normal für BYVAL
+ {
+ // Parameter ist eine Referenz
+ if( bByVal )
+ {
+ // Call by Value ist verlangt -> Kopie anlegen
+ pVar = new SbxVariable( *pVar );
+ pVar->SetFlag( SBX_READWRITE );
+ refExprStk->Put( pVar, refArgv->Count() - 1 );
+ }
+ else
+ pVar->SetFlag( SBX_REFERENCE ); // Ref-Flag für DllMgr
+ }
+ else
+ {
+ // Parameter ist KEINE Referenz
+ if( bByVal )
+ pVar->ResetFlag( SBX_REFERENCE ); // Keine Referenz -> OK
+ else
+ Error( SbERR_BAD_PARAMETERS ); // Referenz verlangt
+ }
+
+ if( pVar->GetType() != t )
+ {
+ // Variant, damit richtige Konvertierung
+ // Ausserdem Fehler, wenn SbxBYREF
+ pVar->Convert( SbxVARIANT );
+ pVar->Convert( t );
+ }
+ }
+}
+
+// String auf feste Laenge bringen (+Laenge)
+
+void SbiRuntime::StepPAD( UINT32 nOp1 )
+{
+ SbxVariable* p = GetTOS();
+ String& s = (String&)(const String&) *p;
+ if( s.Len() > nOp1 )
+ s.Erase( static_cast<xub_StrLen>( nOp1 ) );
+ else
+ s.Expand( static_cast<xub_StrLen>( nOp1 ), ' ' );
+}
+
+// Sprung (+Target)
+
+void SbiRuntime::StepJUMP( UINT32 nOp1 )
+{
+#ifdef DBG_UTIL
+ // #QUESTION shouln't this be
+ // if( (BYTE*)( nOp1+pImagGetCode() ) >= pImg->GetCodeSize() )
+ if( nOp1 >= pImg->GetCodeSize() )
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+#endif
+ pCode = (const BYTE*) pImg->GetCode() + nOp1;
+}
+
+// TOS auswerten, bedingter Sprung (+Target)
+
+void SbiRuntime::StepJUMPT( UINT32 nOp1 )
+{
+ SbxVariableRef p = PopVar();
+ if( p->GetBool() )
+ StepJUMP( nOp1 );
+}
+
+// TOS auswerten, bedingter Sprung (+Target)
+
+void SbiRuntime::StepJUMPF( UINT32 nOp1 )
+{
+ SbxVariableRef p = PopVar();
+ if( !p->GetBool() )
+ StepJUMP( nOp1 );
+}
+
+// TOS auswerten, Sprung in JUMP-Tabelle (+MaxVal)
+// Sieht so aus:
+// ONJUMP 2
+// JUMP target1
+// JUMP target2
+// ...
+//Falls im Operanden 0x8000 gesetzt ist, Returnadresse pushen (ON..GOSUB)
+
+void SbiRuntime::StepONJUMP( UINT32 nOp1 )
+{
+ SbxVariableRef p = PopVar();
+ INT16 n = p->GetInteger();
+ if( nOp1 & 0x8000 )
+ {
+ nOp1 &= 0x7FFF;
+ //PushGosub( pCode + 3 * nOp1 );
+ PushGosub( pCode + 5 * nOp1 );
+ }
+ if( n < 1 || static_cast<UINT32>(n) > nOp1 )
+ n = static_cast<INT16>( nOp1 + 1 );
+ //nOp1 = (UINT32) ( (const char*) pCode - pImg->GetCode() ) + 3 * --n;
+ nOp1 = (UINT32) ( (const char*) pCode - pImg->GetCode() ) + 5 * --n;
+ StepJUMP( nOp1 );
+}
+
+// UP-Aufruf (+Target)
+
+void SbiRuntime::StepGOSUB( UINT32 nOp1 )
+{
+ PushGosub( pCode );
+ if( nOp1 >= pImg->GetCodeSize() )
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ pCode = (const BYTE*) pImg->GetCode() + nOp1;
+}
+
+// UP-Return (+0 oder Target)
+
+void SbiRuntime::StepRETURN( UINT32 nOp1 )
+{
+ PopGosub();
+ if( nOp1 )
+ StepJUMP( nOp1 );
+}
+
+// FOR-Variable testen (+Endlabel)
+
+void SbiRuntime::StepTESTFOR( UINT32 nOp1 )
+{
+ if( !pForStk )
+ {
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ return;
+ }
+
+ bool bEndLoop = false;
+ switch( pForStk->eForType )
+ {
+ case FOR_TO:
+ {
+ SbxOperator eOp = ( pForStk->refInc->GetDouble() < 0 ) ? SbxLT : SbxGT;
+ if( pForStk->refVar->Compare( eOp, *pForStk->refEnd ) )
+ bEndLoop = true;
+ break;
+ }
+ case FOR_EACH_ARRAY:
+ {
+ SbiForStack* p = pForStk;
+ if( p->pArrayCurIndices == NULL )
+ {
+ bEndLoop = true;
+ }
+ else
+ {
+ SbxDimArray* pArray = (SbxDimArray*)(SbxVariable*)p->refEnd;
+ short nDims = pArray->GetDims();
+
+ // Empty array?
+ if( nDims == 1 && p->pArrayLowerBounds[0] > p->pArrayUpperBounds[0] )
+ {
+ bEndLoop = true;
+ break;
+ }
+ SbxVariable* pVal = pArray->Get32( p->pArrayCurIndices );
+ *(p->refVar) = *pVal;
+
+ bool bFoundNext = false;
+ for( short i = 0 ; i < nDims ; i++ )
+ {
+ if( p->pArrayCurIndices[i] < p->pArrayUpperBounds[i] )
+ {
+ bFoundNext = true;
+ p->pArrayCurIndices[i]++;
+ for( short j = i - 1 ; j >= 0 ; j-- )
+ p->pArrayCurIndices[j] = p->pArrayLowerBounds[j];
+ break;
+ }
+ }
+ if( !bFoundNext )
+ {
+ delete[] p->pArrayCurIndices;
+ p->pArrayCurIndices = NULL;
+ }
+ }
+ break;
+ }
+ case FOR_EACH_COLLECTION:
+ {
+ BasicCollection* pCollection = (BasicCollection*)(SbxVariable*)pForStk->refEnd;
+ SbxArrayRef xItemArray = pCollection->xItemArray;
+ INT32 nCount = xItemArray->Count32();
+ if( pForStk->nCurCollectionIndex < nCount )
+ {
+ SbxVariable* pRes = xItemArray->Get32( pForStk->nCurCollectionIndex );
+ pForStk->nCurCollectionIndex++;
+ (*pForStk->refVar) = *pRes;
+ }
+ else
+ {
+ bEndLoop = true;
+ }
+ break;
+ }
+ case FOR_EACH_XENUMERATION:
+ {
+ SbiForStack* p = pForStk;
+ if( p->xEnumeration->hasMoreElements() )
+ {
+ Any aElem = p->xEnumeration->nextElement();
+ SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
+ unoToSbxValue( (SbxVariable*)xVar, aElem );
+ (*pForStk->refVar) = *xVar;
+ }
+ else
+ {
+ bEndLoop = true;
+ }
+ break;
+ }
+ }
+ if( bEndLoop )
+ {
+ PopFor();
+ StepJUMP( nOp1 );
+ }
+}
+
+// Tos+1 <= Tos+2 <= Tos, 2xremove (+Target)
+
+void SbiRuntime::StepCASETO( UINT32 nOp1 )
+{
+ if( !refCaseStk || !refCaseStk->Count() )
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ else
+ {
+ SbxVariableRef xTo = PopVar();
+ SbxVariableRef xFrom = PopVar();
+ SbxVariableRef xCase = refCaseStk->Get( refCaseStk->Count() - 1 );
+ if( *xCase >= *xFrom && *xCase <= *xTo )
+ StepJUMP( nOp1 );
+ }
+}
+
+// Fehler-Handler
+
+void SbiRuntime::StepERRHDL( UINT32 nOp1 )
+{
+ const BYTE* p = pCode;
+ StepJUMP( nOp1 );
+ pError = pCode;
+ pCode = p;
+ pInst->aErrorMsg = String();
+ pInst->nErr = 0;
+ pInst->nErl = 0;
+ nError = 0;
+ SbxErrObject::getUnoErrObject()->Clear();
+}
+
+// Resume nach Fehlern (+0=statement, 1=next or Label)
+
+void SbiRuntime::StepRESUME( UINT32 nOp1 )
+{
+ // AB #32714 Resume ohne Error? -> Fehler
+ if( !bInError )
+ {
+ Error( SbERR_BAD_RESUME );
+ return;
+ }
+ if( nOp1 )
+ {
+ // Code-Zeiger auf naechstes Statement setzen
+ USHORT n1, n2;
+ pCode = pMod->FindNextStmnt( pErrCode, n1, n2, TRUE, pImg );
+ }
+ else
+ pCode = pErrStmnt;
+ if ( pError ) // current in error handler ( and got a Resume Next statment )
+ SbxErrObject::getUnoErrObject()->Clear();
+
+ if( nOp1 > 1 )
+ StepJUMP( nOp1 );
+ pInst->aErrorMsg = String();
+ pInst->nErr = 0;
+ pInst->nErl = 0;
+ nError = 0;
+ bInError = FALSE;
+
+ // Error-Stack loeschen
+ SbErrorStack*& rErrStack = GetSbData()->pErrStack;
+ delete rErrStack;
+ rErrStack = NULL;
+}
+
+// Kanal schliessen (+Kanal, 0=Alle)
+void SbiRuntime::StepCLOSE( UINT32 nOp1 )
+{
+ SbError err;
+ if( !nOp1 )
+ pIosys->Shutdown();
+ else
+ {
+ err = pIosys->GetError();
+ if( !err )
+ {
+ pIosys->Close();
+ }
+ }
+ err = pIosys->GetError();
+ Error( err );
+}
+
+// Zeichen ausgeben (+char)
+
+void SbiRuntime::StepPRCHAR( UINT32 nOp1 )
+{
+ ByteString s( (char) nOp1 );
+ pIosys->Write( s );
+ Error( pIosys->GetError() );
+}
+
+// Check, ob TOS eine bestimmte Objektklasse ist (+StringID)
+
+bool SbiRuntime::implIsClass( SbxObject* pObj, const String& aClass )
+{
+ bool bRet = true;
+
+ if( aClass.Len() != 0 )
+ {
+ bRet = pObj->IsClass( aClass );
+ if( !bRet )
+ bRet = aClass.EqualsIgnoreCaseAscii( String( RTL_CONSTASCII_USTRINGPARAM("object") ) );
+ if( !bRet )
+ {
+ String aObjClass = pObj->GetClassName();
+ SbModule* pClassMod = pCLASSFAC->FindClass( aObjClass );
+ SbClassData* pClassData;
+ if( pClassMod && (pClassData=pClassMod->pClassData) != NULL )
+ {
+ SbxVariable* pClassVar =
+ pClassData->mxIfaces->Find( aClass, SbxCLASS_DONTCARE );
+ bRet = (pClassVar != NULL);
+ }
+ }
+ }
+ return bRet;
+}
+
+bool SbiRuntime::checkClass_Impl( const SbxVariableRef& refVal,
+ const String& aClass, bool bRaiseErrors, bool bDefault )
+{
+ bool bOk = bDefault;
+
+ SbxDataType t = refVal->GetType();
+ if( t == SbxOBJECT )
+ {
+ SbxObject* pObj;
+ SbxVariable* pVal = (SbxVariable*)refVal;
+ if( pVal->IsA( TYPE(SbxObject) ) )
+ pObj = (SbxObject*) pVal;
+ else
+ {
+ pObj = (SbxObject*) refVal->GetObject();
+ if( pObj && !pObj->IsA( TYPE(SbxObject) ) )
+ pObj = NULL;
+ }
+ if( pObj )
+ {
+ if( !implIsClass( pObj, aClass ) )
+ {
+ if ( bVBAEnabled && pObj->IsA( TYPE(SbUnoObject) ) )
+ {
+ SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pObj);
+ bOk = checkUnoObjectType( pUnoObj, aClass );
+ }
+ else
+ bOk = false;
+ if ( !bOk )
+ {
+ if( bRaiseErrors )
+ Error( SbERR_INVALID_USAGE_OBJECT );
+ }
+ }
+ else
+ {
+ bOk = true;
+
+ SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pObj);
+ if( pClassModuleObject != NULL )
+ pClassModuleObject->triggerInitializeEvent();
+ }
+ }
+ }
+ else
+ {
+ if ( !bVBAEnabled )
+ {
+ if( bRaiseErrors )
+ Error( SbERR_NEEDS_OBJECT );
+ bOk = false;
+ }
+ }
+ return bOk;
+}
+
+void SbiRuntime::StepSETCLASS_impl( UINT32 nOp1, bool bHandleDflt )
+{
+ SbxVariableRef refVal = PopVar();
+ SbxVariableRef refVar = PopVar();
+ String aClass( pImg->GetString( static_cast<short>( nOp1 ) ) );
+
+ bool bOk = checkClass_Impl( refVal, aClass, true );
+ if( bOk )
+ StepSET_Impl( refVal, refVar, bHandleDflt ); // don't do handle dflt prop for a "proper" set
+}
+
+void SbiRuntime::StepVBASETCLASS( UINT32 nOp1 )
+{
+ StepSETCLASS_impl( nOp1, false );
+}
+
+void SbiRuntime::StepSETCLASS( UINT32 nOp1 )
+{
+ StepSETCLASS_impl( nOp1, true );
+}
+
+void SbiRuntime::StepTESTCLASS( UINT32 nOp1 )
+{
+ SbxVariableRef xObjVal = PopVar();
+ String aClass( pImg->GetString( static_cast<short>( nOp1 ) ) );
+ bool bDefault = !bVBAEnabled;
+ bool bOk = checkClass_Impl( xObjVal, aClass, false, bDefault );
+
+ SbxVariable* pRet = new SbxVariable;
+ pRet->PutBool( bOk );
+ PushVar( pRet );
+}
+
+// Library fuer anschliessenden Declare-Call definieren
+
+void SbiRuntime::StepLIB( UINT32 nOp1 )
+{
+ aLibName = pImg->GetString( static_cast<short>( nOp1 ) );
+}
+
+// TOS wird um BASE erhoeht, BASE davor gepusht (+BASE)
+// Dieser Opcode wird vor DIM/REDIM-Anweisungen gepusht,
+// wenn nur ein Index angegeben wurde.
+
+void SbiRuntime::StepBASED( UINT32 nOp1 )
+{
+ SbxVariable* p1 = new SbxVariable;
+ SbxVariableRef x2 = PopVar();
+
+ // #109275 Check compatiblity mode
+ bool bCompatible = ((nOp1 & 0x8000) != 0);
+ USHORT uBase = static_cast<USHORT>(nOp1 & 1); // Can only be 0 or 1
+ p1->PutInteger( uBase );
+ if( !bCompatible )
+ x2->Compute( SbxPLUS, *p1 );
+ PushVar( x2 ); // erst die Expr
+ PushVar( p1 ); // dann die Base
+}
+
+
+
+
+
diff --git a/basic/source/runtime/step2.cxx b/basic/source/runtime/step2.cxx
new file mode 100755
index 000000000000..587b0ae7a590
--- /dev/null
+++ b/basic/source/runtime/step2.cxx
@@ -0,0 +1,1261 @@
+/*************************************************************************
+ *
+ * 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 "runtime.hxx"
+#ifndef GCC
+#endif
+#include "iosys.hxx"
+#include "image.hxx"
+#include "sbintern.hxx"
+#include "sbunoobj.hxx"
+#include "opcodes.hxx"
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/script/XDefaultMethod.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <comphelper/processfactory.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::container;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::script;
+
+using com::sun::star::uno::Reference;
+
+SbxVariable* getVBAConstant( const String& rName );
+
+// Suchen eines Elements
+// Die Bits im String-ID:
+// 0x8000 - Argv ist belegt
+
+SbxVariable* SbiRuntime::FindElement
+ ( SbxObject* pObj, UINT32 nOp1, UINT32 nOp2, SbError nNotFound, BOOL bLocal, BOOL bStatic )
+{
+ bool bIsVBAInterOp = SbiRuntime::isVBAEnabled();
+ if( bIsVBAInterOp )
+ {
+ StarBASIC* pMSOMacroRuntimeLib = GetSbData()->pMSOMacroRuntimLib;
+ if( pMSOMacroRuntimeLib != NULL )
+ pMSOMacroRuntimeLib->ResetFlag( SBX_EXTSEARCH );
+ }
+
+ SbxVariable* pElem = NULL;
+ if( !pObj )
+ {
+ Error( SbERR_NO_OBJECT );
+ pElem = new SbxVariable;
+ }
+ else
+ {
+ BOOL bFatalError = FALSE;
+ SbxDataType t = (SbxDataType) nOp2;
+ String aName( pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ) );
+ // Hacky capture of Evaluate [] syntax
+ // this should be tackled I feel at the pcode level
+ if ( bIsVBAInterOp && aName.Search('[') == 0 )
+ {
+ // emulate pcode here
+ StepARGC();
+ // psuedo StepLOADSC
+ String sArg = aName.Copy( 1, aName.Len() - 2 );
+ SbxVariable* p = new SbxVariable;
+ p->PutString( sArg );
+ PushVar( p );
+ //
+ StepARGV();
+ nOp1 = nOp1 | 0x8000; // indicate params are present
+ aName = String::CreateFromAscii("Evaluate");
+ }
+ if( bLocal )
+ {
+ if ( bStatic )
+ {
+ if ( pMeth )
+ pElem = pMeth->GetStatics()->Find( aName, SbxCLASS_DONTCARE );
+ }
+
+ if ( !pElem )
+ pElem = refLocals->Find( aName, SbxCLASS_DONTCARE );
+ }
+ if( !pElem )
+ {
+ // Die RTL brauchen wir nicht mehr zu durchsuchen!
+ BOOL bSave = rBasic.bNoRtl;
+ rBasic.bNoRtl = TRUE;
+ pElem = pObj->Find( aName, SbxCLASS_DONTCARE );
+
+ // #110004, #112015: Make private really private
+ if( bLocal && pElem ) // Local as flag for global search
+ {
+ if( pElem->IsSet( SBX_PRIVATE ) )
+ {
+ SbiInstance* pInst_ = pINST;
+ if( pInst_ && pInst_->IsCompatibility() && pObj != pElem->GetParent() )
+ pElem = NULL; // Found but in wrong module!
+
+ // Interfaces: Use SBX_EXTFOUND
+ }
+ }
+ rBasic.bNoRtl = bSave;
+
+ // Ist es ein globaler Uno-Bezeichner?
+ if( bLocal && !pElem )
+ {
+ bool bSetName = true; // preserve normal behaviour
+
+ // i#i68894# if VBAInterOp favour searching vba globals
+ // over searching for uno classess
+ if ( bVBAEnabled )
+ {
+ // Try Find in VBA symbols space
+ pElem = rBasic.VBAFind( aName, SbxCLASS_DONTCARE );
+ if ( pElem )
+ bSetName = false; // don't overwrite uno name
+ else
+ pElem = getVBAConstant( aName );
+ }
+ // #72382 VORSICHT! Liefert jetzt wegen unbekannten
+ // Modulen IMMER ein Ergebnis!
+ SbUnoClass* pUnoClass = findUnoClass( aName );
+ if( pUnoClass )
+ {
+ pElem = new SbxVariable( t );
+ SbxValues aRes( SbxOBJECT );
+ aRes.pObj = pUnoClass;
+ pElem->SbxVariable::Put( aRes );
+ }
+
+ // #62939 Wenn eine Uno-Klasse gefunden wurde, muss
+ // das Wrapper-Objekt gehalten werden, da sonst auch
+ // die Uno-Klasse, z.B. "stardiv" immer wieder neu
+ // aus der Registry gelesen werden muss
+ if( pElem )
+ {
+ // #63774 Darf nicht mit gespeichert werden!!!
+ pElem->SetFlag( SBX_DONTSTORE );
+ pElem->SetFlag( SBX_NO_MODIFY);
+
+ // #72382 Lokal speichern, sonst werden alle implizit
+ // deklarierten Vars automatisch global !
+ if ( bSetName )
+ pElem->SetName( aName );
+ refLocals->Put( pElem, refLocals->Count() );
+ }
+ }
+
+ if( !pElem )
+ {
+ // Nicht da und nicht im Objekt?
+ // Hat das Ding Parameter, nicht einrichten!
+ if( nOp1 & 0x8000 )
+ bFatalError = TRUE;
+ // ALT: StarBASIC::FatalError( nNotFound );
+
+ // Sonst, falls keine Parameter sind, anderen Error Code verwenden
+ if( !bLocal || pImg->GetFlag( SBIMG_EXPLICIT ) )
+ {
+ // #39108 Bei explizit und als ELEM immer ein Fatal Error
+ bFatalError = TRUE;
+
+ // Falls keine Parameter sind, anderen Error Code verwenden
+ if( !( nOp1 & 0x8000 ) && nNotFound == SbERR_PROC_UNDEFINED )
+ nNotFound = SbERR_VAR_UNDEFINED;
+ }
+ if( bFatalError )
+ {
+ // #39108 Statt FatalError zu setzen, Dummy-Variable liefern
+ if( !xDummyVar.Is() )
+ xDummyVar = new SbxVariable( SbxVARIANT );
+ pElem = xDummyVar;
+
+ // Parameter von Hand loeschen
+ ClearArgvStack();
+
+ // Normalen Error setzen
+ Error( nNotFound, aName );
+ }
+ else
+ {
+ if ( bStatic )
+ pElem = StepSTATIC_Impl( aName, t );
+ if ( !pElem )
+ {
+ // Sonst Variable neu anlegen
+ pElem = new SbxVariable( t );
+ if( t != SbxVARIANT )
+ pElem->SetFlag( SBX_FIXED );
+ pElem->SetName( aName );
+ refLocals->Put( pElem, refLocals->Count() );
+ }
+ }
+ }
+ }
+ // #39108 Args koennen schon geloescht sein!
+ if( !bFatalError )
+ SetupArgs( pElem, nOp1 );
+ // Ein bestimmter Call-Type wurde gewuenscht, daher muessen
+ // wir hier den Typ setzen und das Ding anfassen, um den
+ // korrekten Returnwert zu erhalten!
+ if( pElem->IsA( TYPE(SbxMethod) ) )
+ {
+ // Soll der Typ konvertiert werden?
+ SbxDataType t2 = pElem->GetType();
+ BOOL bSet = FALSE;
+ if( !( pElem->GetFlags() & SBX_FIXED ) )
+ {
+ if( t != SbxVARIANT && t != t2 &&
+ t >= SbxINTEGER && t <= SbxSTRING )
+ pElem->SetType( t ), bSet = TRUE;
+ }
+ // pElem auf eine Ref zuweisen, um ggf. eine Temp-Var zu loeschen
+ SbxVariableRef refTemp = pElem;
+
+ // Moegliche Reste vom letzten Aufruf der SbxMethod beseitigen
+ // Vorher Schreiben freigeben, damit kein Error gesetzt wird.
+ USHORT nSavFlags = pElem->GetFlags();
+ pElem->SetFlag( SBX_READWRITE | SBX_NO_BROADCAST );
+ pElem->SbxValue::Clear();
+ pElem->SetFlags( nSavFlags );
+
+ // Erst nach dem Setzen anfassen, da z.B. LEFT()
+ // den Unterschied zwischen Left$() und Left() kennen muss
+
+ // AB 12.8.96: Da in PopVar() die Parameter von Methoden weggehauen
+ // werden, muessen wir hier explizit eine neue SbxMethod anlegen
+ SbxVariable* pNew = new SbxMethod( *((SbxMethod*)pElem) ); // das ist der Call!
+ //ALT: SbxVariable* pNew = new SbxVariable( *pElem ); // das ist der Call!
+
+ pElem->SetParameters(0); // sonst bleibt Ref auf sich selbst
+ pNew->SetFlag( SBX_READWRITE );
+
+ // den Datentypen zuruecksetzen?
+ if( bSet )
+ pElem->SetType( t2 );
+ pElem = pNew;
+ }
+ // Index-Access bei UnoObjekten beruecksichtigen
+ // definitely we want this for VBA where properties are often
+ // collections ( which need index access ), but lets only do
+ // this if we actually have params following
+ else if( bVBAEnabled && pElem->ISA(SbUnoProperty) && pElem->GetParameters() )
+ {
+ // pElem auf eine Ref zuweisen, um ggf. eine Temp-Var zu loeschen
+ SbxVariableRef refTemp = pElem;
+
+ // Variable kopieren und dabei den Notify aufloesen
+ SbxVariable* pNew = new SbxVariable( *((SbxVariable*)pElem) ); // das ist der Call!
+ pElem->SetParameters( NULL ); // sonst bleibt Ref auf sich selbst
+ pElem = pNew;
+ }
+ }
+ return CheckArray( pElem );
+}
+
+// Find-Funktion ueber Name fuer aktuellen Scope (z.B. Abfrage aus BASIC-IDE)
+SbxBase* SbiRuntime::FindElementExtern( const String& rName )
+{
+ // Hinweis zu #35281#: Es darf nicht davon ausgegangen werden, dass
+ // pMeth != null, da im RunInit noch keine gesetzt ist.
+
+ SbxVariable* pElem = NULL;
+ if( !pMod || !rName.Len() )
+ return NULL;
+
+ // Lokal suchen
+ if( refLocals )
+ pElem = refLocals->Find( rName, SbxCLASS_DONTCARE );
+
+ // In Statics suchen
+ if ( !pElem && pMeth )
+ {
+ // Bei Statics, Name der Methode davor setzen
+ String aMethName = pMeth->GetName();
+ aMethName += ':';
+ aMethName += rName;
+ pElem = pMod->Find(aMethName, SbxCLASS_DONTCARE);
+ }
+
+ // In Parameter-Liste suchen
+ if( !pElem && pMeth )
+ {
+ SbxInfo* pInfo = pMeth->GetInfo();
+ if( pInfo && refParams )
+ {
+ USHORT nParamCount = refParams->Count();
+ USHORT j = 1;
+ const SbxParamInfo* pParam = pInfo->GetParam( j );
+ while( pParam )
+ {
+ if( pParam->aName.EqualsIgnoreCaseAscii( rName ) )
+ {
+ if( j >= nParamCount )
+ {
+ // Parameter is missing
+ pElem = new SbxVariable( SbxSTRING );
+ pElem->PutString( String( RTL_CONSTASCII_USTRINGPARAM("<missing parameter>" ) ) );
+ }
+ else
+ {
+ pElem = refParams->Get( j );
+ }
+ break;
+ }
+ pParam = pInfo->GetParam( ++j );
+ }
+ }
+ }
+
+ // Im Modul suchen
+ if( !pElem )
+ {
+ // RTL nicht durchsuchen!
+ BOOL bSave = rBasic.bNoRtl;
+ rBasic.bNoRtl = TRUE;
+ pElem = pMod->Find( rName, SbxCLASS_DONTCARE );
+ rBasic.bNoRtl = bSave;
+ }
+ return pElem;
+}
+
+
+// Argumente eines Elements setzen
+// Dabei auch die Argumente umsetzen, falls benannte Parameter
+// verwendet wurden
+
+void SbiRuntime::SetupArgs( SbxVariable* p, UINT32 nOp1 )
+{
+ if( nOp1 & 0x8000 )
+ {
+ if( !refArgv )
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ BOOL bHasNamed = FALSE;
+ USHORT i;
+ USHORT nArgCount = refArgv->Count();
+ for( i = 1 ; i < nArgCount ; i++ )
+ {
+ if( refArgv->GetAlias( i ).Len() )
+ {
+ bHasNamed = TRUE; break;
+ }
+ }
+ if( bHasNamed )
+ {
+ // Wir haben mindestens einen benannten Parameter!
+ // Wir muessen also umsortieren
+ // Gibt es Parameter-Infos?
+ SbxInfo* pInfo = p->GetInfo();
+ if( !pInfo )
+ {
+ bool bError_ = true;
+
+ SbUnoMethod* pUnoMethod = PTR_CAST(SbUnoMethod,p);
+ SbUnoProperty* pUnoProperty = PTR_CAST(SbUnoProperty,p);
+ if( pUnoMethod || pUnoProperty )
+ {
+ SbUnoObject* pParentUnoObj = PTR_CAST( SbUnoObject,p->GetParent() );
+ if( pParentUnoObj )
+ {
+ Any aUnoAny = pParentUnoObj->getUnoAny();
+ Reference< XInvocation > xInvocation;
+ aUnoAny >>= xInvocation;
+ if( xInvocation.is() ) // TODO: if( xOLEAutomation.is() )
+ {
+ bError_ = false;
+
+ USHORT nCurPar = 1;
+ AutomationNamedArgsSbxArray* pArg =
+ new AutomationNamedArgsSbxArray( nArgCount );
+ ::rtl::OUString* pNames = pArg->getNames().getArray();
+ for( i = 1 ; i < nArgCount ; i++ )
+ {
+ SbxVariable* pVar = refArgv->Get( i );
+ const String& rName = refArgv->GetAlias( i );
+ if( rName.Len() )
+ pNames[i] = rName;
+ pArg->Put( pVar, nCurPar++ );
+ }
+ refArgv = pArg;
+ }
+ }
+ }
+ if( bError_ )
+ Error( SbERR_NO_NAMED_ARGS );
+ }
+ else
+ {
+ USHORT nCurPar = 1;
+ SbxArray* pArg = new SbxArray;
+ for( i = 1 ; i < nArgCount ; i++ )
+ {
+ SbxVariable* pVar = refArgv->Get( i );
+ const String& rName = refArgv->GetAlias( i );
+ if( rName.Len() )
+ {
+ // nCurPar wird auf den gefundenen Parameter gesetzt
+ USHORT j = 1;
+ const SbxParamInfo* pParam = pInfo->GetParam( j );
+ while( pParam )
+ {
+ if( pParam->aName.EqualsIgnoreCaseAscii( rName ) )
+ {
+ nCurPar = j;
+ break;
+ }
+ pParam = pInfo->GetParam( ++j );
+ }
+ if( !pParam )
+ {
+ Error( SbERR_NAMED_NOT_FOUND ); break;
+ }
+ }
+ pArg->Put( pVar, nCurPar++ );
+ }
+ refArgv = pArg;
+ }
+ }
+ // Eigene Var als Parameter 0
+ refArgv->Put( p, 0 );
+ p->SetParameters( refArgv );
+ PopArgv();
+ }
+ else
+ p->SetParameters( NULL );
+}
+
+// Holen eines Array-Elements
+
+SbxVariable* SbiRuntime::CheckArray( SbxVariable* pElem )
+{
+ // Falls wir ein Array haben, wollen wir bitte das Array-Element!
+ SbxArray* pPar;
+ if( pElem->GetType() & SbxARRAY )
+ {
+ SbxBase* pElemObj = pElem->GetObject();
+ SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj);
+ pPar = pElem->GetParameters();
+ if( pDimArray )
+ {
+ // Die Parameter koennen fehlen, wenn ein Array als
+ // Argument uebergeben wird.
+ if( pPar )
+ pElem = pDimArray->Get( pPar );
+ }
+ else
+ {
+ SbxArray* pArray = PTR_CAST(SbxArray,pElemObj);
+ if( pArray )
+ {
+ if( !pPar )
+ {
+ Error( SbERR_OUT_OF_RANGE );
+ pElem = new SbxVariable;
+ }
+ else
+ pElem = pArray->Get( pPar->Get( 1 )->GetInteger() );
+ }
+ }
+
+ // #42940, 0.Parameter zu NULL setzen, damit sich Var nicht selbst haelt
+ if( pPar )
+ pPar->Put( NULL, 0 );
+ }
+ // Index-Access bei UnoObjekten beruecksichtigen
+ else if( pElem->GetType() == SbxOBJECT && !pElem->ISA(SbxMethod) )
+ {
+ pPar = pElem->GetParameters();
+ if ( pPar )
+ {
+ // Ist es ein Uno-Objekt?
+ SbxBaseRef pObj = (SbxBase*)pElem->GetObject();
+ if( pObj )
+ {
+ if( pObj->ISA(SbUnoObject) )
+ {
+ SbUnoObject* pUnoObj = (SbUnoObject*)(SbxBase*)pObj;
+ Any aAny = pUnoObj->getUnoAny();
+
+ if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
+ {
+ Reference< XInterface > x = *(Reference< XInterface >*)aAny.getValue();
+ Reference< XIndexAccess > xIndexAccess( x, UNO_QUERY );
+ if ( !bVBAEnabled )
+ {
+ // Haben wir Index-Access?
+ if( xIndexAccess.is() )
+ {
+ UINT32 nParamCount = (UINT32)pPar->Count() - 1;
+ if( nParamCount != 1 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return pElem;
+ }
+
+ // Index holen
+ INT32 nIndex = pPar->Get( 1 )->GetLong();
+ Reference< XInterface > xRet;
+ try
+ {
+ Any aAny2 = xIndexAccess->getByIndex( nIndex );
+ TypeClass eType = aAny2.getValueType().getTypeClass();
+ if( eType == TypeClass_INTERFACE )
+ xRet = *(Reference< XInterface >*)aAny2.getValue();
+ }
+ catch (IndexOutOfBoundsException&)
+ {
+ // Bei Exception erstmal immer von Konvertierungs-Problem ausgehen
+ StarBASIC::Error( SbERR_OUT_OF_RANGE );
+ }
+
+ // #57847 Immer neue Variable anlegen, sonst Fehler
+ // durch PutObject(NULL) bei ReadOnly-Properties.
+ pElem = new SbxVariable( SbxVARIANT );
+ if( xRet.is() )
+ {
+ aAny <<= xRet;
+
+ // #67173 Kein Namen angeben, damit echter Klassen-Namen eintragen wird
+ String aName;
+ SbxObjectRef xWrapper = (SbxObject*)new SbUnoObject( aName, aAny );
+ pElem->PutObject( xWrapper );
+ }
+ else
+ {
+ pElem->PutObject( NULL );
+ }
+ }
+ }
+ else
+ {
+ rtl::OUString sDefaultMethod;
+
+ Reference< XDefaultMethod > xDfltMethod( x, UNO_QUERY );
+
+ if ( xDfltMethod.is() )
+ sDefaultMethod = xDfltMethod->getDefaultMethodName();
+ else if( xIndexAccess.is() )
+ sDefaultMethod = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getByIndex" ) );
+
+ if ( sDefaultMethod.getLength() )
+ {
+ SbxVariable* meth = pUnoObj->Find( sDefaultMethod, SbxCLASS_METHOD );
+ SbxVariableRef refTemp = meth;
+ if ( refTemp )
+ {
+ meth->SetParameters( pPar );
+ SbxVariable* pNew = new SbxMethod( *(SbxMethod*)meth );
+ pElem = pNew;
+ }
+ }
+ }
+ }
+
+ // #42940, 0.Parameter zu NULL setzen, damit sich Var nicht selbst haelt
+ pPar->Put( NULL, 0 );
+ }
+ else if( pObj->ISA(BasicCollection) )
+ {
+ BasicCollection* pCol = (BasicCollection*)(SbxBase*)pObj;
+ pElem = new SbxVariable( SbxVARIANT );
+ pPar->Put( pElem, 0 );
+ pCol->CollItem( pPar );
+ }
+ }
+ }
+ }
+
+ return pElem;
+}
+
+// Laden eines Elements aus der Runtime-Library (+StringID+Typ)
+
+void SbiRuntime::StepRTL( UINT32 nOp1, UINT32 nOp2 )
+{
+ PushVar( FindElement( rBasic.pRtl, nOp1, nOp2, SbERR_PROC_UNDEFINED, FALSE ) );
+}
+
+void
+SbiRuntime::StepFIND_Impl( SbxObject* pObj, UINT32 nOp1, UINT32 nOp2, SbError nNotFound, BOOL bLocal, BOOL bStatic )
+{
+ if( !refLocals )
+ refLocals = new SbxArray;
+ PushVar( FindElement( pObj, nOp1, nOp2, nNotFound, bLocal, bStatic ) );
+}
+// Laden einer lokalen/globalen Variablen (+StringID+Typ)
+
+void SbiRuntime::StepFIND( UINT32 nOp1, UINT32 nOp2 )
+{
+ StepFIND_Impl( pMod, nOp1, nOp2, SbERR_PROC_UNDEFINED, TRUE );
+}
+
+// Search inside a class module (CM) to enable global search in time
+void SbiRuntime::StepFIND_CM( UINT32 nOp1, UINT32 nOp2 )
+{
+
+ SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pMod);
+ if( pClassModuleObject )
+ pMod->SetFlag( SBX_GBLSEARCH );
+
+ StepFIND_Impl( pMod, nOp1, nOp2, SbERR_PROC_UNDEFINED, TRUE );
+
+ if( pClassModuleObject )
+ pMod->ResetFlag( SBX_GBLSEARCH );
+}
+
+void SbiRuntime::StepFIND_STATIC( UINT32 nOp1, UINT32 nOp2 )
+{
+ StepFIND_Impl( pMod, nOp1, nOp2, SbERR_PROC_UNDEFINED, TRUE, TRUE );
+}
+
+// Laden eines Objekt-Elements (+StringID+Typ)
+// Das Objekt liegt auf TOS
+
+void SbiRuntime::StepELEM( UINT32 nOp1, UINT32 nOp2 )
+{
+ // Liegt auf dem TOS ein Objekt?
+ SbxVariableRef pObjVar = PopVar();
+
+ SbxObject* pObj = PTR_CAST(SbxObject,(SbxVariable*) pObjVar);
+ if( !pObj )
+ {
+ SbxBase* pObjVarObj = pObjVar->GetObject();
+ pObj = PTR_CAST(SbxObject,pObjVarObj);
+ }
+
+ // #56368 Bei StepElem Referenz sichern, sonst koennen Objekte
+ // in Qualifizierungsketten wie ActiveComponent.Selection(0).Text
+ // zu fueh die Referenz verlieren
+ // #74254 Jetzt per Liste
+ if( pObj )
+ SaveRef( (SbxVariable*)pObj );
+
+ PushVar( FindElement( pObj, nOp1, nOp2, SbERR_NO_METHOD, FALSE ) );
+}
+
+// Laden eines Parameters (+Offset+Typ)
+// Wenn der Datentyp nicht stimmen sollte, eine Kopie anlegen
+// Der Datentyp SbxEMPTY zeigt an, daa kein Parameter angegeben ist.
+// Get( 0 ) darf EMPTY sein
+
+void SbiRuntime::StepPARAM( UINT32 nOp1, UINT32 nOp2 )
+{
+ USHORT i = static_cast<USHORT>( nOp1 & 0x7FFF );
+ SbxDataType t = (SbxDataType) nOp2;
+ SbxVariable* p;
+
+ // #57915 Missing sauberer loesen
+ USHORT nParamCount = refParams->Count();
+ if( i >= nParamCount )
+ {
+ INT16 iLoop = i;
+ while( iLoop >= nParamCount )
+ {
+ p = new SbxVariable();
+
+ if( SbiRuntime::isVBAEnabled() &&
+ (t == SbxOBJECT || t == SbxSTRING) )
+ {
+ if( t == SbxOBJECT )
+ p->PutObject( NULL );
+ else
+ p->PutString( String() );
+ }
+ else
+ p->PutErr( 448 ); // Wie in VB: Error-Code 448 (SbERR_NAMED_NOT_FOUND)
+
+ refParams->Put( p, iLoop );
+ iLoop--;
+ }
+ }
+ p = refParams->Get( i );
+
+ if( p->GetType() == SbxERROR && ( i ) )
+ //if( p->GetType() == SbxEMPTY && ( i ) )
+ {
+ // Wenn ein Parameter fehlt, kann er OPTIONAL sein
+ BOOL bOpt = FALSE;
+ if( pMeth )
+ {
+ SbxInfo* pInfo = pMeth->GetInfo();
+ if ( pInfo )
+ {
+ const SbxParamInfo* pParam = pInfo->GetParam( i );
+ if( pParam && ( (pParam->nFlags & SBX_OPTIONAL) != 0 ) )
+ {
+ // Default value?
+ USHORT nDefaultId = sal::static_int_cast< USHORT >(
+ pParam->nUserData & 0xffff );
+ if( nDefaultId > 0 )
+ {
+ String aDefaultStr = pImg->GetString( nDefaultId );
+ p = new SbxVariable();
+ p->PutString( aDefaultStr );
+ refParams->Put( p, i );
+ }
+ bOpt = TRUE;
+ }
+ }
+ }
+ if( bOpt == FALSE )
+ Error( SbERR_NOT_OPTIONAL );
+ }
+ else if( t != SbxVARIANT && (SbxDataType)(p->GetType() & 0x0FFF ) != t )
+ {
+ SbxVariable* q = new SbxVariable( t );
+ SaveRef( q );
+ *q = *p;
+ p = q;
+ }
+ SetupArgs( p, nOp1 );
+ PushVar( CheckArray( p ) );
+}
+
+// Case-Test (+True-Target+Test-Opcode)
+
+void SbiRuntime::StepCASEIS( UINT32 nOp1, UINT32 nOp2 )
+{
+ if( !refCaseStk || !refCaseStk->Count() )
+ StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+ else
+ {
+ SbxVariableRef xComp = PopVar();
+ SbxVariableRef xCase = refCaseStk->Get( refCaseStk->Count() - 1 );
+ if( xCase->Compare( (SbxOperator) nOp2, *xComp ) )
+ StepJUMP( nOp1 );
+ }
+}
+
+// Aufruf einer DLL-Prozedur (+StringID+Typ)
+// Auch hier zeigt das MSB des StringIDs an, dass Argv belegt ist
+
+void SbiRuntime::StepCALL( UINT32 nOp1, UINT32 nOp2 )
+{
+ String aName = pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) );
+ SbxArray* pArgs = NULL;
+ if( nOp1 & 0x8000 )
+ pArgs = refArgv;
+ DllCall( aName, aLibName, pArgs, (SbxDataType) nOp2, FALSE );
+ aLibName = String();
+ if( nOp1 & 0x8000 )
+ PopArgv();
+}
+
+// Aufruf einer DLL-Prozedur nach CDecl (+StringID+Typ)
+// Auch hier zeigt das MSB des StringIDs an, dass Argv belegt ist
+
+void SbiRuntime::StepCALLC( UINT32 nOp1, UINT32 nOp2 )
+{
+ String aName = pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) );
+ SbxArray* pArgs = NULL;
+ if( nOp1 & 0x8000 )
+ pArgs = refArgv;
+ DllCall( aName, aLibName, pArgs, (SbxDataType) nOp2, TRUE );
+ aLibName = String();
+ if( nOp1 & 0x8000 )
+ PopArgv();
+}
+
+
+// Beginn eines Statements (+Line+Col)
+
+void SbiRuntime::StepSTMNT( UINT32 nOp1, UINT32 nOp2 )
+{
+ // Wenn der Expr-Stack am Anfang einen Statements eine Variable enthaelt,
+ // hat ein Trottel X als Funktion aufgerufen, obwohl es eine Variable ist!
+ BOOL bFatalExpr = FALSE;
+ String sUnknownMethodName;
+ if( nExprLvl > 1 )
+ bFatalExpr = TRUE;
+ else if( nExprLvl )
+ {
+ SbxVariable* p = refExprStk->Get( 0 );
+ if( p->GetRefCount() > 1
+ && refLocals.Is() && refLocals->Find( p->GetName(), p->GetClass() ) )
+ {
+ sUnknownMethodName = p->GetName();
+ bFatalExpr = TRUE;
+ }
+ }
+ // Der Expr-Stack ist nun nicht mehr notwendig
+ ClearExprStack();
+
+ // #56368 Kuenstliche Referenz fuer StepElem wieder freigeben,
+ // damit sie nicht ueber ein Statement hinaus erhalten bleibt
+ //refSaveObj = NULL;
+ // #74254 Jetzt per Liste
+ ClearRefs();
+
+ // Wir muessen hier hart abbrechen, da sonst Zeile und Spalte nicht mehr
+ // stimmen!
+ if( bFatalExpr)
+ {
+ StarBASIC::FatalError( SbERR_NO_METHOD, sUnknownMethodName );
+ return;
+ }
+ pStmnt = pCode - 9;
+ USHORT nOld = nLine;
+ nLine = static_cast<short>( nOp1 );
+
+ // #29955 & 0xFF, um for-Schleifen-Ebene wegzufiltern
+ nCol1 = static_cast<short>( nOp2 & 0xFF );
+
+ // Suchen des naechsten STMNT-Befehls,
+ // um die End-Spalte dieses Statements zu setzen
+ // Searches of the next STMNT instruction,
+ // around the final column of this statement to set
+
+ nCol2 = 0xffff;
+ USHORT n1, n2;
+ const BYTE* p = pMod->FindNextStmnt( pCode, n1, n2 );
+ if( p )
+ {
+ if( n1 == nOp1 )
+ {
+ // #29955 & 0xFF, um for-Schleifen-Ebene wegzufiltern
+ nCol2 = (n2 & 0xFF) - 1;
+ }
+ }
+
+ // #29955 for-Schleifen-Ebene korrigieren, #67452 NICHT im Error-Handler sonst Chaos
+ if( !bInError )
+ {
+ // (Bei Sprüngen aus Schleifen tritt hier eine Differenz auf)
+ USHORT nExspectedForLevel = static_cast<USHORT>( nOp2 / 0x100 );
+ if( pGosubStk )
+ nExspectedForLevel = nExspectedForLevel + pGosubStk->nStartForLvl;
+
+ // Wenn der tatsaechliche For-Level zu klein ist, wurde aus
+ // einer Schleife heraus gesprungen -> korrigieren
+ while( nForLvl > nExspectedForLevel )
+ PopFor();
+ }
+
+ // 16.10.96: #31460 Neues Konzept fuer StepInto/Over/Out
+ // Erklärung siehe bei _ImplGetBreakCallLevel.
+ if( pInst->nCallLvl <= pInst->nBreakCallLvl )
+ //if( nFlags & SbDEBUG_STEPINTO )
+ {
+ StarBASIC* pStepBasic = GetCurrentBasic( &rBasic );
+ USHORT nNewFlags = pStepBasic->StepPoint( nLine, nCol1, nCol2 );
+
+ // Neuen BreakCallLevel ermitteln
+ pInst->CalcBreakCallLevel( nNewFlags );
+ }
+
+ // Breakpoints nur bei STMNT-Befehlen in neuer Zeile!
+ else if( ( nOp1 != nOld )
+ && ( nFlags & SbDEBUG_BREAK )
+ && pMod->IsBP( static_cast<USHORT>( nOp1 ) ) )
+ {
+ StarBASIC* pBreakBasic = GetCurrentBasic( &rBasic );
+ USHORT nNewFlags = pBreakBasic->BreakPoint( nLine, nCol1, nCol2 );
+
+ // Neuen BreakCallLevel ermitteln
+ pInst->CalcBreakCallLevel( nNewFlags );
+ //16.10.96, ALT:
+ //if( nNewFlags != SbDEBUG_CONTINUE )
+ // nFlags = nNewFlags;
+ }
+}
+
+// (+SvStreamFlags+Flags)
+// Stack: Blocklaenge
+// Kanalnummer
+// Dateiname
+
+void SbiRuntime::StepOPEN( UINT32 nOp1, UINT32 nOp2 )
+{
+ SbxVariableRef pName = PopVar();
+ SbxVariableRef pChan = PopVar();
+ SbxVariableRef pLen = PopVar();
+ short nBlkLen = pLen->GetInteger();
+ short nChan = pChan->GetInteger();
+ ByteString aName( pName->GetString(), gsl_getSystemTextEncoding() );
+ pIosys->Open( nChan, aName, static_cast<short>( nOp1 ),
+ static_cast<short>( nOp2 ), nBlkLen );
+ Error( pIosys->GetError() );
+}
+
+// Objekt kreieren (+StringID+StringID)
+
+void SbiRuntime::StepCREATE( UINT32 nOp1, UINT32 nOp2 )
+{
+ String aClass( pImg->GetString( static_cast<short>( nOp2 ) ) );
+ SbxObject *pObj = SbxBase::CreateObject( aClass );
+ if( !pObj )
+ Error( SbERR_INVALID_OBJECT );
+ else
+ {
+ String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
+ pObj->SetName( aName );
+ // Das Objekt muss BASIC rufen koennen
+ pObj->SetParent( &rBasic );
+ SbxVariable* pNew = new SbxVariable;
+ pNew->PutObject( pObj );
+ PushVar( pNew );
+ }
+}
+
+void SbiRuntime::StepDCREATE( UINT32 nOp1, UINT32 nOp2 )
+{
+ StepDCREATE_IMPL( nOp1, nOp2 );
+}
+
+void SbiRuntime::StepDCREATE_REDIMP( UINT32 nOp1, UINT32 nOp2 )
+{
+ StepDCREATE_IMPL( nOp1, nOp2 );
+}
+
+
+// Helper function for StepDCREATE_IMPL / bRedimp = true
+void implCopyDimArray_DCREATE( SbxDimArray* pNewArray, SbxDimArray* pOldArray, short nMaxDimIndex,
+ short nActualDim, sal_Int32* pActualIndices, sal_Int32* pLowerBounds, sal_Int32* pUpperBounds )
+{
+ sal_Int32& ri = pActualIndices[nActualDim];
+ for( ri = pLowerBounds[nActualDim] ; ri <= pUpperBounds[nActualDim] ; ri++ )
+ {
+ if( nActualDim < nMaxDimIndex )
+ {
+ implCopyDimArray_DCREATE( pNewArray, pOldArray, nMaxDimIndex, nActualDim + 1,
+ pActualIndices, pLowerBounds, pUpperBounds );
+ }
+ else
+ {
+ SbxVariable* pSource = pOldArray->Get32( pActualIndices );
+ pNewArray->Put32( pSource, pActualIndices );
+ }
+ }
+}
+
+// #56204 Objekt-Array kreieren (+StringID+StringID), DCREATE == Dim-Create
+void SbiRuntime::StepDCREATE_IMPL( UINT32 nOp1, UINT32 nOp2 )
+{
+ SbxVariableRef refVar = PopVar();
+
+ DimImpl( refVar );
+
+ // Das Array mit Instanzen der geforderten Klasse fuellen
+ SbxBaseRef xObj = (SbxBase*)refVar->GetObject();
+ if( !xObj )
+ {
+ StarBASIC::Error( SbERR_INVALID_OBJECT );
+ return;
+ }
+
+ SbxDimArray* pArray = 0;
+ if( xObj->ISA(SbxDimArray) )
+ {
+ SbxBase* pObj = (SbxBase*)xObj;
+ pArray = (SbxDimArray*)pObj;
+
+ // Dimensionen auswerten
+ short nDims = pArray->GetDims();
+ INT32 nTotalSize = 0;
+
+ // es muss ein eindimensionales Array sein
+ INT32 nLower, nUpper, nSize;
+ INT32 i;
+ for( i = 0 ; i < nDims ; i++ )
+ {
+ pArray->GetDim32( i+1, nLower, nUpper );
+ nSize = nUpper - nLower + 1;
+ if( i == 0 )
+ nTotalSize = nSize;
+ else
+ nTotalSize *= nSize;
+ }
+
+ // Objekte anlegen und ins Array eintragen
+ String aClass( pImg->GetString( static_cast<short>( nOp2 ) ) );
+ for( i = 0 ; i < nTotalSize ; i++ )
+ {
+ SbxObject *pClassObj = SbxBase::CreateObject( aClass );
+ if( !pClassObj )
+ {
+ Error( SbERR_INVALID_OBJECT );
+ break;
+ }
+ else
+ {
+ String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
+ pClassObj->SetName( aName );
+ // Das Objekt muss BASIC rufen koennen
+ pClassObj->SetParent( &rBasic );
+ pArray->SbxArray::Put32( pClassObj, i );
+ }
+ }
+ }
+
+ SbxDimArray* pOldArray = (SbxDimArray*)(SbxArray*)refRedimpArray;
+ if( pArray && pOldArray )
+ {
+ short nDimsNew = pArray->GetDims();
+ short nDimsOld = pOldArray->GetDims();
+ short nDims = nDimsNew;
+ BOOL bRangeError = FALSE;
+
+ // Store dims to use them for copying later
+ sal_Int32* pLowerBounds = new sal_Int32[nDims];
+ sal_Int32* pUpperBounds = new sal_Int32[nDims];
+ sal_Int32* pActualIndices = new sal_Int32[nDims];
+ if( nDimsOld != nDimsNew )
+ {
+ bRangeError = TRUE;
+ }
+ else
+ {
+ // Compare bounds
+ for( short i = 1 ; i <= nDims ; i++ )
+ {
+ sal_Int32 lBoundNew, uBoundNew;
+ sal_Int32 lBoundOld, uBoundOld;
+ pArray->GetDim32( i, lBoundNew, uBoundNew );
+ pOldArray->GetDim32( i, lBoundOld, uBoundOld );
+
+ lBoundNew = std::max( lBoundNew, lBoundOld );
+ uBoundNew = std::min( uBoundNew, uBoundOld );
+ short j = i - 1;
+ pActualIndices[j] = pLowerBounds[j] = lBoundNew;
+ pUpperBounds[j] = uBoundNew;
+ }
+ }
+
+ if( bRangeError )
+ {
+ StarBASIC::Error( SbERR_OUT_OF_RANGE );
+ }
+ else
+ {
+ // Copy data from old array by going recursively through all dimensions
+ // (It would be faster to work on the flat internal data array of an
+ // SbyArray but this solution is clearer and easier)
+ implCopyDimArray_DCREATE( pArray, pOldArray, nDims - 1,
+ 0, pActualIndices, pLowerBounds, pUpperBounds );
+ }
+ delete [] pUpperBounds;
+ delete [] pLowerBounds;
+ delete [] pActualIndices;
+ refRedimpArray = NULL;
+ }
+}
+
+// Objekt aus User-Type kreieren (+StringID+StringID)
+
+SbxObject* createUserTypeImpl( const String& rClassName ); // sb.cxx
+
+void SbiRuntime::StepTCREATE( UINT32 nOp1, UINT32 nOp2 )
+{
+ String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
+ String aClass( pImg->GetString( static_cast<short>( nOp2 ) ) );
+
+ SbxObject* pCopyObj = createUserTypeImpl( aClass );
+ if( pCopyObj )
+ pCopyObj->SetName( aName );
+ SbxVariable* pNew = new SbxVariable;
+ pNew->PutObject( pCopyObj );
+ pNew->SetDeclareClassName( aClass );
+ PushVar( pNew );
+}
+
+void SbiRuntime::implCreateFixedString( SbxVariable* pStrVar, UINT32 nOp2 )
+{
+ USHORT nCount = static_cast<USHORT>( nOp2 >> 17 ); // len = all bits above 0x10000
+ String aStr;
+ aStr.Fill( nCount, 0 );
+ pStrVar->PutString( aStr );
+}
+
+// Einrichten einer lokalen Variablen (+StringID+Typ)
+
+void SbiRuntime::StepLOCAL( UINT32 nOp1, UINT32 nOp2 )
+{
+ if( !refLocals.Is() )
+ refLocals = new SbxArray;
+ String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
+ if( refLocals->Find( aName, SbxCLASS_DONTCARE ) == NULL )
+ {
+ SbxDataType t = (SbxDataType)(nOp2 & 0xffff);
+ SbxVariable* p = new SbxVariable( t );
+ p->SetName( aName );
+ bool bWithEvents = ((t & 0xff) == SbxOBJECT && (nOp2 & SBX_TYPE_WITH_EVENTS_FLAG) != 0);
+ if( bWithEvents )
+ p->SetFlag( SBX_WITH_EVENTS );
+ bool bFixedString = ((t & 0xff) == SbxSTRING && (nOp2 & SBX_FIXED_LEN_STRING_FLAG) != 0);
+ if( bFixedString )
+ implCreateFixedString( p, nOp2 );
+ refLocals->Put( p, refLocals->Count() );
+ }
+}
+
+// Einrichten einer modulglobalen Variablen (+StringID+Typ)
+
+void SbiRuntime::StepPUBLIC_Impl( UINT32 nOp1, UINT32 nOp2, bool bUsedForClassModule )
+{
+ String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
+ SbxDataType t = (SbxDataType)(SbxDataType)(nOp2 & 0xffff);;
+ BOOL bFlag = pMod->IsSet( SBX_NO_MODIFY );
+ pMod->SetFlag( SBX_NO_MODIFY );
+ SbxVariableRef p = pMod->Find( aName, SbxCLASS_PROPERTY );
+ if( p.Is() )
+ pMod->Remove (p);
+ SbProperty* pProp = pMod->GetProperty( aName, t );
+ if( !bUsedForClassModule )
+ pProp->SetFlag( SBX_PRIVATE );
+ if( !bFlag )
+ pMod->ResetFlag( SBX_NO_MODIFY );
+ if( pProp )
+ {
+ pProp->SetFlag( SBX_DONTSTORE );
+ // AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
+ pProp->SetFlag( SBX_NO_MODIFY);
+
+ bool bWithEvents = ((t & 0xff) == SbxOBJECT && (nOp2 & SBX_TYPE_WITH_EVENTS_FLAG) != 0);
+ if( bWithEvents )
+ pProp->SetFlag( SBX_WITH_EVENTS );
+ bool bFixedString = ((t & 0xff) == SbxSTRING && (nOp2 & SBX_FIXED_LEN_STRING_FLAG) != 0);
+ if( bFixedString )
+ implCreateFixedString( p, nOp2 );
+ }
+}
+
+void SbiRuntime::StepPUBLIC( UINT32 nOp1, UINT32 nOp2 )
+{
+ StepPUBLIC_Impl( nOp1, nOp2, false );
+}
+
+void SbiRuntime::StepPUBLIC_P( UINT32 nOp1, UINT32 nOp2 )
+{
+ // Creates module variable that isn't reinitialised when
+ // between invocations ( for VBASupport & document basic only )
+ if( pMod->pImage->bFirstInit )
+ {
+ bool bUsedForClassModule = pImg->GetFlag( SBIMG_CLASSMODULE );
+ StepPUBLIC_Impl( nOp1, nOp2, bUsedForClassModule );
+ }
+}
+
+// Einrichten einer globalen Variablen (+StringID+Typ)
+
+void SbiRuntime::StepGLOBAL( UINT32 nOp1, UINT32 nOp2 )
+{
+ if( pImg->GetFlag( SBIMG_CLASSMODULE ) )
+ StepPUBLIC_Impl( nOp1, nOp2, true );
+
+ String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
+ SbxDataType t = (SbxDataType)(nOp2 & 0xffff);
+
+ // Store module scope variables at module scope
+ // in non vba mode these are stored at the library level :/
+ // not sure if this really should not be enabled for ALL basic
+ SbxObject* pStorage = &rBasic;
+ if ( SbiRuntime::isVBAEnabled() )
+ {
+ pStorage = pMod;
+ pMod->AddVarName( aName );
+ }
+
+ BOOL bFlag = pStorage->IsSet( SBX_NO_MODIFY );
+ rBasic.SetFlag( SBX_NO_MODIFY );
+ SbxVariableRef p = pStorage->Find( aName, SbxCLASS_PROPERTY );
+ if( p.Is() )
+ pStorage->Remove (p);
+ p = pStorage->Make( aName, SbxCLASS_PROPERTY, t );
+ if( !bFlag )
+ pStorage->ResetFlag( SBX_NO_MODIFY );
+ if( p )
+ {
+ p->SetFlag( SBX_DONTSTORE );
+ // AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
+ p->SetFlag( SBX_NO_MODIFY);
+ }
+}
+
+
+// Creates global variable that isn't reinitialised when
+// basic is restarted, P=PERSIST (+StringID+Typ)
+
+void SbiRuntime::StepGLOBAL_P( UINT32 nOp1, UINT32 nOp2 )
+{
+ if( pMod->pImage->bFirstInit )
+ {
+ StepGLOBAL( nOp1, nOp2 );
+ }
+}
+
+
+// Searches for global variable, behavior depends on the fact
+// if the variable is initialised for the first time
+
+void SbiRuntime::StepFIND_G( UINT32 nOp1, UINT32 nOp2 )
+{
+ if( pMod->pImage->bFirstInit )
+ {
+ // Behave like always during first init
+ StepFIND( nOp1, nOp2 );
+ }
+ else
+ {
+ // Return dummy variable
+ SbxDataType t = (SbxDataType) nOp2;
+ String aName( pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ) );
+
+ SbxVariable* pDummyVar = new SbxVariable( t );
+ pDummyVar->SetName( aName );
+ PushVar( pDummyVar );
+ }
+}
+
+
+SbxVariable* SbiRuntime::StepSTATIC_Impl( String& aName, SbxDataType& t )
+{
+ SbxVariable* p = NULL;
+ if ( pMeth )
+ {
+ SbxArray* pStatics = pMeth->GetStatics();
+ if( pStatics && ( pStatics->Find( aName, SbxCLASS_DONTCARE ) == NULL ) )
+ {
+ p = new SbxVariable( t );
+ if( t != SbxVARIANT )
+ p->SetFlag( SBX_FIXED );
+ p->SetName( aName );
+ pStatics->Put( p, pStatics->Count() );
+ }
+ }
+ return p;
+}
+// Einrichten einer statischen Variablen (+StringID+Typ)
+void SbiRuntime::StepSTATIC( UINT32 nOp1, UINT32 nOp2 )
+{
+ String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
+ SbxDataType t = (SbxDataType) nOp2;
+ StepSTATIC_Impl( aName, t );
+}
+
diff --git a/basic/source/runtime/wnt-mingw.s b/basic/source/runtime/wnt-mingw.s
new file mode 100644
index 000000000000..8c332c1a8ce8
--- /dev/null
+++ b/basic/source/runtime/wnt-mingw.s
@@ -0,0 +1,53 @@
+#*************************************************************************
+#
+# 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.
+#
+#***********************************************************************/
+
+.intel_syntax
+
+.globl _DllMgr_call32
+.globl _DllMgr_callFp
+
+_DllMgr_call32:
+_DllMgr_callFp:
+ push ebp
+ mov ebp, esp
+ push esi
+ push edi
+ mov ecx, [ebp+16]
+ jecxz $1
+ sub esp, ecx
+ mov edi, esp
+ mov esi, [ebp+12]
+ shr ecx, 2
+ rep movsd
+$1: call DWORD PTR [ebp+8]
+ # for extra safety, do not trust esp after call (in case the Basic Declare
+ # signature is wrong):
+ mov edi, [ebp-8]
+ mov esi, [ebp-4]
+ mov esp, ebp
+ pop ebp
+ ret 12
diff --git a/basic/source/runtime/wnt.asm b/basic/source/runtime/wnt.asm
new file mode 100644
index 000000000000..2a8710e34243
--- /dev/null
+++ b/basic/source/runtime/wnt.asm
@@ -0,0 +1,56 @@
+;*************************************************************************
+;
+; 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.
+;
+;***********************************************************************/
+
+.386
+
+PUBLIC _DllMgr_call32@12
+PUBLIC _DllMgr_callFp@12
+
+_TEXT SEGMENT
+_DllMgr_call32@12:
+_DllMgr_callFp@12:
+ push ebp
+ mov ebp, esp
+ push esi
+ push edi
+ mov ecx, [ebp+16]
+ jecxz $1
+ sub esp, ecx
+ mov edi, esp
+ mov esi, [ebp+12]
+ shr ecx, 2
+ rep movsd
+$1: call DWORD PTR [ebp+8]
+ ; for extra safety, do not trust esp after call (in case the Basic Declare
+ ; signature is wrong):
+ mov edi, [ebp-8]
+ mov esi, [ebp-4]
+ mov esp, ebp
+ pop ebp
+ ret 12
+_TEXT ENDS
+END
diff --git a/basic/source/sample/collelem.cxx b/basic/source/sample/collelem.cxx
new file mode 100644
index 000000000000..887917048c61
--- /dev/null
+++ b/basic/source/sample/collelem.cxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#include <vcl/msgbox.hxx>
+#include <basic/sbx.hxx>
+#include "collelem.hxx"
+
+// Das Sample-Element ist ein kleines Objekt, das die Properties
+// Name und Value enth„lt sowie die Methode Say, die den bergebenen
+// Text mit dem eigenen Namen verkoppelt und ausgibt.
+
+SampleElement::SampleElement( const String& r ) : SbxObject( r )
+{
+ // Methode Say mit einem String-Parameter
+ SbxVariable* pMeth = Make( String( RTL_CONSTASCII_USTRINGPARAM("Say") ), SbxCLASS_METHOD, SbxEMPTY );
+ pMeth->SetUserData( 0x12345678 );
+ pMeth->ResetFlag( SBX_FIXED );
+ SbxInfo* pInfo_ = new SbxInfo;
+ pInfo_->AddParam( String( RTL_CONSTASCII_USTRINGPARAM("text") ), SbxSTRING, SBX_READ );
+ pMeth->SetInfo( pInfo_ );
+}
+
+void SampleElement::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* pPar_ = pVar->GetParameters();
+ ULONG t = pHint->GetId();
+ if( t == SBX_HINT_DATAWANTED && pVar->GetUserData() == 0x12345678 )
+ {
+ // Die Say-Methode:
+ // 1 Parameter + Returnwert
+ if( !pPar_ || pPar_->Count() != 2 )
+ SetError( SbxERR_WRONG_ARGS );
+ else
+ {
+ String s( GetName() );
+ s.AppendAscii( " says: " );
+ s += pPar_->Get( 1 )->GetString();
+ pPar_->Get( 0 )->SetType(SbxSTRING);
+ pPar_->Get( 0 )->PutString( s );
+ InfoBox( NULL, s ).Execute();
+ }
+ return;
+ }
+ SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+ }
+}
+
diff --git a/basic/source/sample/makefile.mk b/basic/source/sample/makefile.mk
new file mode 100644
index 000000000000..9aeb8e353414
--- /dev/null
+++ b/basic/source/sample/makefile.mk
@@ -0,0 +1,58 @@
+#*************************************************************************
+#
+# 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=sample
+
+# --- Settings ------------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Allgemein ------------------------------------------------------------
+
+CXXFILES = \
+ object.cxx \
+ collelem.cxx
+
+
+OBJFILES = \
+ $(OBJ)$/object.obj \
+ $(OBJ)$/collelem.obj
+
+
+LIBTARGET = NO
+
+LIB1TARGET=$(LB)$/sample.lib
+LIB1ARCHIV=$(LB)$/libsample.a
+
+LIB1OBJFILES = $(OBJFILES)
+
+# --- Targets ------------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/basic/source/sample/object.cxx b/basic/source/sample/object.cxx
new file mode 100644
index 000000000000..3c5fbeb3478c
--- /dev/null
+++ b/basic/source/sample/object.cxx
@@ -0,0 +1,278 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#include <basic/sbxobj.hxx>
+#include <basic/sbx.hxx>
+#ifndef __SBX_SBXVARIABLE_HXX //autogen
+#include <basic/sbxvar.hxx>
+#endif
+#ifndef _MSGBOX_HXX //autogen
+#include <vcl/msgbox.hxx>
+#endif
+
+#include "object.hxx"
+#include "collelem.hxx"
+
+// Das Sample-Objekt hat folgende Elemente:
+// 1) Properties:
+// Name der Name
+// Value ein double-Wert, beide bereits als Default drin
+// 2) Methoden:
+// Create Erzeugen eines neuen Unterelements
+// Display Ausgabe eines Textes
+// Square Argument * Argument
+// Event Aufruf eines Basic-Eventhandlers
+// 3) Unterobjekte:
+// Per Create() kann ein neues Unterelement eingerichtet werden,
+// das indiziert werden kann, falls mehrere Objekte gleichen Namens
+// existieren.
+// Diese Implementation ist ein Beispiel fuer eine tabellengesteuerte
+// Version, die sehr viele Elemente enthalten kann. Die Elemente werden
+// je nach Bedarf aus der Tabelle in das Objekt uebernommen.
+// Die Collection findet sich in COLLECTN.*, die in der Collection
+// enthaltenen Objekte in COLLELEM.*
+
+// Das Sample-Objekt wird in ..\app\mybasic.cxx wie folgt in StarBASIC
+// eingebaut:
+
+// MyBasic::MyBasic() : StarBASIC()
+// {
+// AddFactory( new SampleObjectFac() );
+// }
+
+// Das nArgs-Feld eines Tabelleneintrags ist wie folgt verschluesselt:
+
+#define _ARGSMASK 0x00FF // Bis zu 255 Argumente
+#define _RWMASK 0x0F00 // Maske fuer R/W-Bits
+#define _TYPEMASK 0xF000 // Maske fuer den Typ des Eintrags
+
+#define _READ 0x0100 // kann gelesen werden
+#define _BWRITE 0x0200 // kann as Lvalue verwendet werden
+#define _LVALUE _BWRITE // kann as Lvalue verwendet werden
+#define _READWRITE 0x0300 // beides
+#define _OPT 0x0400 // TRUE: optionaler Parameter
+#define _METHOD 0x1000 // Masken-Bit fuer eine Methode
+#define _PROPERTY 0x2000 // Masken-Bit fuer eine Property
+#define _COLL 0x4000 // Masken-Bit fuer eine Collection
+ // Kombination von oberen Bits:
+#define _FUNCTION 0x1100 // Maske fuer Function
+#define _LFUNCTION 0x1300 // Maske fuer Function, die auch als Lvalue geht
+#define _ROPROP 0x2100 // Maske Read Only-Property
+#define _WOPROP 0x2200 // Maske Write Only-Property
+#define _RWPROP 0x2300 // Maske Read/Write-Property
+#define _COLLPROP 0x4100 // Maske Read-Collection-Element
+
+#define COLLNAME "Elements" // Name der Collection, hier mal hart verdrahtet
+
+SampleObject::Methods SampleObject::aMethods[] = {
+// Eine Sample-Methode (der Returnwert ist SbxNULL)
+{ "Display", SbxEMPTY, &SampleObject::Display, 1 | _FUNCTION },
+ // Ein Named Parameter
+ { "message", SbxSTRING, NULL, 0 },
+// Eine Sample-Funktion
+{ "Square", SbxDOUBLE, &SampleObject::Square, 1 | _FUNCTION },
+ // Ein Named Parameter
+ { "value", SbxDOUBLE, NULL, 0 },
+// Basic-Callback
+{ "Event", SbxEMPTY, &SampleObject::Event, 1 | _FUNCTION },
+ // Ein Named Parameter
+ { "event", SbxSTRING, NULL, 0 },
+// Element erzeugen
+{ "Create", SbxEMPTY, &SampleObject::Create, 1 | _FUNCTION },
+ // Ein Named Parameter
+ { "name", SbxSTRING, NULL, 0 },
+
+{ NULL, SbxNULL, NULL, -1 }}; // Tabellenende
+
+SampleObject::SampleObject( const String& rClass ) : SbxObject( rClass )
+{
+ SetName( String( RTL_CONSTASCII_USTRINGPARAM("Sample") ) );
+ PutDouble( 1.0 ); // Startwert fuer Value
+}
+
+// Suche nach einem Element:
+// Hier wird linear durch die Methodentabelle gegangen, bis eine
+// passende Methode gefunden wurde.
+// Wenn die Methode/Property nicht gefunden wurde, nur NULL ohne
+// Fehlercode zurueckliefern, da so auch eine ganze Chain von
+// Objekten nach der Methode/Property befragt werden kann.
+
+SbxVariable* SampleObject::Find( const String& rName, SbxClassType t )
+{
+ // Ist das Element bereits vorhanden?
+ SbxVariable* pRes = SbxObject::Find( rName, t );
+ if( !pRes && t != SbxCLASS_OBJECT )
+ {
+ // sonst suchen
+ Methods* p = aMethods;
+ short nIndex = 0;
+ BOOL bFound = FALSE;
+ while( p->nArgs != -1 )
+ {
+ if( rName.EqualsIgnoreCaseAscii( p->pName ) )
+ {
+ bFound = TRUE; break;
+ }
+ nIndex += ( p->nArgs & _ARGSMASK ) + 1;
+ p = aMethods + nIndex;
+ }
+ if( bFound )
+ {
+ // Args-Felder isolieren:
+ short nAccess = ( p->nArgs & _RWMASK ) >> 8;
+ short nType = ( p->nArgs & _TYPEMASK );
+ String aName_ = String::CreateFromAscii( p->pName );
+ SbxClassType eCT = SbxCLASS_OBJECT;
+ if( nType & _PROPERTY )
+ eCT = SbxCLASS_PROPERTY;
+ else if( nType & _METHOD )
+ eCT = SbxCLASS_METHOD;
+ pRes = Make( aName_, eCT, p->eType );
+ // Wir setzen den Array-Index + 1, da ja noch andere
+ // Standard-Properties existieren, die auch aktiviert
+ // werden muessen.
+ pRes->SetUserData( nIndex + 1 );
+ pRes->SetFlags( nAccess );
+ }
+ }
+ return pRes;
+}
+
+// Aktivierung eines Elements oder Anfordern eines Infoblocks
+
+void SampleObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCT,
+ const SfxHint& rHint, const TypeId& rHT )
+{
+ const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
+ if( pHint )
+ {
+ SbxVariable* pVar = pHint->GetVar();
+ SbxArray* pPar_ = pVar->GetParameters();
+ USHORT nIndex = (USHORT) pVar->GetUserData();
+ // kein Index: weiterreichen!
+ if( nIndex )
+ {
+ ULONG t = pHint->GetId();
+ if( t == SBX_HINT_INFOWANTED )
+ pVar->SetInfo( GetInfo( (short) pVar->GetUserData() ) );
+ else
+ {
+ BOOL bWrite = FALSE;
+ if( t == SBX_HINT_DATACHANGED )
+ bWrite = TRUE;
+ if( t == SBX_HINT_DATAWANTED || bWrite )
+ {
+ // Parameter-Test fuer Methoden:
+ USHORT nPar = aMethods[ --nIndex ].nArgs & 0x00FF;
+ // Element 0 ist der Returnwert
+ if( ( !pPar_ && nPar )
+ || ( pPar_->Count() != nPar+1 ) )
+ SetError( SbxERR_WRONG_ARGS );
+ // Alles klar, man kann den Call ausfuehren
+ else
+ {
+ (this->*(aMethods[ nIndex ].pFunc))( pVar, pPar_, bWrite );
+ }
+ }
+ }
+ }
+ SbxObject::SFX_NOTIFY( rBC, rBCT, rHint, rHT );
+ }
+}
+
+// Zusammenbau der Infostruktur fuer einzelne Elemente
+
+SbxInfo* SampleObject::GetInfo( short nIdx )
+{
+ Methods* p = &aMethods[ nIdx ];
+ // Wenn mal eine Hilfedatei zur Verfuegung steht:
+ // SbxInfo* pInfo_ = new SbxInfo( Hilfedateiname, p->nHelpId );
+ SbxInfo* pInfo_ = new SbxInfo;
+ short nPar = p->nArgs & _ARGSMASK;
+ for( short i = 0; i < nPar; i++ )
+ {
+ p++;
+ String aName_ = String::CreateFromAscii( p->pName );
+ USHORT nFlags_ = ( p->nArgs >> 8 ) & 0x03;
+ if( p->nArgs & _OPT )
+ nFlags_ |= SBX_OPTIONAL;
+ pInfo_->AddParam( aName_, p->eType, nFlags_ );
+ }
+ return pInfo_;
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+// Properties und Methoden legen beim Get (bPut = FALSE) den Returnwert
+// im Element 0 des Argv ab; beim Put (bPut = TRUE) wird der Wert aus
+// Element 0 gespeichert.
+
+// Die Methoden:
+
+void SampleObject::Display( SbxVariable*, SbxArray* pPar_, BOOL )
+{
+ // GetString() loest u.U. auch einen Error aus!
+ String s( pPar_->Get( 1 )->GetString() );
+ if( !IsError() )
+ InfoBox( NULL, s ).Execute();
+}
+
+void SampleObject::Square( SbxVariable* pVar, SbxArray* pPar_, BOOL )
+{
+ double n = pPar_->Get( 1 )->GetDouble();
+ pVar->PutDouble( n * n );
+}
+
+// Callback nach BASIC:
+
+void SampleObject::Event( SbxVariable*, SbxArray* pPar_, BOOL )
+{
+ Call( pPar_->Get( 1 )->GetString(), NULL );
+}
+
+// Neues Element anlegen
+
+void SampleObject::Create( SbxVariable* pVar, SbxArray* pPar_, BOOL )
+{
+ pVar->PutObject(
+ MakeObject( pPar_->Get( 1 )->GetString(), String( RTL_CONSTASCII_USTRINGPARAM("SampleElement") ) ) );
+}
+
+// Die Factory legt unsere beiden Objekte an.
+
+SbxObject* SampleObjectFac::CreateObject( const String& rClass )
+{
+ if( rClass.EqualsIgnoreCaseAscii( "SampleObject" ) )
+ return new SampleObject( rClass );
+ if( rClass.EqualsIgnoreCaseAscii( "SampleElement" ) )
+ return new SampleElement( rClass );
+ return NULL;
+}
+
diff --git a/basic/source/sample/sample.bas b/basic/source/sample/sample.bas
new file mode 100644
index 000000000000..d0e416871af0
--- /dev/null
+++ b/basic/source/sample/sample.bas
@@ -0,0 +1,39 @@
+' Sample-Programm fuer Sample-Objekte
+
+Sub Main
+ Dim Sample As SampleObject
+ Dim Element1 As Object, Element2 As Object
+ Set Element1 = Sample!Create "Objekt"
+ Set Element2 = Sample.Create "Objekt"
+ Element1 = "Element 1"
+ Element2 = "Element 2"
+ For i = 0 to 1
+ Print Sample.Objekt( i )
+ Next
+ 'Test der Event-Methode im Sample-Objekt
+ Sample.Event "Bang"
+End Sub
+
+Sub Bang
+ print "Sample-Callback: BANG!"
+End Sub
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/basic/source/sbx/format.src b/basic/source/sbx/format.src
new file mode 100644
index 000000000000..7e576134fad5
--- /dev/null
+++ b/basic/source/sbx/format.src
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include "svtools/svtools.hrc"
+
+String STR_BASICKEY_FORMAT_ON
+{
+ Text [ en-US ] = "On" ;
+};
+String STR_BASICKEY_FORMAT_OFF
+{
+ Text [ en-US ] = "Off" ;
+};
+String STR_BASICKEY_FORMAT_TRUE
+{
+ Text [ en-US ] = "True" ;
+};
+String STR_BASICKEY_FORMAT_FALSE
+{
+ Text [ en-US ] = "False" ;
+};
+String STR_BASICKEY_FORMAT_YES
+{
+ Text [ en-US ] = "Yes" ;
+};
+String STR_BASICKEY_FORMAT_NO
+{
+ Text [ en-US ] = "No" ;
+};
+String STR_BASICKEY_FORMAT_CURRENCY
+{
+ Text [ en-US ] = "@0.00 $;@(0.00 $)" ;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/basic/source/sbx/makefile.mk b/basic/source/sbx/makefile.mk
new file mode 100644
index 000000000000..dfd8e72bf4da
--- /dev/null
+++ b/basic/source/sbx/makefile.mk
@@ -0,0 +1,77 @@
+#*************************************************************************
+#
+# 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=sbx
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+
+# --- Allgemein -----------------------------------------------------------
+
+SRS1NAME=$(TARGET)
+SRC1FILES= format.src
+
+SLOFILES= \
+ $(SLO)$/sbxbase.obj \
+ $(SLO)$/sbxres.obj \
+ $(SLO)$/sbxvalue.obj \
+ $(SLO)$/sbxvals.obj \
+ $(SLO)$/sbxvar.obj \
+ $(SLO)$/sbxarray.obj \
+ $(SLO)$/sbxobj.obj \
+ $(SLO)$/sbxcoll.obj \
+ $(SLO)$/sbxexec.obj \
+ $(SLO)$/sbxint.obj \
+ $(SLO)$/sbxlng.obj \
+ $(SLO)$/sbxsng.obj \
+ $(SLO)$/sbxmstrm.obj \
+ $(SLO)$/sbxdbl.obj \
+ $(SLO)$/sbxcurr.obj \
+ $(SLO)$/sbxdate.obj \
+ $(SLO)$/sbxstr.obj \
+ $(SLO)$/sbxbool.obj \
+ $(SLO)$/sbxchar.obj \
+ $(SLO)$/sbxbyte.obj \
+ $(SLO)$/sbxuint.obj \
+ $(SLO)$/sbxulng.obj \
+ $(SLO)$/sbxform.obj \
+ $(SLO)$/sbxscan.obj \
+ $(SLO)$/sbxdec.obj
+
+
+EXCEPTIONSFILES=$(SLO)$/sbxarray.obj
+
+# --- Targets -------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+
diff --git a/basic/source/sbx/sbxarray.cxx b/basic/source/sbx/sbxarray.cxx
new file mode 100644
index 000000000000..67e7ce71aded
--- /dev/null
+++ b/basic/source/sbx/sbxarray.cxx
@@ -0,0 +1,857 @@
+/*************************************************************************
+ *
+ * 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 <basic/sbx.hxx>
+#include "runtime.hxx"
+#include <vector>
+using namespace std;
+
+struct SbxDim { // eine Array-Dimension:
+ SbxDim* pNext; // Link
+ INT32 nLbound, nUbound; // Begrenzungen
+ INT32 nSize; // Anzahl Elemente
+};
+
+class SbxVarEntry : public SbxVariableRef {
+public:
+ XubString* pAlias;
+ SbxVarEntry() : SbxVariableRef(), pAlias( NULL ) {}
+ ~SbxVarEntry() { delete pAlias; }
+};
+
+typedef SbxVarEntry* SbxVarEntryPtr;
+typedef vector< SbxVarEntryPtr > SbxVarEntryPtrVector;
+class SbxVarRefs : public SbxVarEntryPtrVector
+{
+public:
+ SbxVarRefs( void ) {}
+};
+
+
+TYPEINIT1(SbxArray,SbxBase)
+TYPEINIT1(SbxDimArray,SbxArray)
+
+//////////////////////////////////////////////////////////////////////////
+//
+// SbxArray
+//
+//////////////////////////////////////////////////////////////////////////
+
+SbxArray::SbxArray( SbxDataType t ) : SbxBase()
+{
+ pData = new SbxVarRefs;
+ eType = t;
+ if( t != SbxVARIANT )
+ SetFlag( SBX_FIXED );
+}
+
+SbxArray::SbxArray( const SbxArray& rArray ) :
+ SvRefBase( rArray ), SbxBase()
+{
+ pData = new SbxVarRefs;
+ if( rArray.eType != SbxVARIANT )
+ SetFlag( SBX_FIXED );
+ *this = rArray;
+}
+
+SbxArray& SbxArray::operator=( const SbxArray& rArray )
+{
+ if( &rArray != this )
+ {
+ eType = rArray.eType;
+ Clear();
+ SbxVarRefs* pSrc = rArray.pData;
+ for( UINT32 i = 0; i < pSrc->size(); i++ )
+ {
+ SbxVarEntryPtr pSrcRef = (*pSrc)[i];
+ const SbxVariable* pSrc_ = *pSrcRef;
+ if( !pSrc_ )
+ continue;
+ SbxVarEntryPtr pDstRef = new SbxVarEntry;
+ *((SbxVariableRef*) pDstRef) = *((SbxVariableRef*) pSrcRef);
+ if( pSrcRef->pAlias )
+ pDstRef->pAlias = new XubString( *pSrcRef->pAlias );
+ if( eType != SbxVARIANT )
+ // Keine Objekte konvertieren
+ if( eType != SbxOBJECT || pSrc_->GetClass() != SbxCLASS_OBJECT )
+ ((SbxVariable*) pSrc_)->Convert( eType );
+ pData->push_back( pDstRef );
+ }
+ }
+ return *this;
+}
+
+SbxArray::~SbxArray()
+{
+ Clear();
+ delete pData;
+}
+
+SbxDataType SbxArray::GetType() const
+{
+ return (SbxDataType) ( eType | SbxARRAY );
+}
+
+SbxClassType SbxArray::GetClass() const
+{
+ return SbxCLASS_ARRAY;
+}
+
+void SbxArray::Clear()
+{
+ UINT32 nSize = pData->size();
+ for( UINT32 i = 0 ; i < nSize ; i++ )
+ {
+ SbxVarEntry* pEntry = (*pData)[i];
+ delete pEntry;
+ }
+ pData->clear();
+}
+
+UINT32 SbxArray::Count32() const
+{
+ return pData->size();
+}
+
+USHORT SbxArray::Count() const
+{
+ UINT32 nCount = pData->size();
+ DBG_ASSERT( nCount <= SBX_MAXINDEX, "SBX: Array-Index > SBX_MAXINDEX" );
+ return (USHORT)nCount;
+}
+
+SbxVariableRef& SbxArray::GetRef32( UINT32 nIdx )
+{
+ // Array ggf. vergroessern
+ DBG_ASSERT( nIdx <= SBX_MAXINDEX32, "SBX: Array-Index > SBX_MAXINDEX32" );
+ // Very Hot Fix
+ if( nIdx > SBX_MAXINDEX32 )
+ {
+ SetError( SbxERR_BOUNDS );
+ nIdx = 0;
+ }
+ while( pData->size() <= nIdx )
+ {
+ const SbxVarEntryPtr p = new SbxVarEntry;
+ pData->push_back( p );
+ }
+ return *((*pData)[nIdx]);
+}
+
+SbxVariableRef& SbxArray::GetRef( USHORT nIdx )
+{
+ // Array ggf. vergroessern
+ DBG_ASSERT( nIdx <= SBX_MAXINDEX, "SBX: Array-Index > SBX_MAXINDEX" );
+ // Very Hot Fix
+ if( nIdx > SBX_MAXINDEX )
+ {
+ SetError( SbxERR_BOUNDS );
+ nIdx = 0;
+ }
+ while( pData->size() <= nIdx )
+ {
+ const SbxVarEntryPtr p = new SbxVarEntry;
+ pData->push_back( p );
+ }
+ return *((*pData)[nIdx]);
+}
+
+SbxVariable* SbxArray::Get32( UINT32 nIdx )
+{
+ if( !CanRead() )
+ {
+ SetError( SbxERR_PROP_WRITEONLY );
+ return NULL;
+ }
+ SbxVariableRef& rRef = GetRef32( nIdx );
+
+ if ( !rRef.Is() )
+ rRef = new SbxVariable( eType );
+#ifdef DBG_UTIL
+ else
+ DBG_CHKOBJ( rRef, SbxBase, 0 );
+#endif
+
+ return rRef;
+}
+
+SbxVariable* SbxArray::Get( USHORT nIdx )
+{
+ if( !CanRead() )
+ {
+ SetError( SbxERR_PROP_WRITEONLY );
+ return NULL;
+ }
+ SbxVariableRef& rRef = GetRef( nIdx );
+
+ if ( !rRef.Is() )
+ rRef = new SbxVariable( eType );
+#ifdef DBG_UTIL
+ else
+ DBG_CHKOBJ( rRef, SbxBase, 0 );
+#endif
+
+ return rRef;
+}
+
+void SbxArray::Put32( SbxVariable* pVar, UINT32 nIdx )
+{
+ if( !CanWrite() )
+ SetError( SbxERR_PROP_READONLY );
+ else
+ {
+ if( pVar )
+ if( eType != SbxVARIANT )
+ // Keine Objekte konvertieren
+ if( eType != SbxOBJECT || pVar->GetClass() != SbxCLASS_OBJECT )
+ pVar->Convert( eType );
+ SbxVariableRef& rRef = GetRef32( nIdx );
+ if( (SbxVariable*) rRef != pVar )
+ {
+ rRef = pVar;
+ SetFlag( SBX_MODIFIED );
+ }
+ }
+}
+
+void SbxArray::Put( SbxVariable* pVar, USHORT nIdx )
+{
+ if( !CanWrite() )
+ SetError( SbxERR_PROP_READONLY );
+ else
+ {
+ if( pVar )
+ if( eType != SbxVARIANT )
+ // Keine Objekte konvertieren
+ if( eType != SbxOBJECT || pVar->GetClass() != SbxCLASS_OBJECT )
+ pVar->Convert( eType );
+ SbxVariableRef& rRef = GetRef( nIdx );
+ if( (SbxVariable*) rRef != pVar )
+ {
+ rRef = pVar;
+ SetFlag( SBX_MODIFIED );
+ }
+ }
+}
+
+const XubString& SbxArray::GetAlias( USHORT nIdx )
+{
+ if( !CanRead() )
+ {
+ SetError( SbxERR_PROP_WRITEONLY );
+ return String::EmptyString();
+ }
+ SbxVarEntry& rRef = (SbxVarEntry&) GetRef( nIdx );
+
+ if ( !rRef.pAlias )
+ return String::EmptyString();
+#ifdef DBG_UTIL
+ else
+ DBG_CHKOBJ( rRef, SbxBase, 0 );
+#endif
+
+ return *rRef.pAlias;
+}
+
+void SbxArray::PutAlias( const XubString& rAlias, USHORT nIdx )
+{
+ if( !CanWrite() )
+ SetError( SbxERR_PROP_READONLY );
+ else
+ {
+ SbxVarEntry& rRef = (SbxVarEntry&) GetRef( nIdx );
+ if( !rRef.pAlias )
+ rRef.pAlias = new XubString( rAlias );
+ else
+ *rRef.pAlias = rAlias;
+ }
+}
+
+void SbxArray::Insert32( SbxVariable* pVar, UINT32 nIdx )
+{
+ DBG_ASSERT( pData->size() <= SBX_MAXINDEX32, "SBX: Array wird zu gross" );
+ if( pData->size() > SBX_MAXINDEX32 )
+ return;
+ SbxVarEntryPtr p = new SbxVarEntry;
+ *((SbxVariableRef*) p) = pVar;
+ SbxVarEntryPtrVector::size_type nSize = pData->size();
+ if( nIdx > nSize )
+ nIdx = nSize;
+ if( eType != SbxVARIANT && pVar )
+ (*p)->Convert( eType );
+ if( nIdx == nSize )
+ {
+ pData->push_back( p );
+ }
+ else
+ {
+ pData->insert( pData->begin() + nIdx, p );
+ }
+ SetFlag( SBX_MODIFIED );
+}
+
+void SbxArray::Insert( SbxVariable* pVar, USHORT nIdx )
+{
+ DBG_ASSERT( pData->size() <= 0x3FF0, "SBX: Array wird zu gross" );
+ if( pData->size() > 0x3FF0 )
+ return;
+ Insert32( pVar, nIdx );
+}
+
+void SbxArray::Remove32( UINT32 nIdx )
+{
+ if( nIdx < pData->size() )
+ {
+ SbxVariableRef* pRef = (*pData)[nIdx];
+ pData->erase( pData->begin() + nIdx );
+ delete pRef;
+ SetFlag( SBX_MODIFIED );
+ }
+}
+
+void SbxArray::Remove( USHORT nIdx )
+{
+ if( nIdx < pData->size() )
+ {
+ SbxVariableRef* pRef = (*pData)[nIdx];
+ pData->erase( pData->begin() + nIdx );
+ delete pRef;
+ SetFlag( SBX_MODIFIED );
+ }
+}
+
+void SbxArray::Remove( SbxVariable* pVar )
+{
+ if( pVar )
+ {
+ for( UINT32 i = 0; i < pData->size(); i++ )
+ {
+ SbxVariableRef* pRef = (*pData)[i];
+ // SbxVariableRef* pRef = pData->GetObject( i );
+ if( *pRef == pVar )
+ {
+ Remove32( i ); break;
+ }
+ }
+ }
+}
+
+// Uebernahme der Daten aus dem uebergebenen Array, wobei
+// gleichnamige Variable ueberschrieben werden.
+
+void SbxArray::Merge( SbxArray* p )
+{
+ if( p )
+ {
+ UINT32 nSize = p->Count();
+ for( UINT32 i = 0; i < nSize; i++ )
+ {
+ SbxVarEntryPtr pRef1 = (*(p->pData))[i];
+ // Ist das Element by name schon drin?
+ // Dann ueberschreiben!
+ SbxVariable* pVar = *pRef1;
+ if( pVar )
+ {
+ XubString aName = pVar->GetName();
+ USHORT nHash = pVar->GetHashCode();
+ for( UINT32 j = 0; j < pData->size(); j++ )
+ {
+ SbxVariableRef* pRef2 = (*pData)[j];
+ if( (*pRef2)->GetHashCode() == nHash
+ && (*pRef2)->GetName().EqualsIgnoreCaseAscii( aName ) )
+ {
+ *pRef2 = pVar; pRef1 = NULL;
+ break;
+ }
+ }
+ if( pRef1 )
+ {
+ SbxVarEntryPtr pRef = new SbxVarEntry;
+ const SbxVarEntryPtr pTemp = pRef;
+ pData->push_back( pTemp );
+ *((SbxVariableRef*) pRef) = *((SbxVariableRef*) pRef1);
+ if( pRef1->pAlias )
+ pRef->pAlias = new XubString( *pRef1->pAlias );
+ }
+ }
+ }
+ }
+}
+
+// Suchen eines Elements ueber die Userdaten. Falls ein Element
+// ein Objekt ist, wird dieses ebenfalls durchsucht.
+
+SbxVariable* SbxArray::FindUserData( UINT32 nData )
+{
+ SbxVariable* p = NULL;
+ for( UINT32 i = 0; i < pData->size(); i++ )
+ {
+ SbxVariableRef* pRef = (*pData)[i];
+ SbxVariable* pVar = *pRef;
+ if( pVar )
+ {
+ if( pVar->IsVisible() && pVar->GetUserData() == nData )
+ {
+ p = pVar;
+ p->ResetFlag( SBX_EXTFOUND );
+ break; // JSM 06.10.95
+ }
+ // Haben wir ein Array/Objekt mit Extended Search?
+ else if( pVar->IsSet( SBX_EXTSEARCH ) )
+ {
+ switch( pVar->GetClass() )
+ {
+ case SbxCLASS_OBJECT:
+ {
+ // Objekte duerfen ihren Parent nicht durchsuchen
+ USHORT nOld = pVar->GetFlags();
+ pVar->ResetFlag( SBX_GBLSEARCH );
+ p = ((SbxObject*) pVar)->FindUserData( nData );
+ pVar->SetFlags( nOld );
+ break;
+ }
+ case SbxCLASS_ARRAY:
+ p = ((SbxArray*) pVar)->FindUserData( nData );
+ break;
+ default: break;
+ }
+ if( p )
+ {
+ p->SetFlag( SBX_EXTFOUND );
+ break;
+ }
+ }
+ }
+ }
+ return p;
+}
+
+// Suchen eines Elements ueber den Namen und den Typ. Falls ein Element
+// ein Objekt ist, wird dieses ebenfalls durchsucht.
+
+SbxVariable* SbxArray::Find( const XubString& rName, SbxClassType t )
+{
+ SbxVariable* p = NULL;
+ UINT32 nCount = pData->size();
+ if( !nCount )
+ return NULL;
+ BOOL bExtSearch = IsSet( SBX_EXTSEARCH );
+ USHORT nHash = SbxVariable::MakeHashCode( rName );
+ for( UINT32 i = 0; i < nCount; i++ )
+ {
+ SbxVariableRef* pRef = (*pData)[i];
+ SbxVariable* pVar = *pRef;
+ if( pVar && pVar->IsVisible() )
+ {
+ // Die ganz sichere Suche klappt auch, wenn es
+ // keinen Hascode gibt!
+ USHORT nVarHash = pVar->GetHashCode();
+ if( ( !nVarHash || nVarHash == nHash )
+ && ( t == SbxCLASS_DONTCARE || pVar->GetClass() == t )
+ && ( pVar->GetName().EqualsIgnoreCaseAscii( rName ) ) )
+ {
+ p = pVar;
+ p->ResetFlag( SBX_EXTFOUND );
+ break;
+ }
+ // Haben wir ein Array/Objekt mit Extended Search?
+ else if( bExtSearch && pVar->IsSet( SBX_EXTSEARCH ) )
+ {
+ switch( pVar->GetClass() )
+ {
+ case SbxCLASS_OBJECT:
+ {
+ // Objekte duerfen ihren Parent nicht durchsuchen
+ USHORT nOld = pVar->GetFlags();
+ pVar->ResetFlag( SBX_GBLSEARCH );
+ p = ((SbxObject*) pVar)->Find( rName, t );
+ pVar->SetFlags( nOld );
+ break;
+ }
+ case SbxCLASS_ARRAY:
+ p = ((SbxArray*) pVar)->Find( rName, t );
+ break;
+ default: break;
+ }
+ if( p )
+ {
+ p->SetFlag( SBX_EXTFOUND );
+ break;
+ }
+ }
+ }
+ }
+ return p;
+}
+
+BOOL SbxArray::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ UINT16 nElem;
+ Clear();
+ BOOL bRes = TRUE;
+ USHORT f = nFlags;
+ nFlags |= SBX_WRITE;
+ rStrm >> nElem;
+ nElem &= 0x7FFF;
+ for( UINT32 n = 0; n < nElem; n++ )
+ {
+ UINT16 nIdx;
+ rStrm >> nIdx;
+ SbxVariable* pVar = (SbxVariable*) Load( rStrm );
+ if( pVar )
+ {
+ SbxVariableRef& rRef = GetRef( nIdx );
+ rRef = pVar;
+ }
+ else
+ {
+ bRes = FALSE; break;
+ }
+ }
+ if( bRes )
+ bRes = LoadPrivateData( rStrm, nVer );
+ nFlags = f;
+ return bRes;
+}
+
+BOOL SbxArray::StoreData( SvStream& rStrm ) const
+{
+ UINT32 nElem = 0;
+ UINT32 n;
+ // Welche Elemente sind ueberhaupt definiert?
+ for( n = 0; n < pData->size(); n++ )
+ {
+ SbxVariableRef* pRef = (*pData)[n];
+ SbxVariable* p = *pRef;
+ if( p && !( p->GetFlags() & SBX_DONTSTORE ) )
+ nElem++;
+ }
+ rStrm << (UINT16) nElem;
+ for( n = 0; n < pData->size(); n++ )
+ {
+ SbxVariableRef* pRef = (*pData)[n];
+ SbxVariable* p = *pRef;
+ if( p && !( p->GetFlags() & SBX_DONTSTORE ) )
+ {
+ rStrm << (UINT16) n;
+ if( !p->Store( rStrm ) )
+ return FALSE;
+ }
+ }
+ return StorePrivateData( rStrm );
+}
+
+// #100883 Method to set method directly to parameter array
+void SbxArray::PutDirect( SbxVariable* pVar, UINT32 nIdx )
+{
+ SbxVariableRef& rRef = GetRef32( nIdx );
+ rRef = pVar;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+//
+// SbxArray
+//
+//////////////////////////////////////////////////////////////////////////
+
+SbxDimArray::SbxDimArray( SbxDataType t ) : SbxArray( t ), mbHasFixedSize( false )
+{
+ pFirst = pLast = NULL;
+ nDim = 0;
+}
+
+SbxDimArray::SbxDimArray( const SbxDimArray& rArray )
+ : SvRefBase( rArray ), SbxArray( rArray.eType )
+{
+ pFirst = pLast = NULL;
+ nDim = 0;
+ *this = rArray;
+}
+
+SbxDimArray& SbxDimArray::operator=( const SbxDimArray& rArray )
+{
+ if( &rArray != this )
+ {
+ SbxArray::operator=( (const SbxArray&) rArray );
+ SbxDim* p = rArray.pFirst;
+ while( p )
+ {
+ AddDim32( p->nLbound, p->nUbound );
+ p = p->pNext;
+ }
+ this->mbHasFixedSize = rArray.mbHasFixedSize;
+ }
+ return *this;
+}
+
+SbxDimArray::~SbxDimArray()
+{
+ Clear();
+}
+
+void SbxDimArray::Clear()
+{
+ SbxDim* p = pFirst;
+ while( p )
+ {
+ SbxDim* q = p->pNext;
+ delete p;
+ p = q;
+ }
+ pFirst = pLast = NULL;
+ nDim = 0;
+}
+
+// Dimension hinzufuegen
+
+void SbxDimArray::AddDimImpl32( INT32 lb, INT32 ub, BOOL bAllowSize0 )
+{
+ SbxError eRes = SbxERR_OK;
+ if( ub < lb && !bAllowSize0 )
+ {
+ eRes = SbxERR_BOUNDS;
+ ub = lb;
+ }
+ SbxDim* p = new SbxDim;
+ p->nLbound = lb;
+ p->nUbound = ub;
+ p->nSize = ub - lb + 1;
+ p->pNext = NULL;
+ if( !pFirst )
+ pFirst = pLast = p;
+ else
+ pLast->pNext = p, pLast = p;
+ nDim++;
+ if( eRes )
+ SetError( eRes );
+}
+
+void SbxDimArray::AddDim( short lb, short ub )
+{
+ AddDimImpl32( lb, ub, FALSE );
+}
+
+void SbxDimArray::unoAddDim( short lb, short ub )
+{
+ AddDimImpl32( lb, ub, TRUE );
+}
+
+void SbxDimArray::AddDim32( INT32 lb, INT32 ub )
+{
+ AddDimImpl32( lb, ub, FALSE );
+}
+
+void SbxDimArray::unoAddDim32( INT32 lb, INT32 ub )
+{
+ AddDimImpl32( lb, ub, TRUE );
+}
+
+
+// Dimensionsdaten auslesen
+
+BOOL SbxDimArray::GetDim32( INT32 n, INT32& rlb, INT32& rub ) const
+{
+ if( n < 1 || n > nDim )
+ {
+ SetError( SbxERR_BOUNDS ); rub = rlb = 0; return FALSE;
+ }
+ SbxDim* p = pFirst;
+ while( --n )
+ p = p->pNext;
+ rub = p->nUbound;
+ rlb = p->nLbound;
+ return TRUE;
+}
+
+BOOL SbxDimArray::GetDim( short n, short& rlb, short& rub ) const
+{
+ INT32 rlb32, rub32;
+ BOOL bRet = GetDim32( n, rlb32, rub32 );
+ if( bRet )
+ {
+ if( rlb32 < -SBX_MAXINDEX || rub32 > SBX_MAXINDEX )
+ {
+ SetError( SbxERR_BOUNDS );
+ return FALSE;
+ }
+ rub = (short)rub32;
+ rlb = (short)rlb32;
+ }
+ return bRet;
+}
+
+// Element-Ptr anhand einer Index-Liste
+
+UINT32 SbxDimArray::Offset32( const INT32* pIdx )
+{
+ UINT32 nPos = 0;
+ for( SbxDim* p = pFirst; p; p = p->pNext )
+ {
+ INT32 nIdx = *pIdx++;
+ if( nIdx < p->nLbound || nIdx > p->nUbound )
+ {
+ nPos = (UINT32)SBX_MAXINDEX32 + 1; break;
+ }
+ nPos = nPos * p->nSize + nIdx - p->nLbound;
+ }
+ if( nDim == 0 || nPos > SBX_MAXINDEX32 )
+ {
+ SetError( SbxERR_BOUNDS ); nPos = 0;
+ }
+ return nPos;
+}
+
+USHORT SbxDimArray::Offset( const short* pIdx )
+{
+ long nPos = 0;
+ for( SbxDim* p = pFirst; p; p = p->pNext )
+ {
+ short nIdx = *pIdx++;
+ if( nIdx < p->nLbound || nIdx > p->nUbound )
+ {
+ nPos = SBX_MAXINDEX + 1; break;
+ }
+ nPos = nPos * p->nSize + nIdx - p->nLbound;
+ }
+ if( nDim == 0 || nPos > SBX_MAXINDEX )
+ {
+ SetError( SbxERR_BOUNDS ); nPos = 0;
+ }
+ return (USHORT) nPos;
+}
+
+SbxVariableRef& SbxDimArray::GetRef( const short* pIdx )
+{
+ return SbxArray::GetRef( Offset( pIdx ) );
+}
+
+SbxVariable* SbxDimArray::Get( const short* pIdx )
+{
+ return SbxArray::Get( Offset( pIdx ) );
+}
+
+void SbxDimArray::Put( SbxVariable* p, const short* pIdx )
+{
+ SbxArray::Put( p, Offset( pIdx ) );
+}
+
+SbxVariableRef& SbxDimArray::GetRef32( const INT32* pIdx )
+{
+ return SbxArray::GetRef32( Offset32( pIdx ) );
+}
+
+SbxVariable* SbxDimArray::Get32( const INT32* pIdx )
+{
+ return SbxArray::Get32( Offset32( pIdx ) );
+}
+
+void SbxDimArray::Put32( SbxVariable* p, const INT32* pIdx )
+{
+ SbxArray::Put32( p, Offset32( pIdx ) );
+}
+
+
+// Element-Nr anhand eines Parameter-Arrays
+
+UINT32 SbxDimArray::Offset32( SbxArray* pPar )
+{
+ if( nDim == 0 || !pPar || ( ( nDim != ( pPar->Count() - 1 ) ) && SbiRuntime::isVBAEnabled() ) )
+ {
+ SetError( SbxERR_BOUNDS ); return 0;
+ }
+ UINT32 nPos = 0;
+ USHORT nOff = 1; // Nicht Element 0!
+ for( SbxDim* p = pFirst; p && !IsError(); p = p->pNext )
+ {
+ INT32 nIdx = pPar->Get( nOff++ )->GetLong();
+ if( nIdx < p->nLbound || nIdx > p->nUbound )
+ {
+ nPos = (UINT32) SBX_MAXINDEX32+1; break;
+ }
+ nPos = nPos * p->nSize + nIdx - p->nLbound;
+ }
+ if( nPos > (UINT32) SBX_MAXINDEX32 )
+ {
+ SetError( SbxERR_BOUNDS ); nPos = 0;
+ }
+ return nPos;
+}
+
+USHORT SbxDimArray::Offset( SbxArray* pPar )
+{
+ UINT32 nPos = Offset32( pPar );
+ if( nPos > (long) SBX_MAXINDEX )
+ {
+ SetError( SbxERR_BOUNDS ); nPos = 0;
+ }
+ return (USHORT) nPos;
+}
+
+SbxVariableRef& SbxDimArray::GetRef( SbxArray* pPar )
+{
+ return SbxArray::GetRef32( Offset32( pPar ) );
+}
+
+SbxVariable* SbxDimArray::Get( SbxArray* pPar )
+{
+ return SbxArray::Get32( Offset32( pPar ) );
+}
+
+void SbxDimArray::Put( SbxVariable* p, SbxArray* pPar )
+{
+ SbxArray::Put32( p, Offset32( pPar ) );
+}
+
+BOOL SbxDimArray::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ short nDimension;
+ rStrm >> nDimension;
+ for( short i = 0; i < nDimension && rStrm.GetError() == SVSTREAM_OK; i++ )
+ {
+ INT16 lb, ub;
+ rStrm >> lb >> ub;
+ AddDim( lb, ub );
+ }
+ return SbxArray::LoadData( rStrm, nVer );
+}
+
+BOOL SbxDimArray::StoreData( SvStream& rStrm ) const
+{
+ rStrm << (INT16) nDim;
+ for( short i = 0; i < nDim; i++ )
+ {
+ short lb, ub;
+ GetDim( i, lb, ub );
+ rStrm << (INT16) lb << (INT16) ub;
+ }
+ return SbxArray::StoreData( rStrm );
+}
+
diff --git a/basic/source/sbx/sbxbase.cxx b/basic/source/sbx/sbxbase.cxx
new file mode 100644
index 000000000000..b1815228cd99
--- /dev/null
+++ b/basic/source/sbx/sbxbase.cxx
@@ -0,0 +1,462 @@
+/*************************************************************************
+ *
+ * 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 <tools/stream.hxx>
+
+#include <basic/sbx.hxx>
+#include <basic/sbxfac.hxx>
+#include <basic/sbxbase.hxx>
+
+// AppData-Struktur fuer SBX:
+
+SV_IMPL_PTRARR(SbxParams,SbxParamInfo*);
+SV_IMPL_PTRARR(SbxFacs,SbxFactory*);
+
+TYPEINIT0(SbxBase)
+
+// SBX-Daten anfordern oder ggf. anlegen
+// wir legen den Bereich einfach an und verzichten auf die Freigabe!
+
+SbxAppData* GetSbxData_Impl()
+{
+#ifndef DOS
+ SbxAppData** ppData = (SbxAppData**) ::GetAppData( SHL_SBX );
+ SbxAppData* p = *ppData;
+ if( !p )
+ p = *ppData = new SbxAppData;
+ return p;
+#else
+ SbxAppData** ppData;
+ SbxAppData* p;
+ p = *ppData = new SbxAppData;
+ return p;
+#endif
+}
+
+SbxAppData::~SbxAppData()
+{
+ if( pBasicFormater )
+ delete pBasicFormater;
+}
+
+
+//////////////////////////////// SbxBase /////////////////////////////////
+
+DBG_NAME(SbxBase);
+
+SbxBase::SbxBase()
+{
+ DBG_CTOR( SbxBase, 0 );
+ nFlags = SBX_READWRITE;
+}
+
+SbxBase::SbxBase( const SbxBase& r )
+ : SvRefBase( r )
+{
+ DBG_CTOR( SbxBase, 0 );
+ nFlags = r.nFlags;
+}
+
+SbxBase::~SbxBase()
+{
+ DBG_DTOR(SbxBase,0);
+}
+
+SbxBase& SbxBase::operator=( const SbxBase& r )
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ nFlags = r.nFlags;
+ return *this;
+}
+
+SbxDataType SbxBase::GetType() const
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return SbxEMPTY;
+}
+
+SbxClassType SbxBase::GetClass() const
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return SbxCLASS_DONTCARE;
+}
+
+void SbxBase::Clear()
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+}
+
+BOOL SbxBase::IsFixed() const
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return IsSet( SBX_FIXED );
+}
+
+void SbxBase::SetModified( BOOL b )
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ if( IsSet( SBX_NO_MODIFY ) )
+ return;
+ if( b )
+ SetFlag( SBX_MODIFIED );
+ else
+ ResetFlag( SBX_MODIFIED );
+}
+
+SbxError SbxBase::GetError()
+{
+ return GetSbxData_Impl()->eSbxError;
+}
+
+void SbxBase::SetError( SbxError e )
+{
+ SbxAppData* p = GetSbxData_Impl();
+ if( e && p->eSbxError == SbxERR_OK )
+ p->eSbxError = e;
+}
+
+BOOL SbxBase::IsError()
+{
+ return BOOL( GetSbxData_Impl()->eSbxError != SbxERR_OK );
+}
+
+void SbxBase::ResetError()
+{
+ GetSbxData_Impl()->eSbxError = SbxERR_OK;
+}
+
+void SbxBase::AddFactory( SbxFactory* pFac )
+{
+ SbxAppData* p = GetSbxData_Impl();
+ const SbxFactory* pTemp = pFac;
+
+ // AB, 6.3.96: HandleLast-Flag beruecksichtigen
+ USHORT nPos = p->aFacs.Count(); // Einfuege-Position
+ if( !pFac->IsHandleLast() ) // Nur, wenn nicht selbst HandleLast
+ {
+ // Neue Factory vor Factories mit HandleLast einordnen
+ while( nPos > 0 &&
+ (static_cast<SbxFactory*>(p->aFacs.GetObject( nPos-1 )))->IsHandleLast() )
+ nPos--;
+ }
+ p->aFacs.Insert( pTemp, nPos );
+}
+
+void SbxBase::RemoveFactory( SbxFactory* pFac )
+{
+ SbxAppData* p = GetSbxData_Impl();
+ for( USHORT i = 0; i < p->aFacs.Count(); i++ )
+ {
+ if( p->aFacs.GetObject( i ) == pFac )
+ {
+ p->aFacs.Remove( i, 1 ); break;
+ }
+ }
+}
+
+
+SbxBase* SbxBase::Create( UINT16 nSbxId, UINT32 nCreator )
+{
+ // #91626: Hack to skip old Basic dialogs
+ // Problem: There does not exist a factory any more,
+ // so we have to create a dummy SbxVariable instead
+ if( nSbxId == 0x65 ) // Dialog Id
+ return new SbxVariable;
+
+ XubString aEmptyStr;
+ if( nCreator == SBXCR_SBX )
+ switch( nSbxId )
+ {
+ case SBXID_VALUE: return new SbxValue;
+ case SBXID_VARIABLE: return new SbxVariable;
+ case SBXID_ARRAY: return new SbxArray;
+ case SBXID_DIMARRAY: return new SbxDimArray;
+ case SBXID_OBJECT: return new SbxObject( aEmptyStr );
+ case SBXID_COLLECTION: return new SbxCollection( aEmptyStr );
+ case SBXID_FIXCOLLECTION:
+ return new SbxStdCollection( aEmptyStr, aEmptyStr );
+ case SBXID_METHOD: return new SbxMethod( aEmptyStr, SbxEMPTY );
+ case SBXID_PROPERTY: return new SbxProperty( aEmptyStr, SbxEMPTY );
+ }
+ // Unbekanter Typ: ber die Factories gehen!
+ SbxAppData* p = GetSbxData_Impl();
+ SbxBase* pNew = NULL;
+ for( USHORT i = 0; i < p->aFacs.Count(); i++ )
+ {
+ SbxFactory* pFac = p->aFacs.GetObject( i );
+ pNew = pFac->Create( nSbxId, nCreator );
+ if( pNew )
+ break;
+ }
+#ifdef DBG_UTIL
+ if( !pNew )
+ {
+ ByteString aMsg( "SBX: Keine Factory fuer SBX-ID " );
+ aMsg += ByteString::CreateFromInt32(nSbxId);
+ DbgError( aMsg.GetBuffer() );
+ }
+#endif
+ return pNew;
+}
+
+SbxObject* SbxBase::CreateObject( const XubString& rClass )
+{
+ SbxAppData* p = GetSbxData_Impl();
+ SbxObject* pNew = NULL;
+ for( USHORT i = 0; i < p->aFacs.Count(); i++ )
+ {
+ pNew = p->aFacs.GetObject( i )->CreateObject( rClass );
+ if( pNew )
+ break;
+ }
+#ifdef DBG_UTIL
+ if( !pNew )
+ {
+ ByteString aMsg( "SBX: Keine Factory fuer Objektklasse " );
+ ByteString aClassStr( (const UniString&)rClass, RTL_TEXTENCODING_ASCII_US );
+ aMsg += aClassStr;
+ DbgError( (const char*)aMsg.GetBuffer() );
+ }
+#endif
+ return pNew;
+}
+
+static BOOL bStaticEnableBroadcasting = TRUE;
+
+// Sbx-Loesung als Ersatz fuer SfxBroadcaster::Enable()
+void SbxBase::StaticEnableBroadcasting( BOOL bEnable )
+{
+ bStaticEnableBroadcasting = bEnable;
+}
+
+BOOL SbxBase::StaticIsEnabledBroadcasting( void )
+{
+ return bStaticEnableBroadcasting;
+}
+
+
+SbxBase* SbxBase::Load( SvStream& rStrm )
+{
+ UINT16 nSbxId, nFlags, nVer;
+ UINT32 nCreator, nSize;
+ rStrm >> nCreator >> nSbxId >> nFlags >> nVer;
+
+ // Eine Dummheit meinerseits korrigieren:
+ if( nFlags & SBX_RESERVED )
+ nFlags = ( nFlags & ~SBX_RESERVED ) | SBX_GBLSEARCH;
+
+ ULONG nOldPos = rStrm.Tell();
+ rStrm >> nSize;
+ SbxBase* p = Create( nSbxId, nCreator );
+ if( p )
+ {
+ p->nFlags = nFlags;
+ if( p->LoadData( rStrm, nVer ) )
+ {
+ ULONG nNewPos = rStrm.Tell();
+ nOldPos += nSize;
+ DBG_ASSERT( nOldPos >= nNewPos, "SBX: Zu viele Daten eingelesen" );
+ if( nOldPos != nNewPos )
+ rStrm.Seek( nOldPos );
+ if( !p->LoadCompleted() )
+ {
+ // Loeschen des Objekts
+ SbxBaseRef aRef( p );
+ p = NULL;
+ }
+ }
+ else
+ {
+ rStrm.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ // Loeschen des Objekts
+ SbxBaseRef aRef( p );
+ p = NULL;
+ }
+ }
+ else
+ rStrm.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ return p;
+}
+
+// Sbx-Objekt im Stream ueberspringen
+void SbxBase::Skip( SvStream& rStrm )
+{
+ UINT16 nSbxId, nFlags, nVer;
+ UINT32 nCreator, nSize;
+ rStrm >> nCreator >> nSbxId >> nFlags >> nVer;
+
+ ULONG nStartPos = rStrm.Tell();
+ rStrm >> nSize;
+
+ rStrm.Seek( nStartPos + nSize );
+}
+
+BOOL SbxBase::Store( SvStream& rStrm )
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ if( !( nFlags & SBX_DONTSTORE ) )
+ {
+ rStrm << (UINT32) GetCreator()
+ << (UINT16) GetSbxId()
+ << (UINT16) GetFlags()
+ << (UINT16) GetVersion();
+ ULONG nOldPos = rStrm.Tell();
+ rStrm << (UINT32) 0L;
+ BOOL bRes = StoreData( rStrm );
+ ULONG nNewPos = rStrm.Tell();
+ rStrm.Seek( nOldPos );
+ rStrm << (UINT32) ( nNewPos - nOldPos );
+ rStrm.Seek( nNewPos );
+ if( rStrm.GetError() != SVSTREAM_OK )
+ bRes = FALSE;
+ if( bRes )
+ bRes = StoreCompleted();
+ return bRes;
+ }
+ else
+ return TRUE;
+}
+
+BOOL SbxBase::LoadData( SvStream&, USHORT )
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return FALSE;
+}
+
+BOOL SbxBase::StoreData( SvStream& ) const
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return FALSE;
+}
+
+BOOL SbxBase::LoadPrivateData( SvStream&, USHORT )
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return TRUE;
+}
+
+BOOL SbxBase::StorePrivateData( SvStream& ) const
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return TRUE;
+}
+
+BOOL SbxBase::LoadCompleted()
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return TRUE;
+}
+
+BOOL SbxBase::StoreCompleted()
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return TRUE;
+}
+
+//////////////////////////////// SbxFactory ////////////////////////////////
+
+SbxBase* SbxFactory::Create( UINT16, UINT32 )
+{
+ return NULL;
+}
+
+SbxObject* SbxFactory::CreateObject( const XubString& )
+{
+ return NULL;
+}
+
+///////////////////////////////// SbxInfo //////////////////////////////////
+
+SbxInfo::~SbxInfo()
+{}
+
+void SbxInfo::AddParam
+ ( const XubString& rName, SbxDataType eType, USHORT nFlags )
+{
+ const SbxParamInfo* p = new SbxParamInfo( rName, eType, nFlags );
+ aParams.Insert( p, aParams.Count() );
+}
+
+void SbxInfo::AddParam( const SbxParamInfo& r )
+{
+ const SbxParamInfo* p = new SbxParamInfo
+ ( r.aName, r.eType, r.nFlags, r.aTypeRef );
+ aParams.Insert( p, aParams.Count() );
+}
+
+const SbxParamInfo* SbxInfo::GetParam( USHORT n ) const
+{
+ if( n < 1 || n > aParams.Count() )
+ return NULL;
+ else
+ return aParams.GetObject( n-1 );
+}
+
+BOOL SbxInfo::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ aParams.Remove( 0, aParams.Count() );
+ UINT16 nParam;
+ rStrm.ReadByteString( aComment, RTL_TEXTENCODING_ASCII_US );
+ rStrm.ReadByteString( aHelpFile, RTL_TEXTENCODING_ASCII_US );
+ rStrm >> nHelpId >> nParam;
+ while( nParam-- )
+ {
+ XubString aName;
+ UINT16 nType, nFlags;
+ UINT32 nUserData = 0;
+ rStrm.ReadByteString( aName, RTL_TEXTENCODING_ASCII_US );
+ rStrm >> nType >> nFlags;
+ if( nVer > 1 )
+ rStrm >> nUserData;
+ AddParam( aName, (SbxDataType) nType, nFlags );
+ SbxParamInfo* p = aParams.GetObject( aParams.Count() - 1 );
+ p->nUserData = nUserData;
+ }
+ return TRUE;
+}
+
+BOOL SbxInfo::StoreData( SvStream& rStrm ) const
+{
+ rStrm.WriteByteString( aComment, RTL_TEXTENCODING_ASCII_US );
+ rStrm.WriteByteString( aHelpFile, RTL_TEXTENCODING_ASCII_US );
+ rStrm << nHelpId << aParams.Count();
+ for( USHORT i = 0; i < aParams.Count(); i++ )
+ {
+ SbxParamInfo* p = aParams.GetObject( i );
+ rStrm.WriteByteString( p->aName, RTL_TEXTENCODING_ASCII_US );
+ rStrm << (UINT16) p->eType
+ << (UINT16) p->nFlags
+ << (UINT32) p->nUserData;
+ }
+ return TRUE;
+}
+
diff --git a/basic/source/sbx/sbxbool.cxx b/basic/source/sbx/sbxbool.cxx
new file mode 100644
index 000000000000..3216e401b707
--- /dev/null
+++ b/basic/source/sbx/sbxbool.cxx
@@ -0,0 +1,252 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#include <basic/sbx.hxx>
+#include "sbxconv.hxx"
+#include "sbxres.hxx"
+
+// AB 29.10.99 Unicode
+#ifndef _USE_NO_NAMESPACE
+using namespace rtl;
+#endif
+
+enum SbxBOOL ImpGetBool( const SbxValues* p )
+{
+ enum SbxBOOL nRes;
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = SbxFALSE; break;
+ case SbxCHAR:
+ nRes = p->nChar ? SbxTRUE : SbxFALSE; break;
+ case SbxBYTE:
+ nRes = p->nByte ? SbxTRUE : SbxFALSE; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger ? SbxTRUE : SbxFALSE; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort ? SbxTRUE : SbxFALSE; break;
+ case SbxLONG:
+ nRes = p->nLong ? SbxTRUE : SbxFALSE; break;
+ case SbxULONG:
+ nRes = p->nULong ? SbxTRUE : SbxFALSE; break;
+ case SbxSINGLE:
+ nRes = p->nSingle ? SbxTRUE : SbxFALSE; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ nRes = p->nDouble ? SbxTRUE : SbxFALSE; break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double dVal = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( dVal );
+ nRes = dVal ? SbxTRUE : SbxFALSE;
+ }
+ break;
+ case SbxSALINT64:
+ nRes = p->nInt64 ? SbxTRUE : SbxFALSE; break;
+ case SbxSALUINT64:
+ nRes = p->uInt64 ? SbxTRUE : SbxFALSE; break;
+ case SbxULONG64:
+ nRes = !!p->nULong64 ? SbxTRUE : SbxFALSE; break;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ nRes = !!p->nLong64 ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ nRes = SbxFALSE;
+ if ( p->pOUString )
+ {
+ if( p->pOUString->equalsIgnoreAsciiCase( SbxRes( STRING_TRUE ) ) )
+ nRes = SbxTRUE;
+ else if( p->pOUString->equalsIgnoreAsciiCase( SbxRes( STRING_FALSE ) ) )
+ {
+ // Jetzt kann es noch in eine Zahl konvertierbar sein
+ BOOL bError = TRUE;
+ double n;
+ SbxDataType t;
+ USHORT nLen = 0;
+ if( ImpScan( *p->pOUString, n, t, &nLen ) == SbxERR_OK )
+ {
+ if( nLen == p->pOUString->getLength() )
+ {
+ bError = FALSE;
+ if( n != 0.0 )
+ nRes = SbxTRUE;
+ }
+ }
+ if( bError )
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetBool() ? SbxTRUE : SbxFALSE;
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = SbxFALSE;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxLONG:
+ nRes = *p->pLong ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxULONG:
+ nRes = *p->pULong ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ nRes = *p->pUShort ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxSINGLE:
+ nRes = ( *p->pSingle != 0 ) ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ nRes = ( *p->pDouble != 0 ) ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxSALINT64:
+ nRes = ( *p->pnInt64 ) ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxSALUINT64:
+ nRes = ( *p->puInt64 ) ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxULONG64:
+ nRes = !!*p->pULong64 ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ nRes = !!*p->pLong64 ? SbxTRUE : SbxFALSE; break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = SbxFALSE;
+ }
+ return nRes;
+}
+
+void ImpPutBool( SbxValues* p, INT16 n )
+{
+ if( n )
+ n = SbxTRUE;
+ switch( +p->eType )
+ {
+ case SbxCHAR:
+ p->nChar = (xub_Unicode) n; break;
+ case SbxUINT:
+ p->nByte = (BYTE) n; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ p->nInteger = n; break;
+ case SbxLONG:
+ p->nLong = n; break;
+ case SbxULONG:
+ p->nULong = (UINT32) n; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ p->nUShort = (UINT16) n; break;
+ case SbxSINGLE:
+ p->nSingle = n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxSALUINT64:
+ p->uInt64 = n; break;
+ case SbxULONG64:
+ p->nULong64.Set( (UINT32)n ); break;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ p->nLong64.Set( (INT32)n ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ ImpCreateDecimal( p )->setInt( (INT16)n );
+ break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if ( !p->pOUString )
+ p->pOUString = new ::rtl::OUString( SbxRes( n ? STRING_TRUE : STRING_FALSE ) );
+ else
+ *p->pOUString = SbxRes( n ? STRING_TRUE : STRING_FALSE );
+ break;
+
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutBool( BOOL( n != 0 ) );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ *p->pLong = n; break;
+ case SbxBYREF | SbxULONG:
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = n; break;
+ case SbxBYREF | SbxULONG64:
+ p->pULong64->Set( (UINT32)n ); break;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ p->pLong64->Set( (INT32)n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
diff --git a/basic/source/sbx/sbxbyte.cxx b/basic/source/sbx/sbxbyte.cxx
new file mode 100644
index 000000000000..e13c63967fc3
--- /dev/null
+++ b/basic/source/sbx/sbxbyte.cxx
@@ -0,0 +1,329 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#include <basic/sbx.hxx>
+#include "sbxconv.hxx"
+
+BYTE ImpGetByte( const SbxValues* p )
+{
+ SbxValues aTmp;
+ BYTE nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ if( p->nChar > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (BYTE) p->nChar;
+ break;
+ case SbxBYTE:
+ nRes = (BYTE) p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ if( p->nInteger > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else if( p->nInteger < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (BYTE) p->nInteger;
+ break;
+ case SbxERROR:
+ case SbxUSHORT:
+ if( p->nUShort > (USHORT) SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else
+ nRes = (BYTE) p->nUShort;
+ break;
+ case SbxLONG:
+ if( p->nLong > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else if( p->nLong < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (BYTE) p->nLong;
+ break;
+ case SbxULONG:
+ if( p->nULong > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else
+ nRes = (BYTE) p->nULong;
+ break;
+ case SbxSALINT64:
+ if( p->nInt64 > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else if( p->nInt64 < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (BYTE) p->nInt64;
+ break;
+ case SbxSALUINT64:
+ if( p->uInt64 > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else
+ nRes = (BYTE) p->uInt64;
+ break;
+ case SbxSINGLE:
+ if( p->nSingle > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else if( p->nSingle < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (BYTE) ImpRound( p->nSingle );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else if( p->eType == SbxDECIMAL )
+ {
+ dVal = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( dVal );
+ }
+ else
+ dVal = p->nDouble;
+
+ if( dVal > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else if( dVal < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (BYTE) ImpRound( dVal );
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ nRes = 0;
+ else
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else if( d < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (BYTE) ( d + 0.5 );
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetByte();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxBYTE:
+ nRes = p->nByte; break;
+
+ // ab hier wird getestet
+ case SbxBYREF | SbxCHAR:
+ aTmp.nChar = *p->pChar; goto ref;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ aTmp.nInteger = *p->pInteger; goto ref;
+ case SbxBYREF | SbxLONG:
+ aTmp.nLong = *p->pLong; goto ref;
+ case SbxBYREF | SbxULONG:
+ aTmp.nULong = *p->pULong; goto ref;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ aTmp.nUShort = *p->pUShort; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutByte( SbxValues* p, BYTE n )
+{
+ switch( +p->eType )
+ {
+ case SbxBYTE:
+ p->nByte = n; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ p->nInteger = n; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ p->nUShort = n; break;
+ case SbxLONG:
+ p->nLong = n; break;
+ case SbxULONG:
+ p->nULong = n; break;
+ case SbxSINGLE:
+ p->nSingle = n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxSALUINT64:
+ p->uInt64 = n; break;
+ case SbxULONG64:
+ p->nULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxLONG64:
+ p->nLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxCURRENCY:
+ p->nLong64 = ImpDoubleToCurrency( (double)n ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ ImpCreateDecimal( p )->setByte( n );
+ break;
+
+ case SbxCHAR:
+ p->nChar = (xub_Unicode) n; break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ p->pOUString = new ::rtl::OUString;
+ ImpCvtNum( (double) n, 0, *p->pOUString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutByte( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ *p->pByte = n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ *p->pInteger = n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ *p->pUShort = n; break;
+ case SbxBYREF | SbxLONG:
+ *p->pLong = n; break;
+ case SbxBYREF | SbxULONG:
+ *p->pULong = n; break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = n; break;
+ case SbxBYREF | SbxULONG64:
+ *p->pULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxBYREF | SbxLONG64:
+ *p->pLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = n; break;
+ case SbxBYREF | SbxCURRENCY:
+ *p->pLong64 = ImpDoubleToCurrency( (double)n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
diff --git a/basic/source/sbx/sbxchar.cxx b/basic/source/sbx/sbxchar.cxx
new file mode 100644
index 000000000000..bd4ce91f451b
--- /dev/null
+++ b/basic/source/sbx/sbxchar.cxx
@@ -0,0 +1,324 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#include <basic/sbx.hxx>
+#include "sbxconv.hxx"
+
+// AB 29.10.99 Unicode
+#ifndef _USE_NO_NAMESPACE
+using namespace rtl;
+#endif
+
+xub_Unicode ImpGetChar( const SbxValues* p )
+{
+ SbxValues aTmp;
+ xub_Unicode nRes = 0;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = (xub_Unicode) p->nByte;
+ break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ if( p->nInteger < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
+ }
+ else
+ nRes = (xub_Unicode) p->nInteger;
+ break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = (xub_Unicode) p->nUShort;
+ break;
+ case SbxLONG:
+ if( p->nLong > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
+ }
+ else if( p->nLong < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
+ }
+ else
+ nRes = (xub_Unicode) p->nLong;
+ break;
+ case SbxULONG:
+ if( p->nULong > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
+ }
+ else
+ nRes = (xub_Unicode) p->nULong;
+ break;
+ case SbxSALINT64:
+ if( p->nInt64 > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
+ }
+ else if( p->nInt64 < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
+ }
+ else
+ nRes = (xub_Unicode) p->nInt64;
+ break;
+ case SbxSALUINT64:
+ if( p->uInt64 > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
+ }
+ else
+ nRes = (xub_Unicode) p->uInt64;
+ break;
+ case SbxSINGLE:
+ if( p->nSingle > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
+ }
+ else if( p->nSingle < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
+ }
+ else
+ nRes = (xub_Unicode) ImpRound( p->nSingle );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else if( p->eType == SbxDECIMAL )
+ {
+ dVal = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( dVal );
+ }
+ else
+ dVal = p->nDouble;
+
+ if( dVal > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
+ }
+ else if( dVal < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
+ }
+ else
+ nRes = (BYTE) ImpRound( dVal );
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if ( p->pOUString )
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
+ }
+ else if( d < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
+ }
+ else
+ nRes = (xub_Unicode) ImpRound( d );
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetChar();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ // ab hier wird getestet
+ case SbxBYREF | SbxBYTE:
+ aTmp.nByte = *p->pByte; goto ref;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ aTmp.nInteger = *p->pInteger; goto ref;
+ case SbxBYREF | SbxLONG:
+ aTmp.nLong = *p->pLong; goto ref;
+ case SbxBYREF | SbxULONG:
+ aTmp.nULong = *p->pULong; goto ref;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ aTmp.nUShort = *p->pUShort; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutChar( SbxValues* p, xub_Unicode n )
+{
+ SbxValues aTmp;
+start:
+ switch( +p->eType )
+ {
+ case SbxCHAR:
+ p->nChar = n; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ p->nInteger = n; break;
+ case SbxLONG:
+ p->nLong = n; break;
+ case SbxSINGLE:
+ p->nSingle = n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxSALUINT64:
+ p->uInt64 = n; break;
+ case SbxULONG64:
+ p->nULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxLONG64:
+ p->nLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxCURRENCY:
+ p->nLong64 = ImpDoubleToCurrency( (double)n ); break;
+ case SbxBYREF | SbxDECIMAL:
+ ImpCreateDecimal( p )->setChar( n );
+ break;
+
+ // ab hier wird getestet
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if ( !p->pOUString )
+ p->pOUString = new ::rtl::OUString( n );
+ else
+ *p->pOUString = ::rtl::OUString( n );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutChar( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ *p->pChar = n; break;
+ case SbxBYREF | SbxBYTE:
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ *p->pInteger = n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ *p->pLong = (INT32) n; break;
+ case SbxBYREF | SbxULONG:
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = n; break;
+ case SbxBYREF | SbxULONG64:
+ *p->pULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxBYREF | SbxLONG64:
+ *p->pLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxBYREF | SbxCURRENCY:
+ *p->pLong64 = ImpDoubleToCurrency( (double)n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+
diff --git a/basic/source/sbx/sbxcoll.cxx b/basic/source/sbx/sbxcoll.cxx
new file mode 100644
index 000000000000..7bd32900ecc9
--- /dev/null
+++ b/basic/source/sbx/sbxcoll.cxx
@@ -0,0 +1,301 @@
+/*************************************************************************
+ *
+ * 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 <basic/sbx.hxx>
+#include "sbxres.hxx"
+
+TYPEINIT1(SbxCollection,SbxObject)
+TYPEINIT1(SbxStdCollection,SbxCollection)
+
+static const char* pCount;
+static const char* pAdd;
+static const char* pItem;
+static const char* pRemove;
+static USHORT nCountHash = 0, nAddHash, nItemHash, nRemoveHash;
+
+/////////////////////////////////////////////////////////////////////////
+
+SbxCollection::SbxCollection( const XubString& rClass )
+ : SbxObject( rClass )
+{
+ if( !nCountHash )
+ {
+ pCount = GetSbxRes( STRING_COUNTPROP );
+ pAdd = GetSbxRes( STRING_ADDMETH );
+ pItem = GetSbxRes( STRING_ITEMMETH );
+ pRemove = GetSbxRes( STRING_REMOVEMETH );
+ nCountHash = MakeHashCode( String::CreateFromAscii( pCount ) );
+ nAddHash = MakeHashCode( String::CreateFromAscii( pAdd ) );
+ nItemHash = MakeHashCode( String::CreateFromAscii( pItem ) );
+ nRemoveHash = MakeHashCode( String::CreateFromAscii( pRemove ) );
+ }
+ Initialize();
+ // Fuer Zugriffe auf sich selbst
+ StartListening( GetBroadcaster(), TRUE );
+}
+
+SbxCollection::SbxCollection( const SbxCollection& rColl )
+ : SvRefBase( rColl ), SbxObject( rColl )
+{}
+
+SbxCollection& SbxCollection::operator=( const SbxCollection& r )
+{
+ if( &r != this )
+ SbxObject::operator=( r );
+ return *this;
+}
+
+SbxCollection::~SbxCollection()
+{}
+
+void SbxCollection::Clear()
+{
+ SbxObject::Clear();
+ Initialize();
+}
+
+void SbxCollection::Initialize()
+{
+ SetType( SbxOBJECT );
+ SetFlag( SBX_FIXED );
+ ResetFlag( SBX_WRITE );
+ SbxVariable* p;
+ p = Make( String::CreateFromAscii( pCount ), SbxCLASS_PROPERTY, SbxINTEGER );
+ p->ResetFlag( SBX_WRITE );
+ p->SetFlag( SBX_DONTSTORE );
+ p = Make( String::CreateFromAscii( pAdd ), SbxCLASS_METHOD, SbxEMPTY );
+ p->SetFlag( SBX_DONTSTORE );
+ p = Make( String::CreateFromAscii( pItem ), SbxCLASS_METHOD, SbxOBJECT );
+ p->SetFlag( SBX_DONTSTORE );
+ p = Make( String::CreateFromAscii( pRemove ), SbxCLASS_METHOD, SbxEMPTY );
+ p->SetFlag( SBX_DONTSTORE );
+}
+
+SbxVariable* SbxCollection::FindUserData( UINT32 nData )
+{
+ if( GetParameters() )
+ {
+ SbxObject* pObj = (SbxObject*) GetObject();
+ return pObj ? pObj->FindUserData( nData ) : NULL;
+ }
+ else
+ return SbxObject::FindUserData( nData );
+}
+
+SbxVariable* SbxCollection::Find( const XubString& rName, SbxClassType t )
+{
+ if( GetParameters() )
+ {
+ SbxObject* pObj = (SbxObject*) GetObject();
+ return pObj ? pObj->Find( rName, t ) : NULL;
+ }
+ else
+ return SbxObject::Find( rName, t );
+}
+
+void SbxCollection::SFX_NOTIFY( SfxBroadcaster& rCst, const TypeId& rId1,
+ const SfxHint& rHint, const TypeId& rId2 )
+{
+ const SbxHint* p = PTR_CAST(SbxHint,&rHint);
+ if( p )
+ {
+ ULONG nId = p->GetId();
+ BOOL bRead = BOOL( nId == SBX_HINT_DATAWANTED );
+ BOOL bWrite = BOOL( nId == SBX_HINT_DATACHANGED );
+ SbxVariable* pVar = p->GetVar();
+ SbxArray* pArg = pVar->GetParameters();
+ if( bRead || bWrite )
+ {
+ XubString aVarName( pVar->GetName() );
+ if( pVar == this )
+ CollItem( pArg );
+ else if( pVar->GetHashCode() == nCountHash
+ && aVarName.EqualsIgnoreCaseAscii( pCount ) )
+ pVar->PutLong( pObjs->Count() );
+ else if( pVar->GetHashCode() == nAddHash
+ && aVarName.EqualsIgnoreCaseAscii( pAdd ) )
+ CollAdd( pArg );
+ else if( pVar->GetHashCode() == nItemHash
+ && aVarName.EqualsIgnoreCaseAscii( pItem ) )
+ CollItem( pArg );
+ else if( pVar->GetHashCode() == nRemoveHash
+ && aVarName.EqualsIgnoreCaseAscii( pRemove ) )
+ CollRemove( pArg );
+ else
+ SbxObject::SFX_NOTIFY( rCst, rId1, rHint, rId2 );
+ return;
+ }
+ }
+ SbxObject::SFX_NOTIFY( rCst, rId1, rHint, rId2 );
+}
+
+// Default: Argument ist Objekt
+
+void SbxCollection::CollAdd( SbxArray* pPar_ )
+{
+ if( pPar_->Count() != 2 )
+ SetError( SbxERR_WRONG_ARGS );
+ else
+ {
+ SbxBase* pObj = pPar_->Get( 1 )->GetObject();
+ if( !pObj || !( pObj->ISA(SbxObject) ) )
+ SetError( SbxERR_NOTIMP );
+ else
+ Insert( (SbxObject*) pObj );
+ }
+}
+
+// Default: Index ab 1 oder der Objektname
+
+void SbxCollection::CollItem( SbxArray* pPar_ )
+{
+ if( pPar_->Count() != 2 )
+ SetError( SbxERR_WRONG_ARGS );
+ else
+ {
+ SbxVariable* pRes = NULL;
+ SbxVariable* p = pPar_->Get( 1 );
+ if( p->GetType() == SbxSTRING )
+ pRes = Find( p->GetString(), SbxCLASS_OBJECT );
+ else
+ {
+ short n = p->GetInteger();
+ if( n >= 1 && n <= (short) pObjs->Count() )
+ pRes = pObjs->Get( (USHORT) n - 1 );
+ }
+ if( !pRes )
+ SetError( SbxERR_BAD_INDEX );
+ pPar_->Get( 0 )->PutObject( pRes );
+ }
+}
+
+// Default: Index ab 1
+
+void SbxCollection::CollRemove( SbxArray* pPar_ )
+{
+ if( pPar_->Count() != 2 )
+ SetError( SbxERR_WRONG_ARGS );
+ else
+ {
+ short n = pPar_->Get( 1 )->GetInteger();
+ if( n < 1 || n > (short) pObjs->Count() )
+ SetError( SbxERR_BAD_INDEX );
+ else
+ Remove( pObjs->Get( (USHORT) n - 1 ) );
+ }
+}
+
+BOOL SbxCollection::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ BOOL bRes = SbxObject::LoadData( rStrm, nVer );
+ Initialize();
+ return bRes;
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+SbxStdCollection::SbxStdCollection
+ ( const XubString& rClass, const XubString& rElem, BOOL b )
+ : SbxCollection( rClass ), aElemClass( rElem ),
+ bAddRemoveOk( b )
+{}
+
+SbxStdCollection::SbxStdCollection( const SbxStdCollection& r )
+ : SvRefBase( r ), SbxCollection( r ),
+ aElemClass( r.aElemClass ), bAddRemoveOk( r.bAddRemoveOk )
+{}
+
+SbxStdCollection& SbxStdCollection::operator=( const SbxStdCollection& r )
+{
+ if( &r != this )
+ {
+ if( !r.aElemClass.EqualsIgnoreCaseAscii( aElemClass ) )
+ SetError( SbxERR_CONVERSION );
+ else
+ SbxCollection::operator=( r );
+ }
+ return *this;
+}
+
+SbxStdCollection::~SbxStdCollection()
+{}
+
+// Default: Fehler, wenn falsches Objekt
+
+void SbxStdCollection::Insert( SbxVariable* p )
+{
+ SbxObject* pObj = PTR_CAST(SbxObject,p);
+ if( pObj && !pObj->IsClass( aElemClass ) )
+ SetError( SbxERR_BAD_ACTION );
+ else
+ SbxCollection::Insert( p );
+}
+
+void SbxStdCollection::CollAdd( SbxArray* pPar_ )
+{
+ if( !bAddRemoveOk )
+ SetError( SbxERR_BAD_ACTION );
+ else
+ SbxCollection::CollAdd( pPar_ );
+}
+
+void SbxStdCollection::CollRemove( SbxArray* pPar_ )
+{
+ if( !bAddRemoveOk )
+ SetError( SbxERR_BAD_ACTION );
+ else
+ SbxCollection::CollRemove( pPar_ );
+}
+
+BOOL SbxStdCollection::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ BOOL bRes = SbxCollection::LoadData( rStrm, nVer );
+ if( bRes )
+ {
+ rStrm.ReadByteString( aElemClass, RTL_TEXTENCODING_ASCII_US );
+ rStrm >> bAddRemoveOk;
+ }
+ return bRes;
+}
+
+BOOL SbxStdCollection::StoreData( SvStream& rStrm ) const
+{
+ BOOL bRes = SbxCollection::StoreData( rStrm );
+ if( bRes )
+ {
+ rStrm.WriteByteString( aElemClass, RTL_TEXTENCODING_ASCII_US );
+ rStrm << bAddRemoveOk;
+ }
+ return bRes;
+}
+
diff --git a/basic/source/sbx/sbxconv.hxx b/basic/source/sbx/sbxconv.hxx
new file mode 100644
index 000000000000..16fec542cded
--- /dev/null
+++ b/basic/source/sbx/sbxconv.hxx
@@ -0,0 +1,151 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBXCONV_HXX
+#define _SBXCONV_HXX
+
+#include "sbxdec.hxx"
+
+class SbxArray;
+
+// SBXSCAN.CXX
+extern void ImpCvtNum( double nNum, short nPrec, ::rtl::OUString& rRes, BOOL bCoreString=FALSE );
+extern SbxError ImpScan
+ ( const ::rtl::OUString& rSrc, double& nVal, SbxDataType& rType, USHORT* pLen,
+ BOOL bAllowIntntl=FALSE, BOOL bOnlyIntntl=FALSE );
+
+// mit erweiterter Auswertung (International, "TRUE"/"FALSE")
+extern BOOL ImpConvStringExt( ::rtl::OUString& rSrc, SbxDataType eTargetType );
+
+// SBXINT.CXX
+
+double ImpRound( double );
+INT16 ImpGetInteger( const SbxValues* );
+void ImpPutInteger( SbxValues*, INT16 );
+sal_Int64 ImpGetInt64( const SbxValues* );
+void ImpPutInt64( SbxValues*, sal_Int64 );
+sal_uInt64 ImpGetUInt64( const SbxValues* );
+void ImpPutUInt64( SbxValues*, sal_uInt64 );
+
+sal_Int64 ImpDoubleToSalInt64( double d );
+sal_uInt64 ImpDoubleToSalUInt64( double d );
+double ImpSalUInt64ToDouble( sal_uInt64 n );
+
+// SBXLNG.CXX
+
+INT32 ImpGetLong( const SbxValues* );
+void ImpPutLong( SbxValues*, INT32 );
+
+// SBXSNG.CXX
+
+float ImpGetSingle( const SbxValues* );
+void ImpPutSingle( SbxValues*, float );
+
+// SBXDBL.CXX
+
+double ImpGetDouble( const SbxValues* );
+void ImpPutDouble( SbxValues*, double, BOOL bCoreString=FALSE );
+
+#if FALSE
+// SBX64.CXX
+
+SbxINT64 ImpGetINT64( const SbxValues* );
+void ImpPutINT64( SbxValues*, const SbxINT64& );
+SbxUINT64 ImpGetUINT64( const SbxValues* );
+void ImpPutUINT64( SbxValues*, const SbxUINT64& );
+#endif
+
+// SBXCURR.CXX
+
+SbxUINT64 ImpDoubleToUINT64( double );
+double ImpUINT64ToDouble( const SbxUINT64& );
+SbxINT64 ImpDoubleToINT64( double );
+double ImpINT64ToDouble( const SbxINT64& );
+
+#if TRUE
+INT32 ImpGetCurrLong( const SbxValues* );
+void ImpPutCurrLong( SbxValues*, INT32 );
+INT32 ImpDoubleToCurrLong( double );
+double ImpCurrLongToDouble( INT32 );
+#endif
+
+SbxINT64 ImpGetCurrency( const SbxValues* );
+void ImpPutCurrency( SbxValues*, const SbxINT64& );
+inline
+SbxINT64 ImpDoubleToCurrency( double d )
+ { return ImpDoubleToINT64( d * CURRENCY_FACTOR ); }
+inline
+double ImpCurrencyToDouble( const SbxINT64 &r )
+ { return ImpINT64ToDouble( r ) / CURRENCY_FACTOR; }
+
+
+// SBXDEC.CXX
+
+SbxDecimal* ImpCreateDecimal( SbxValues* p );
+SbxDecimal* ImpGetDecimal( const SbxValues* p );
+void ImpPutDecimal( SbxValues* p, SbxDecimal* pDec );
+
+// SBXDATE.CXX
+
+double ImpGetDate( const SbxValues* );
+void ImpPutDate( SbxValues*, double );
+
+// SBXSTR.CXX
+
+::rtl::OUString ImpGetString( const SbxValues* );
+::rtl::OUString ImpGetCoreString( const SbxValues* );
+void ImpPutString( SbxValues*, const ::rtl::OUString* );
+
+// SBXCHAR.CXX
+
+sal_Unicode ImpGetChar( const SbxValues* );
+void ImpPutChar( SbxValues*, sal_Unicode );
+
+// SBXBYTE.CXX
+BYTE ImpGetByte( const SbxValues* );
+void ImpPutByte( SbxValues*, BYTE );
+
+// SBXUINT.CXX
+
+UINT16 ImpGetUShort( const SbxValues* );
+void ImpPutUShort( SbxValues*, UINT16 );
+
+// SBXULNG.CXX
+
+UINT32 ImpGetULong( const SbxValues* );
+void ImpPutULong( SbxValues*, UINT32 );
+
+// SBXBOOL.CXX
+
+enum SbxBOOL ImpGetBool( const SbxValues* );
+void ImpPutBool( SbxValues*, INT16 );
+
+// ByteArry <--> String
+SbxArray* StringToByteArray(const ::rtl::OUString& rStr);
+::rtl::OUString ByteArrayToString(SbxArray* pArr);
+
+#endif
diff --git a/basic/source/sbx/sbxcurr.cxx b/basic/source/sbx/sbxcurr.cxx
new file mode 100644
index 000000000000..e27b11d5166c
--- /dev/null
+++ b/basic/source/sbx/sbxcurr.cxx
@@ -0,0 +1,395 @@
+/*************************************************************************
+ *
+ * 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 <basic/sbx.hxx>
+#include <tools/errcode.hxx>
+
+#define _TLBIGINT_INT64
+#include <tools/bigint.hxx>
+
+#include <basic/sbxvar.hxx>
+#include "sbxconv.hxx"
+
+static ::rtl::OUString ImpCurrencyToString( const SbxINT64& );
+static SbxINT64 ImpStringToCurrency( const ::rtl::OUString& );
+
+SbxINT64 ImpGetCurrency( const SbxValues* p )
+{
+ SbxValues aTmp;
+ SbxINT64 nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes.SetNull(); break;
+ case SbxCHAR:
+ nRes = ImpDoubleToCurrency( (double)p->nChar ); break;
+ case SbxBYTE:
+ nRes = ImpDoubleToCurrency( (double)p->nByte ); break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = ImpDoubleToCurrency( (double)p->nInteger ); break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = ImpDoubleToCurrency( (double)p->nUShort ); break;
+ case SbxCURRENCY:
+ nRes = p->nLong64; break;
+ case SbxLONG:
+ nRes = ImpDoubleToCurrency( (double)p->nLong );
+ break;
+ case SbxULONG:
+ nRes = ImpDoubleToCurrency( (double)p->nULong );
+ break;
+ case SbxSALINT64:
+ nRes = ImpDoubleToCurrency( (double)p->nInt64 );
+ break;
+ case SbxSALUINT64:
+ nRes = ImpDoubleToCurrency( ImpSalUInt64ToDouble( p->uInt64 ) );
+ break;
+ case SbxSINGLE:
+ if( p->nSingle > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes.SetMax();
+ }
+ else if( p->nSingle < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes.SetMin();
+ }
+ else
+ nRes = ImpDoubleToCurrency( (double)p->nSingle );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ if( p->nDouble > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes.SetMax();
+ }
+ else if( p->nDouble < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes.SetMin();
+ }
+ else
+ nRes = ImpDoubleToCurrency( p->nDouble );
+ break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double d = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( d );
+ if( d > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes.SetMax();
+ }
+ else if( d < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes.SetMin();
+ }
+ else
+ nRes = ImpDoubleToCurrency( d );
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ nRes.SetNull();
+ else
+ nRes = ImpStringToCurrency( *p->pOUString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetCurrency();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes.SetNull();
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = ImpDoubleToCurrency( (double)*p->pChar ); break;
+ case SbxBYREF | SbxBYTE:
+ nRes = ImpDoubleToCurrency( (double)*p->pByte ); break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = ImpDoubleToCurrency( (double)*p->pInteger ); break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ nRes = ImpDoubleToCurrency( (double)*p->pUShort ); break;
+ case SbxBYREF | SbxCURRENCY:
+ nRes = *p->pLong64; break;
+
+ // ab hier muss getestet werden
+ case SbxBYREF | SbxLONG:
+ aTmp.nLong = *p->pLong; goto ref;
+ case SbxBYREF | SbxULONG:
+ aTmp.nULong = *p->pULong; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes.SetNull();
+ }
+ return nRes;
+}
+
+void ImpPutCurrency( SbxValues* p, const SbxINT64 &r )
+{
+ double dVal = ImpCurrencyToDouble( r );
+ SbxValues aTmp;
+start:
+ switch( +p->eType )
+ {
+ // Hier sind Tests notwendig
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxLONG:
+ aTmp.pLong = &p->nLong; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // ab hier nicht mehr
+ case SbxSINGLE:
+ p->nSingle = (float)dVal; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = dVal; break;
+ case SbxSALINT64:
+ p->nInt64 = ImpDoubleToSalInt64( dVal ); break;
+ case SbxSALUINT64:
+ p->uInt64 = ImpDoubleToSalUInt64( dVal ); break;
+ case SbxCURRENCY:
+ p->nLong64 = r; break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ SbxDecimal* pDec = ImpCreateDecimal( p );
+ if( !pDec->setDouble( dVal ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ p->pOUString = new ::rtl::OUString;
+
+ *p->pOUString = ImpCurrencyToString( r );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutCurrency( r );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( dVal > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMAXCHAR;
+ }
+ else if( dVal < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMINCHAR;
+ }
+ *p->pChar = (xub_Unicode) dVal; break;
+ case SbxBYREF | SbxBYTE:
+ if( dVal > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMAXBYTE;
+ }
+ else if( dVal < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = 0;
+ }
+ *p->pByte = (BYTE) dVal; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( dVal > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMAXINT;
+ }
+ else if( dVal < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMININT;
+ }
+ *p->pInteger = (INT16) dVal; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( dVal > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMAXUINT;
+ }
+ else if( dVal < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = 0;
+ }
+ *p->pUShort = (UINT16) dVal; break;
+ case SbxBYREF | SbxLONG:
+ if( dVal > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMAXLNG;
+ }
+ else if( dVal < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMINLNG;
+ }
+ *p->pLong = (INT32) dVal; break;
+ case SbxBYREF | SbxULONG:
+ if( dVal > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMAXULNG;
+ }
+ else if( dVal < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = 0;
+ }
+ *p->pULong = (UINT32) dVal; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = ImpDoubleToSalInt64( dVal ); break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = ImpDoubleToSalUInt64( dVal ); break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = (float) dVal; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) dVal; break;
+ case SbxBYREF | SbxCURRENCY:
+ *p->pLong64 = r; break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+// Hilfs-Funktionen zur Wandlung
+
+static ::rtl::OUString ImpCurrencyToString( const SbxINT64 &r )
+{
+ BigInt a10000 = 10000;
+
+ //return GetpApp()->GetAppInternational().GetCurr( BigInt( r ), 4 );
+ BigInt aInt( r );
+ aInt.Abs();
+ BigInt aFrac = aInt;
+ aInt /= a10000;
+ aFrac %= a10000;
+ aFrac += a10000;
+
+ ::rtl::OUString aString;
+ if( r.nHigh < 0 )
+ aString = ::rtl::OUString( (sal_Unicode)'-' );
+ aString += aInt.GetString();
+ aString += ::rtl::OUString( (sal_Unicode)'.' );
+ aString += aFrac.GetString().GetBuffer()+1;
+ return aString;
+}
+
+static SbxINT64 ImpStringToCurrency( const ::rtl::OUString &r )
+{
+ int nDec = 4;
+ String aStr;
+ const sal_Unicode* p = r.getStr();
+
+ if( *p == '-' )
+ aStr += *p++;
+
+ while( *p >= '0' && *p <= '9' ) {
+ aStr += *p++;
+ if( *p == ',' )
+ p++;
+ }
+
+ if( *p == '.' ) {
+ p++;
+ while( nDec && *p >= '0' && *p <= '9' ) {
+ aStr += *p++;
+ nDec--;
+ }
+ }
+ while( nDec ) {
+ aStr += '0';
+ nDec--;
+ }
+
+ BigInt aBig( aStr );
+ SbxINT64 nRes;
+ aBig.INT64( &nRes );
+ return nRes;
+}
+
+double ImpINT64ToDouble( const SbxINT64 &r )
+{ return (double)r.nHigh*(double)4294967296.0 + (double)r.nLow; }
+
+SbxINT64 ImpDoubleToINT64( double d )
+{
+ SbxINT64 nRes;
+ nRes.Set( d );
+ return nRes;
+}
+
+double ImpUINT64ToDouble( const SbxUINT64 &r )
+{ return (double)r.nHigh*(double)4294967296.0 + (double)r.nLow; }
+
+SbxUINT64 ImpDoubleToUINT64( double d )
+{
+ SbxUINT64 nRes;
+ nRes.Set( d );
+ return nRes;
+}
+
diff --git a/basic/source/sbx/sbxdate.cxx b/basic/source/sbx/sbxdate.cxx
new file mode 100644
index 000000000000..3a0636e4e7fc
--- /dev/null
+++ b/basic/source/sbx/sbxdate.cxx
@@ -0,0 +1,414 @@
+/*************************************************************************
+ *
+ * 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 <vcl/svapp.hxx>
+#include <svl/zforlist.hxx>
+#include <tools/errcode.hxx>
+#include <tools/color.hxx>
+#include <i18npool/lang.h>
+#include <basic/sbx.hxx>
+#include "sbxconv.hxx"
+#include "math.h"
+#include <comphelper/processfactory.hxx>
+
+
+double ImpGetDate( const SbxValues* p )
+{
+ double nRes;
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort; break;
+ case SbxLONG:
+ nRes = (double) p->nLong; break;
+ case SbxULONG:
+ nRes = (double) p->nULong; break;
+ case SbxSINGLE:
+ nRes = p->nSingle; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ nRes = p->nDouble; break;
+ case SbxULONG64:
+ nRes = ImpUINT64ToDouble( p->nULong64 ); break;
+ case SbxLONG64:
+ nRes = ImpINT64ToDouble( p->nLong64 ); break;
+ case SbxCURRENCY:
+ nRes = ImpCurrencyToDouble( p->nLong64 ); break;
+ case SbxSALINT64:
+ nRes = static_cast< double >(p->nInt64); break;
+ case SbxSALUINT64:
+ nRes = ImpSalUInt64ToDouble( p->uInt64 ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ if( p->pDecimal )
+ p->pDecimal->getDouble( nRes );
+ else
+ nRes = 0.0;
+ break;
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ nRes = 0;
+ else
+ {
+#ifndef DOS
+ LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
+
+ SvNumberFormatter* pFormatter;
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ xFactory = comphelper::getProcessServiceFactory();
+ pFormatter = new SvNumberFormatter( xFactory, eLangType );
+
+ sal_uInt32 nIndex;
+ xub_StrLen nCheckPos = 0;
+ short nType = 127;
+
+ // Standard-Vorlagen des Formatters haben nur zweistellige
+ // Jahreszahl. Deshalb eigenes Format registrieren
+
+ // HACK, da der Numberformatter in PutandConvertEntry die Platzhalter
+ // fuer Monat, Tag, Jahr nicht entsprechend der Systemeinstellung
+ // austauscht. Problem: Print Year(Date) unter engl. BS
+ // siehe auch basic\source\runtime\runtime.cxx
+
+ SvtSysLocale aSysLocale;
+ DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
+ String aDateStr;
+ switch( eDate )
+ {
+ case MDY: aDateStr.AssignAscii( "MM.TT.JJJJ" ); break;
+ case DMY: aDateStr.AssignAscii( "TT.MM.JJJJ" ); break;
+ case YMD: aDateStr.AssignAscii( "JJJJ.MM.TT" ); break;
+ default: aDateStr.AssignAscii( "MM.TT.JJJJ" );
+ }
+
+ String aStr( aDateStr );
+ aStr.AppendAscii( " HH:MM:SS" );
+
+ pFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
+ nIndex, LANGUAGE_GERMAN, eLangType );
+ BOOL bSuccess = pFormatter->IsNumberFormat( *p->pOUString, nIndex, nRes );
+ if ( bSuccess )
+ {
+ short nType_ = pFormatter->GetType( nIndex );
+ if(!(nType_ & ( NUMBERFORMAT_DATETIME | NUMBERFORMAT_DATE |
+ NUMBERFORMAT_TIME | NUMBERFORMAT_DEFINED )))
+ bSuccess = FALSE;
+ }
+
+ if ( !bSuccess )
+ {
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+
+ delete pFormatter;
+#else
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+#endif
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetDate();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger; break;
+ case SbxBYREF | SbxLONG:
+ nRes = *p->pLong; break;
+ case SbxBYREF | SbxULONG:
+ nRes = *p->pULong; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ nRes = *p->pUShort; break;
+ case SbxBYREF | SbxSINGLE:
+ nRes = *p->pSingle; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ nRes = *p->pDouble; break;
+ case SbxBYREF | SbxULONG64:
+ nRes = ImpUINT64ToDouble( *p->pULong64 ); break;
+ case SbxBYREF | SbxLONG64:
+ nRes = ImpINT64ToDouble( *p->pLong64 ); break;
+ case SbxBYREF | SbxCURRENCY:
+ nRes = ImpCurrencyToDouble( *p->pLong64 ); break;
+ case SbxBYREF | SbxSALINT64:
+ nRes = static_cast< double >(*p->pnInt64); break;
+ case SbxBYREF | SbxSALUINT64:
+ nRes = ImpSalUInt64ToDouble( *p->puInt64 ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutDate( SbxValues* p, double n )
+{
+ SbxValues aTmp;
+
+start:
+ switch( +p->eType )
+ {
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+
+ // ab hier wird getestet
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxLONG:
+ aTmp.pLong = &p->nLong; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxSINGLE:
+ aTmp.pSingle = &p->nSingle; goto direct;
+ case SbxULONG64:
+ aTmp.pULong64 = &p->nULong64; goto direct;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ aTmp.pLong64 = &p->nLong64; goto direct;
+ case SbxSALINT64:
+ aTmp.pnInt64 = &p->nInt64; goto direct;
+ case SbxSALUINT64:
+ aTmp.puInt64 = &p->uInt64; goto direct;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ SbxDecimal* pDec = ImpCreateDecimal( p );
+ if( !pDec->setDouble( n ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ break;
+ }
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+#ifndef DOS
+ {
+ if( !p->pOUString )
+ p->pOUString = new ::rtl::OUString;
+ Color* pColor;
+
+ LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
+ SvNumberFormatter* pFormatter;
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ xFactory = comphelper::getProcessServiceFactory();
+ pFormatter = new SvNumberFormatter( xFactory, eLangType );
+
+ sal_uInt32 nIndex;
+ xub_StrLen nCheckPos = 0;
+ short nType;
+
+ SvtSysLocale aSysLocale;
+ DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
+ String aStr;
+ // ist der ganzzahlige Teil 0, wollen wir kein Jahr!
+ if( n <= -1.0 || n >= 1.0 )
+ {
+ // Time only if != 00:00:00
+ if( floor( n ) == n )
+ {
+ switch( eDate )
+ {
+ case MDY: aStr.AssignAscii( "MM.TT.JJJJ" ); break;
+ case DMY: aStr.AssignAscii( "TT.MM.JJJJ" ); break;
+ case YMD: aStr.AssignAscii( "JJJJ.MM.TT" ); break;
+ default: aStr.AssignAscii( "MM.TT.JJJJ" );
+ }
+ }
+ else
+ {
+ switch( eDate )
+ {
+ case MDY: aStr.AssignAscii( "MM.TT.JJJJ HH:MM:SS" ); break;
+ case DMY: aStr.AssignAscii( "TT.MM.JJJJ HH:MM:SS" ); break;
+ case YMD: aStr.AssignAscii( "JJJJ.MM.TT HH:MM:SS" ); break;
+ default: aStr.AssignAscii( "MM.TT.JJJJ HH:MM:SS" );
+ }
+ }
+ }
+ else
+ aStr.AppendAscii( "HH:MM:SS" );
+
+ pFormatter->PutandConvertEntry( aStr,
+ nCheckPos,
+ nType,
+ nIndex,
+ LANGUAGE_GERMAN,
+ eLangType );
+ String aTmpString;
+ pFormatter->GetOutputString( n, nIndex, aTmpString, &pColor );
+ *p->pOUString = aTmpString;
+ delete pFormatter;
+#endif
+ break;
+#ifndef DOS
+ }
+#endif
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutDate( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
+ }
+ else if( n < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
+ }
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ else if( n < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ if( n > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
+ }
+ else if( n < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
+ }
+ *p->pLong = (INT32) n; break;
+ case SbxBYREF | SbxULONG:
+ if( n > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSINGLE:
+ if( n > SbxMAXSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG;
+ }
+ else if( n < SbxMINSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG;
+ }
+ *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = ImpDoubleToSalInt64( n ); break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = ImpDoubleToSalUInt64( n ); break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) n; break;
+ case SbxBYREF | SbxCURRENCY:
+ if( n > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCURR;
+ }
+ else if( n < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCURR;
+ }
+ *p->pLong64 = ImpDoubleToCurrency( n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
diff --git a/basic/source/sbx/sbxdbl.cxx b/basic/source/sbx/sbxdbl.cxx
new file mode 100644
index 000000000000..be55d3409131
--- /dev/null
+++ b/basic/source/sbx/sbxdbl.cxx
@@ -0,0 +1,306 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#include <basic/sbx.hxx>
+#include "sbxconv.hxx"
+#include "runtime.hxx"
+
+double ImpGetDouble( const SbxValues* p )
+{
+ double nRes;
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort; break;
+ case SbxLONG:
+ nRes = p->nLong; break;
+ case SbxULONG:
+ nRes = p->nULong; break;
+ case SbxSINGLE:
+ nRes = p->nSingle; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ nRes = p->nDouble; break;
+ case SbxCURRENCY:
+ nRes = ImpCurrencyToDouble( p->nLong64 ); break;
+ case SbxSALINT64:
+ nRes = static_cast< double >(p->nInt64); break;
+ case SbxSALUINT64:
+ nRes = ImpSalUInt64ToDouble( p->uInt64 ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ if( p->pDecimal )
+ p->pDecimal->getDouble( nRes );
+ else
+ nRes = 0.0;
+ break;
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ {
+ nRes = 0;
+ if ( SbiRuntime::isVBAEnabled() )// VBA only behaviour
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+ else
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
+ {
+ nRes = 0;
+ if ( SbiRuntime::isVBAEnabled() )// VBA only behaviour
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+ else
+ nRes = d;
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetDouble();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger; break;
+ case SbxBYREF | SbxLONG:
+ nRes = *p->pLong; break;
+ case SbxBYREF | SbxULONG:
+ nRes = *p->pULong; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ nRes = *p->pUShort; break;
+ case SbxBYREF | SbxSINGLE:
+ nRes = *p->pSingle; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ nRes = *p->pDouble; break;
+ case SbxBYREF | SbxCURRENCY:
+ nRes = ImpCurrencyToDouble( *p->pLong64 ); break;
+ case SbxBYREF | SbxSALINT64:
+ nRes = static_cast< double >(*p->pnInt64); break;
+ case SbxBYREF | SbxSALUINT64:
+ nRes = ImpSalUInt64ToDouble( *p->puInt64 ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutDouble( SbxValues* p, double n, BOOL bCoreString )
+{
+ SbxValues aTmp;
+start:
+ switch( +p->eType )
+ {
+ // Hier sind Tests notwendig
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxLONG:
+ case SbxCURRENCY:
+ aTmp.pLong = &p->nLong; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxSINGLE:
+ aTmp.pSingle = &p->nSingle; goto direct;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ SbxDecimal* pDec = ImpCreateDecimal( p );
+ if( !pDec->setDouble( n ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ break;
+ }
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // ab hier nicht mehr
+ case SbxSALINT64:
+ p->nInt64 = ImpDoubleToSalInt64( n ); break;
+ case SbxSALUINT64:
+ p->uInt64 = ImpDoubleToSalUInt64( n ); break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ p->pOUString = new ::rtl::OUString;
+ ImpCvtNum( (double) n, 14, *p->pOUString, bCoreString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutDouble( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
+ }
+ else if( n < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
+ }
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ else if( n < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ if( n > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
+ }
+ else if( n < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
+ }
+ *p->pLong = (INT32) n; break;
+ case SbxBYREF | SbxULONG:
+ if( n > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSINGLE:
+ if( n > SbxMAXSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG;
+ }
+ else if( n < SbxMINSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG;
+ }
+ else if( n > 0 && n < SbxMAXSNG2 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG2;
+ }
+ else if( n < 0 && n > SbxMINSNG2 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG2;
+ }
+ *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = ImpDoubleToSalInt64( n ); break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = ImpDoubleToSalUInt64( n ); break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) n; break;
+ case SbxBYREF | SbxCURRENCY:
+ if( n > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCURR;
+ }
+ else if( n < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCURR;
+ }
+ *p->pLong64 = ImpDoubleToCurrency( n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
diff --git a/basic/source/sbx/sbxdec.cxx b/basic/source/sbx/sbxdec.cxx
new file mode 100644
index 000000000000..2191d91c8d82
--- /dev/null
+++ b/basic/source/sbx/sbxdec.cxx
@@ -0,0 +1,797 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+
+#include <basic/sbx.hxx>
+#include "sbxconv.hxx"
+
+#include <com/sun/star/bridge/oleautomation/Decimal.hpp>
+
+
+// int GnDecCounter = 0;
+
+// Implementation SbxDecimal
+SbxDecimal::SbxDecimal( void )
+{
+ setInt( 0 );
+ mnRefCount = 0;
+ // GnDecCounter++;
+}
+
+SbxDecimal::SbxDecimal( const SbxDecimal& rDec )
+{
+#ifdef WIN32
+ maDec = rDec.maDec;
+#else
+ (void)rDec;
+#endif
+ mnRefCount = 0;
+ // GnDecCounter++;
+}
+
+SbxDecimal::SbxDecimal
+ ( const com::sun::star::bridge::oleautomation::Decimal& rAutomationDec )
+{
+#ifdef WIN32
+ maDec.scale = rAutomationDec.Scale;
+ maDec.sign = rAutomationDec.Sign;
+ maDec.Lo32 = rAutomationDec.LowValue;
+ maDec.Mid32 = rAutomationDec.MiddleValue;
+ maDec.Hi32 = rAutomationDec.HighValue;
+#else
+ (void)rAutomationDec;
+#endif
+ mnRefCount = 0;
+ // GnDecCounter++;
+}
+
+void SbxDecimal::fillAutomationDecimal
+ ( com::sun::star::bridge::oleautomation::Decimal& rAutomationDec )
+{
+#ifdef WIN32
+ rAutomationDec.Scale = maDec.scale;
+ rAutomationDec.Sign = maDec.sign;
+ rAutomationDec.LowValue = maDec.Lo32;
+ rAutomationDec.MiddleValue = maDec.Mid32;
+ rAutomationDec.HighValue = maDec.Hi32;
+#else
+ (void)rAutomationDec;
+#endif
+}
+
+SbxDecimal::~SbxDecimal()
+{
+ // GnDecCounter--;
+}
+
+void releaseDecimalPtr( SbxDecimal*& rpDecimal )
+{
+ if( rpDecimal )
+ {
+ rpDecimal->mnRefCount--;
+ if( rpDecimal->mnRefCount == 0 )
+ {
+ delete rpDecimal;
+ rpDecimal = NULL;
+ }
+ }
+}
+
+#ifdef WIN32
+
+bool SbxDecimal::operator -= ( const SbxDecimal &r )
+{
+ HRESULT hResult = VarDecSub( &maDec, (LPDECIMAL)&r.maDec, &maDec );
+ bool bRet = ( hResult == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::operator += ( const SbxDecimal &r )
+{
+ HRESULT hResult = VarDecAdd( &maDec, (LPDECIMAL)&r.maDec, &maDec );
+ bool bRet = ( hResult == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::operator /= ( const SbxDecimal &r )
+{
+ HRESULT hResult = VarDecDiv( &maDec, (LPDECIMAL)&r.maDec, &maDec );
+ bool bRet = ( hResult == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::operator *= ( const SbxDecimal &r )
+{
+ HRESULT hResult = VarDecMul( &maDec, (LPDECIMAL)&r.maDec, &maDec );
+ bool bRet = ( hResult == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::neg( void )
+{
+ HRESULT hResult = VarDecNeg( &maDec, &maDec );
+ bool bRet = ( hResult == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::isZero( void )
+{
+ SbxDecimal aZeroDec;
+ aZeroDec.setLong( 0 );
+ bool bZero = ( EQ == compare( *this, aZeroDec ) );
+ return bZero;
+}
+
+SbxDecimal::CmpResult compare( const SbxDecimal &rLeft, const SbxDecimal &rRight )
+{
+ HRESULT hResult = VarDecCmp( (LPDECIMAL)&rLeft.maDec, (LPDECIMAL)&rRight.maDec );
+ SbxDecimal::CmpResult eRes = (SbxDecimal::CmpResult)hResult;
+ return eRes;
+}
+
+void SbxDecimal::setChar( sal_Unicode val )
+{
+ VarDecFromUI2( (USHORT)val, &maDec );
+}
+
+void SbxDecimal::setByte( BYTE val )
+{
+ VarDecFromUI1( (BYTE)val, &maDec );
+}
+
+void SbxDecimal::setShort( INT16 val )
+{
+ VarDecFromI2( (short)val, &maDec );
+}
+
+void SbxDecimal::setLong( INT32 val )
+{
+ VarDecFromI4( (long)val, &maDec );
+}
+
+void SbxDecimal::setUShort( UINT16 val )
+{
+ VarDecFromUI2( (USHORT)val, &maDec );
+}
+
+void SbxDecimal::setULong( UINT32 val )
+{
+ VarDecFromUI4( (ULONG)val, &maDec );
+}
+
+bool SbxDecimal::setSingle( float val )
+{
+ bool bRet = ( VarDecFromR4( val, &maDec ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::setDouble( double val )
+{
+ bool bRet = ( VarDecFromR8( val, &maDec ) == S_OK );
+ return bRet;
+}
+
+void SbxDecimal::setInt( int val )
+{
+ setLong( (INT32)val );
+}
+
+void SbxDecimal::setUInt( unsigned int val )
+{
+ setULong( (UINT32)val );
+}
+
+// sbxscan.cxx
+void ImpGetIntntlSep( sal_Unicode& rcDecimalSep, sal_Unicode& rcThousandSep );
+
+bool SbxDecimal::setString( ::rtl::OUString* pOUString )
+{
+ static LCID nLANGID = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US );
+
+ // Convert delimiter
+ sal_Unicode cDecimalSep;
+ sal_Unicode cThousandSep;
+ ImpGetIntntlSep( cDecimalSep, cThousandSep );
+
+ bool bRet = false;
+ HRESULT hResult;
+ if( cDecimalSep != '.' || cThousandSep != ',' )
+ {
+ int nLen = pOUString->getLength();
+ sal_Unicode* pBuffer = new sal_Unicode[nLen + 1];
+ pBuffer[nLen] = 0;
+
+ const sal_Unicode* pSrc = pOUString->getStr();
+ int i;
+ for( i = 0 ; i < nLen ; ++i )
+ pBuffer[i] = pSrc[i];
+
+ sal_Unicode c;
+ i = 0;
+ while( (c = pBuffer[i]) != 0 )
+ {
+ if( c == cDecimalSep )
+ pBuffer[i] = '.';
+ else if( c == cThousandSep )
+ pBuffer[i] = ',';
+ i++;
+ }
+ hResult = VarDecFromStr( (OLECHAR*)pBuffer, nLANGID, 0, &maDec );
+ delete pBuffer;
+ }
+ else
+ {
+ hResult = VarDecFromStr( (OLECHAR*)pOUString->getStr(), nLANGID, 0, &maDec );
+ }
+ bRet = ( hResult == S_OK );
+ return bRet;
+}
+
+
+bool SbxDecimal::getChar( sal_Unicode& rVal )
+{
+ bool bRet = ( VarUI2FromDec( &maDec, &rVal ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::getByte( BYTE& rVal )
+{
+ bool bRet = ( VarUI1FromDec( &maDec, &rVal ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::getShort( INT16& rVal )
+{
+ bool bRet = ( VarI2FromDec( &maDec, &rVal ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::getLong( INT32& rVal )
+{
+ bool bRet = ( VarI4FromDec( &maDec, &rVal ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::getUShort( UINT16& rVal )
+{
+ bool bRet = ( VarUI2FromDec( &maDec, &rVal ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::getULong( UINT32& rVal )
+{
+ bool bRet = ( VarUI4FromDec( &maDec, &rVal ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::getSingle( float& rVal )
+{
+ bool bRet = ( VarR4FromDec( &maDec, &rVal ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::getDouble( double& rVal )
+{
+ bool bRet = ( VarR8FromDec( &maDec, &rVal ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::getInt( int& rVal )
+{
+ INT32 TmpVal;
+ bool bRet = getLong( TmpVal );
+ rVal = TmpVal;
+ return bRet;
+}
+
+bool SbxDecimal::getUInt( unsigned int& rVal )
+{
+ UINT32 TmpVal;
+ bool bRet = getULong( TmpVal );
+ rVal = TmpVal;
+ return bRet;
+}
+
+#else
+// !WIN32
+
+bool SbxDecimal::operator -= ( const SbxDecimal &r )
+{
+ (void)r;
+ return false;
+}
+
+bool SbxDecimal::operator += ( const SbxDecimal &r )
+{
+ (void)r;
+ return false;
+}
+
+bool SbxDecimal::operator /= ( const SbxDecimal &r )
+{
+ (void)r;
+ return false;
+}
+
+bool SbxDecimal::operator *= ( const SbxDecimal &r )
+{
+ (void)r;
+ return false;
+}
+
+bool SbxDecimal::neg( void )
+{
+ return false;
+}
+
+bool SbxDecimal::isZero( void )
+{
+ return false;
+}
+
+SbxDecimal::CmpResult compare( const SbxDecimal &rLeft, const SbxDecimal &rRight )
+{
+ (void)rLeft;
+ (void)rRight;
+ return (SbxDecimal::CmpResult)0;
+}
+
+void SbxDecimal::setChar( sal_Unicode val ) { (void)val; }
+void SbxDecimal::setByte( BYTE val ) { (void)val; }
+void SbxDecimal::setShort( INT16 val ) { (void)val; }
+void SbxDecimal::setLong( INT32 val ) { (void)val; }
+void SbxDecimal::setUShort( UINT16 val ) { (void)val; }
+void SbxDecimal::setULong( UINT32 val ) { (void)val; }
+bool SbxDecimal::setSingle( float val ) { (void)val; return false; }
+bool SbxDecimal::setDouble( double val ) { (void)val; return false; }
+void SbxDecimal::setInt( int val ) { (void)val; }
+void SbxDecimal::setUInt( unsigned int val ) { (void)val; }
+bool SbxDecimal::setString( ::rtl::OUString* pOUString ) { (void)pOUString; return false; }
+
+bool SbxDecimal::getChar( sal_Unicode& rVal ) { (void)rVal; return false; }
+bool SbxDecimal::getByte( BYTE& rVal ) { (void)rVal; return false; }
+bool SbxDecimal::getShort( INT16& rVal ) { (void)rVal; return false; }
+bool SbxDecimal::getLong( INT32& rVal ) { (void)rVal; return false; }
+bool SbxDecimal::getUShort( UINT16& rVal ) { (void)rVal; return false; }
+bool SbxDecimal::getULong( UINT32& rVal ) { (void)rVal; return false; }
+bool SbxDecimal::getSingle( float& rVal ) { (void)rVal; return false; }
+bool SbxDecimal::getDouble( double& rVal ) { (void)rVal; return false; }
+bool SbxDecimal::getInt( int& rVal ) { (void)rVal; return false; }
+bool SbxDecimal::getUInt( unsigned int& rVal ) { (void)rVal; return false; }
+
+#endif
+
+bool SbxDecimal::getString( ::rtl::OUString& rString )
+{
+#ifdef WIN32
+ static LCID nLANGID = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US );
+
+ bool bRet = false;
+
+ OLECHAR sz[100];
+ BSTR aBStr = SysAllocString( sz );
+ if( aBStr != NULL )
+ {
+ HRESULT hResult = VarBstrFromDec( &maDec, nLANGID, 0, &aBStr );
+ bRet = ( hResult == S_OK );
+ if( bRet )
+ {
+ // Convert delimiter
+ sal_Unicode cDecimalSep;
+ sal_Unicode cThousandSep;
+ ImpGetIntntlSep( cDecimalSep, cThousandSep );
+
+ if( cDecimalSep != '.' || cThousandSep != ',' )
+ {
+ sal_Unicode c;
+ int i = 0;
+ while( (c = aBStr[i]) != 0 )
+ {
+ if( c == '.' )
+ aBStr[i] = cDecimalSep;
+ else if( c == ',' )
+ aBStr[i] = cThousandSep;
+ i++;
+ }
+ }
+ rString = reinterpret_cast<const sal_Unicode*>(aBStr);
+ }
+
+ SysFreeString( aBStr );
+ }
+ return bRet;
+#else
+ (void)rString;
+ return false;
+#endif
+}
+
+SbxDecimal* ImpCreateDecimal( SbxValues* p )
+{
+#ifdef WIN32
+ if( !p )
+ return NULL;
+
+ SbxDecimal*& rpDecimal = p->pDecimal;
+ if( rpDecimal == NULL )
+ {
+ rpDecimal = new SbxDecimal();
+ rpDecimal->addRef();
+ }
+ return rpDecimal;
+#else
+ (void)p;
+ return NULL;
+#endif
+}
+
+SbxDecimal* ImpGetDecimal( const SbxValues* p )
+{
+#ifdef WIN32
+ SbxValues aTmp;
+ SbxDecimal* pnDecRes;
+
+ SbxDataType eType = p->eType;
+ if( eType == SbxDECIMAL && p->pDecimal )
+ {
+ pnDecRes = new SbxDecimal( *p->pDecimal );
+ pnDecRes->addRef();
+ return pnDecRes;
+ }
+ pnDecRes = new SbxDecimal();
+ pnDecRes->addRef();
+
+start:
+ switch( +eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ pnDecRes->setShort( 0 ); break;
+ case SbxCHAR:
+ pnDecRes->setChar( p->nChar ); break;
+ case SbxBYTE:
+ pnDecRes->setByte( p->nByte ); break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ pnDecRes->setInt( p->nInteger ); break;
+ case SbxERROR:
+ case SbxUSHORT:
+ pnDecRes->setUShort( p->nUShort ); break;
+ case SbxLONG:
+ pnDecRes->setLong( p->nLong ); break;
+ case SbxULONG:
+ pnDecRes->setULong( p->nULong ); break;
+ case SbxSINGLE:
+ if( !pnDecRes->setSingle( p->nSingle ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ break;
+ case SbxSALINT64:
+ {
+ double d = (double)p->nInt64;
+ pnDecRes->setDouble( d );
+ break;
+ }
+ case SbxSALUINT64:
+ {
+ double d = ImpSalUInt64ToDouble( p->uInt64 );
+ pnDecRes->setDouble( d );
+ break;
+ }
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else
+ dVal = p->nDouble;
+
+ if( !pnDecRes->setDouble( dVal ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ break;
+ }
+ case SbxLPSTR:
+ case SbxSTRING:
+ case SbxBYREF | SbxSTRING:
+ pnDecRes->setString( p->pOUString ); break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pnDecRes->setDecimal( pVal->GetDecimal() );
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ pnDecRes->setShort( 0 );
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ pnDecRes->setChar( *p->pChar ); break;
+ case SbxBYREF | SbxBYTE:
+ pnDecRes->setByte( *p->pByte ); break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ pnDecRes->setInt( *p->pInteger ); break;
+ case SbxBYREF | SbxLONG:
+ pnDecRes->setLong( *p->pLong ); break;
+ case SbxBYREF | SbxULONG:
+ pnDecRes->setULong( *p->pULong ); break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ pnDecRes->setUShort( *p->pUShort ); break;
+
+ // ab hier muss getestet werden
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); pnDecRes->setShort( 0 );
+ }
+ return pnDecRes;
+#else
+ (void)p;
+ return NULL;
+#endif
+}
+
+
+void ImpPutDecimal( SbxValues* p, SbxDecimal* pDec )
+{
+#ifdef WIN32
+ if( !pDec )
+ return;
+
+ SbxValues aTmp;
+start:
+ switch( +p->eType )
+ {
+ // hier muss getestet werden
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxSALUINT64:
+ aTmp.puInt64 = &p->uInt64; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxLONG:
+ aTmp.pLong = &p->nLong; goto direct;
+ case SbxSALINT64:
+ aTmp.pnInt64 = &p->nInt64; goto direct;
+ case SbxCURRENCY:
+ aTmp.pLong64 = &p->nLong64; goto direct;
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // ab hier nicht mehr
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ if( pDec != p->pDecimal )
+ {
+ releaseDecimalPtr( p->pDecimal );
+ // if( p->pDecimal )
+ // p->pDecimal->ReleaseRef();
+ p->pDecimal = pDec;
+ if( pDec )
+ pDec->addRef();
+ }
+ break;
+ }
+ case SbxSINGLE:
+ {
+ float f;
+ pDec->getSingle( f );
+ p->nSingle = f;
+ break;
+ }
+ case SbxDATE:
+ case SbxDOUBLE:
+ {
+ double d;
+ pDec->getDouble( d );
+ p->nDouble = d;
+ break;
+ }
+ case SbxULONG64:
+ {
+ double d;
+ pDec->getDouble( d );
+ p->nULong64 = ImpDoubleToUINT64( d );
+ break;
+ }
+ case SbxLONG64:
+ {
+ double d;
+ pDec->getDouble( d );
+ p->nLong64 = ImpDoubleToINT64( d );
+ break;
+ }
+
+ case SbxLPSTR:
+ case SbxSTRING:
+ case SbxBYREF | SbxSTRING:
+ if( !p->pOUString )
+ p->pOUString = new ::rtl::OUString;
+ // ImpCvtNum( (double) n, 0, *p->pString );
+ pDec->getString( *p->pOUString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutDecimal( pDec );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ if( !pDec->getChar( *p->pChar ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pChar = 0;
+ }
+ break;
+ case SbxBYREF | SbxBYTE:
+ if( !pDec->getChar( *p->pChar ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pByte = 0;
+ }
+ break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( !pDec->getShort( *p->pInteger ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pInteger = 0;
+ }
+ break;
+ // *p->pInteger = n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( !pDec->getUShort( *p->pUShort ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pUShort = 0;
+ }
+ break;
+ case SbxBYREF | SbxLONG:
+ if( !pDec->getLong( *p->pLong ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pLong = 0;
+ }
+ break;
+ case SbxBYREF | SbxULONG:
+ if( !pDec->getULong( *p->pULong ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pULong = 0;
+ }
+ break;
+ case SbxBYREF | SbxSALINT64:
+ {
+ double d;
+ if( !pDec->getDouble( d ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ else
+ *p->pnInt64 = ImpDoubleToSalInt64( d );
+ break;
+ }
+ case SbxBYREF | SbxSALUINT64:
+ {
+ double d;
+ if( !pDec->getDouble( d ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ else
+ *p->puInt64 = ImpDoubleToSalUInt64( d );
+ break;
+ }
+ case SbxBYREF | SbxSINGLE:
+ if( !pDec->getSingle( *p->pSingle ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pSingle = 0;
+ }
+ break;
+ // *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ if( !pDec->getDouble( *p->pDouble ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pDouble = 0;
+ }
+ break;
+ case SbxBYREF | SbxULONG64:
+ {
+ double d;
+ pDec->getDouble( d );
+ *p->pULong64 = ImpDoubleToUINT64( d );
+ break;
+ }
+ case SbxBYREF | SbxLONG64:
+ {
+ double d;
+ pDec->getDouble( d );
+ *p->pLong64 = ImpDoubleToINT64( d );
+ break;
+ }
+ case SbxBYREF | SbxCURRENCY:
+ {
+ double d;
+ pDec->getDouble( d );
+ *p->pLong64 = ImpDoubleToCurrency( d );
+ break;
+ }
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+#else
+ (void)p;
+ (void)pDec;
+#endif
+}
+
diff --git a/basic/source/sbx/sbxdec.hxx b/basic/source/sbx/sbxdec.hxx
new file mode 100644
index 000000000000..cd80bbad282e
--- /dev/null
+++ b/basic/source/sbx/sbxdec.hxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+
+#ifndef __SBX_SBX_DEC_HXX
+#define __SBX_SBX_DEC_HXX
+
+#ifdef WIN32
+
+#undef WB_LEFT
+#undef WB_RIGHT
+#include <tools/prewin.h>
+} // close extern "C" {
+
+#ifndef __MINGW32__
+#include <comutil.h>
+#endif
+#include <oleauto.h>
+
+extern "C" { // reopen extern "C" {
+#include <tools/postwin.h>
+
+#endif
+#endif
+#include <basic/sbx.hxx>
+
+#include <com/sun/star/bridge/oleautomation/Decimal.hpp>
+
+
+// Decimal support
+// Implementation only for windows
+
+class SbxDecimal
+{
+ friend void releaseDecimalPtr( SbxDecimal*& rpDecimal );
+
+#ifdef WIN32
+ DECIMAL maDec;
+#endif
+ INT32 mnRefCount;
+
+public:
+ SbxDecimal( void );
+ SbxDecimal( const SbxDecimal& rDec );
+ SbxDecimal( const com::sun::star::bridge::oleautomation::Decimal& rAutomationDec );
+
+ ~SbxDecimal();
+
+ void addRef( void )
+ { mnRefCount++; }
+
+ void fillAutomationDecimal( com::sun::star::bridge::oleautomation::Decimal& rAutomationDec );
+
+ void setChar( sal_Unicode val );
+ void setByte( BYTE val );
+ void setShort( INT16 val );
+ void setLong( INT32 val );
+ void setUShort( UINT16 val );
+ void setULong( UINT32 val );
+ bool setSingle( float val );
+ bool setDouble( double val );
+ void setInt( int val );
+ void setUInt( unsigned int val );
+ bool setString( ::rtl::OUString* pOUString );
+ void setDecimal( SbxDecimal* pDecimal )
+ {
+#ifdef WIN32
+ if( pDecimal )
+ maDec = pDecimal->maDec;
+#else
+ (void)pDecimal;
+#endif
+ }
+
+ bool getChar( sal_Unicode& rVal );
+ bool getByte( BYTE& rVal );
+ bool getShort( INT16& rVal );
+ bool getLong( INT32& rVal );
+ bool getUShort( UINT16& rVal );
+ bool getULong( UINT32& rVal );
+ bool getSingle( float& rVal );
+ bool getDouble( double& rVal );
+ bool getInt( int& rVal );
+ bool getUInt( unsigned int& rVal );
+ bool getString( ::rtl::OUString& rString );
+
+ bool operator -= ( const SbxDecimal &r );
+ bool operator += ( const SbxDecimal &r );
+ bool operator /= ( const SbxDecimal &r );
+ bool operator *= ( const SbxDecimal &r );
+ bool neg( void );
+
+ bool isZero( void );
+
+ enum CmpResult { LT, EQ, GT };
+ friend CmpResult compare( const SbxDecimal &rLeft, const SbxDecimal &rRight );
+};
+
diff --git a/basic/source/sbx/sbxexec.cxx b/basic/source/sbx/sbxexec.cxx
new file mode 100644
index 000000000000..c602b130fc5e
--- /dev/null
+++ b/basic/source/sbx/sbxexec.cxx
@@ -0,0 +1,401 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#ifndef _APP_HXX //autogen
+#include <vcl/svapp.hxx>
+#endif
+#include <basic/sbx.hxx>
+
+
+class SbxSimpleCharClass
+{
+public:
+ BOOL isAlpha( sal_Unicode c ) const
+ {
+ BOOL bRet = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+ return bRet;
+ }
+
+ BOOL isDigit( sal_Unicode c ) const
+ {
+ BOOL bRet = (c >= '0' && c <= '9');
+ return bRet;
+ }
+
+ BOOL isAlphaNumeric( sal_Unicode c ) const
+ {
+ BOOL bRet = isDigit( c ) || isAlpha( c );
+ return bRet;
+ }
+};
+
+
+static SbxVariable* Element
+ ( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf,
+ SbxClassType, const SbxSimpleCharClass& rCharClass );
+
+static const xub_Unicode* SkipWhitespace( const xub_Unicode* p )
+{
+ while( *p && ( *p == ' ' || *p == '\t' ) )
+ p++;
+ return p;
+}
+
+// Scannen eines Symbol. Das Symbol wird in rSym eingetragen, der Returnwert
+// ist die neue Scanposition. Bei Fehlern ist das Symbol leer.
+
+static const xub_Unicode* Symbol( const xub_Unicode* p, XubString& rSym, const SbxSimpleCharClass& rCharClass )
+{
+ USHORT nLen = 0;
+ // Haben wir ein Sondersymbol?
+ if( *p == '[' )
+ {
+ rSym = ++p;
+ while( *p && *p != ']' )
+ p++, nLen++;
+ p++;
+ }
+ else
+ {
+ // Ein Symbol muss mit einem Buchstaben oder einem Underline beginnen
+ if( !rCharClass.isAlpha( *p ) && *p != '_' )
+ SbxBase::SetError( SbxERR_SYNTAX );
+ else
+ {
+ rSym = p;
+ // Dann darf es Buchstaben, Zahlen oder Underlines enthalten
+ while( *p && (rCharClass.isAlphaNumeric( *p ) || *p == '_') )
+ p++, nLen++;
+ // BASIC-Standard-Suffixe werden ignoriert
+ if( *p && (*p == '%' || *p == '&' || *p == '!' || *p == '#' || *p == '$' ) )
+ p++;
+ }
+ }
+ rSym.Erase( nLen );
+ return p;
+}
+
+// Qualifizierter Name. Element.Element....
+
+static SbxVariable* QualifiedName
+ ( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf, SbxClassType t )
+{
+ static SbxSimpleCharClass aCharClass;
+
+ SbxVariableRef refVar;
+ const xub_Unicode* p = SkipWhitespace( *ppBuf );
+ if( aCharClass.isAlpha( *p ) || *p == '_' || *p == '[' )
+ {
+ // Element einlesen
+ refVar = Element( pObj, pGbl, &p, t, aCharClass );
+ while( refVar.Is() && (*p == '.' || *p == '!') )
+ {
+ // Es folgt noch ein Objektelement. Das aktuelle Element
+ // muss also ein SBX-Objekt sein oder liefern!
+ pObj = PTR_CAST(SbxObject,(SbxVariable*) refVar);
+ if( !pObj )
+ // Dann muss es ein Objekt liefern
+ pObj = PTR_CAST(SbxObject,refVar->GetObject());
+ refVar.Clear();
+ if( !pObj )
+ break;
+ p++;
+ // Und das naechste Element bitte
+ refVar = Element( pObj, pGbl, &p, t, aCharClass );
+ }
+ }
+ else
+ SbxBase::SetError( SbxERR_SYNTAX );
+ *ppBuf = p;
+ if( refVar.Is() )
+ refVar->AddRef();
+ return refVar;
+}
+
+// Einlesen eines Operanden. Dies kann eine Zahl, ein String oder
+// eine Funktion (mit optionalen Parametern) sein.
+
+static SbxVariable* Operand
+ ( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf, BOOL bVar )
+{
+ static SbxSimpleCharClass aCharClass;
+
+ SbxVariableRef refVar( new SbxVariable );
+ const xub_Unicode* p = SkipWhitespace( *ppBuf );
+ if( !bVar && ( aCharClass.isDigit( *p )
+ || ( *p == '.' && aCharClass.isDigit( *( p+1 ) ) )
+ || *p == '-'
+ || *p == '&' ) )
+ {
+ // Eine Zahl kann direkt eingescant werden!
+ USHORT nLen;
+ if( !refVar->Scan( XubString( p ), &nLen ) )
+ refVar.Clear();
+ else
+ p += nLen;
+ }
+ else if( !bVar && *p == '"' )
+ {
+ // Ein String
+ XubString aString;
+ p++;
+ for( ;; )
+ {
+ // Das ist wohl ein Fehler
+ if( !*p )
+ return NULL;
+ // Doppelte Quotes sind OK
+ if( *p == '"' )
+ if( *++p != '"' )
+ break;
+ aString += *p++;
+ }
+ refVar->PutString( aString );
+ }
+ else
+ refVar = QualifiedName( pObj, pGbl, &p, SbxCLASS_DONTCARE );
+ *ppBuf = p;
+ if( refVar.Is() )
+ refVar->AddRef();
+ return refVar;
+}
+
+// Einlesen einer einfachen Term. Die Operatoren +, -, * und /
+// werden unterstuetzt.
+
+static SbxVariable* MulDiv( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf )
+{
+ const xub_Unicode* p = *ppBuf;
+ SbxVariableRef refVar( Operand( pObj, pGbl, &p, FALSE ) );
+ p = SkipWhitespace( p );
+ while( refVar.Is() && ( *p == '*' || *p == '/' ) )
+ {
+ xub_Unicode cOp = *p++;
+ SbxVariableRef refVar2( Operand( pObj, pGbl, &p, FALSE ) );
+ if( refVar2.Is() )
+ {
+ // temporaere Variable!
+ SbxVariable* pVar = refVar;
+ pVar = new SbxVariable( *pVar );
+ refVar = pVar;
+ if( cOp == '*' )
+ *refVar *= *refVar2;
+ else
+ *refVar /= *refVar2;
+ }
+ else
+ {
+ refVar.Clear();
+ break;
+ }
+ }
+ *ppBuf = p;
+ if( refVar.Is() )
+ refVar->AddRef();
+ return refVar;
+}
+
+static SbxVariable* PlusMinus( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf )
+{
+ const xub_Unicode* p = *ppBuf;
+ SbxVariableRef refVar( MulDiv( pObj, pGbl, &p ) );
+ p = SkipWhitespace( p );
+ while( refVar.Is() && ( *p == '+' || *p == '-' ) )
+ {
+ xub_Unicode cOp = *p++;
+ SbxVariableRef refVar2( MulDiv( pObj, pGbl, &p ) );
+ if( refVar2.Is() )
+ {
+ // temporaere Variable!
+ SbxVariable* pVar = refVar;
+ pVar = new SbxVariable( *pVar );
+ refVar = pVar;
+ if( cOp == '+' )
+ *refVar += *refVar2;
+ else
+ *refVar -= *refVar2;
+ }
+ else
+ {
+ refVar.Clear();
+ break;
+ }
+ }
+ *ppBuf = p;
+ if( refVar.Is() )
+ refVar->AddRef();
+ return refVar;
+}
+
+static SbxVariable* Assign( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf )
+{
+ const xub_Unicode* p = *ppBuf;
+ SbxVariableRef refVar( Operand( pObj, pGbl, &p, TRUE ) );
+ p = SkipWhitespace( p );
+ if( refVar.Is() )
+ {
+ if( *p == '=' )
+ {
+ // Nur auf Props zuweisen!
+ if( refVar->GetClass() != SbxCLASS_PROPERTY )
+ {
+ SbxBase::SetError( SbxERR_BAD_ACTION );
+ refVar.Clear();
+ }
+ else
+ {
+ p++;
+ SbxVariableRef refVar2( PlusMinus( pObj, pGbl, &p ) );
+ if( refVar2.Is() )
+ {
+ SbxVariable* pVar = refVar;
+ SbxVariable* pVar2 = refVar2;
+ *pVar = *pVar2;
+ pVar->SetParameters( NULL );
+ }
+ }
+ }
+ else
+ // Einfacher Aufruf: einmal aktivieren
+ refVar->Broadcast( SBX_HINT_DATAWANTED );
+ }
+ *ppBuf = p;
+ if( refVar.Is() )
+ refVar->AddRef();
+ return refVar;
+}
+
+// Einlesen eines Elements. Dies ist ein Symbol, optional gefolgt
+// von einer Parameterliste. Das Symbol wird im angegebenen Objekt
+// gesucht und die Parameterliste wird ggf. angefuegt.
+
+static SbxVariable* Element
+ ( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf,
+ SbxClassType t, const SbxSimpleCharClass& rCharClass )
+{
+ XubString aSym;
+ const xub_Unicode* p = Symbol( *ppBuf, aSym, rCharClass );
+ SbxVariableRef refVar;
+ if( aSym.Len() )
+ {
+ USHORT nOld = pObj->GetFlags();
+ if( pObj == pGbl )
+ pObj->SetFlag( SBX_GBLSEARCH );
+ refVar = pObj->Find( aSym, t );
+ pObj->SetFlags( nOld );
+ if( refVar.Is() )
+ {
+ refVar->SetParameters( NULL );
+ // folgen noch Parameter?
+ p = SkipWhitespace( p );
+ if( *p == '(' )
+ {
+ p++;
+ SbxArrayRef refPar = new SbxArray;
+ USHORT nArg = 0;
+ // Wird sind mal relaxed und akzeptieren auch
+ // das Zeilen- oder Komandoende als Begrenzer
+ // Parameter immer global suchen!
+ while( *p && *p != ')' && *p != ']' )
+ {
+ SbxVariableRef refArg = PlusMinus( pGbl, pGbl, &p );
+ if( !refArg )
+ {
+ // Fehler beim Parsing
+ refVar.Clear(); break;
+ }
+ else
+ {
+ // Man kopiere den Parameter, damit
+ // man den aktuellen Zustand hat (loest auch
+ // den Aufruf per Zugriff aus)
+ SbxVariable* pArg = refArg;
+ refPar->Put( new SbxVariable( *pArg ), ++nArg );
+ }
+ p = SkipWhitespace( p );
+ if( *p == ',' )
+ p++;
+ }
+ if( *p == ')' )
+ p++;
+ if( refVar.Is() )
+ refVar->SetParameters( refPar );
+ }
+ }
+ else
+ SbxBase::SetError( SbxERR_NO_METHOD );
+ }
+ *ppBuf = p;
+ if( refVar.Is() )
+ refVar->AddRef();
+ return refVar;
+}
+
+// Hauptroutine
+
+SbxVariable* SbxObject::Execute( const XubString& rTxt )
+{
+ SbxVariable* pVar = NULL;
+ const xub_Unicode* p = rTxt.GetBuffer();
+ for( ;; )
+ {
+ p = SkipWhitespace( p );
+ if( !*p )
+ break;
+ if( *p++ != '[' )
+ {
+ SetError( SbxERR_SYNTAX ); break;
+ }
+ pVar = Assign( this, this, &p );
+ if( !pVar )
+ break;
+ p = SkipWhitespace( p );
+ if( *p++ != ']' )
+ {
+ SetError( SbxERR_SYNTAX ); break;
+ }
+ }
+ return pVar;
+}
+
+SbxVariable* SbxObject::FindQualified( const XubString& rName, SbxClassType t )
+{
+ SbxVariable* pVar = NULL;
+ const xub_Unicode* p = rName.GetBuffer();
+ p = SkipWhitespace( p );
+ if( !*p )
+ return NULL;;
+ pVar = QualifiedName( this, this, &p, t );
+ p = SkipWhitespace( p );
+ if( *p )
+ SetError( SbxERR_SYNTAX );
+ return pVar;
+}
+
diff --git a/basic/source/sbx/sbxform.cxx b/basic/source/sbx/sbxform.cxx
new file mode 100644
index 000000000000..b53612f1e642
--- /dev/null
+++ b/basic/source/sbx/sbxform.cxx
@@ -0,0 +1,1168 @@
+/*************************************************************************
+ *
+ * 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 <stdlib.h>
+
+#include <basic/sbxform.hxx>
+
+/*
+TODO: gibt es noch irgend welche Star-Basic Besonderheiten ?
+
+ was bedeutet: * als Platzhalter
+
+BEMERKUNG: Visual-Basic behandelt folgende (ung"ultige) Format-Strings
+ wie angezeigt:
+
+ ##0##.##0## --> ##000.000##
+
+ (diese Klasse verh"alt sich genau so).
+*/
+
+#include <stdio.h> // f"ur: sprintf()
+#include <float.h> // f"ur: DBL_DIG, DBL_EPSILON
+#include <math.h> // f"ur: floor(), fabs(), log10(), pow()
+
+//=================================================================
+//=========================== DEFINES =============================
+//=================================================================
+
+#define _NO_DIGIT -1
+
+#define MAX_NO_OF_EXP_DIGITS 5
+ // +4 wegen dem Wertebereich: zwischen -308 und +308
+ // +1 f"ur abschliessende 0
+#define MAX_NO_OF_DIGITS DBL_DIG
+#define MAX_DOUBLE_BUFFER_LENGTH MAX_NO_OF_DIGITS + 9
+ // +1 f"ur Vorzeichen
+ // +1 f"ur Ziffer vor dem Dezimal-Punkt
+ // +1 f"ur Dezimal-Punkt
+ // +2 f"ur Exponent E und Exp. Vorzeichen
+ // +3 f"ur den Wert des Exponenten
+ // +1 f"ur abschliessende 0
+
+// Defines f"ur die Ziffern:
+#define ASCII_0 '0' // 48
+#define ASCII_9 '9' // 57
+
+#define CREATE_1000SEP_CHAR '@'
+
+#define FORMAT_SEPARATOR ';'
+
+// vordefinierte Formate f"ur den Format$()-Befehl:
+#define BASICFORMAT_GENERALNUMBER "General Number"
+#define BASICFORMAT_CURRENCY "Currency"
+#define BASICFORMAT_FIXED "Fixed"
+#define BASICFORMAT_STANDARD "Standard"
+#define BASICFORMAT_PERCENT "Percent"
+#define BASICFORMAT_SCIENTIFIC "Scientific"
+#define BASICFORMAT_YESNO "Yes/No"
+#define BASICFORMAT_TRUEFALSE "True/False"
+#define BASICFORMAT_ONOFF "On/Off"
+
+#define EMPTYFORMATSTRING ""
+
+// Bem.: Visual-Basic hat bei Floating-Point-Zahlen maximal 12 Stellen
+// nach dem Dezimal-Punkt.
+// Alle Format-Strings sind kompatibel zu Visual-Basic:
+#define GENERALNUMBER_FORMAT "0.############"
+ // max. 12 Stellen in Visual-Basic !
+#define CURRENCY_FORMAT "@$0.00;@($0.00)"
+#define FIXED_FORMAT "0.00"
+#define STANDARD_FORMAT "@0.00"
+#define PERCENT_FORMAT "0.00%"
+#define SCIENTIFIC_FORMAT "#.00E+00"
+// BEMERKUNG: das Zeichen @ bedeutet, das Tausender-Separatoren erzeugt
+// weden sollen. Dies ist eine StarBasic 'Erweiterung'.
+
+//=================================================================
+
+// zur Bestimmung der Anzahl Stellen in dNumber
+double get_number_of_digits( double dNumber )
+//double floor_log10_fabs( double dNumber )
+{
+ if( dNumber==0.0 )
+ // 0 hat zumindest auch eine Stelle !
+ return 0.0; //ehemals 1.0, jetzt 0.0 wegen #40025;
+ else
+ return floor( log10( fabs( dNumber ) ) );
+}
+
+//=================================================================
+//======================= IMPLEMENTATION ==========================
+//=================================================================
+
+SbxBasicFormater::SbxBasicFormater( sal_Unicode _cDecPoint, sal_Unicode _cThousandSep,
+ String _sOnStrg,
+ String _sOffStrg,
+ String _sYesStrg,
+ String _sNoStrg,
+ String _sTrueStrg,
+ String _sFalseStrg,
+ String _sCurrencyStrg,
+ String _sCurrencyFormatStrg )
+{
+ cDecPoint = _cDecPoint;
+ cThousandSep = _cThousandSep;
+ sOnStrg = _sOnStrg;
+ sOffStrg = _sOffStrg;
+ sYesStrg = _sYesStrg;
+ sNoStrg = _sNoStrg;
+ sTrueStrg = _sTrueStrg;
+ sFalseStrg = _sFalseStrg;
+ sCurrencyStrg = _sCurrencyStrg;
+ sCurrencyFormatStrg = _sCurrencyFormatStrg;
+}
+
+// Funktion zur Ausgabe eines Fehler-Textes (zum Debuggen)
+/*
+void SbxBasicFormater::ShowError( char * sErrMsg )
+{
+// cout << "ERROR in Format$(): " << sErrMsg << endl;
+}
+*/
+// verschiebt alle Zeichen des Strings, angefangen von der nStartPos,
+// um eine Position zu gr"osseren Indizes, d.h. es wird Platz f"ur
+// ein neues (einzuf"ugendes) Zeichen geschafft.
+// ACHTUNG: der String MUSS gross genug sein !
+inline void SbxBasicFormater::ShiftString( String& sStrg, USHORT nStartPos )
+{
+ sStrg.Erase( nStartPos,1 );
+}
+
+// Funktion um ein Zeichen an einen String anzuh"angen
+inline void SbxBasicFormater::StrAppendChar( String& sStrg, sal_Unicode ch )
+{
+ sStrg.Insert( ch );
+}
+
+// h"angt die "ubergebene Ziffer nDigit an den "ubergebenen String sStrg
+// an, dabei wird "uberpr"uft ob nDigit eine g"ultige Ziffer ist,
+// falls dies nicht der Fall ist, wird nichts gemacht.
+void SbxBasicFormater::AppendDigit( String& sStrg, short nDigit )
+{
+ if( nDigit>=0 && nDigit<=9 )
+ StrAppendChar( sStrg, (sal_Unicode)(nDigit+ASCII_0) );
+}
+
+// verschiebt den Dezimal-Punkt um eine Stelle nach links
+void SbxBasicFormater::LeftShiftDecimalPoint( String& sStrg )
+{
+ USHORT nPos = sStrg.Search( cDecPoint );
+
+ if( nPos!=STRING_NOTFOUND )
+ {
+ // vertausche Dezimal-Punkt
+ sStrg.SetChar( nPos, sStrg.GetChar( nPos - 1 ) );
+ sStrg.SetChar( nPos-1, cDecPoint );
+ }
+}
+
+// rundet in einem String die Ziffer an der angegebenen Stelle,
+// es wird ein Flag zur"uckgeliefert, falls ein Overflow auftrat,
+// d.h. 99.99 --> 100.00, d.h. ein Gr"ossenordung ge"andert wurde
+// (geschieht beim Runden einer 9).
+void SbxBasicFormater::StrRoundDigit( String& sStrg, short nPos, BOOL& bOverflow )
+{
+ // wurde ggf ein falscher Index uebergeben --> Aufruf ignorieren
+ if( nPos<0 )
+ return;
+
+ bOverflow = FALSE;
+ // "uberspringe den Dezimalpunkt und Tausender-Trennzeichen
+ sal_Unicode c = sStrg.GetChar( nPos );
+ if( nPos>0 && (c == cDecPoint || c == cThousandSep) )
+ {
+ StrRoundDigit( sStrg,nPos-1,bOverflow );
+ // AENDERUNG ab 9.3.1997: nach rekursivem Call die Methode SOFORT beenden !
+ return;
+ }
+ // "uberspringe alle nicht-Ziffern:
+ // BEMERKUNG:
+ // in einem g"ultigen Format-String sollte die Ausgabe
+ // der Zahl an einem St"uck geschen, d.h. Sonderzeichen sollten
+ // NUR vor ODER nach der Zahl stehen und nicht mitten in der
+ // Format-Angabe f"ur die Zahl
+ while( nPos>=0 && (sStrg.GetChar( nPos )<ASCII_0 || sStrg.GetChar( nPos )>ASCII_9) )
+ nPos--;
+ // muss ggf. noch Platz f"ur eine weitere (f"uhrende) Ziffer
+ // geschaffen werden ?
+ if( nPos==-1 )
+ {
+ ShiftString( sStrg,0 );
+ // f"uhrende 1 einf"ugen: z.B. 99.99 f"ur 0.0
+ sStrg.SetChar( 0, '1' );
+ bOverflow = TRUE;
+ }
+ else
+ {
+ // ist die zu rundende Position eine Ziffer ?
+ sal_Unicode c2 = sStrg.GetChar( nPos );
+ if( c2 >= ASCII_0 && c2 <= ASCII_9 )
+ {
+ // muss eine 9 gerundet werden? Falls: Ja --> rekursiver Aufruf
+ if( c2 == ASCII_9 )
+ {
+ sStrg.SetChar( nPos, '0' );
+ StrRoundDigit( sStrg,nPos-1,bOverflow );
+ }
+ else
+ sStrg.SetChar( nPos, c2+1 );
+ }
+ else
+ {
+ // --> Nein, d.h. Platz f"ur Ziffer schaffen: z.B. -99.99 f"ur #0.0
+ // da gerundet wird MUSS es immer eine g"ultige Position
+ // nPos+1 geben !
+ ShiftString( sStrg,nPos+1 );
+ // f"uhrende 1 einf"ugen
+ sStrg.SetChar( nPos+1, '1' );
+ bOverflow = TRUE;
+ }
+ }
+}
+
+// rundet in einem String die Ziffer an der angegebenen Stelle
+void SbxBasicFormater::StrRoundDigit( String& sStrg, short nPos )
+{
+ BOOL bOverflow;
+
+ StrRoundDigit( sStrg,nPos,bOverflow );
+}
+
+// parse den Formatstring von der "ubergebenen Position zur"uck
+// und l"osche ggf. "uberf"ussige 0en, z.B. 4.50 in 0.0#
+void SbxBasicFormater::ParseBack( String& sStrg, const String& sFormatStrg,
+ short nFormatPos )
+{
+ // WICHTIG: nFormatPos kann auch negativ sein, in diesem Fall Aufruf ignorieren
+ for( short i=nFormatPos;
+ i>0 && sFormatStrg.GetChar( i ) == '#' && sStrg.GetChar( (sStrg.Len()-1) ) == '0';
+ i-- )
+ { sStrg.Erase( sStrg.Len()-1 ); }
+}
+
+#ifdef _with_sprintf
+
+/*
+ Bemerkung:
+ Zahl wird mit maximaler (sinnvollen) Genauigkeit in einen String
+ umgewandelt (mit sprintf()), dieser String wird dann im Schleifen-
+ Durchlauf nach der entsprechenden Ziffer durchsucht.
+*/
+// initialisiert die Daten der Klasse um einen Scan-Durchlauf durchzuf"uhren
+void SbxBasicFormater::InitScan( double _dNum )
+{
+ char sBuffer[ MAX_DOUBLE_BUFFER_LENGTH ];
+
+ dNum = _dNum;
+ InitExp( get_number_of_digits( dNum ) );
+ // maximal 15 Nachkomma-Stellen, Format-Beispiel: -1.234000000000000E-001
+ /*int nCount =*/ sprintf( sBuffer,"%+22.15lE",dNum );
+ sSciNumStrg.AssignAscii( sBuffer );
+}
+
+void SbxBasicFormater::InitExp( double _dNewExp )
+{
+ char sBuffer[ MAX_DOUBLE_BUFFER_LENGTH ];
+ // bestimme den Exponenten (kann immer GENAU durch int dargestellt werden)
+ nNumExp = (short)_dNewExp;
+ // und dessen String
+ /*int nCount =*/ sprintf( sBuffer,"%+i",nNumExp );
+ sNumExpStrg.AssignAscii( sBuffer );
+ // bestimme die Anzahl der Stellen im Exponenten
+ nExpExp = (short)get_number_of_digits( (double)nNumExp );
+}
+
+// bestimmt die Ziffer an der angegebenen Stelle (gedacht zur Anwendung im
+// Scan-Durchlauf)
+short SbxBasicFormater::GetDigitAtPosScan( short nPos, BOOL& bFoundFirstDigit )
+{
+ // Versuch eine gr"ossere Ziffer zu lesen,
+ // z.B. Stelle 4 in 1.234,
+ // oder eine Ziffer ausserhalb der Aufl"osung der
+ // Zahl (double) zu lesen (z.B. max. 15 Stellen).
+ if( nPos>nNumExp || abs(nNumExp-nPos)>MAX_NO_OF_DIGITS )
+ return _NO_DIGIT;
+ // bestimme den Index der Stelle in dem Number-String:
+ // "uberlese das Vorzeichen
+ USHORT no = 1;
+ // falls notwendig den Dezimal-Punkt "uberlesen:
+ if( nPos<nNumExp )
+ no++;
+ no += nNumExp-nPos;
+ // Abfrage der ersten (g"ultigen) Ziffer der Zahl --> Flag setzen
+ if( nPos==nNumExp )
+ bFoundFirstDigit = TRUE;
+ return (short)(sSciNumStrg.GetChar( no ) - ASCII_0);
+}
+
+short SbxBasicFormater::GetDigitAtPosExpScan( short nPos, BOOL& bFoundFirstDigit )
+{
+ // ist die abgefragte Stelle zu gross f"ur den Exponenten ?
+ if( nPos>nExpExp )
+ return -1;
+
+ // bestimme den Index der Stelle in dem Number-String:
+ // "uberlese das Vorzeichen
+ USHORT no = 1;
+ no += nExpExp-nPos;
+ // Abfrage der ersten (g"ultigen) Ziffer der Zahl --> Flag setzen
+ if( nPos==nExpExp )
+ bFoundFirstDigit = TRUE;
+ return (short)(sNumExpStrg.GetChar( no ) - ASCII_0);
+}
+
+// es kann ein Wert f"ur den Exponent angegeben werden, da ggf. die
+// Zahl ggf. NICHT normiert (z.B. 1.2345e-03) dargestellt werden soll,
+// sondern eventuell 123.345e-3 !
+short SbxBasicFormater::GetDigitAtPosExpScan( double dNewExponent, short nPos,
+ BOOL& bFoundFirstDigit )
+{
+ // neuer Exponent wurde "ubergeben, aktualisiere
+ // die tempor"aren Klassen-Variablen
+ InitExp( dNewExponent );
+ // und jetzt die Stelle bestimmen
+ return GetDigitAtPosExpScan( nPos,bFoundFirstDigit );
+}
+
+#else
+
+/* Probleme mit der folgenden Methode:
+
+TODO: ggf einen 'intelligenten' Peek-Parser um Rundungsfehler bei
+ double-Zahlen herauszufinden ? z.B. f"ur 0.00115 #.#e-000
+
+ Problem mit: format( 0.3345 , "0.000" )
+ Problem mit: format( 0.00115 , "0.0000" )
+
+*/
+// liefert die Ziffer an der angegebenen '10er System'-Position,
+// d.h. positive nPos f"ur Stellen vor dem Komma und negative
+// f"ur Stellen nach dem Komma.
+// nPos==0 bedeutet erste Stelle vor dem Komma, also 10^0.
+// liefert 0..9 f"ur g"ultige Ziffern und -1 f"ur nicht vorhanden,
+// d.h. falls die "ubergebene Zahl zu klein ist
+// (z.B. Stelle 5 bei dNumber=123).
+// Weiter wird in dNextNumber die um die f"uhrenden Stellen
+// (bis nPos) gek"urzte Zahl zur"uckgeliefert, z.B.
+// GetDigitAtPos( 3434.565 , 2 , dNewNumber ) --> dNewNumber = 434.565
+// dies kann f"ur Schleifenabarbeitung g"unstiger sein, d.h.
+// die Zahlen immer von der gr"ossten Stelle abarbeiten/scanen.
+// In bFoundFirstDigit wird ggf. ein Flag gesetzt wenn eine Ziffer
+// gefunden wurde, dies wird dazu verwendet um 'Fehler' beim Parsen 202
+// zu vermeiden, die
+//
+// ACHTUNG: anscheinend gibt es manchmal noch Probleme mit Rundungs-Fehlern!
+short SbxBasicFormater::GetDigitAtPos( double dNumber, short nPos,
+ double& dNextNumber, BOOL& bFoundFirstDigit )
+// ACHTUNG: nPos kann auch negativ werden, f"ur Stellen nach dem Dezimal-Punkt
+{
+ double dTemp = dNumber;
+ double dDigit,dPos;
+ short nMaxDigit;
+
+ // erst mal aus der Zahl eine positive Zahl machen:
+ dNumber = fabs( dNumber );
+ dPos = (double)nPos;
+
+ // "uberpr"ufe ob Zahl zu klein f"ur angegebene Stelle ist
+ nMaxDigit = (short)get_number_of_digits( dNumber );
+ // f"uhrende Ziffern 'l"oschen'
+ // Bem.: Fehler nur bei Zahlen gr"osser 0, d.h. bei Ziffern vor dem
+ // Dezimal-Punkt
+ if( nMaxDigit<nPos && !bFoundFirstDigit && nPos>=0 )
+ return _NO_DIGIT;
+ // Ziffer gefunden, setze Flag:
+ bFoundFirstDigit = TRUE;
+ for( short i=nMaxDigit; i>=nPos; i-- )
+ {
+ double dI = (double)i;
+ double dTemp1 = pow( 10.0,dI );
+ // pr"apariere nun die gesuchte Ziffer:
+ dDigit = floor( pow( 10.0,log10( fabs( dNumber ) )-dI ) );
+ dNumber -= dTemp1 * dDigit;
+ }
+ // Zuweisung f"ur optimierte Schleifen-Durchl"aufe
+ dNextNumber = dNumber;
+ // und zum Schluss noch die float-Rundungsungenauigkeiten heraus filtern
+ return RoundDigit( dDigit );
+}
+
+// rundet eine double-Zahl zwischen 0 und 9 auf die genaue
+// Integer-Zahl, z.B. 2.8 -> 3 und 2.2 -> 2
+short SbxBasicFormater::RoundDigit( double dNumber )
+{
+ // ist der Wertebereich g"ultig ?
+ if( dNumber<0.0 || dNumber>10.0 )
+ return -1;
+ short nTempHigh = (short)(dNumber+0.5); // ggf. floor( )
+ return nTempHigh;
+}
+
+#endif
+
+// kopiert den entsprechenden Teil des Format-Strings, falls vorhanden,
+// und liefert diesen zur"uck.
+// Somit wird ein neuer String erzeugt, der vom Aufrufer wieder freigegeben
+// werden muss
+String SbxBasicFormater::GetPosFormatString( const String& sFormatStrg, BOOL & bFound )
+{
+ bFound = FALSE; // default...
+ USHORT nPos = sFormatStrg.Search( FORMAT_SEPARATOR );
+
+ if( nPos!=STRING_NOTFOUND )
+ {
+ bFound = TRUE;
+ // der Format-String f"ur die positiven Zahlen ist alles
+ // vor dem ersten ';'
+ return sFormatStrg.Copy( 0,nPos );
+ }
+ // kein ; gefunden, liefere Leerstring
+ String aRetStr;
+ aRetStr.AssignAscii( EMPTYFORMATSTRING );
+ return aRetStr;
+}
+
+// siehe auch GetPosFormatString()
+String SbxBasicFormater::GetNegFormatString( const String& sFormatStrg, BOOL & bFound )
+{
+ bFound = FALSE; // default...
+ USHORT nPos = sFormatStrg.Search( FORMAT_SEPARATOR );
+
+ if( nPos!=STRING_NOTFOUND )
+ {
+ // der Format-String f"ur die negative Zahlen ist alles
+ // zwischen dem ersten und dem zweiten ';'.
+ // Daher: hole erst mal alles nach dem ersten ';'
+ String sTempStrg = sFormatStrg.Copy( nPos+1 );
+ // und suche darin ggf. ein weiteres ';'
+ nPos = sTempStrg.Search( FORMAT_SEPARATOR );
+ bFound = TRUE;
+ if( nPos==STRING_NOTFOUND )
+ // keins gefunden, liefere alles...
+ return sTempStrg;
+ else
+ // ansonsten den String zwischen den beiden ';' liefern
+ return sTempStrg.Copy( 0,nPos );
+ }
+ String aRetStr;
+ aRetStr.AssignAscii( EMPTYFORMATSTRING );
+ return aRetStr;
+}
+
+// siehe auch GetPosFormatString()
+String SbxBasicFormater::Get0FormatString( const String& sFormatStrg, BOOL & bFound )
+{
+ bFound = FALSE; // default...
+ USHORT nPos = sFormatStrg.Search( FORMAT_SEPARATOR );
+
+ if( nPos!=STRING_NOTFOUND )
+ {
+ // der Format-String f"ur die Null ist alles
+ // was nach dem zweiten ';' kommt.
+ // Daher: hole erst mal alles nach dem ersten ';'
+ String sTempStrg = sFormatStrg.Copy( nPos+1 );
+ // und suche darin ggf. ein weiteres ';'
+ nPos = sTempStrg.Search( FORMAT_SEPARATOR );
+ if( nPos!=STRING_NOTFOUND )
+ {
+ bFound = TRUE;
+ sTempStrg = sTempStrg.Copy( nPos+1 );
+ nPos = sTempStrg.Search( FORMAT_SEPARATOR );
+ if( nPos==STRING_NOTFOUND )
+ // keins gefunden, liefere alles...
+ return sTempStrg;
+ else
+ return sTempStrg.Copy( 0,nPos );
+ }
+ }
+ // kein ; gefunden, liefere Leerstring
+ String aRetStr;
+ aRetStr.AssignAscii( EMPTYFORMATSTRING );
+ return aRetStr;
+}
+
+// siehe auch GetPosFormatString()
+String SbxBasicFormater::GetNullFormatString( const String& sFormatStrg, BOOL & bFound )
+{
+ bFound = FALSE; // default...
+ USHORT nPos = sFormatStrg.Search( FORMAT_SEPARATOR );
+
+ if( nPos!=STRING_NOTFOUND )
+ {
+ // der Format-String f"ur die Null ist alles
+ // was nach dem dritten ';' kommt.
+ // Daher: hole erst mal alles nach dem ersten ';'
+ String sTempStrg = sFormatStrg.Copy( nPos+1 );
+ // und suche darin ggf. ein weiteres ';'
+ nPos = sTempStrg.Search( FORMAT_SEPARATOR );
+ if( nPos!=STRING_NOTFOUND )
+ {
+ // und suche nun nach dem dritten ';'
+ sTempStrg = sTempStrg.Copy( nPos+1 );
+ nPos = sTempStrg.Search( FORMAT_SEPARATOR );
+ if( nPos!=STRING_NOTFOUND )
+ {
+ bFound = TRUE;
+ return sTempStrg.Copy( nPos+1 );
+ }
+ }
+ }
+ // kein ; gefunden, liefere Leerstring
+ String aRetStr;
+ aRetStr.AssignAscii( EMPTYFORMATSTRING );
+ return aRetStr;
+}
+
+// analysiert den Format-String, liefert Wert <> 0 falls ein Fehler
+// aufgetreten ist
+short SbxBasicFormater::AnalyseFormatString( const String& sFormatStrg,
+ short& nNoOfDigitsLeft, short& nNoOfDigitsRight,
+ short& nNoOfOptionalDigitsLeft,
+ short& nNoOfExponentDigits, short& nNoOfOptionalExponentDigits,
+ BOOL& bPercent, BOOL& bCurrency, BOOL& bScientific,
+ BOOL& bGenerateThousandSeparator,
+ short& nMultipleThousandSeparators )
+{
+ USHORT nLen;
+ short nState = 0;
+
+ nLen = sFormatStrg.Len();
+ // initialisiere alle Z"ahler und Flags
+ nNoOfDigitsLeft = 0;
+ nNoOfDigitsRight = 0;
+ nNoOfOptionalDigitsLeft = 0;
+ nNoOfExponentDigits = 0;
+ nNoOfOptionalExponentDigits = 0;
+ bPercent = FALSE;
+ bCurrency = FALSE;
+ bScientific = FALSE;
+ // ab 11.7.97: sobald ein Komma in dem Format String gefunden wird,
+ // werden alle 3 Zehnerpotenzen markiert (d.h. tausender, milionen, ...)
+ // bisher wurde nur an den gesetzten Position ein Tausender-Separator
+ // ausgegeben oder wenn ein @ im Format-String stand.
+ // Dies war ein Missverstaendnis der VB Kompatiblitaet.
+ bGenerateThousandSeparator = sFormatStrg.Search( ',' ) != STRING_NOTFOUND;
+ nMultipleThousandSeparators = 0;
+ // und untersuche den Format-String nach den gew"unschten Informationen
+ for( USHORT i=0; i<nLen; i++ )
+ {
+ sal_Unicode c = sFormatStrg.GetChar( i );
+ switch( c ) {
+ case '#':
+ case '0':
+ if( nState==0 )
+ {
+ nNoOfDigitsLeft++;
+// TODO hier ggf. bessere Fehler-"Uberpr"ufung der Mantisse auf g"ultige Syntax (siehe Grammatik)
+ // ACHTUNG: 'undefiniertes' Verhalten falls # und 0
+ // gemischt werden !!!
+ // BEMERKUNG: eigentlich sind #-Platzhalter bei Scientific
+ // Darstellung vor dem Dezimal-Punkt sinnlos !
+ if( c=='#' )
+ nNoOfOptionalDigitsLeft++;
+ }
+ else if( nState==1 )
+ nNoOfDigitsRight++;
+ else if( nState==-1 ) // suche 0 im Exponent
+ {
+ if( c=='#' ) // # schaltet den Zustand weiter
+ {
+ nNoOfOptionalExponentDigits++;
+ nState = -2;
+ }
+ nNoOfExponentDigits++;
+ }
+ else if( nState==-2 ) // suche # im Exponent
+ {
+ if( c=='0' )
+ // ERROR: 0 nach # im Exponent ist NICHT erlaubt !!
+ return -4;
+ nNoOfOptionalExponentDigits++;
+ nNoOfExponentDigits++;
+ }
+ break;
+ case '.':
+ nState++;
+ if( nState>1 )
+ return -1; // ERROR: zu viele Dezimal-Punkte
+ break;
+ case '%':
+ bPercent = TRUE;
+ /* old:
+ bPercent++;
+ if( bPercent>1 )
+ return -2; // ERROR: zu viele Prozent-Zeichen
+ */
+ break;
+ case '(':
+ bCurrency = TRUE;
+ break;
+ case ',':
+ {
+ sal_Unicode ch = sFormatStrg.GetChar( i+1 );
+ // vorl"aufig wird NUR auf zwei aufeinanderfolgede
+ // Zeichen gepr"uft
+ if( ch!=0 && (ch==',' || ch=='.') )
+ nMultipleThousandSeparators++;
+ } break;
+ case 'e':
+ case 'E':
+ // #i13821 not when no digits before
+ if( nNoOfDigitsLeft > 0 || nNoOfDigitsRight > 0 )
+ {
+ nState = -1; // breche jetzt das Z"ahlen der Stellen ab
+ bScientific = TRUE;
+ }
+ /* old:
+ bScientific++;
+ if( bScientific>1 )
+ return -3; // ERROR: zu viele Exponent-Zeichen
+ */
+ break;
+ // EIGENES Kommando-Zeichen, das die Erzeugung der
+ // Tausender-Trennzeichen einschaltet
+ case '\\':
+ // Ignore next char
+ i++;
+ break;
+ case CREATE_1000SEP_CHAR:
+ bGenerateThousandSeparator = TRUE;
+ break;
+ }
+ }
+ return 0;
+}
+
+// das Flag bCreateSign zeigt an, dass bei der Mantisse ein Vorzeichen
+// erzeugt werden soll
+void SbxBasicFormater::ScanFormatString( double dNumber,
+ const String& sFormatStrg, String& sReturnStrg,
+ BOOL bCreateSign )
+{
+ short /*nErr,*/nNoOfDigitsLeft,nNoOfDigitsRight,nNoOfOptionalDigitsLeft,
+ nNoOfExponentDigits,nNoOfOptionalExponentDigits,
+ nMultipleThousandSeparators;
+ BOOL bPercent,bCurrency,bScientific,bGenerateThousandSeparator;
+
+ // Initialisiere den Return-String
+ sReturnStrg = String();
+
+ // analysiere den Format-String, d.h. bestimme folgende Werte:
+ /*
+ - Anzahl der Ziffern vor dem Komma
+ - Anzahl der Ziffern nach dem Komma
+ - optionale Ziffern vor dem Komma
+ - Anzahl der Ziffern im Exponent
+ - optionale Ziffern im Exponent
+ - Prozent-Zeichen gefunden ?
+ - () f"ur negatives Vorzeichen ?
+ - Exponetial-Schreibweise ?
+ - sollen Tausender-Separatoren erzeugt werden ?
+ - wird ein Prozent-Zeichen gefunden ? --> dNumber *= 100.0;
+ - gibt es aufeinanderfolgende Tausender-Trennzeichen ?
+ ,, oder ,. --> dNumber /= 1000.0;
+ - sonstige Fehler ? mehrfache Dezimalpunkte, E's, etc.
+ --> Fehler werden zur Zeit einfach ignoriert
+ */
+ /*nErr =*/ AnalyseFormatString( sFormatStrg,nNoOfDigitsLeft,nNoOfDigitsRight,
+ nNoOfOptionalDigitsLeft,nNoOfExponentDigits,
+ nNoOfOptionalExponentDigits,
+ bPercent,bCurrency,bScientific,bGenerateThousandSeparator,
+ nMultipleThousandSeparators );
+ /* es werden alle Fehler ignoriert, wie in Visual-Basic
+ if( nErr!=0 )
+ {
+ char sBuffer[512];
+
+ //sprintf( sBuffer,"bad format-string >%s< err=%i",sFormatStrg,nErr );
+ strcpy( sBuffer,"bad format-string" );
+ ShowError( sBuffer );
+ }
+ else
+ */
+ {
+ // Spezialbehandlung f"ur Spezialzeichen
+ if( bPercent )
+ dNumber *= 100.0;
+// TODO: diese Vorgabe (,, oder ,.) ist NICHT Visual-Basic kompatibel !
+ // Frage: soll das hier stehen bleiben (Anforderungen) ?
+ if( nMultipleThousandSeparators )
+ dNumber /= 1000.0;
+
+ // einige Arbeits-Variablen
+ double dExponent;
+ short i,nLen;
+ short nState,nDigitPos,nExponentPos,nMaxDigit,nMaxExponentDigit;
+ BOOL bFirstDigit,bFirstExponentDigit,bFoundFirstDigit,
+ bIsNegative,bZeroSpaceOn, bSignHappend,bDigitPosNegative;
+
+ // Initialisierung der Arbeits-Variablen
+ bSignHappend = FALSE;
+ bFoundFirstDigit = FALSE;
+ bIsNegative = dNumber<0.0;
+ nLen = sFormatStrg.Len();
+ dExponent = get_number_of_digits( dNumber );
+ nExponentPos = 0;
+ nMaxExponentDigit = 0;
+ nMaxDigit = (short)dExponent;
+ bDigitPosNegative = false;
+ if( bScientific )
+ {
+ //if( nNoOfOptionalDigitsLeft>0 )
+ // ShowError( "# in scientific-format in front of the decimal-point has no effect" );
+ // beim Exponent ggf. "uberz"ahlige Stellen vor dem Komma abziehen
+ dExponent = dExponent - (double)(nNoOfDigitsLeft-1);
+ nDigitPos = nMaxDigit;
+ nMaxExponentDigit = (short)get_number_of_digits( dExponent );
+ nExponentPos = nNoOfExponentDigits-1 - nNoOfOptionalExponentDigits;
+ }
+ else
+ {
+ nDigitPos = nNoOfDigitsLeft-1; // Z"ahlweise f"angt bei 0 an, 10^0
+ // hier ben"otigt man keine Exponent-Daten !
+ bDigitPosNegative = (nDigitPos < 0);
+ }
+ bFirstDigit = TRUE;
+ bFirstExponentDigit = TRUE;
+ nState = 0; // 0 --> Mantisse; 1 --> Exponent
+ bZeroSpaceOn = 0;
+
+
+#ifdef _with_sprintf
+ InitScan( dNumber );
+#endif
+ // scanne jetzt den Format-String:
+ sal_Unicode cForce = 0;
+ for( i=0; i<nLen; i++ )
+ {
+ sal_Unicode c;
+ if( cForce )
+ {
+ c = cForce;
+ cForce = 0;
+ }
+ else
+ {
+ c = sFormatStrg.GetChar( i );
+ }
+ switch( c ) {
+ case '0':
+ case '#':
+ if( nState==0 )
+ {
+ // Behandlung der Mantisse
+ if( bFirstDigit )
+ {
+ //org:bFirstDigit = FALSE;
+ // ggf. Vorzeichen erzeugen
+ // Bem.: bei bCurrency soll das negative
+ // Vorzeichen durch () angezeigt werden
+ if( bIsNegative && !bCreateSign/*!bCurrency*/ && !bSignHappend )
+ {
+ // nur einmal ein Vorzeichen ausgeben
+ bSignHappend = TRUE;
+ StrAppendChar( sReturnStrg,'-' );
+ }
+ // hier jetzt "uberz"ahlige Stellen ausgeben,
+ // d.h. vom Format-String nicht erfasste Stellen
+ if( nMaxDigit>nDigitPos )
+ {
+ for( short j=nMaxDigit; j>nDigitPos; j-- )
+ {
+ short nTempDigit;
+#ifdef _with_sprintf
+ AppendDigit( sReturnStrg,nTempDigit = GetDigitAtPosScan( j,bFoundFirstDigit ) );
+#else
+ AppendDigit( sReturnStrg,nTempDigit = GetDigitAtPos( dNumber,j,dNumber,bFoundFirstDigit ) );
+#endif
+ // wurde wirklich eine Ziffer eingefuegt ?
+ if( nTempDigit!=_NO_DIGIT )
+ // jetzt wurde wirklich eine Ziffer ausgegeben, Flag setzen
+ bFirstDigit = FALSE;
+ // muss ggf. ein Tausender-Trennzeichen erzeugt werden?
+ if( bGenerateThousandSeparator && ( c=='0' || nMaxDigit>=nDigitPos ) && j>0 && (j % 3 == 0) )
+ StrAppendChar( sReturnStrg,cThousandSep );
+ }
+ }
+ }
+ // muss f"ur eine leere Stelle eventuell eine 0 ausgegeben werden ?
+ if( nMaxDigit<nDigitPos && ( c=='0' || bZeroSpaceOn ) )
+ {
+ AppendDigit( sReturnStrg,0 ); // Ja
+ // jetzt wurde wirklich eine Ziffer ausgegeben, Flag setzen
+ bFirstDigit = FALSE;
+ bZeroSpaceOn = 1;
+ // BEM.: bei Visual-Basic schaltet die erste 0 f"ur alle
+ // nachfolgenden # (bis zum Dezimal-Punkt) die 0 ein,
+ // dieses Verhalten wird hier mit dem Flag simmuliert.
+ // muss ggf. ein Tausender-Trennzeichen erzeugt werden?
+ if( bGenerateThousandSeparator && ( c=='0' || nMaxDigit>=nDigitPos ) && nDigitPos>0 && (nDigitPos % 3 == 0) )
+ StrAppendChar( sReturnStrg,cThousandSep );
+ }
+ else
+ {
+ short nTempDigit;
+#ifdef _with_sprintf
+ AppendDigit( sReturnStrg,nTempDigit = GetDigitAtPosScan( nDigitPos,bFoundFirstDigit ) );
+#else
+ AppendDigit( sReturnStrg,nTempDigit = GetDigitAtPos( dNumber,nDigitPos,dNumber,bFoundFirstDigit ) );
+#endif
+ // wurde wirklich eine Ziffer eingefuegt ?
+ if( nTempDigit!=_NO_DIGIT )
+ // jetzt wurde wirklich eine Ziffer ausgegeben, Flag setzen
+ bFirstDigit = FALSE;
+ // muss ggf. ein Tausender-Trennzeichen erzeugt werden?
+ if( bGenerateThousandSeparator && ( c=='0' || nMaxDigit>=nDigitPos ) && nDigitPos>0 && (nDigitPos % 3 == 0) )
+ StrAppendChar( sReturnStrg,cThousandSep );
+ }
+ // und Position aktualisieren
+ nDigitPos--;
+ }
+ else
+ {
+ // Behandlung des Exponenten
+ if( bFirstExponentDigit )
+ {
+ // Vorzeichen wurde schon bei e/E ausgegeben
+ bFirstExponentDigit = FALSE;
+ if( nMaxExponentDigit>nExponentPos )
+ // hier jetzt "uberz"ahlige Stellen ausgeben,
+ // d.h. vom Format-String nicht erfasste Stellen
+ {
+ for( short j=nMaxExponentDigit; j>nExponentPos; j-- )
+ {
+#ifdef _with_sprintf
+ AppendDigit( sReturnStrg,GetDigitAtPosExpScan( dExponent,j,bFoundFirstDigit ) );
+#else
+ AppendDigit( sReturnStrg,GetDigitAtPos( dExponent,j,dExponent,bFoundFirstDigit ) );
+#endif
+ }
+ }
+ }
+ // muss f"ur eine leere Stelle eventuell eine 0 ausgegeben werden ?
+ if( nMaxExponentDigit<nExponentPos && c=='0' )
+ AppendDigit( sReturnStrg,0 ); // Ja
+ else
+#ifdef _with_sprintf
+ AppendDigit( sReturnStrg,GetDigitAtPosExpScan( dExponent,nExponentPos,bFoundFirstDigit ) );
+#else
+ AppendDigit( sReturnStrg,GetDigitAtPos( dExponent,nExponentPos,dExponent,bFoundFirstDigit ) );
+#endif
+ nExponentPos--;
+ }
+ break;
+ case '.':
+ if( bDigitPosNegative ) // #i13821: If no digits before .
+ {
+ bDigitPosNegative = false;
+ nDigitPos = 0;
+ cForce = '#';
+ i-=2;
+ break;
+ }
+ // gebe Komma aus
+ StrAppendChar( sReturnStrg,cDecPoint );
+ break;
+ case '%':
+ // ggf. "uberf"ussige 0en l"oschen, z.B. 4.500e4 in 0.0##e-00
+ ParseBack( sReturnStrg,sFormatStrg,i-1 );
+ // gebe Prozent-Zeichen aus
+ sReturnStrg.Insert('%');
+ break;
+ case 'e':
+ case 'E':
+ // muss Mantisse noch gerundet werden, bevor der Exponent angezeigt wird ?
+ {
+ // gibt es ueberhaupt eine Mantisse ?
+ if( bFirstDigit )
+ {
+ // anscheinend nicht, d.h. ungueltiger Format String, z.B. E000.00
+ // d.h. ignoriere diese e bzw. E Zeichen
+ // ggf. einen Fehler (wie Visual Basic) ausgeben ?
+
+ // #i13821: VB 6 behaviour
+ StrAppendChar( sReturnStrg,c );
+ break;
+ }
+
+ BOOL bOverflow = FALSE;
+#ifdef _with_sprintf
+ short nNextDigit = GetDigitAtPosScan( nDigitPos,bFoundFirstDigit );
+#else
+ short nNextDigit = GetDigitAtPos( dNumber,nDigitPos,dNumber,bFoundFirstDigit );
+#endif
+ if( nNextDigit>=5 )
+ StrRoundDigit( sReturnStrg,sReturnStrg.Len()-1,bOverflow );
+ if( bOverflow )
+ {
+ // es wurde eine f"uhrende 9 gerundet, d.h.
+ // verschiebe den Dezimal-Punkt um eine Stelle nach links
+ LeftShiftDecimalPoint( sReturnStrg );
+ // und l"osche die letzte Ziffer, diese wird
+ // duch die f"uhrende 1 ersetzt:
+ sReturnStrg.SetChar( sReturnStrg.Len()-1 , 0 );
+ // der Exponent muss um 1 erh"oht werden,
+ // da der Dezimalpunkt verschoben wurde
+ dExponent += 1.0;
+ }
+ // ggf. "uberf"ussige 0en l"oschen, z.B. 4.500e4 in 0.0##e-00
+ ParseBack( sReturnStrg,sFormatStrg,i-1 );
+ }
+ // "andere Zustand des Scanners
+ nState++;
+ // gebe Exponent-Zeichen aus
+ StrAppendChar( sReturnStrg,c );
+ // i++; // MANIPULATION der Schleifen-Variable !
+ c = sFormatStrg.GetChar( ++i );
+ // und gebe Vorzeichen / Exponent aus
+ if( c!=0 )
+ {
+ if( c=='-' )
+ {
+ // falls Exponent < 0 gebe - aus
+ if( dExponent<0.0 )
+ StrAppendChar( sReturnStrg,'-' );
+ }
+ else if( c=='+' )
+ {
+ // gebe auf jeden Fall das Vorzeichen des Exponenten aus !
+ if( dExponent<0.0 )
+ StrAppendChar( sReturnStrg,'-' );
+ else
+ StrAppendChar( sReturnStrg,'+' );
+ }
+ //else
+ // ShowError( "operator e/E did not find + or -" );
+ }
+ //else
+ // ShowError( "operator e/E ended with 0" );
+ break;
+ case ',':
+ // ACHTUNG: nur falls Zahl bisher ausgegeben wurde
+ // das Zeichen ausgeben
+ ////--> Siehe Kommentar vom 11.7. in AnalyseFormatString()
+ ////if( !bFirstDigit )
+ //// // gebe Tausender-Trennzeichen aus
+ //// StrAppendChar( sReturnStrg,cThousandSep );
+ break;
+ case ';':
+ break;
+ case '(':
+ case ')':
+ // ggf. "uberf"ussige 0en l"oschen, z.B. 4.500e4 in 0.0##e-00
+ ParseBack( sReturnStrg,sFormatStrg,i-1 );
+ if( bIsNegative )
+ StrAppendChar( sReturnStrg,c );
+ break;
+ case '$':
+ // den String fuer die Waehrung dranhengen:
+ sReturnStrg += sCurrencyStrg;
+ break;
+ case ' ':
+ case '-':
+ case '+':
+ // ggf. "uberf"ussige 0en l"oschen, z.B. 4.500e4 in 0.0##e-00
+ ParseBack( sReturnStrg,sFormatStrg,i-1 );
+ // gebe das jeweilige Zeichen direkt aus
+ StrAppendChar( sReturnStrg,c );
+ break;
+ case '\\':
+ // ggf. "uberf"ussige 0en l"oschen, z.B. 4.500e4 in 0.0##e-00
+ // falls Sonderzeichen am Ende oder mitten in
+ // Format-String vorkommen
+ ParseBack( sReturnStrg,sFormatStrg,i-1 );
+ // Sonderzeichen gefunden, gebe N"ACHSTES
+ // Zeichen direkt aus (falls es existiert)
+ // i++;
+ c = sFormatStrg.GetChar( ++i );
+ if( c!=0 )
+ StrAppendChar( sReturnStrg,c );
+ //else
+ // ShowError( "operator \\ ended with 0" );
+ break;
+ case CREATE_1000SEP_CHAR:
+ // hier ignorieren, Aktion wurde schon in
+ // AnalyseFormatString durchgef"uhrt
+ break;
+ default:
+ // auch die Zeichen und Ziffern ausgeben (wie in Visual-Basic)
+ if( ( c>='a' && c<='z' ) ||
+ ( c>='A' && c<='Z' ) ||
+ ( c>='1' && c<='9' ) )
+ StrAppendChar( sReturnStrg,c );
+ // else
+ // ignorieren !
+ // ehemals: ShowError( "bad character in format-string" );
+ }
+ }
+ // Format-String wurde vollst"andig gescanned,
+ // muss die letzte Stelle nun gerundet werden ?
+ // Dies hier ist jedoch NUR notwendig, falls das
+ // Zahlenformat NICHT Scientific-Format ist !
+ if( !bScientific )
+ {
+#ifdef _with_sprintf
+ short nNextDigit = GetDigitAtPosScan( nDigitPos,bFoundFirstDigit );
+#else
+ short nNextDigit = GetDigitAtPos( dNumber,nDigitPos,dNumber,bFoundFirstDigit );
+#endif
+ if( nNextDigit>=5 )
+ StrRoundDigit( sReturnStrg,sReturnStrg.Len()-1 );
+ }
+ // und ganz zum Schluss:
+ // ggf. "uberf"ussige 0en l"oschen, z.B. 4.500e4 in 0.0##e-00#,
+ // ABER nur Stellen nach dem Dezimal-Punkt k"onnen gel"oscht werden
+ if( nNoOfDigitsRight>0 )
+ ParseBack( sReturnStrg,sFormatStrg,sFormatStrg.Len()-1 );
+ }
+}
+
+String SbxBasicFormater::BasicFormatNull( String sFormatStrg )
+{
+ BOOL bNullFormatFound;
+ String sNullFormatStrg = GetNullFormatString( sFormatStrg,bNullFormatFound );
+
+ if( bNullFormatFound )
+ return sNullFormatStrg;
+ String aRetStr;
+ aRetStr.AssignAscii( "null" );
+ return aRetStr;
+}
+
+String SbxBasicFormater::BasicFormat( double dNumber, String sFormatStrg )
+{
+ BOOL bPosFormatFound,bNegFormatFound,b0FormatFound;
+
+ // analysiere Format-String auf vordefinierte Formate:
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_GENERALNUMBER ) )
+ sFormatStrg.AssignAscii( GENERALNUMBER_FORMAT );
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_CURRENCY ) )
+ sFormatStrg = sCurrencyFormatStrg; // old: CURRENCY_FORMAT;
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_FIXED ) )
+ sFormatStrg.AssignAscii( FIXED_FORMAT );
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_STANDARD ) )
+ sFormatStrg.AssignAscii( STANDARD_FORMAT );
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_PERCENT ) )
+ sFormatStrg.AssignAscii( PERCENT_FORMAT );
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_SCIENTIFIC ) )
+ sFormatStrg.AssignAscii( SCIENTIFIC_FORMAT );
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_YESNO ) )
+ return ( dNumber==0.0 ) ? sNoStrg : sYesStrg ;
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_TRUEFALSE ) )
+ return ( dNumber==0.0 ) ? sFalseStrg : sTrueStrg ;
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_ONOFF ) )
+ return ( dNumber==0.0 ) ? sOffStrg : sOnStrg ;
+
+ // analysiere Format-String auf ';', d.h. Format-Strings f"ur
+ // positive-, negative- und 0-Werte
+ String sPosFormatStrg = GetPosFormatString( sFormatStrg, bPosFormatFound );
+ String sNegFormatStrg = GetNegFormatString( sFormatStrg, bNegFormatFound );
+ String s0FormatStrg = Get0FormatString( sFormatStrg, b0FormatFound );
+ //String sNullFormatStrg = GetNullFormatString( sFormatStrg, bNullFormatFound );
+
+ String sReturnStrg;
+ String sTempStrg;
+
+ if( dNumber==0.0 )
+ {
+ sTempStrg = sFormatStrg;
+ if( b0FormatFound )
+ {
+ // wurde ggf. Leer-String uebergeben ?
+ if( s0FormatStrg.Len() == 0 && bPosFormatFound )
+ // --> Ja, dann verwende String fuer positive Werte
+ sTempStrg = sPosFormatStrg;
+ else
+ sTempStrg = s0FormatStrg;
+ }
+ else if( bPosFormatFound )
+ {
+ // verwende String fuer positive Werte
+ sTempStrg = sPosFormatStrg;
+ }
+ ScanFormatString( dNumber, sTempStrg, sReturnStrg,/*bCreateSign=*/FALSE );
+ }
+ else
+ {
+ if( dNumber<0.0 )
+ {
+ if( bNegFormatFound )
+ {
+ // wurde ggf. Leer-String uebergeben ?
+ if( sNegFormatStrg.Len() == 0 && bPosFormatFound )
+ {
+ // --> Ja, dann verwende String fuer positive Werte
+ // und setzte Minus-Zeichen davor !
+ sTempStrg = String::CreateFromAscii("-");
+ sTempStrg += sPosFormatStrg;
+ }
+ else
+ sTempStrg = sNegFormatStrg;
+ }
+ else
+ sTempStrg = sFormatStrg;
+ // falls KEIN Format-String speziell f"ur negative Werte angegeben
+ // wurde, so soll das Vorzeichen ausgegeben werden
+ ScanFormatString( dNumber, sTempStrg, sReturnStrg,/*bCreateSign=*/bNegFormatFound/*sNegFormatStrg!=EMPTYFORMATSTRING*/ );
+ }
+ else // if( dNumber>0.0 )
+ {
+ ScanFormatString( dNumber,
+ (/*sPosFormatStrg!=EMPTYFORMATSTRING*/bPosFormatFound ? sPosFormatStrg : sFormatStrg),
+ sReturnStrg,/*bCreateSign=*/FALSE );
+ }
+ }
+ return sReturnStrg;
+}
+
+BOOL SbxBasicFormater::isBasicFormat( String sFormatStrg )
+{
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_GENERALNUMBER ) )
+ return TRUE;
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_CURRENCY ) )
+ return TRUE;
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_FIXED ) )
+ return TRUE;
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_STANDARD ) )
+ return TRUE;
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_PERCENT ) )
+ return TRUE;
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_SCIENTIFIC ) )
+ return TRUE;
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_YESNO ) )
+ return TRUE;
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_TRUEFALSE ) )
+ return TRUE;
+ if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_ONOFF ) )
+ return TRUE;
+ return FALSE;
+}
+
diff --git a/basic/source/sbx/sbxint.cxx b/basic/source/sbx/sbxint.cxx
new file mode 100644
index 000000000000..47c38aecb1c2
--- /dev/null
+++ b/basic/source/sbx/sbxint.cxx
@@ -0,0 +1,963 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#include <basic/sbx.hxx>
+#include "sbxconv.hxx"
+
+double ImpRound( double d )
+{
+ return d + ( d < 0 ? -0.5 : 0.5 );
+}
+
+INT16 ImpGetInteger( const SbxValues* p )
+{
+ SbxValues aTmp;
+ INT16 nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ if( p->nUShort > (USHORT) SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else
+ nRes = (INT16) p->nUShort;
+ break;
+ case SbxLONG:
+ if( p->nLong > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else if( p->nLong < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
+ }
+ else
+ nRes = (INT16) p->nLong;
+ break;
+ case SbxULONG:
+ if( p->nULong > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else
+ nRes = (INT16) p->nULong;
+ break;
+ case SbxSINGLE:
+ if( p->nSingle > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else if( p->nSingle < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
+ }
+ else
+ nRes = (INT16) ImpRound( p->nSingle );
+ break;
+ case SbxSALINT64:
+ if( p->nInt64 > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else if( p->nInt64 < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
+ }
+ else
+ nRes = (INT16) p->nInt64;
+ break;
+ case SbxSALUINT64:
+ if( p->uInt64 > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else
+ nRes = (INT16) p->uInt64;
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else if( p->eType == SbxDECIMAL )
+ {
+ dVal = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( dVal );
+ }
+ else
+ dVal = p->nDouble;
+
+ if( dVal > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else if( dVal < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
+ }
+ else
+ nRes = (INT16) ImpRound( dVal );
+ break;
+ }
+ case SbxLPSTR:
+ case SbxSTRING:
+ case SbxBYREF | SbxSTRING:
+ if( !p->pOUString )
+ nRes = 0;
+ else
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else if( d < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
+ }
+ else
+ nRes = (INT16) ImpRound( d );
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetInteger();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger; break;
+
+ // ab hier muss getestet werden
+ case SbxBYREF | SbxLONG:
+ aTmp.nLong = *p->pLong; goto ref;
+ case SbxBYREF | SbxULONG:
+ aTmp.nULong = *p->pULong; goto ref;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ aTmp.nUShort = *p->pUShort; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutInteger( SbxValues* p, INT16 n )
+{
+ SbxValues aTmp;
+start:
+ switch( +p->eType )
+ {
+ // hier muss getestet werden
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxSALUINT64:
+ aTmp.puInt64 = &p->uInt64; goto direct;
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // ab hier nicht mehr
+ case SbxINTEGER:
+ case SbxBOOL:
+ p->nInteger = n; break;
+ case SbxLONG:
+ p->nLong = n; break;
+ case SbxSINGLE:
+ p->nSingle = n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxULONG64:
+ p->nULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxLONG64:
+ p->nLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxCURRENCY:
+ p->nLong64 = ImpDoubleToCurrency( (double)n ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ ImpCreateDecimal( p )->setInt( n );
+ break;
+
+ case SbxLPSTR:
+ case SbxSTRING:
+ case SbxBYREF | SbxSTRING:
+ if( !p->pOUString )
+ p->pOUString = new ::rtl::OUString;
+ ImpCvtNum( (double) n, 0, *p->pOUString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutInteger( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
+ }
+ *p->pChar = (char) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ *p->pInteger = n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ *p->pLong = (INT32) n; break;
+ case SbxBYREF | SbxULONG:
+ if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); *p->puInt64 = 0;
+ }
+ else
+ *p->puInt64 = n;
+ break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) n; break;
+ case SbxBYREF | SbxULONG64:
+ *p->pULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxBYREF | SbxLONG64:
+ *p->pLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxBYREF | SbxCURRENCY:
+ *p->pLong64 = ImpDoubleToCurrency( (double)n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+
+// sal_Int64 / hyper
+
+sal_Int64 ImpDoubleToSalInt64( double d )
+{
+ sal_Int64 nRes;
+ if( d > SbxMAXSALINT64 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALINT64;
+ }
+ else if( d < SbxMINSALINT64 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINSALINT64;
+ }
+ else
+ nRes = (sal_Int64) ImpRound( d );
+ return nRes;
+}
+
+sal_uInt64 ImpDoubleToSalUInt64( double d )
+{
+ sal_uInt64 nRes;
+ if( d > SbxMAXSALUINT64 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALUINT64;
+ }
+ else if( d < 0.0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (sal_uInt64) ImpRound( d );
+ return nRes;
+}
+
+double ImpSalUInt64ToDouble( sal_uInt64 n )
+{
+ double d = 0.0;
+ if( n > SbxMAXSALINT64 )
+ SbxBase::SetError( SbxERR_CONVERSION );
+ else
+ d = (double)(sal_Int64) n;
+ return d;
+}
+
+
+sal_Int64 ImpGetInt64( const SbxValues* p )
+{
+ SbxValues aTmp;
+ sal_Int64 nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort; break;
+ case SbxLONG:
+ nRes = p->nLong; break;
+ case SbxULONG:
+ nRes = (sal_Int64) p->nULong; break;
+ case SbxSINGLE:
+ nRes = ImpDoubleToSalInt64( (double)p->nSingle );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else
+ dVal = p->nDouble;
+
+ nRes = ImpDoubleToSalInt64( dVal );
+ break;
+ }
+ case SbxSALINT64:
+ nRes = p->nInt64; break;
+ case SbxSALUINT64:
+ if( p->uInt64 > SbxMAXSALINT64 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALINT64;
+ }
+ else
+ nRes = (sal_Int64) p->uInt64;
+ break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ nRes = 0;
+ else
+ {
+ ::rtl::OString aOStr = ::rtl::OUStringToOString
+ ( *p->pOUString, RTL_TEXTENCODING_ASCII_US );
+ nRes = aOStr.toInt64();
+ if( nRes == 0 )
+ {
+ // Check if really 0 or invalid conversion
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else
+ nRes = ImpDoubleToSalInt64( d );
+ }
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetInt64();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger; break;
+ case SbxBYREF | SbxLONG:
+ nRes = *p->pLong; break;
+ case SbxBYREF | SbxULONG:
+ nRes = *p->pULong; break;
+ case SbxBYREF | SbxSALINT64:
+ nRes = *p->pnInt64; break;
+
+ // from here the values has to be checked
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ aTmp.nUShort = *p->pUShort; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutInt64( SbxValues* p, sal_Int64 n )
+{
+ SbxValues aTmp;
+
+start:
+ switch( +p->eType )
+ {
+ // Check neccessary
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxULONG64:
+ aTmp.pULong64 = &p->nULong64; goto direct;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ aTmp.pLong64 = &p->nLong64; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxLONG:
+ aTmp.pnInt64 = &p->nInt64; goto direct;
+ case SbxSALUINT64:
+ aTmp.puInt64 = &p->uInt64; goto direct;
+
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // Check not neccessary
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxSINGLE:
+ p->nSingle = (float) n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = (double) n; break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ {
+ if( !p->pOUString )
+ p->pOUString = new ::rtl::OUString;
+
+ ::rtl::OString aOStr = ::rtl::OString::valueOf( n );
+ (*p->pOUString) = ::rtl::OStringToOUString
+ ( aOStr, RTL_TEXTENCODING_ASCII_US );
+ break;
+ }
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutInt64( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
+ }
+ else if( n < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
+ }
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ else if( n < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ if( n > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
+ }
+ else if( n < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
+ }
+ *p->pLong = (INT32) n; break;
+ case SbxBYREF | SbxULONG:
+ if( n > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) n; break;
+ case SbxBYREF | SbxCURRENCY:
+ if( n > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = (sal_Int64) SbxMAXCURR;
+ }
+ else if( n < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = (sal_Int64) SbxMINCURR;
+ }
+ *p->pLong64 = ImpDoubleToCurrency( (double)n ); break;
+
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->puInt64 = (sal_Int64) n; break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+sal_uInt64 ImpGetUInt64( const SbxValues* p )
+{
+ SbxValues aTmp;
+ sal_uInt64 nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort; break;
+ case SbxLONG:
+ nRes = p->nLong; break;
+ case SbxULONG:
+ nRes = (sal_uInt64) p->nULong; break;
+ case SbxSINGLE:
+ nRes = ImpDoubleToSalUInt64( (double)p->nSingle );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else
+ dVal = p->nDouble;
+
+ nRes = ImpDoubleToSalUInt64( dVal );
+ break;
+ }
+ case SbxSALINT64:
+ if( p->nInt64 < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (sal_uInt64) p->nInt64;
+ case SbxSALUINT64:
+ nRes = p->uInt64; break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ nRes = 0;
+ else
+ {
+ ::rtl::OString aOStr = ::rtl::OUStringToOString
+ ( *p->pOUString, RTL_TEXTENCODING_ASCII_US );
+ sal_Int64 n64 = aOStr.toInt64();
+ if( n64 == 0 )
+ {
+ // Check if really 0 or invalid conversion
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXSALUINT64 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALUINT64;
+ }
+ else if( d < 0.0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (sal_uInt64) ImpRound( d );
+ }
+ else if( n64 < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ {
+ nRes = n64;
+ }
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetUInt64();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger; break;
+ case SbxBYREF | SbxLONG:
+ nRes = *p->pLong; break;
+ case SbxBYREF | SbxULONG:
+ nRes = *p->pULong; break;
+ case SbxBYREF | SbxSALUINT64:
+ nRes = *p->puInt64; break;
+
+ // from here the values has to be checked
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ aTmp.nUShort = *p->pUShort; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutUInt64( SbxValues* p, sal_uInt64 n )
+{
+ SbxValues aTmp;
+
+start:
+ switch( +p->eType )
+ {
+ // Check neccessary
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxULONG64:
+ aTmp.pULong64 = &p->nULong64; goto direct;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ aTmp.pLong64 = &p->nLong64; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxLONG:
+ aTmp.pnInt64 = &p->nInt64; goto direct;
+ case SbxSALINT64:
+ aTmp.pnInt64 = &p->nInt64; goto direct;
+ case SbxSINGLE:
+ aTmp.pSingle = &p->nSingle; goto direct;
+ case SbxDATE:
+ case SbxDOUBLE:
+ aTmp.pDouble = &p->nDouble; goto direct;
+
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // Check not neccessary
+ case SbxSALUINT64:
+ p->uInt64 = n; break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ p->pOUString = new ::rtl::OUString;
+ if( n > SbxMAXSALINT64 )
+ SbxBase::SetError( SbxERR_CONVERSION );
+ else
+ {
+ ::rtl::OString aOStr = ::rtl::OString::valueOf( (sal_Int64)n );
+ (*p->pOUString) = ::rtl::OStringToOUString
+ ( aOStr, RTL_TEXTENCODING_ASCII_US );
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutUInt64( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
+ }
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ if( n > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
+ }
+ *p->pLong = (INT32) n; break;
+ case SbxBYREF | SbxULONG:
+ if( n > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
+ }
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pDouble = (float)ImpSalUInt64ToDouble( n ); break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = ImpSalUInt64ToDouble( n ); break;
+ case SbxBYREF | SbxCURRENCY:
+ if( n > SbxMAXSALINT64 || (sal_Int64)n > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = (sal_Int64) SbxMAXCURR;
+ }
+ *p->pLong64 = ImpDoubleToCurrency( (double)(sal_Int64) n ); break;
+
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = n; break;
+ case SbxBYREF | SbxSALINT64:
+ if( n > SbxMAXSALINT64 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pnInt64 = (sal_Int64) n; break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+
diff --git a/basic/source/sbx/sbxlng.cxx b/basic/source/sbx/sbxlng.cxx
new file mode 100644
index 000000000000..1cf2d84061f9
--- /dev/null
+++ b/basic/source/sbx/sbxlng.cxx
@@ -0,0 +1,341 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#include <basic/sbx.hxx>
+#include "sbxconv.hxx"
+
+INT32 ImpGetLong( const SbxValues* p )
+{
+ SbxValues aTmp;
+ INT32 nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort; break;
+ case SbxLONG:
+ nRes = p->nLong; break;
+ case SbxULONG:
+ if( p->nULong > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXLNG;
+ }
+ else
+ nRes = (INT32) p->nULong;
+ break;
+ case SbxSINGLE:
+ if( p->nSingle > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXLNG;
+ }
+ else if( p->nSingle < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINLNG;
+ }
+ else
+ nRes = (INT32) ImpRound( p->nSingle );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxSALINT64:
+ case SbxSALUINT64:
+ case SbxCURRENCY:
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else if( p->eType == SbxSALINT64 )
+ dVal = static_cast< double >(p->nInt64);
+ else if( p->eType == SbxSALUINT64 )
+ dVal = ImpSalUInt64ToDouble( p->uInt64 );
+ else if( p->eType == SbxDECIMAL )
+ {
+ dVal = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( dVal );
+ }
+ else
+ dVal = p->nDouble;
+
+ if( dVal > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXLNG;
+ }
+ else if( dVal < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINLNG;
+ }
+ else
+ nRes = (INT32) ImpRound( dVal );
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ nRes = 0;
+ else
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXLNG;
+ }
+ else if( d < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINLNG;
+ }
+ else
+ nRes = (INT32) ImpRound( d );
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetLong();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger; break;
+ case SbxBYREF | SbxLONG:
+ nRes = *p->pLong; break;
+
+ // ab hier muss getestet werden
+ case SbxBYREF | SbxULONG:
+ aTmp.nULong = *p->pULong; goto ref;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ aTmp.nUShort = *p->pUShort; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutLong( SbxValues* p, INT32 n )
+{
+ SbxValues aTmp;
+
+start:
+ switch( +p->eType )
+ {
+ // Ab hier muss getestet werden
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxULONG64:
+ aTmp.pULong64 = &p->nULong64; goto direct;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ aTmp.pLong64 = &p->nLong64; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxSALUINT64:
+ aTmp.puInt64 = &p->uInt64; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort;
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // ab hier nicht mehr
+ case SbxLONG:
+ p->nLong = n; break;
+ case SbxSINGLE:
+ p->nSingle = (float) n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ ImpCreateDecimal( p )->setLong( n );
+ break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ p->pOUString = new ::rtl::OUString;
+ ImpCvtNum( (double) n, 0, *p->pOUString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutLong( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
+ }
+ else if( n < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
+ }
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ else if( n < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ *p->pLong = n; break;
+ case SbxBYREF | SbxULONG:
+ if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); *p->puInt64 = 0;
+ }
+ else
+ *p->puInt64 = n;
+ break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) n; break;
+ case SbxBYREF | SbxCURRENCY:
+ double d;
+ if( n > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); d = SbxMAXCURR;
+ }
+ else if( n < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); d = SbxMINCURR;
+ }
+ else
+ {
+ d = n;
+ }
+ *p->pLong64 = ImpDoubleToCurrency( d ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
diff --git a/basic/source/sbx/sbxmstrm.cxx b/basic/source/sbx/sbxmstrm.cxx
new file mode 100644
index 000000000000..671c0bc5d1d9
--- /dev/null
+++ b/basic/source/sbx/sbxmstrm.cxx
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * 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 <basic/sbxmstrm.hxx>
+
+SbxDataType SbxMemoryStream::GetType() const
+{
+ return SbxMEMORYSTREAM;
+}
+
+SbxMemoryStream::~SbxMemoryStream()
+{
+}
diff --git a/basic/source/sbx/sbxobj.cxx b/basic/source/sbx/sbxobj.cxx
new file mode 100644
index 000000000000..b2b67fe3774f
--- /dev/null
+++ b/basic/source/sbx/sbxobj.cxx
@@ -0,0 +1,1145 @@
+/*************************************************************************
+ *
+ * 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 <vcl/sound.hxx>
+#include <basic/sbx.hxx>
+#include <basic/sbxbase.hxx>
+#include "sbxres.hxx"
+#include <svl/brdcst.hxx>
+
+TYPEINIT1(SbxMethod,SbxVariable)
+TYPEINIT1(SbxProperty,SbxVariable)
+TYPEINIT2(SbxObject,SbxVariable,SfxListener)
+
+static const char* pNameProp; // Name-Property
+static const char* pParentProp; // Parent-Property
+
+static USHORT nNameHash = 0, nParentHash = 0;
+
+/////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////
+
+SbxObject::SbxObject( const XubString& rClass )
+ : SbxVariable( SbxOBJECT ), aClassName( rClass )
+{
+ aData.pObj = this;
+ if( !nNameHash )
+ {
+ pNameProp = GetSbxRes( STRING_NAMEPROP );
+ pParentProp = GetSbxRes( STRING_PARENTPROP );
+ nNameHash = MakeHashCode( String::CreateFromAscii( pNameProp ) );
+ nParentHash = MakeHashCode( String::CreateFromAscii( pParentProp ) );
+ }
+ SbxObject::Clear();
+ SbxObject::SetName( rClass );
+}
+
+SbxObject::SbxObject( const SbxObject& rObj )
+ : SvRefBase( rObj ), SbxVariable( rObj.GetType() ),
+ SfxListener( rObj )
+{
+ *this = rObj;
+}
+
+SbxObject& SbxObject::operator=( const SbxObject& r )
+{
+ if( &r != this )
+ {
+ SbxVariable::operator=( r );
+ aClassName = r.aClassName;
+ pMethods = new SbxArray;
+ pProps = new SbxArray;
+ pObjs = new SbxArray( SbxOBJECT );
+ // Die Arrays werden kopiert, die Inhalte uebernommen
+ *pMethods = *r.pMethods;
+ *pProps = *r.pProps;
+ *pObjs = *r.pObjs;
+ // Da die Variablen uebernommen wurden, ist dies OK
+ pDfltProp = r.pDfltProp;
+ SetName( r.GetName() );
+ SetFlags( r.GetFlags() );
+ SetModified( TRUE );
+ }
+ return *this;
+}
+
+static void CheckParentsOnDelete( SbxObject* pObj, SbxArray* p )
+{
+ for( USHORT i = 0; i < p->Count(); i++ )
+ {
+ SbxVariableRef& rRef = p->GetRef( i );
+ if( rRef->IsBroadcaster() )
+ pObj->EndListening( rRef->GetBroadcaster(), TRUE );
+ // Hat das Element mehr als eine Referenz und noch einen Listener?
+ if( rRef->GetRefCount() > 1 )
+ {
+ rRef->SetParent( NULL );
+ DBG_ASSERT( !rRef->IsBroadcaster() || rRef->GetBroadcaster().GetListenerCount(), "Object element with dangling parent" );
+ }
+ }
+}
+
+SbxObject::~SbxObject()
+{
+ CheckParentsOnDelete( this, pProps );
+ CheckParentsOnDelete( this, pMethods );
+ CheckParentsOnDelete( this, pObjs );
+}
+
+SbxDataType SbxObject::GetType() const
+{
+ return SbxOBJECT;
+}
+
+SbxClassType SbxObject::GetClass() const
+{
+ return SbxCLASS_OBJECT;
+}
+
+void SbxObject::Clear()
+{
+ pMethods = new SbxArray;
+ pProps = new SbxArray;
+ pObjs = new SbxArray( SbxOBJECT );
+ SbxVariable* p;
+ p = Make( String::CreateFromAscii( pNameProp ), SbxCLASS_PROPERTY, SbxSTRING );
+ p->SetFlag( SBX_DONTSTORE );
+ p = Make( String::CreateFromAscii( pParentProp ), SbxCLASS_PROPERTY, SbxOBJECT );
+ p->ResetFlag( SBX_WRITE );
+ p->SetFlag( SBX_DONTSTORE );
+ pDfltProp = NULL;
+ SetModified( FALSE );
+}
+
+void SbxObject::SFX_NOTIFY( SfxBroadcaster&, const TypeId&,
+ const SfxHint& rHint, const TypeId& )
+{
+ const SbxHint* p = PTR_CAST(SbxHint,&rHint);
+ if( p )
+ {
+ ULONG nId = p->GetId();
+ BOOL bRead = BOOL( nId == SBX_HINT_DATAWANTED );
+ BOOL bWrite = BOOL( nId == SBX_HINT_DATACHANGED );
+ SbxVariable* pVar = p->GetVar();
+ if( bRead || bWrite )
+ {
+ XubString aVarName( pVar->GetName() );
+ USHORT nHash_ = MakeHashCode( aVarName );
+ if( nHash_ == nNameHash
+ && aVarName.EqualsIgnoreCaseAscii( pNameProp ) )
+ {
+ if( bRead )
+ pVar->PutString( GetName() );
+ else
+ SetName( pVar->GetString() );
+ }
+ else if( nHash_ == nParentHash
+ && aVarName.EqualsIgnoreCaseAscii( pParentProp ) )
+ {
+ SbxObject* p_ = GetParent();
+ if( !p_ )
+ p_ = this;
+ pVar->PutObject( p_ );
+ }
+ }
+ }
+}
+
+BOOL SbxObject::IsClass( const XubString& rName ) const
+{
+ return BOOL( aClassName.EqualsIgnoreCaseAscii( rName ) );
+}
+
+SbxVariable* SbxObject::FindUserData( UINT32 nData )
+{
+ if( !GetAll( SbxCLASS_DONTCARE ) )
+ return NULL;
+
+ SbxVariable* pRes = pMethods->FindUserData( nData );
+ if( !pRes )
+ pRes = pProps->FindUserData( nData );
+ if( !pRes )
+ pRes = pObjs->FindUserData( nData );
+ // Search in den Parents?
+ if( !pRes && IsSet( SBX_GBLSEARCH ) )
+ {
+ SbxObject* pCur = this;
+ while( !pRes && pCur->pParent )
+ {
+ // Ich selbst bin schon durchsucht worden!
+ USHORT nOwn = pCur->GetFlags();
+ pCur->ResetFlag( SBX_EXTSEARCH );
+ // Ich suche bereits global!
+ USHORT nPar = pCur->pParent->GetFlags();
+ pCur->pParent->ResetFlag( SBX_GBLSEARCH );
+ pRes = pCur->pParent->FindUserData( nData );
+ pCur->SetFlags( nOwn );
+ pCur->pParent->SetFlags( nPar );
+ pCur = pCur->pParent;
+ }
+ }
+ return pRes;
+}
+
+SbxVariable* SbxObject::Find( const XubString& rName, SbxClassType t )
+{
+#ifdef DBG_UTIL
+ static USHORT nLvl = 0;
+ static const char* pCls[] =
+ { "DontCare","Array","Value","Variable","Method","Property","Object" };
+ ByteString aNameStr1( (const UniString&)rName, RTL_TEXTENCODING_ASCII_US );
+ ByteString aNameStr2( (const UniString&)SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US );
+ DbgOutf( "SBX: Search %.*s %s %s in %s",
+ nLvl++, " ",
+ ( t >= SbxCLASS_DONTCARE && t <= SbxCLASS_OBJECT )
+ ? pCls[ t-1 ] : "Unknown class", aNameStr1.GetBuffer(), aNameStr1.GetBuffer() );
+#endif
+
+ if( !GetAll( t ) )
+ return NULL;
+ SbxVariable* pRes = NULL;
+ pObjs->SetFlag( SBX_EXTSEARCH );
+ if( t == SbxCLASS_DONTCARE )
+ {
+ pRes = pMethods->Find( rName, SbxCLASS_METHOD );
+ if( !pRes )
+ pRes = pProps->Find( rName, SbxCLASS_PROPERTY );
+ if( !pRes )
+ pRes = pObjs->Find( rName, t );
+ }
+ else
+ {
+ SbxArray* pArray = NULL;
+ switch( t )
+ {
+ case SbxCLASS_VARIABLE:
+ case SbxCLASS_PROPERTY: pArray = pProps; break;
+ case SbxCLASS_METHOD: pArray = pMethods; break;
+ case SbxCLASS_OBJECT: pArray = pObjs; break;
+ default:
+ DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
+ }
+ if( pArray )
+ pRes = pArray->Find( rName, t );
+ }
+ // Extended Search im Objekt-Array?
+ // Fuer Objekte und DontCare ist das Objektarray bereits
+ // durchsucht worden
+ if( !pRes && ( t == SbxCLASS_METHOD || t == SbxCLASS_PROPERTY ) )
+ pRes = pObjs->Find( rName, t );
+ // Search in den Parents?
+ if( !pRes && IsSet( SBX_GBLSEARCH ) )
+ {
+ SbxObject* pCur = this;
+ while( !pRes && pCur->pParent )
+ {
+ // Ich selbst bin schon durchsucht worden!
+ USHORT nOwn = pCur->GetFlags();
+ pCur->ResetFlag( SBX_EXTSEARCH );
+ // Ich suche bereits global!
+ USHORT nPar = pCur->pParent->GetFlags();
+ pCur->pParent->ResetFlag( SBX_GBLSEARCH );
+ pRes = pCur->pParent->Find( rName, t );
+ pCur->SetFlags( nOwn );
+ pCur->pParent->SetFlags( nPar );
+ pCur = pCur->pParent;
+ }
+ }
+#ifdef DBG_UTIL
+ nLvl--;
+ if( pRes )
+ {
+ ByteString aNameStr3( (const UniString&)rName, RTL_TEXTENCODING_ASCII_US );
+ ByteString aNameStr4( (const UniString&)SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US );
+ DbgOutf( "SBX: Found %.*s %s in %s",
+ nLvl, " ", aNameStr3.GetBuffer(), aNameStr4.GetBuffer() );
+ }
+#endif
+ return pRes;
+}
+
+// Kurzform: Die Parent-Kette wird durchsucht
+// Das ganze rekursiv, da Call() ueberladen sein kann
+// Qualified Names sind zugelassen
+
+BOOL SbxObject::Call( const XubString& rName, SbxArray* pParam )
+{
+ SbxVariable* pMeth = FindQualified( rName, SbxCLASS_DONTCARE);
+ if( pMeth && pMeth->ISA(SbxMethod) )
+ {
+ // FindQualified() koennte schon zugeschlagen haben!
+ if( pParam )
+ pMeth->SetParameters( pParam );
+ pMeth->Broadcast( SBX_HINT_DATAWANTED );
+ pMeth->SetParameters( NULL );
+ return TRUE;
+ }
+ SetError( SbxERR_NO_METHOD );
+ return FALSE;
+}
+
+SbxProperty* SbxObject::GetDfltProperty()
+{
+ if ( !pDfltProp && aDfltPropName.Len() )
+ {
+ pDfltProp = (SbxProperty*) Find( aDfltPropName, SbxCLASS_PROPERTY );
+ if( !pDfltProp )
+ pDfltProp = (SbxProperty*) Make( aDfltPropName, SbxCLASS_PROPERTY, SbxVARIANT );
+ }
+ return pDfltProp;
+}
+void SbxObject::SetDfltProperty( const XubString& rName )
+{
+ if ( rName != aDfltPropName )
+ pDfltProp = NULL;
+ aDfltPropName = rName;
+ SetModified( TRUE );
+}
+
+void SbxObject::SetDfltProperty( SbxProperty* p )
+{
+ if( p )
+ {
+ USHORT n;
+ SbxArray* pArray = FindVar( p, n );
+ pArray->Put( p, n );
+ if( p->GetParent() != this )
+ p->SetParent( this );
+ Broadcast( SBX_HINT_OBJECTCHANGED );
+ }
+ pDfltProp = p;
+ SetModified( TRUE );
+}
+
+// Suchen einer bereits vorhandenen Variablen. Falls sie gefunden wurde,
+// wird der Index gesetzt, sonst wird der Count des Arrays geliefert.
+// In jedem Fall wird das korrekte Array geliefert.
+
+SbxArray* SbxObject::FindVar( SbxVariable* pVar, USHORT& nArrayIdx )
+{
+ SbxArray* pArray = NULL;
+ if( pVar ) switch( pVar->GetClass() )
+ {
+ case SbxCLASS_VARIABLE:
+ case SbxCLASS_PROPERTY: pArray = pProps; break;
+ case SbxCLASS_METHOD: pArray = pMethods; break;
+ case SbxCLASS_OBJECT: pArray = pObjs; break;
+ default:
+ DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
+ }
+ if( pArray )
+ {
+ nArrayIdx = pArray->Count();
+ // ist die Variable per Name vorhanden?
+ pArray->ResetFlag( SBX_EXTSEARCH );
+ SbxVariable* pOld = pArray->Find( pVar->GetName(), pVar->GetClass() );
+ if( pOld )
+ for( USHORT i = 0; i < pArray->Count(); i++ )
+ {
+ SbxVariableRef& rRef = pArray->GetRef( i );
+ if( (SbxVariable*) rRef == pOld )
+ {
+ nArrayIdx = i; break;
+ }
+ }
+ }
+ return pArray;
+}
+
+// Falls ein neues Objekt eingerichtet wird, wird es, falls es bereits
+// eines mit diesem Namen gibt, indiziert.
+
+SbxVariable* SbxObject::Make( const XubString& rName, SbxClassType ct, SbxDataType dt )
+{
+ // Ist das Objekt bereits vorhanden?
+ SbxArray* pArray = NULL;
+ switch( ct )
+ {
+ case SbxCLASS_VARIABLE:
+ case SbxCLASS_PROPERTY: pArray = pProps; break;
+ case SbxCLASS_METHOD: pArray = pMethods; break;
+ case SbxCLASS_OBJECT: pArray = pObjs; break;
+ default:
+ DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
+ }
+ if( !pArray )
+ return NULL;
+ // Collections duerfen gleichnamige Objekte enthalten
+ if( !( ct == SbxCLASS_OBJECT && ISA(SbxCollection) ) )
+ {
+ SbxVariable* pRes = pArray->Find( rName, ct );
+ if( pRes )
+ {
+/* Wegen haeufiger Probleme (z.B. #67000) erstmal ganz raus
+#ifdef DBG_UTIL
+ if( pRes->GetHashCode() != nNameHash
+ && pRes->GetHashCode() != nParentHash )
+ {
+ XubString aMsg( "SBX-Element \"" );
+ aMsg += pRes->GetName();
+ aMsg += "\"\n in Objekt \"";
+ aMsg += GetName();
+ aMsg += "\" bereits vorhanden";
+ DbgError( (const char*)aMsg.GetStr() );
+ }
+#endif
+*/
+ return pRes;
+ }
+ }
+ SbxVariable* pVar = NULL;
+ switch( ct )
+ {
+ case SbxCLASS_VARIABLE:
+ case SbxCLASS_PROPERTY:
+ pVar = new SbxProperty( rName, dt );
+ break;
+ case SbxCLASS_METHOD:
+ pVar = new SbxMethod( rName, dt );
+ break;
+ case SbxCLASS_OBJECT:
+ pVar = CreateObject( rName );
+ break;
+ default: break;
+ }
+ pVar->SetParent( this );
+ pArray->Put( pVar, pArray->Count() );
+ SetModified( TRUE );
+ // Das Objekt lauscht immer
+ StartListening( pVar->GetBroadcaster(), TRUE );
+ Broadcast( SBX_HINT_OBJECTCHANGED );
+ return pVar;
+}
+
+SbxObject* SbxObject::MakeObject( const XubString& rName, const XubString& rClass )
+{
+ // Ist das Objekt bereits vorhanden?
+ if( !ISA(SbxCollection) )
+ {
+ SbxVariable* pRes = pObjs->Find( rName, SbxCLASS_OBJECT );
+ if( pRes )
+ {
+/* Wegen haeufiger Probleme (z.B. #67000) erstmal ganz raus
+#ifdef DBG_UTIL
+ if( pRes->GetHashCode() != nNameHash
+ && pRes->GetHashCode() != nParentHash )
+ {
+ XubString aMsg( "SBX-Objekt \"" );
+ aMsg += pRes->GetName();
+ aMsg += "\"\n in Objekt \"";
+ aMsg += GetName();
+ aMsg += "\" bereits vorhanden";
+ DbgError( (const char*)aMsg.GetStr() );
+ }
+#endif
+*/
+ return PTR_CAST(SbxObject,pRes);
+ }
+ }
+ SbxObject* pVar = CreateObject( rClass );
+ if( pVar )
+ {
+ pVar->SetName( rName );
+ pVar->SetParent( this );
+ pObjs->Put( pVar, pObjs->Count() );
+ SetModified( TRUE );
+ // Das Objekt lauscht immer
+ StartListening( pVar->GetBroadcaster(), TRUE );
+ Broadcast( SBX_HINT_OBJECTCHANGED );
+ }
+ return pVar;
+}
+
+void SbxObject::Insert( SbxVariable* pVar )
+{
+ USHORT nIdx;
+ SbxArray* pArray = FindVar( pVar, nIdx );
+ if( pArray )
+ {
+ // Hinein damit. Man sollte allerdings auf die Pointer aufpassen!
+ if( nIdx < pArray->Count() )
+ {
+ // dann gibt es dieses Element bereits
+ // Bei Collections duerfen gleichnamige Objekte hinein
+ if( pArray == pObjs && ISA(SbxCollection) )
+ nIdx = pArray->Count();
+ else
+ {
+ SbxVariable* pOld = pArray->Get( nIdx );
+ // schon drin: ueberschreiben
+ if( pOld == pVar )
+ return;
+
+/* Wegen haeufiger Probleme (z.B. #67000) erstmal ganz raus
+#ifdef DBG_UTIL
+ if( pOld->GetHashCode() != nNameHash
+ && pOld->GetHashCode() != nParentHash )
+ {
+ XubString aMsg( "SBX-Element \"" );
+ aMsg += pVar->GetName();
+ aMsg += "\"\n in Objekt \"";
+ aMsg += GetName();
+ aMsg += "\" bereits vorhanden";
+ DbgError( (const char*)aMsg.GetStr() );
+ }
+#endif
+*/
+ EndListening( pOld->GetBroadcaster(), TRUE );
+ if( pVar->GetClass() == SbxCLASS_PROPERTY )
+ {
+ if( pOld == pDfltProp )
+ pDfltProp = (SbxProperty*) pVar;
+ }
+ }
+ }
+ StartListening( pVar->GetBroadcaster(), TRUE );
+ pArray->Put( pVar, nIdx );
+ if( pVar->GetParent() != this )
+ pVar->SetParent( this );
+ SetModified( TRUE );
+ Broadcast( SBX_HINT_OBJECTCHANGED );
+#ifdef DBG_UTIL
+ static const char* pCls[] =
+ { "DontCare","Array","Value","Variable","Method","Property","Object" };
+ XubString aVarName( pVar->GetName() );
+ if ( !aVarName.Len() && pVar->ISA(SbxObject) )
+ aVarName = PTR_CAST(SbxObject,pVar)->GetClassName();
+ ByteString aNameStr1( (const UniString&)aVarName, RTL_TEXTENCODING_ASCII_US );
+ ByteString aNameStr2( (const UniString&)SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US );
+ DbgOutf( "SBX: Insert %s %s in %s",
+ ( pVar->GetClass() >= SbxCLASS_DONTCARE &&
+ pVar->GetClass() <= SbxCLASS_OBJECT )
+ ? pCls[ pVar->GetClass()-1 ] : "Unknown class", aNameStr1.GetBuffer(), aNameStr1.GetBuffer() );
+#endif
+ }
+}
+
+// AB 23.4.1997, Optimierung, Einfuegen ohne Ueberpruefung auf doppelte
+// Eintraege und ohne Broadcasts, wird nur in SO2/auto.cxx genutzt
+void SbxObject::QuickInsert( SbxVariable* pVar )
+{
+ SbxArray* pArray = NULL;
+ if( pVar )
+ {
+ switch( pVar->GetClass() )
+ {
+ case SbxCLASS_VARIABLE:
+ case SbxCLASS_PROPERTY: pArray = pProps; break;
+ case SbxCLASS_METHOD: pArray = pMethods; break;
+ case SbxCLASS_OBJECT: pArray = pObjs; break;
+ default:
+ DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
+ }
+ }
+ if( pArray )
+ {
+ StartListening( pVar->GetBroadcaster(), TRUE );
+ pArray->Put( pVar, pArray->Count() );
+ if( pVar->GetParent() != this )
+ pVar->SetParent( this );
+ SetModified( TRUE );
+#ifdef DBG_UTIL
+ static const char* pCls[] =
+ { "DontCare","Array","Value","Variable","Method","Property","Object" };
+ XubString aVarName( pVar->GetName() );
+ if ( !aVarName.Len() && pVar->ISA(SbxObject) )
+ aVarName = PTR_CAST(SbxObject,pVar)->GetClassName();
+ ByteString aNameStr1( (const UniString&)aVarName, RTL_TEXTENCODING_ASCII_US );
+ ByteString aNameStr2( (const UniString&)SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US );
+ DbgOutf( "SBX: Insert %s %s in %s",
+ ( pVar->GetClass() >= SbxCLASS_DONTCARE &&
+ pVar->GetClass() <= SbxCLASS_OBJECT )
+ ? pCls[ pVar->GetClass()-1 ] : "Unknown class", aNameStr1.GetBuffer(), aNameStr1.GetBuffer() );
+#endif
+ }
+}
+
+// AB 23.3.1997, Spezial-Methode, gleichnamige Controls zulassen
+void SbxObject::VCPtrInsert( SbxVariable* pVar )
+{
+ SbxArray* pArray = NULL;
+ if( pVar )
+ {
+ switch( pVar->GetClass() )
+ {
+ case SbxCLASS_VARIABLE:
+ case SbxCLASS_PROPERTY: pArray = pProps; break;
+ case SbxCLASS_METHOD: pArray = pMethods; break;
+ case SbxCLASS_OBJECT: pArray = pObjs; break;
+ default:
+ DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
+ }
+ }
+ if( pArray )
+ {
+ StartListening( pVar->GetBroadcaster(), TRUE );
+ pArray->Put( pVar, pArray->Count() );
+ if( pVar->GetParent() != this )
+ pVar->SetParent( this );
+ SetModified( TRUE );
+ Broadcast( SBX_HINT_OBJECTCHANGED );
+ }
+}
+
+void SbxObject::Remove( const XubString& rName, SbxClassType t )
+{
+ Remove( SbxObject::Find( rName, t ) );
+}
+
+void SbxObject::Remove( SbxVariable* pVar )
+{
+ USHORT nIdx;
+ SbxArray* pArray = FindVar( pVar, nIdx );
+ if( pArray && nIdx < pArray->Count() )
+ {
+#ifdef DBG_UTIL
+ XubString aVarName( pVar->GetName() );
+ if ( !aVarName.Len() && pVar->ISA(SbxObject) )
+ aVarName = PTR_CAST(SbxObject,pVar)->GetClassName();
+ ByteString aNameStr1( (const UniString&)aVarName, RTL_TEXTENCODING_ASCII_US );
+ ByteString aNameStr2( (const UniString&)SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US );
+#endif
+ SbxVariableRef pVar_ = pArray->Get( nIdx );
+ if( pVar_->IsBroadcaster() )
+ EndListening( pVar_->GetBroadcaster(), TRUE );
+ if( (SbxVariable*) pVar_ == pDfltProp )
+ pDfltProp = NULL;
+ pArray->Remove( nIdx );
+ if( pVar_->GetParent() == this )
+ pVar_->SetParent( NULL );
+ SetModified( TRUE );
+ Broadcast( SBX_HINT_OBJECTCHANGED );
+ }
+}
+
+// AB 23.3.1997, Loeschen per Pointer fuer Controls (doppelte Namen!)
+void SbxObject::VCPtrRemove( SbxVariable* pVar )
+{
+ USHORT nIdx;
+ // Neu FindVar-Methode, sonst identisch mit normaler Methode
+ SbxArray* pArray = VCPtrFindVar( pVar, nIdx );
+ if( pArray && nIdx < pArray->Count() )
+ {
+ SbxVariableRef xVar = pArray->Get( nIdx );
+ if( xVar->IsBroadcaster() )
+ EndListening( xVar->GetBroadcaster(), TRUE );
+ if( (SbxVariable*) xVar == pDfltProp )
+ pDfltProp = NULL;
+ pArray->Remove( nIdx );
+ if( xVar->GetParent() == this )
+ xVar->SetParent( NULL );
+ SetModified( TRUE );
+ Broadcast( SBX_HINT_OBJECTCHANGED );
+ }
+}
+
+// AB 23.3.1997, Zugehoerige Spezial-Methode, nur ueber Pointer suchen
+SbxArray* SbxObject::VCPtrFindVar( SbxVariable* pVar, USHORT& nArrayIdx )
+{
+ SbxArray* pArray = NULL;
+ if( pVar ) switch( pVar->GetClass() )
+ {
+ case SbxCLASS_VARIABLE:
+ case SbxCLASS_PROPERTY: pArray = pProps; break;
+ case SbxCLASS_METHOD: pArray = pMethods; break;
+ case SbxCLASS_OBJECT: pArray = pObjs; break;
+ default:
+ DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
+ }
+ if( pArray )
+ {
+ nArrayIdx = pArray->Count();
+ for( USHORT i = 0; i < pArray->Count(); i++ )
+ {
+ SbxVariableRef& rRef = pArray->GetRef( i );
+ if( (SbxVariable*) rRef == pVar )
+ {
+ nArrayIdx = i; break;
+ }
+ }
+ }
+ return pArray;
+}
+
+
+
+void SbxObject::SetPos( SbxVariable* pVar, USHORT nPos )
+{
+ USHORT nIdx;
+ SbxArray* pArray = FindVar( pVar, nIdx );
+ if( pArray )
+ {
+ if( nPos >= pArray->Count() )
+ nPos = pArray->Count() - 1;
+ if( nIdx < ( pArray->Count() - 1 ) )
+ {
+ SbxVariableRef refVar = pArray->Get( nIdx );
+ pArray->Remove( nIdx );
+ pArray->Insert( refVar, nPos );
+ }
+ }
+// SetModified( TRUE );
+// Broadcast( SBX_HINT_OBJECTCHANGED );
+}
+
+static BOOL LoadArray( SvStream& rStrm, SbxObject* pThis, SbxArray* pArray )
+{
+ SbxArrayRef p = (SbxArray*) SbxBase::Load( rStrm );
+ if( !p.Is() )
+ return FALSE;
+ for( USHORT i = 0; i < p->Count(); i++ )
+ {
+ SbxVariableRef& r = p->GetRef( i );
+ SbxVariable* pVar = r;
+ if( pVar )
+ {
+ pVar->SetParent( pThis );
+ pThis->StartListening( pVar->GetBroadcaster(), TRUE );
+ }
+ }
+ pArray->Merge( p );
+ return TRUE;
+}
+
+// Der Load eines Objekts ist additiv!
+
+BOOL SbxObject::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ // Hilfe fuer das Einlesen alter Objekte: einfach TRUE zurueck,
+ // LoadPrivateData() muss Default-Zustand herstellen
+ if( !nVer )
+ return TRUE;
+
+ pDfltProp = NULL;
+ if( !SbxVariable::LoadData( rStrm, nVer ) )
+ return FALSE;
+ // Wenn kein fremdes Objekt enthalten ist, uns selbst eintragen
+ if( aData.eType == SbxOBJECT && !aData.pObj )
+ aData.pObj = this;
+ sal_uInt32 nSize;
+ XubString aDfltProp;
+ rStrm.ReadByteString( aClassName, RTL_TEXTENCODING_ASCII_US );
+ rStrm.ReadByteString( aDfltProp, RTL_TEXTENCODING_ASCII_US );
+ ULONG nPos = rStrm.Tell();
+ rStrm >> nSize;
+ if( !LoadPrivateData( rStrm, nVer ) )
+ return FALSE;
+ ULONG nNewPos = rStrm.Tell();
+ nPos += nSize;
+ DBG_ASSERT( nPos >= nNewPos, "SBX: Zu viele Daten eingelesen" );
+ if( nPos != nNewPos )
+ rStrm.Seek( nPos );
+ if( !LoadArray( rStrm, this, pMethods )
+ || !LoadArray( rStrm, this, pProps )
+ || !LoadArray( rStrm, this, pObjs ) )
+ return FALSE;
+ // Properties setzen
+ if( aDfltProp.Len() )
+ pDfltProp = (SbxProperty*) pProps->Find( aDfltProp, SbxCLASS_PROPERTY );
+ SetModified( FALSE );
+ return TRUE;
+}
+
+BOOL SbxObject::StoreData( SvStream& rStrm ) const
+{
+ if( !SbxVariable::StoreData( rStrm ) )
+ return FALSE;
+ XubString aDfltProp;
+ if( pDfltProp )
+ aDfltProp = pDfltProp->GetName();
+ rStrm.WriteByteString( aClassName, RTL_TEXTENCODING_ASCII_US );
+ rStrm.WriteByteString( aDfltProp, RTL_TEXTENCODING_ASCII_US );
+ ULONG nPos = rStrm.Tell();
+ rStrm << (UINT32) 0L;
+ if( !StorePrivateData( rStrm ) )
+ return FALSE;
+ ULONG nNew = rStrm.Tell();
+ rStrm.Seek( nPos );
+ rStrm << (UINT32) ( nNew - nPos );
+ rStrm.Seek( nNew );
+ if( !pMethods->Store( rStrm ) )
+ return FALSE;
+ if( !pProps->Store( rStrm ) )
+ return FALSE;
+ if( !pObjs->Store( rStrm ) )
+ return FALSE;
+ ((SbxObject*) this)->SetModified( FALSE );
+ return TRUE;
+}
+
+XubString SbxObject::GenerateSource( const XubString &rLinePrefix,
+ const SbxObject* )
+{
+ // Properties in einem String einsammeln
+ XubString aSource;
+ SbxArrayRef xProps( GetProperties() );
+ FASTBOOL bLineFeed = FALSE;
+ for ( USHORT nProp = 0; nProp < xProps->Count(); ++nProp )
+ {
+ SbxPropertyRef xProp = (SbxProperty*) xProps->Get(nProp);
+ XubString aPropName( xProp->GetName() );
+ if ( xProp->CanWrite()
+ && !( xProp->GetHashCode() == nNameHash
+ && aPropName.EqualsIgnoreCaseAscii( pNameProp ) ) )
+ {
+ // ausser vor dem ersten Property immer einen Umbruch einfuegen
+ if ( bLineFeed )
+ aSource.AppendAscii( "\n" );
+ else
+ bLineFeed = TRUE;
+
+ aSource += rLinePrefix;
+ aSource += '.';
+ aSource += aPropName;
+ aSource.AppendAscii( " = " );
+
+ // den Property-Wert textuell darstellen
+ switch ( xProp->GetType() )
+ {
+ case SbxEMPTY:
+ case SbxNULL:
+ // kein Wert
+ break;
+
+ case SbxSTRING:
+ {
+ // Strings in Anf"uhrungszeichen
+ aSource.AppendAscii( "\"" );
+ aSource += xProp->GetString();
+ aSource.AppendAscii( "\"" );
+ break;
+ }
+
+ default:
+ {
+ // sonstiges wie z.B. Zahlen direkt
+ aSource += xProp->GetString();
+ break;
+ }
+ }
+ }
+ }
+ return aSource;
+}
+
+static BOOL CollectAttrs( const SbxBase* p, XubString& rRes )
+{
+ XubString aAttrs;
+ if( p->IsHidden() )
+ aAttrs.AssignAscii( "Hidden" );
+ if( p->IsSet( SBX_EXTSEARCH ) )
+ {
+ if( aAttrs.Len() )
+ aAttrs += ',';
+ aAttrs.AppendAscii( "ExtSearch" );
+ }
+ if( !p->IsVisible() )
+ {
+ if( aAttrs.Len() )
+ aAttrs += ',';
+ aAttrs.AppendAscii( "Invisible" );
+ }
+ if( p->IsSet( SBX_DONTSTORE ) )
+ {
+ if( aAttrs.Len() )
+ aAttrs += ',';
+ aAttrs.AppendAscii( "DontStore" );
+ }
+ if( aAttrs.Len() )
+ {
+ rRes.AssignAscii( " (" );
+ rRes += aAttrs;
+ rRes += ')';
+ return TRUE;
+ }
+ else
+ {
+ rRes.Erase();
+ return FALSE;
+ }
+}
+
+void SbxObject::Dump( SvStream& rStrm, BOOL bFill )
+{
+ // Einr"uckung
+ static USHORT nLevel = 0;
+ if ( nLevel > 10 )
+ {
+ rStrm << "<too deep>" << endl;
+ return;
+ }
+ ++nLevel;
+ String aIndent;
+ for ( USHORT n = 1; n < nLevel; ++n )
+ aIndent.AppendAscii( " " );
+
+ // ggf. Objekt vervollst"andigen
+ if ( bFill )
+ GetAll( SbxCLASS_DONTCARE );
+
+ // Daten des Objekts selbst ausgeben
+ ByteString aNameStr( (const UniString&)GetName(), RTL_TEXTENCODING_ASCII_US );
+ ByteString aClassNameStr( (const UniString&)aClassName, RTL_TEXTENCODING_ASCII_US );
+ rStrm << "Object( "
+ << ByteString::CreateFromInt64( (ULONG) this ).GetBuffer() << "=='"
+ << ( aNameStr.Len() ? aNameStr.GetBuffer() : "<unnamed>" ) << "', "
+ << "of class '" << aClassNameStr.GetBuffer() << "', "
+ << "counts "
+ << ByteString::CreateFromInt64( GetRefCount() ).GetBuffer()
+ << " refs, ";
+ if ( GetParent() )
+ {
+ ByteString aParentNameStr( (const UniString&)GetName(), RTL_TEXTENCODING_ASCII_US );
+ rStrm << "in parent "
+ << ByteString::CreateFromInt64( (ULONG) GetParent() ).GetBuffer()
+ << "=='" << ( aParentNameStr.Len() ? aParentNameStr.GetBuffer() : "<unnamed>" ) << "'";
+ }
+ else
+ rStrm << "no parent ";
+ rStrm << " )" << endl;
+ ByteString aIndentNameStr( (const UniString&)aIndent, RTL_TEXTENCODING_ASCII_US );
+ rStrm << aIndentNameStr.GetBuffer() << "{" << endl;
+
+ // Flags
+ XubString aAttrs;
+ if( CollectAttrs( this, aAttrs ) )
+ {
+ ByteString aAttrStr( (const UniString&)aAttrs, RTL_TEXTENCODING_ASCII_US );
+ rStrm << aIndentNameStr.GetBuffer() << "- Flags: " << aAttrStr.GetBuffer() << endl;
+ }
+
+ // Methods
+ rStrm << aIndentNameStr.GetBuffer() << "- Methods:" << endl;
+ for( USHORT i = 0; i < pMethods->Count(); i++ )
+ {
+ SbxVariableRef& r = pMethods->GetRef( i );
+ SbxVariable* pVar = r;
+ if( pVar )
+ {
+ XubString aLine( aIndent );
+ aLine.AppendAscii( " - " );
+ aLine += pVar->GetName( SbxNAME_SHORT_TYPES );
+ XubString aAttrs2;
+ if( CollectAttrs( pVar, aAttrs2 ) )
+ aLine += aAttrs2;
+ if( !pVar->IsA( TYPE(SbxMethod) ) )
+ aLine.AppendAscii( " !! Not a Method !!" );
+ rStrm.WriteByteString( aLine, RTL_TEXTENCODING_ASCII_US );
+
+ // bei Object-Methods auch das Object ausgeben
+ if ( pVar->GetValues_Impl().eType == SbxOBJECT &&
+ pVar->GetValues_Impl().pObj &&
+ pVar->GetValues_Impl().pObj != this &&
+ pVar->GetValues_Impl().pObj != GetParent() )
+ {
+ rStrm << " contains ";
+ ((SbxObject*) pVar->GetValues_Impl().pObj)->Dump( rStrm, bFill );
+ }
+ else
+ rStrm << endl;
+ }
+ }
+
+ // Properties
+ rStrm << aIndentNameStr.GetBuffer() << "- Properties:" << endl;
+ {
+ for( USHORT i = 0; i < pProps->Count(); i++ )
+ {
+ SbxVariableRef& r = pProps->GetRef( i );
+ SbxVariable* pVar = r;
+ if( pVar )
+ {
+ XubString aLine( aIndent );
+ aLine.AppendAscii( " - " );
+ aLine += pVar->GetName( SbxNAME_SHORT_TYPES );
+ XubString aAttrs3;
+ if( CollectAttrs( pVar, aAttrs3 ) )
+ aLine += aAttrs3;
+ if( !pVar->IsA( TYPE(SbxProperty) ) )
+ aLine.AppendAscii( " !! Not a Property !!" );
+ rStrm.WriteByteString( aLine, RTL_TEXTENCODING_ASCII_US );
+
+ // bei Object-Properties auch das Object ausgeben
+ if ( pVar->GetValues_Impl().eType == SbxOBJECT &&
+ pVar->GetValues_Impl().pObj &&
+ pVar->GetValues_Impl().pObj != this &&
+ pVar->GetValues_Impl().pObj != GetParent() )
+ {
+ rStrm << " contains ";
+ ((SbxObject*) pVar->GetValues_Impl().pObj)->Dump( rStrm, bFill );
+ }
+ else
+ rStrm << endl;
+ }
+ }
+ }
+
+ // Objects
+ rStrm << aIndentNameStr.GetBuffer() << "- Objects:" << endl;
+ {
+ for( USHORT i = 0; i < pObjs->Count(); i++ )
+ {
+ SbxVariableRef& r = pObjs->GetRef( i );
+ SbxVariable* pVar = r;
+ if ( pVar )
+ {
+ rStrm << aIndentNameStr.GetBuffer() << " - Sub";
+ if ( pVar->ISA(SbxObject) )
+ ((SbxObject*) pVar)->Dump( rStrm, bFill );
+ else if ( pVar->ISA(SbxVariable) )
+ ((SbxVariable*) pVar)->Dump( rStrm, bFill );
+ }
+ }
+ }
+
+ rStrm << aIndentNameStr.GetBuffer() << "}" << endl << endl;
+ --nLevel;
+}
+
+SvDispatch* SbxObject::GetSvDispatch()
+{
+ return NULL;
+}
+
+BOOL SbxMethod::Run( SbxValues* pValues )
+{
+ SbxValues aRes;
+ if( !pValues )
+ pValues = &aRes;
+ pValues->eType = SbxVARIANT;
+ return Get( *pValues );
+}
+
+SbxClassType SbxMethod::GetClass() const
+{
+ return SbxCLASS_METHOD;
+}
+
+SbxClassType SbxProperty::GetClass() const
+{
+ return SbxCLASS_PROPERTY;
+}
+
+void SbxObject::GarbageCollection( ULONG nObjects )
+
+/* [Beschreibung]
+
+ Diese statische Methode durchsucht die n"achsten 'nObjects' der zur Zeit
+ existierenden <SbxObject>-Instanzen nach zyklischen Referenzen, die sich
+ nur noch selbst am Leben erhalten. Ist 'nObjects==0', dann werden
+ alle existierenden durchsucht.
+
+ zur Zeit nur implementiert: Object -> Parent-Property -> Parent -> Object
+*/
+
+{
+ (void)nObjects;
+
+ static BOOL bInGarbageCollection = FALSE;
+ if ( bInGarbageCollection )
+ return;
+ bInGarbageCollection = TRUE;
+
+#if 0
+ // erstes Object dieser Runde anspringen
+ BOOL bAll = !nObjects;
+ if ( bAll )
+ rObjects.First();
+ SbxObject *pObj = rObjects.GetCurObject();
+ if ( !pObj )
+ pObj = rObjects.First();
+
+ while ( pObj && 0 != nObjects-- )
+ {
+ // hat der Parent nur noch 1 Ref-Count?
+ SbxObject *pParent = PTR_CAST( SbxObject, pObj->GetParent() );
+ if ( pParent && 1 == pParent->GetRefCount() )
+ {
+ // dann alle Properies des Objects durchsuchen
+ SbxArray *pProps = pObj->GetProperties();
+ for ( USHORT n = 0; n < pProps->Count(); ++n )
+ {
+ // verweist die Property auf den Parent des Object?
+ SbxVariable *pProp = pProps->Get(n);
+ const SbxValues &rValues = pProp->GetValues_Impl();
+ if ( SbxOBJECT == rValues.eType &&
+ pParent == rValues.pObj )
+ {
+#ifdef DBG_UTIL
+ DbgOutf( "SBX: %s.%s with Object %s was garbage",
+ pObj->GetName().GetStr(),
+ pProp->GetName().GetStr(),
+ pParent->GetName().GetStr() );
+#endif
+ // dann freigeben
+ pProp->SbxValue::Clear();
+ Sound::Beep();
+ break;
+ }
+ }
+ }
+
+ // zum n"achsten
+ pObj = rObjects.Next();
+ if ( !bAll && !pObj )
+ pObj = rObjects.First();
+ }
+#endif
+
+// AB 28.10. Zur 507a vorerst raus, da SfxBroadcaster::Enable() wegfaellt
+#if 0
+#ifdef DBG_UTIL
+ SbxVarList_Impl &rVars = GetSbxData_Impl()->aVars;
+ DbgOutf( "SBX: garbage collector done, %lu objects remainding",
+ rVars.Count() );
+ if ( rVars.Count() > 200 && rVars.Count() < 210 )
+ {
+ SvFileStream aStream( "d:\\tmp\\dump.sbx", STREAM_STD_WRITE );
+ SfxBroadcaster::Enable(FALSE);
+ for ( ULONG n = 0; n < rVars.Count(); ++n )
+ {
+ SbxVariable *pVar = rVars.GetObject(n);
+ SbxObject *pObj = PTR_CAST(SbxObject, pVar);
+ USHORT nFlags = pVar->GetFlags();
+ pVar->SetFlag(SBX_NO_BROADCAST);
+ if ( pObj )
+ pObj->Dump(aStream);
+ else if ( !pVar->GetParent() || !pVar->GetParent()->ISA(SbxObject) )
+ pVar->Dump(aStream);
+ pVar->SetFlags(nFlags);
+ }
+ SfxBroadcaster::Enable(TRUE);
+ }
+#endif
+#endif
+ bInGarbageCollection = FALSE;
+}
+
diff --git a/basic/source/sbx/sbxres.cxx b/basic/source/sbx/sbxres.cxx
new file mode 100644
index 000000000000..369349e72069
--- /dev/null
+++ b/basic/source/sbx/sbxres.cxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * 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 "sbxres.hxx"
+
+static const char* pSbxRes[] = {
+ "Empty",
+ "Null",
+ "Integer",
+ "Long",
+ "Single",
+ "Double",
+ "Currency",
+ "Date",
+ "String",
+ "Object",
+ "Error",
+ "Boolean",
+ "Variant",
+ "Any",
+ "Type14",
+ "Type15",
+ "Char",
+ "Byte",
+ "UShort",
+ "ULong",
+ "Long64",
+ "ULong64",
+ "Int",
+ "UInt",
+ "Void",
+ "HResult",
+ "Pointer",
+ "DimArray",
+ "CArray",
+ "Any",
+ "LpStr",
+ "LpWStr",
+ " As ",
+ "Optional ",
+ "Byref ",
+
+ "Name",
+ "Parent",
+ "Application",
+ "Count",
+ "Add",
+ "Item",
+ "Remove",
+
+ "Error ", // mit Blank!
+ "False",
+ "True"
+};
+
+const char* GetSbxRes( USHORT nId )
+{
+ return ( ( nId > SBXRES_MAX ) ? "???" : pSbxRes[ nId ] );
+}
+
+SbxRes::SbxRes( USHORT nId )
+ : ::rtl::OUString( ::rtl::OUString::createFromAscii( GetSbxRes( nId ) ) )
+{}
+
diff --git a/basic/source/sbx/sbxres.hxx b/basic/source/sbx/sbxres.hxx
new file mode 100644
index 000000000000..8ed3c7054278
--- /dev/null
+++ b/basic/source/sbx/sbxres.hxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SBXRES_HXX
+#define _SBXRES_HXX
+
+#include <tools/string.hxx>
+
+// Zur Zeit sind Ressources im SVTOOLS-Projekt nicht vorgesehen.
+// Da es sich um unkritische Ressourcen handelt (BASIC-Keywords),
+// koennen wir mit Dummies arbeiten.
+
+#define STRING_TYPES 0
+#define STRING_EMPTY 0
+#define STRING_NULL 1
+#define STRING_INTEGER 2
+#define STRING_LONG 3
+#define STRING_SINGLE 4
+#define STRING_DOUBLE 5
+#define STRING_CURRENCY 6
+#define STRING_DATE 7
+#define STRING_STRING 8
+#define STRING_OBJECT 9
+#define STRING_ERROR 10
+#define STRING_BOOL 11
+#define STRING_VARIANT 12
+#define STRING_ANY 13
+#define STRING_CHAR 16
+#define STRING_BYTE 17
+#define STRING_USHORT 18
+#define STRING_ULONG 19
+#define STRING_INT 22
+#define STRING_UINT 23
+#define STRING_LPSTR 30
+#define STRING_LPWSTR 31
+#define STRING_AS 32
+#define STRING_OPTIONAL 33
+#define STRING_BYREF 34
+
+#define STRING_NAMEPROP 35
+#define STRING_PARENTPROP 36
+#define STRING_APPLPROP 37
+#define STRING_COUNTPROP 38
+#define STRING_ADDMETH 39
+#define STRING_ITEMMETH 40
+#define STRING_REMOVEMETH 41
+
+#define STRING_ERRORMSG 42
+#define STRING_FALSE 43
+#define STRING_TRUE 44
+
+#define SBXRES_MAX 44
+
+class SbxRes : public ::rtl::OUString
+{
+public:
+ SbxRes( USHORT );
+};
+
+const char* GetSbxRes( USHORT );
+
+
+#endif
diff --git a/basic/source/sbx/sbxscan.cxx b/basic/source/sbx/sbxscan.cxx
new file mode 100644
index 000000000000..b8aad9bbf2e4
--- /dev/null
+++ b/basic/source/sbx/sbxscan.cxx
@@ -0,0 +1,968 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#include <basic/sbx.hxx>
+#include "sbxconv.hxx"
+
+#include "unotools/syslocale.hxx"
+
+#if defined ( UNX )
+#include <stdlib.h>
+#endif
+
+#ifndef _APP_HXX //autogen
+#include <vcl/svapp.hxx>
+#endif
+#include <math.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "sbxres.hxx"
+#include <basic/sbxbase.hxx>
+#include <basic/sbxform.hxx>
+#include <svtools/svtools.hrc>
+
+#include "basrid.hxx"
+#include "runtime.hxx"
+
+#include <svl/zforlist.hxx>
+#include <comphelper/processfactory.hxx>
+
+
+void ImpGetIntntlSep( sal_Unicode& rcDecimalSep, sal_Unicode& rcThousandSep )
+{
+ SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& rData = aSysLocale.GetLocaleData();
+ rcDecimalSep = rData.getNumDecimalSep().GetBuffer()[0];
+ rcThousandSep = rData.getNumThousandSep().GetBuffer()[0];
+}
+
+// Scannen eines Strings nach BASIC-Konventionen
+// Dies entspricht den ueblichen Konventionen, nur dass der Exponent
+// auch ein D sein darf, was den Datentyp auf SbxDOUBLE festlegt.
+// Die Routine versucht, den Datentyp so klein wie moeglich zu gestalten.
+// Das ganze gibt auch noch einen Konversionsfehler, wenn der Datentyp
+// Fixed ist und das ganze nicht hineinpasst!
+
+SbxError ImpScan( const ::rtl::OUString& rWSrc, double& nVal, SbxDataType& rType,
+ USHORT* pLen, BOOL bAllowIntntl, BOOL bOnlyIntntl )
+{
+ ::rtl::OString aBStr( ::rtl::OUStringToOString( rWSrc, RTL_TEXTENCODING_ASCII_US ) );
+
+ // Bei International Komma besorgen
+ char cIntntlComma, cIntntl1000;
+ char cNonIntntlComma = '.';
+
+ sal_Unicode cDecimalSep, cThousandSep = 0;
+ if( bAllowIntntl || bOnlyIntntl )
+ {
+ ImpGetIntntlSep( cDecimalSep, cThousandSep );
+ cIntntlComma = (char)cDecimalSep;
+ cIntntl1000 = (char)cThousandSep;
+ }
+ // Sonst einfach auch auf . setzen
+ else
+ {
+ cIntntlComma = cNonIntntlComma;
+ cIntntl1000 = cNonIntntlComma; // Unschaedlich machen
+ }
+ // Nur International -> IntnlComma uebernehmen
+ if( bOnlyIntntl )
+ {
+ cNonIntntlComma = cIntntlComma;
+ cIntntl1000 = (char)cThousandSep;
+ }
+
+ const char* pStart = aBStr.getStr();
+ const char* p = pStart;
+ char buf[ 80 ], *q = buf;
+ BOOL bRes = TRUE;
+ BOOL bMinus = FALSE;
+ nVal = 0;
+ SbxDataType eScanType = SbxSINGLE;
+ // Whitespace wech
+ while( *p &&( *p == ' ' || *p == '\t' ) ) p++;
+ // Zahl? Dann einlesen und konvertieren.
+ if( *p == '-' )
+ p++, bMinus = TRUE;
+ if( isdigit( *p ) ||( (*p == cNonIntntlComma || *p == cIntntlComma ||
+ *p == cIntntl1000) && isdigit( *(p+1 ) ) ) )
+ {
+ short exp = 0; // >0: Exponentteil
+ short comma = 0; // >0: Nachkomma
+ short ndig = 0; // Anzahl Ziffern
+ short ncdig = 0; // Anzahl Ziffern nach Komma
+ ByteString aSearchStr( "0123456789DEde" );
+ // Kommas ergaenzen
+ aSearchStr += cNonIntntlComma;
+ if( cIntntlComma != cNonIntntlComma )
+ aSearchStr += cIntntlComma;
+ if( bOnlyIntntl )
+ aSearchStr += cIntntl1000;
+ const char* pSearchStr = aSearchStr.GetBuffer();
+ while( strchr( pSearchStr, *p ) && *p )
+ {
+ // 1000er-Trenner ueberlesen
+ if( bOnlyIntntl && *p == cIntntl1000 )
+ {
+ p++;
+ continue;
+ }
+
+ // Komma oder Exponent?
+ if( *p == cNonIntntlComma || *p == cIntntlComma )
+ {
+ // Immer '.' einfuegen, damit atof funktioniert
+ p++;
+ if( ++comma > 1 )
+ continue;
+ else
+ *q++ = '.';
+ }
+ else if( strchr( "DdEe", *p ) )
+ {
+ if( ++exp > 1 )
+ {
+ p++; continue;
+ }
+ if( toupper( *p ) == 'D' )
+ eScanType = SbxDOUBLE;
+ *q++ = 'E'; p++;
+ // Vorzeichen hinter Exponent?
+ if( *p == '+' )
+ p++;
+ else
+ if( *p == '-' )
+ *q++ = *p++;
+ }
+ else
+ {
+ *q++ = *p++;
+ if( comma && !exp ) ncdig++;
+ }
+ if( !exp ) ndig++;
+ }
+ *q = 0;
+ // Komma, Exponent mehrfach vorhanden?
+ if( comma > 1 || exp > 1 )
+ bRes = FALSE;
+ // Kann auf Integer gefaltet werden?
+ if( !comma && !exp )
+ {
+ if( nVal >= SbxMININT && nVal <= SbxMAXINT )
+ eScanType = SbxINTEGER;
+ else if( nVal >= SbxMINLNG && nVal <= SbxMAXLNG )
+ eScanType = SbxLONG;
+ }
+
+ nVal = atof( buf );
+ ndig = ndig - comma;
+ // zu viele Zahlen fuer SINGLE?
+ if( ndig > 15 || ncdig > 6 )
+ eScanType = SbxDOUBLE;
+
+ // Typkennung?
+ if( strchr( "%!&#", *p ) && *p ) p++;
+ }
+ // Hex/Oktalzahl? Einlesen und konvertieren:
+ else if( *p == '&' )
+ {
+ p++;
+ eScanType = SbxLONG;
+ const char *cmp = "0123456789ABCDEF";
+ char base = 16;
+ char ndig = 8;
+ char xch = *p++;
+ switch( toupper( xch ) )
+ {
+ case 'O': cmp = "01234567"; base = 8; ndig = 11; break;
+ case 'H': break;
+ default : bRes = FALSE;
+ }
+ long l = 0;
+ int i;
+ while( isalnum( *p ) )
+ {
+ char ch = sal::static_int_cast< char >( toupper( *p ) );
+ p++;
+ if( strchr( cmp, ch ) ) *q++ = ch;
+ else bRes = FALSE;
+ }
+ *q = 0;
+ for( q = buf; *q; q++ )
+ {
+ i =( *q & 0xFF ) - '0';
+ if( i > 9 ) i -= 7;
+ l =( l * base ) + i;
+ if( !ndig-- )
+ bRes = FALSE;
+ }
+ if( *p == '&' ) p++;
+ nVal = (double) l;
+ if( l >= SbxMININT && l <= SbxMAXINT )
+ eScanType = SbxINTEGER;
+ }
+ else if ( SbiRuntime::isVBAEnabled() )
+ {
+ OSL_TRACE("Reporting error converting");
+ return SbxERR_CONVERSION;
+ }
+ if( pLen )
+ *pLen = (USHORT) ( p - pStart );
+ if( !bRes )
+ return SbxERR_CONVERSION;
+ if( bMinus )
+ nVal = -nVal;
+ rType = eScanType;
+ return SbxERR_OK;
+}
+
+// Schnittstelle fuer CDbl im Basic
+SbxError SbxValue::ScanNumIntnl( const String& rSrc, double& nVal, BOOL bSingle )
+{
+ SbxDataType t;
+ USHORT nLen = 0;
+ SbxError nRetError = ImpScan( rSrc, nVal, t, &nLen,
+ /*bAllowIntntl*/FALSE, /*bOnlyIntntl*/TRUE );
+ // Komplett gelesen?
+ if( nRetError == SbxERR_OK && nLen != rSrc.Len() )
+ nRetError = SbxERR_CONVERSION;
+
+ if( bSingle )
+ {
+ SbxValues aValues( nVal );
+ nVal = (double)ImpGetSingle( &aValues ); // Hier Error bei Overflow
+ }
+ return nRetError;
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+static double roundArray[] = {
+ 5.0e+0, 0.5e+0, 0.5e-1, 0.5e-2, 0.5e-3, 0.5e-4, 0.5e-5, 0.5e-6, 0.5e-7,
+ 0.5e-8, 0.5e-9, 0.5e-10,0.5e-11,0.5e-12,0.5e-13,0.5e-14,0.5e-15 };
+
+/***************************************************************************
+|*
+|* void myftoa( double, char *, short, short, BOOL, BOOL )
+|*
+|* Beschreibung: Konversion double --> ASCII
+|* Parameter: double die Zahl.
+|* char * der Zielpuffer
+|* short Anzahl Nachkommastellen
+|* short Weite des Exponenten( 0=kein E )
+|* BOOL TRUE: mit 1000er Punkten
+|* BOOL TRUE: formatfreie Ausgabe
+|*
+***************************************************************************/
+
+static void myftoa( double nNum, char * pBuf, short nPrec, short nExpWidth,
+ BOOL bPt, BOOL bFix, sal_Unicode cForceThousandSep = 0 )
+{
+
+ short nExp = 0; // Exponent
+ short nDig = nPrec + 1; // Anzahl Digits in Zahl
+ short nDec; // Anzahl Vorkommastellen
+ register int i, digit;
+
+ // Komma besorgen
+ sal_Unicode cDecimalSep, cThousandSep;
+ ImpGetIntntlSep( cDecimalSep, cThousandSep );
+ if( cForceThousandSep )
+ cThousandSep = cForceThousandSep;
+
+ // Exponentberechnung:
+ nExp = 0;
+ if( nNum > 0.0 )
+ {
+ while( nNum < 1.0 ) nNum *= 10.0, nExp--;
+ while( nNum >= 10.0 ) nNum /= 10.0, nExp++;
+ }
+ if( !bFix && !nExpWidth )
+ nDig = nDig + nExp;
+ else if( bFix && !nPrec )
+ nDig = nExp + 1;
+
+ // Zahl runden:
+ if( (nNum += roundArray [( nDig > 16 ) ? 16 : nDig] ) >= 10.0 )
+ {
+ nNum = 1.0;
+ ++nExp;
+ if( !nExpWidth ) ++nDig;
+ }
+
+ // Bestimmung der Vorkommastellen:
+ if( !nExpWidth )
+ {
+ if( nExp < 0 )
+ {
+ // #41691: Auch bei bFix eine 0 spendieren
+ *pBuf++ = '0';
+ if( nPrec ) *pBuf++ = (char)cDecimalSep;
+ i = -nExp - 1;
+ if( nDig <= 0 ) i = nPrec;
+ while( i-- ) *pBuf++ = '0';
+ nDec = 0;
+ }
+ else
+ nDec = nExp+1;
+ }
+ else
+ nDec = 1;
+
+ // Zahl ausgeben:
+ if( nDig > 0 )
+ {
+ for( i = 0 ; ; ++i )
+ {
+ if( i < 16 )
+ {
+ digit = (int) nNum;
+ *pBuf++ = sal::static_int_cast< char >(digit + '0');
+ nNum =( nNum - digit ) * 10.0;
+ } else
+ *pBuf++ = '0';
+ if( --nDig == 0 ) break;
+ if( nDec )
+ {
+ nDec--;
+ if( !nDec )
+ *pBuf++ = (char)cDecimalSep;
+ else if( !(nDec % 3 ) && bPt )
+ *pBuf++ = (char)cThousandSep;
+ }
+ }
+ }
+
+ // Exponent ausgeben:
+ if( nExpWidth )
+ {
+ if( nExpWidth < 3 ) nExpWidth = 3;
+ nExpWidth -= 2;
+ *pBuf++ = 'E';
+ *pBuf++ =( nExp < 0 ) ?( (nExp = -nExp ), '-' ) : '+';
+ while( nExpWidth > 3 ) *pBuf++ = '0', nExpWidth--;
+ if( nExp >= 100 || nExpWidth == 3 )
+ {
+ *pBuf++ = sal::static_int_cast< char >(nExp/100 + '0');
+ nExp %= 100;
+ }
+ if( nExp/10 || nExpWidth >= 2 )
+ *pBuf++ = sal::static_int_cast< char >(nExp/10 + '0');
+ *pBuf++ = sal::static_int_cast< char >(nExp%10 + '0');
+ }
+ *pBuf = 0;
+}
+
+// Die Zahl wird unformatiert mit der angegebenen Anzahl NK-Stellen
+// aufbereitet. Evtl. wird ein Minus vorangestellt.
+// Diese Routine ist public, weil sie auch von den Put-Funktionen
+// der Klasse SbxImpSTRING verwendet wird.
+
+#ifdef _MSC_VER
+#pragma optimize( "", off )
+#pragma warning(disable: 4748) // "... because optimizations are disabled ..."
+#endif
+
+void ImpCvtNum( double nNum, short nPrec, ::rtl::OUString& rRes, BOOL bCoreString )
+{
+ char *q;
+ char cBuf[ 40 ], *p = cBuf;
+
+ sal_Unicode cDecimalSep, cThousandSep;
+ ImpGetIntntlSep( cDecimalSep, cThousandSep );
+ if( bCoreString )
+ cDecimalSep = '.';
+
+ if( nNum < 0.0 ) {
+ nNum = -nNum;
+ *p++ = '-';
+ }
+ double dMaxNumWithoutExp = (nPrec == 6) ? 1E6 : 1E14;
+ myftoa( nNum, p, nPrec,( nNum &&( nNum < 1E-1 || nNum > dMaxNumWithoutExp ) ) ? 4:0,
+ FALSE, TRUE, cDecimalSep );
+ // Trailing Zeroes weg:
+ for( p = cBuf; *p &&( *p != 'E' ); p++ ) {}
+ q = p; p--;
+ while( nPrec && *p == '0' ) nPrec--, p--;
+ if( *p == cDecimalSep ) p--;
+ while( *q ) *++p = *q++;
+ *++p = 0;
+ rRes = ::rtl::OUString::createFromAscii( cBuf );
+}
+
+#ifdef _MSC_VER
+#pragma optimize( "", on )
+#endif
+
+BOOL ImpConvStringExt( ::rtl::OUString& rSrc, SbxDataType eTargetType )
+{
+ // Merken, ob ueberhaupt was geaendert wurde
+ BOOL bChanged = FALSE;
+ ::rtl::OUString aNewString;
+
+ // Nur Spezial-Fälle behandeln, als Default tun wir nichts
+ switch( eTargetType )
+ {
+ // Bei Fliesskomma International beruecksichtigen
+ case SbxSINGLE:
+ case SbxDOUBLE:
+ case SbxCURRENCY:
+ {
+ ::rtl::OString aBStr( ::rtl::OUStringToOString( rSrc, RTL_TEXTENCODING_ASCII_US ) );
+
+ // Komma besorgen
+ sal_Unicode cDecimalSep, cThousandSep;
+ ImpGetIntntlSep( cDecimalSep, cThousandSep );
+ aNewString = rSrc;
+
+ // Ersetzen, wenn DecimalSep kein '.' (nur den ersten)
+ if( cDecimalSep != (sal_Unicode)'.' )
+ {
+ sal_Int32 nPos = aNewString.indexOf( cDecimalSep );
+ if( nPos != -1 )
+ {
+ sal_Unicode* pStr = (sal_Unicode*)aNewString.getStr();
+ pStr[nPos] = (sal_Unicode)'.';
+ bChanged = TRUE;
+ }
+ }
+ break;
+ }
+
+ // Bei BOOL TRUE und FALSE als String pruefen
+ case SbxBOOL:
+ {
+ if( rSrc.equalsIgnoreAsciiCaseAscii( "true" ) )
+ {
+ aNewString = ::rtl::OUString::valueOf( (sal_Int32)SbxTRUE );
+ bChanged = TRUE;
+ }
+ else
+ if( rSrc.equalsIgnoreAsciiCaseAscii( "false" ) )
+ {
+ aNewString = ::rtl::OUString::valueOf( (sal_Int32)SbxFALSE );
+ bChanged = TRUE;
+ }
+ break;
+ }
+ default: break;
+ }
+ // String bei Aenderung uebernehmen
+ if( bChanged )
+ rSrc = aNewString;
+ return bChanged;
+}
+
+
+// Formatierte Zahlenausgabe
+// Der Returnwert ist die Anzahl Zeichen, die aus dem
+// Format verwendt wurden.
+
+#ifdef _old_format_code_
+// lasse diesen Code vorl"aufig drin, zum 'abgucken'
+// der bisherigen Implementation
+
+static USHORT printfmtnum( double nNum, XubString& rRes, const XubString& rWFmt )
+{
+ const String& rFmt = rWFmt;
+ char cFill = ' '; // Fuellzeichen
+ char cPre = 0; // Startzeichen( evtl. "$" )
+ short nExpDig= 0; // Anzahl Exponentstellen
+ short nPrec = 0; // Anzahl Nachkommastellen
+ short nWidth = 0; // Zahlenweite gesamnt
+ short nLen; // Laenge konvertierte Zahl
+ BOOL bPoint = FALSE; // TRUE: mit 1000er Kommas
+ BOOL bTrail = FALSE; // TRUE, wenn folgendes Minus
+ BOOL bSign = FALSE; // TRUE: immer mit Vorzeichen
+ BOOL bNeg = FALSE; // TRUE: Zahl ist negativ
+ char cBuf [1024]; // Zahlenpuffer
+ char * p;
+ const char* pFmt = rFmt;
+ rRes.Erase();
+ // $$ und ** abfangen. Einfach wird als Zeichen ausgegeben.
+ if( *pFmt == '$' )
+ if( *++pFmt != '$' ) rRes += '$';
+ if( *pFmt == '*' )
+ if( *++pFmt != '*' ) rRes += '*';
+
+ switch( *pFmt++ )
+ {
+ case 0:
+ break;
+ case '+':
+ bSign = TRUE; nWidth++; break;
+ case '*':
+ nWidth++; cFill = '*';
+ if( *pFmt == '$' ) nWidth++, pFmt++, cPre = '$';
+ break;
+ case '$':
+ nWidth++; cPre = '$'; break;
+ case '#':
+ case '.':
+ case ',':
+ pFmt--; break;
+ }
+ // Vorkomma:
+ for( ;; )
+ {
+ while( *pFmt == '#' ) pFmt++, nWidth++;
+ // 1000er Kommas?
+ if( *pFmt == ',' )
+ {
+ nWidth++; pFmt++; bPoint = TRUE;
+ } else break;
+ }
+ // Nachkomma:
+ if( *pFmt == '.' )
+ {
+ while( *++pFmt == '#' ) nPrec++;
+ nWidth += nPrec + 1;
+ }
+ // Exponent:
+ while( *pFmt == '^' )
+ pFmt++, nExpDig++, nWidth++;
+ // Folgendes Minus:
+ if( !bSign && *pFmt == '-' )
+ pFmt++, bTrail = TRUE;
+
+ // Zahl konvertieren:
+ if( nPrec > 15 ) nPrec = 15;
+ if( nNum < 0.0 ) nNum = -nNum, bNeg = TRUE;
+ p = cBuf;
+ if( bSign ) *p++ = bNeg ? '-' : '+';
+ myftoa( nNum, p, nPrec, nExpDig, bPoint, FALSE );
+ nLen = strlen( cBuf );
+
+ // Ueberlauf?
+ if( cPre ) nLen++;
+ if( nLen > nWidth ) rRes += '%';
+ else {
+ nWidth -= nLen;
+ while( nWidth-- ) rRes += (xub_Unicode)cFill;
+ if( cPre ) rRes += (xub_Unicode)cPre;
+ }
+ rRes += (xub_Unicode*)&(cBuf[0]);
+ if( bTrail )
+ rRes += bNeg ? '-' : ' ';
+
+ return (USHORT) ( pFmt - (const char*) rFmt );
+}
+
+#endif //_old_format_code_
+
+static USHORT printfmtstr( const XubString& rStr, XubString& rRes, const XubString& rFmt )
+{
+ const xub_Unicode* pStr = rStr.GetBuffer();
+ const xub_Unicode* pFmtStart = rFmt.GetBuffer();
+ const xub_Unicode* pFmt = pFmtStart;
+ rRes.Erase();
+ switch( *pFmt )
+ {
+ case '!':
+ rRes += *pStr++; pFmt++; break;
+ case '\\':
+ do
+ {
+ rRes += *pStr ? *pStr++ : static_cast< xub_Unicode >(' ');
+ pFmt++;
+ } while( *pFmt != '\\' );
+ rRes += *pStr ? *pStr++ : static_cast< xub_Unicode >(' ');
+ pFmt++; break;
+ case '&':
+ rRes = rStr;
+ pFmt++; break;
+ default:
+ rRes = rStr;
+ break;
+ }
+ return (USHORT) ( pFmt - pFmtStart );
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+BOOL SbxValue::Scan( const XubString& rSrc, USHORT* pLen )
+{
+ SbxError eRes = SbxERR_OK;
+ if( !CanWrite() )
+ eRes = SbxERR_PROP_READONLY;
+ else
+ {
+ double n;
+ SbxDataType t;
+ eRes = ImpScan( rSrc, n, t, pLen );
+ if( eRes == SbxERR_OK )
+ {
+ if( !IsFixed() )
+ SetType( t );
+ PutDouble( n );
+ }
+ }
+ if( eRes )
+ {
+ SetError( eRes ); return FALSE;
+ }
+ else
+ return TRUE;
+}
+
+
+ResMgr* implGetResMgr( void )
+{
+ static ResMgr* pResMgr = NULL;
+ if( !pResMgr )
+ {
+ ::com::sun::star::lang::Locale aLocale = Application::GetSettings().GetUILocale();
+ pResMgr = ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(sb), aLocale );
+ }
+ return pResMgr;
+}
+
+class SbxValueFormatResId : public ResId
+{
+public:
+ SbxValueFormatResId( USHORT nId )
+ : ResId( nId, *implGetResMgr() )
+ {}
+};
+
+
+enum VbaFormatType
+{
+ VBA_FORMAT_TYPE_OFFSET, // standard number format
+ VBA_FORMAT_TYPE_USERDEFINED, // user defined number format
+ VBA_FORMAT_TYPE_NULL
+};
+
+struct VbaFormatInfo
+{
+ VbaFormatType meType;
+ const char* mpVbaFormat; // Format string in vba
+ NfIndexTableOffset meOffset; // SvNumberFormatter format index, if meType = VBA_FORMAT_TYPE_OFFSET
+ const char* mpOOoFormat; // if meType = VBA_FORMAT_TYPE_USERDEFINED
+};
+
+#define VBA_FORMAT_OFFSET( pcUtf8, eOffset ) \
+ { VBA_FORMAT_TYPE_OFFSET, pcUtf8, eOffset, 0 }
+
+#define VBA_FORMAT_USERDEFINED( pcUtf8, pcDefinedUtf8 ) \
+ { VBA_FORMAT_TYPE_USERDEFINED, pcUtf8, NF_NUMBER_STANDARD, pcDefinedUtf8 }
+
+static VbaFormatInfo pFormatInfoTable[] =
+{
+ VBA_FORMAT_OFFSET( "Long Date", NF_DATE_SYSTEM_LONG ),
+ VBA_FORMAT_USERDEFINED( "Medium Date", "DD-MMM-YY" ),
+ VBA_FORMAT_OFFSET( "Short Date", NF_DATE_SYSTEM_SHORT ),
+ VBA_FORMAT_USERDEFINED( "Long Time", "H:MM:SS AM/PM" ),
+ VBA_FORMAT_OFFSET( "Medium Time", NF_TIME_HHMMAMPM ),
+ VBA_FORMAT_OFFSET( "Short Time", NF_TIME_HHMM ),
+ VBA_FORMAT_OFFSET( "ddddd", NF_DATE_SYSTEM_SHORT ),
+ VBA_FORMAT_OFFSET( "dddddd", NF_DATE_SYSTEM_LONG ),
+ VBA_FORMAT_USERDEFINED( "ttttt", "H:MM:SS AM/PM" ),
+ VBA_FORMAT_OFFSET( "ww", NF_DATE_WW ),
+ { VBA_FORMAT_TYPE_NULL, 0, NF_INDEX_TABLE_ENTRIES, 0 }
+};
+
+VbaFormatInfo* getFormatInfo( const String& rFmt )
+{
+ VbaFormatInfo* pInfo = NULL;
+ INT16 i = 0;
+ while( (pInfo = pFormatInfoTable + i )->mpVbaFormat != NULL )
+ {
+ if( rFmt.EqualsIgnoreCaseAscii( pInfo->mpVbaFormat ) )
+ break;
+ i++;
+ }
+ return pInfo;
+}
+
+#define VBAFORMAT_GENERALDATE "General Date"
+#define VBAFORMAT_C "c"
+#define VBAFORMAT_N "n"
+#define VBAFORMAT_NN "nn"
+#define VBAFORMAT_W "w"
+#define VBAFORMAT_Y "y"
+#define VBAFORMAT_LOWERCASE "<"
+#define VBAFORMAT_UPPERCASE ">"
+
+// From methods1.cxx
+INT16 implGetWeekDay( double aDate, bool bFirstDayParam = false, INT16 nFirstDay = 0 );
+// from methods.cxx
+INT16 implGetMinute( double dDate );
+INT16 implGetDateYear( double aDate );
+BOOL implDateSerial( INT16 nYear, INT16 nMonth, INT16 nDay, double& rdRet );
+
+void SbxValue::Format( XubString& rRes, const XubString* pFmt ) const
+{
+ short nComma = 0;
+ double d = 0;
+
+ // pflin, It is better to use SvNumberFormatter to handle the date/time/number format.
+ // the SvNumberFormatter output is mostly compatible with
+ // VBA output besides the OOo-basic output
+ if( pFmt && !SbxBasicFormater::isBasicFormat( *pFmt ) )
+ {
+ String aStr = GetString();
+
+ if( pFmt->EqualsIgnoreCaseAscii( VBAFORMAT_LOWERCASE ) )
+ {
+ rRes = aStr.ToLowerAscii();
+ return;
+ }
+ if( pFmt->EqualsIgnoreCaseAscii( VBAFORMAT_UPPERCASE ) )
+ {
+ rRes = aStr.ToUpperAscii();
+ return;
+ }
+
+ LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ xFactory = comphelper::getProcessServiceFactory();
+ SvNumberFormatter aFormatter( xFactory, eLangType );
+
+ sal_uInt32 nIndex;
+ xub_StrLen nCheckPos = 0;
+ short nType;
+ double nNumber;
+ Color* pCol;
+
+ BOOL bSuccess = aFormatter.IsNumberFormat( aStr, nIndex, nNumber );
+
+ // number format, use SvNumberFormatter to handle it.
+ if( bSuccess )
+ {
+ String aFmtStr = *pFmt;
+ VbaFormatInfo* pInfo = getFormatInfo( aFmtStr );
+ if( pInfo && pInfo->meType != VBA_FORMAT_TYPE_NULL )
+ {
+ if( pInfo->meType == VBA_FORMAT_TYPE_OFFSET )
+ {
+ nIndex = aFormatter.GetFormatIndex( pInfo->meOffset, eLangType );
+ }
+ else
+ {
+ aFmtStr.AssignAscii( pInfo->mpOOoFormat );
+ aFormatter.PutandConvertEntry( aFmtStr, nCheckPos, nType, nIndex, LANGUAGE_ENGLISH, eLangType );
+ }
+ aFormatter.GetOutputString( nNumber, nIndex, rRes, &pCol );
+ }
+ else if( aFmtStr.EqualsIgnoreCaseAscii( VBAFORMAT_GENERALDATE )
+ || aFmtStr.EqualsIgnoreCaseAscii( VBAFORMAT_C ))
+ {
+ if( nNumber <=-1.0 || nNumber >= 1.0 )
+ {
+ // short date
+ nIndex = aFormatter.GetFormatIndex( NF_DATE_SYSTEM_SHORT, eLangType );
+ aFormatter.GetOutputString( nNumber, nIndex, rRes, &pCol );
+
+ // long time
+ if( floor( nNumber ) != nNumber )
+ {
+ aFmtStr.AssignAscii( "H:MM:SS AM/PM" );
+ aFormatter.PutandConvertEntry( aFmtStr, nCheckPos, nType, nIndex, LANGUAGE_ENGLISH, eLangType );
+ String aTime;
+ aFormatter.GetOutputString( nNumber, nIndex, aTime, &pCol );
+ rRes.AppendAscii(" ");
+ rRes += aTime;
+ }
+ }
+ else
+ {
+ // long time only
+ aFmtStr.AssignAscii( "H:MM:SS AM/PM" );
+ aFormatter.PutandConvertEntry( aFmtStr, nCheckPos, nType, nIndex, LANGUAGE_ENGLISH, eLangType );
+ aFormatter.GetOutputString( nNumber, nIndex, rRes, &pCol );
+ }
+ }
+ else if( aFmtStr.EqualsIgnoreCaseAscii( VBAFORMAT_N )
+ || aFmtStr.EqualsIgnoreCaseAscii( VBAFORMAT_NN ))
+ {
+ INT32 nMin = implGetMinute( nNumber );
+ if( nMin < 10 && aFmtStr.EqualsIgnoreCaseAscii( VBAFORMAT_NN ) )
+ {
+ // Minute in two digits
+ sal_Unicode* p = rRes.AllocBuffer( 2 );
+ *p++ = '0';
+ *p = sal_Unicode( '0' + nMin );
+ }
+ else
+ {
+ rRes = String::CreateFromInt32( nMin );
+ }
+ }
+ else if( aFmtStr.EqualsIgnoreCaseAscii( VBAFORMAT_W ))
+ {
+ INT32 nWeekDay = implGetWeekDay( nNumber );
+ rRes = String::CreateFromInt32( nWeekDay );
+ }
+ else if( aFmtStr.EqualsIgnoreCaseAscii( VBAFORMAT_Y ))
+ {
+ INT16 nYear = implGetDateYear( nNumber );
+ double dBaseDate;
+ implDateSerial( nYear, 1, 1, dBaseDate );
+ INT32 nYear32 = 1 + INT32( nNumber - dBaseDate );
+ rRes = String::CreateFromInt32( nYear32 );
+ }
+ else
+ {
+ aFormatter.PutandConvertEntry( aFmtStr, nCheckPos, nType, nIndex, LANGUAGE_ENGLISH, eLangType );
+ aFormatter.GetOutputString( nNumber, nIndex, rRes, &pCol );
+ }
+
+ return;
+ }
+ }
+
+ SbxDataType eType = GetType();
+ switch( eType )
+ {
+ case SbxCHAR:
+ case SbxBYTE:
+ case SbxINTEGER:
+ case SbxUSHORT:
+ case SbxLONG:
+ case SbxULONG:
+ case SbxINT:
+ case SbxUINT:
+ case SbxNULL: // #45929 NULL mit durchschummeln
+ nComma = 0; goto cvt;
+ case SbxSINGLE:
+ nComma = 6; goto cvt;
+ case SbxDOUBLE:
+ nComma = 14;
+
+ cvt:
+ if( eType != SbxNULL )
+ d = GetDouble();
+
+ // #45355 weiterer Einsprungpunkt fuer isnumeric-String
+ cvt2:
+ if( pFmt )
+ {
+ // hole die 'statischen' Daten f"ur Sbx
+ SbxAppData* pData = GetSbxData_Impl();
+
+ LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
+ if( pData->pBasicFormater )
+ {
+ if( pData->eBasicFormaterLangType != eLangType )
+ {
+ delete pData->pBasicFormater;
+ pData->pBasicFormater = NULL;
+ }
+ }
+ pData->eBasicFormaterLangType = eLangType;
+
+ // falls bisher noch kein BasicFormater-Objekt
+ // existiert, so erzeuge dieses
+ if( !pData->pBasicFormater )
+ {
+ SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& rData = aSysLocale.GetLocaleData();
+ sal_Unicode cComma = rData.getNumDecimalSep().GetBuffer()[0];
+ sal_Unicode c1000 = rData.getNumThousandSep().GetBuffer()[0];
+ String aCurrencyStrg = rData.getCurrSymbol();
+
+ // Initialisierung des Basic-Formater-Hilfsobjekts:
+ // hole die Resourcen f"ur die vordefinierten Ausgaben
+ // des Format()-Befehls, z.B. f"ur "On/Off".
+ String aOnStrg = String( SbxValueFormatResId(
+ STR_BASICKEY_FORMAT_ON ) );
+ String aOffStrg = String( SbxValueFormatResId(
+ STR_BASICKEY_FORMAT_OFF) );
+ String aYesStrg = String( SbxValueFormatResId(
+ STR_BASICKEY_FORMAT_YES) );
+ String aNoStrg = String( SbxValueFormatResId(
+ STR_BASICKEY_FORMAT_NO) );
+ String aTrueStrg = String( SbxValueFormatResId(
+ STR_BASICKEY_FORMAT_TRUE) );
+ String aFalseStrg = String( SbxValueFormatResId(
+ STR_BASICKEY_FORMAT_FALSE) );
+ String aCurrencyFormatStrg = String( SbxValueFormatResId(
+ STR_BASICKEY_FORMAT_CURRENCY) );
+ // erzeuge das Basic-Formater-Objekt
+ pData->pBasicFormater
+ = new SbxBasicFormater( cComma,c1000,aOnStrg,aOffStrg,
+ aYesStrg,aNoStrg,aTrueStrg,aFalseStrg,
+ aCurrencyStrg,aCurrencyFormatStrg );
+ }
+ // Bem.: Aus Performance-Gr"unden wird nur EIN BasicFormater-
+ // Objekt erzeugt und 'gespeichert', dadurch erspart man
+ // sich das teure Resourcen-Laden (f"ur landesspezifische
+ // vordefinierte Ausgaben, z.B. "On/Off") und die st"andige
+ // String-Erzeugungs Operationen.
+ // ABER: dadurch ist dieser Code NICHT multithreading f"ahig !
+
+ // hier gibt es Probleme mit ;;;Null, da diese Methode nur aufgerufen
+ // wird, wenn der SbxValue eine Zahl ist !!!
+ // dazu koennte: pData->pBasicFormater->BasicFormatNull( *pFmt ); aufgerufen werden !
+ if( eType != SbxNULL )
+ {
+ rRes = pData->pBasicFormater->BasicFormat( d ,*pFmt );
+ }
+ else
+ {
+ rRes = pData->pBasicFormater->BasicFormatNull( *pFmt );
+ }
+
+ // Die alte Implementierung:
+ //old: printfmtnum( GetDouble(), rRes, *pFmt );
+ }
+ else
+ {
+ ::rtl::OUString aTmpString( rRes );
+ ImpCvtNum( GetDouble(), nComma, aTmpString );
+ rRes = aTmpString;
+ }
+ break;
+ case SbxSTRING:
+ if( pFmt )
+ {
+ // #45355 wenn es numerisch ist, muss gewandelt werden
+ if( IsNumericRTL() )
+ {
+ ScanNumIntnl( GetString(), d, /*bSingle*/FALSE );
+ goto cvt2;
+ }
+ else
+ {
+ // Sonst String-Formatierung
+ printfmtstr( GetString(), rRes, *pFmt );
+ }
+ }
+ else
+ rRes = GetString();
+ break;
+ default:
+ rRes = GetString();
+ }
+}
+
+
diff --git a/basic/source/sbx/sbxsng.cxx b/basic/source/sbx/sbxsng.cxx
new file mode 100644
index 000000000000..70ef1653666b
--- /dev/null
+++ b/basic/source/sbx/sbxsng.cxx
@@ -0,0 +1,359 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#include <basic/sbx.hxx>
+#include "sbxconv.hxx"
+
+float ImpGetSingle( const SbxValues* p )
+{
+ SbxValues aTmp;
+ float nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort; break;
+ case SbxLONG:
+ nRes = (float) p->nLong; break;
+ case SbxULONG:
+ nRes = (float) p->nULong; break;
+ case SbxSINGLE:
+ nRes = p->nSingle; break;
+ case SbxSALINT64:
+ nRes = (float) p->nInt64; break;
+ case SbxSALUINT64:
+ nRes = (float) ImpSalUInt64ToDouble( p->uInt64 ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ if( p->pDecimal )
+ p->pDecimal->getSingle( nRes );
+ else
+ nRes = 0.0;
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else
+ dVal = p->nDouble;
+
+ if( dVal > SbxMAXSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ nRes = static_cast< float >(SbxMAXSNG);
+ }
+ else if( dVal < SbxMINSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ nRes = static_cast< float >(SbxMINSNG);
+ }
+ else if( dVal > 0 && dVal < SbxMAXSNG2 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ nRes = static_cast< float >(SbxMAXSNG2);
+ }
+ else if( dVal < 0 && dVal > SbxMINSNG2 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ nRes = static_cast< float >(SbxMINSNG2);
+ }
+ else
+ nRes = (float) dVal;
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ nRes = 0;
+ else
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ nRes = static_cast< float >(SbxMAXSNG);
+ }
+ else if( d < SbxMINSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ nRes = static_cast< float >(SbxMINSNG);
+ }
+ else
+ nRes = (float) d;
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetSingle();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger; break;
+ case SbxBYREF | SbxLONG:
+ nRes = (float) *p->pLong; break;
+ case SbxBYREF | SbxULONG:
+ nRes = (float) *p->pULong; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ nRes = *p->pUShort; break;
+ case SbxBYREF | SbxSINGLE:
+ nRes = *p->pSingle; break;
+ // ab hier muss getestet werden
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxSALINT64:
+ nRes = (float) *p->pnInt64; break;
+ case SbxBYREF | SbxSALUINT64:
+ nRes = (float) ImpSalUInt64ToDouble( *p->puInt64 ); break;
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutSingle( SbxValues* p, float n )
+{
+ SbxValues aTmp;
+start:
+ switch( +p->eType )
+ {
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxLONG:
+ aTmp.pLong = &p->nLong; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxULONG64:
+ aTmp.pULong64 = &p->nULong64; goto direct;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ aTmp.pLong64 = &p->nLong64; goto direct;
+ case SbxSALINT64:
+ aTmp.pnInt64 = &p->nInt64; goto direct;
+ case SbxSALUINT64:
+ aTmp.puInt64 = &p->uInt64; goto direct;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ SbxDecimal* pDec = ImpCreateDecimal( p );
+ if( !pDec->setSingle( n ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ break;
+ }
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // keine Tests ab hier
+ case SbxSINGLE:
+ p->nSingle = n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ {
+ if( !p->pOUString )
+ p->pOUString = new ::rtl::OUString;
+ ImpCvtNum( (double) n, 6, *p->pOUString );
+ break;
+ }
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutSingle( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
+ }
+ else if( n < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
+ }
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ else if( n < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ {
+ INT32 i;
+ if( n > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); i = SbxMAXLNG;
+ }
+ else if( n < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); i = SbxMINLNG;
+ }
+ else
+ {
+ i = sal::static_int_cast< INT32 >(n);
+ }
+ *p->pLong = i; break;
+ }
+ case SbxBYREF | SbxULONG:
+ {
+ UINT32 i;
+ if( n > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); i = SbxMAXULNG;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); i = 0;
+ }
+ else
+ {
+ i = sal::static_int_cast< UINT32 >(n);
+ }
+ *p->pULong = i; break;
+ }
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = ImpDoubleToSalInt64( (double) n ); break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = ImpDoubleToSalUInt64( (double) n ); break;
+ case SbxBYREF | SbxCURRENCY:
+ double d;
+ if( n > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); d = SbxMAXCURR;
+ }
+ else if( n < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); d = SbxMINCURR;
+ }
+ else
+ {
+ d = n;
+ }
+ *p->pLong64 = ImpDoubleToCurrency( n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
diff --git a/basic/source/sbx/sbxstr.cxx b/basic/source/sbx/sbxstr.cxx
new file mode 100644
index 000000000000..b4156a116ddc
--- /dev/null
+++ b/basic/source/sbx/sbxstr.cxx
@@ -0,0 +1,319 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#include <basic/sbx.hxx>
+#include "sbxconv.hxx"
+#include "sbxres.hxx"
+#include "runtime.hxx"
+#ifndef _RTL_USTRBUF_HXX_
+#include <rtl/ustrbuf.hxx>
+#endif
+// AB 29.10.99 Unicode
+#ifndef _USE_NO_NAMESPACE
+using namespace rtl;
+#endif
+
+
+// Die Konversion eines Items auf String wird ueber die Put-Methoden
+// der einzelnen Datentypen abgewickelt, um doppelten Code zu vermeiden.
+
+::rtl::OUString ImpGetString( const SbxValues* p )
+{
+ SbxValues aTmp;
+ ::rtl::OUString aRes;
+ aTmp.eType = SbxSTRING;
+ aTmp.pOUString = &aRes;
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ break;
+ case SbxCHAR:
+ ImpPutChar( &aTmp, p->nChar ); break;
+ case SbxBYTE:
+ ImpPutByte( &aTmp, p->nByte ); break;
+ case SbxINTEGER:
+ ImpPutInteger( &aTmp, p->nInteger ); break;
+ case SbxBOOL:
+ ImpPutBool( &aTmp, p->nUShort ); break;
+ case SbxUSHORT:
+ ImpPutUShort( &aTmp, p->nUShort ); break;
+ case SbxLONG:
+ ImpPutLong( &aTmp, p->nLong ); break;
+ case SbxULONG:
+ ImpPutULong( &aTmp, p->nULong ); break;
+ case SbxSINGLE:
+ ImpPutSingle( &aTmp, p->nSingle ); break;
+ case SbxDOUBLE:
+ ImpPutDouble( &aTmp, p->nDouble ); break;
+ case SbxCURRENCY:
+ ImpPutCurrency( &aTmp, p->nLong64 ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ ImpPutDecimal( &aTmp, p->pDecimal ); break;
+ case SbxSALINT64:
+ ImpPutInt64( &aTmp, p->nInt64 ); break;
+ case SbxSALUINT64:
+ ImpPutUInt64( &aTmp, p->uInt64 ); break;
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if ( p->pOUString )
+ *aTmp.pOUString = *p->pOUString;
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ aRes = pVal->GetString();
+ else if( p->pObj && p->pObj->IsFixed()
+ && (p->pObj->GetType() == (SbxARRAY | SbxBYTE )) )
+ {
+ // convert byte array to string
+ SbxArray* pArr = PTR_CAST(SbxArray, p->pObj);
+ if( pArr )
+ aRes = ByteArrayToString( pArr );
+ }
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxERROR:
+ // Hier wird der String "Error n" erzeugt
+ aRes = SbxRes( STRING_ERRORMSG );
+ aRes += ::rtl::OUString( p->nUShort ); break;
+ case SbxDATE:
+ ImpPutDate( &aTmp, p->nDouble ); break;
+
+ case SbxBYREF | SbxCHAR:
+ ImpPutChar( &aTmp, *p->pChar ); break;
+ case SbxBYREF | SbxBYTE:
+ ImpPutByte( &aTmp, *p->pByte ); break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ ImpPutInteger( &aTmp, *p->pInteger ); break;
+ case SbxBYREF | SbxLONG:
+ ImpPutLong( &aTmp, *p->pLong ); break;
+ case SbxBYREF | SbxULONG:
+ ImpPutULong( &aTmp, *p->pULong ); break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ ImpPutUShort( &aTmp, *p->pUShort ); break;
+ case SbxBYREF | SbxSINGLE:
+ ImpPutSingle( &aTmp, *p->pSingle ); break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ ImpPutDouble( &aTmp, *p->pDouble ); break;
+ case SbxBYREF | SbxCURRENCY:
+ ImpPutCurrency( &aTmp, *p->pLong64 ); break;
+ case SbxBYREF | SbxSALINT64:
+ ImpPutInt64( &aTmp, *p->pnInt64 ); break;
+ case SbxBYREF | SbxSALUINT64:
+ ImpPutUInt64( &aTmp, *p->puInt64 ); break;
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+ return aRes;
+}
+
+// AB 10.4.97, neue Funktion fuer SbxValue::GetCoreString()
+::rtl::OUString ImpGetCoreString( const SbxValues* p )
+{
+ // Vorerst nur fuer double
+ if( ( p->eType & (~SbxBYREF) ) == SbxDOUBLE )
+ {
+ SbxValues aTmp;
+ XubString aRes;
+ aTmp.eType = SbxSTRING;
+ if( p->eType == SbxDOUBLE )
+ ImpPutDouble( &aTmp, p->nDouble, /*bCoreString=*/TRUE );
+ else
+ ImpPutDouble( &aTmp, *p->pDouble, /*bCoreString=*/TRUE );
+ return aRes;
+ }
+ else
+ return ImpGetString( p );
+}
+
+void ImpPutString( SbxValues* p, const ::rtl::OUString* n )
+{
+ SbxValues aTmp;
+ aTmp.eType = SbxSTRING;
+ ::rtl::OUString* pTmp = NULL;
+ // Sicherheitshalber, falls ein NULL-Ptr kommt
+ if( !n )
+ n = pTmp = new ::rtl::OUString;
+ aTmp.pOUString = (::rtl::OUString*)n;
+ switch( +p->eType )
+ {
+ case SbxCHAR:
+ p->nChar = ImpGetChar( &aTmp ); break;
+ case SbxBYTE:
+ p->nByte = ImpGetByte( &aTmp ); break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ p->nInteger = ImpGetInteger( &aTmp ); break;
+ case SbxLONG:
+ p->nLong = ImpGetLong( &aTmp ); break;
+ case SbxULONG:
+ p->nULong = ImpGetULong( &aTmp ); break;
+ case SbxERROR:
+ case SbxUSHORT:
+ p->nUShort = ImpGetUShort( &aTmp ); break;
+ case SbxSINGLE:
+ p->nSingle = ImpGetSingle( &aTmp ); break;
+ case SbxDATE:
+ p->nDouble = ImpGetDate( &aTmp ); break;
+ case SbxDOUBLE:
+ p->nDouble = ImpGetDouble( &aTmp ); break;
+ case SbxULONG64:
+ p->nLong64 = ImpGetCurrency( &aTmp ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ releaseDecimalPtr( p->pDecimal );
+ p->pDecimal = ImpGetDecimal( &aTmp ); break;
+ case SbxSALINT64:
+ p->nInt64 = ImpGetInt64( &aTmp ); break;
+ case SbxSALUINT64:
+ p->uInt64 = ImpGetUInt64( &aTmp ); break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( n->getLength() )
+ {
+ if( !p->pOUString )
+ p->pOUString = new ::rtl::OUString( *n );
+ else
+ *p->pOUString = *n;
+ }
+ else
+ delete p->pOUString, p->pOUString = NULL;
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutString( *n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ *p->pChar = ImpGetChar( p ); break;
+ case SbxBYREF | SbxBYTE:
+ *p->pByte = ImpGetByte( p ); break;
+ case SbxBYREF | SbxINTEGER:
+ *p->pInteger = ImpGetInteger( p ); break;
+ case SbxBYREF | SbxBOOL:
+ *p->pUShort = sal::static_int_cast< UINT16 >( ImpGetBool( p ) );
+ break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ *p->pUShort = ImpGetUShort( p ); break;
+ case SbxBYREF | SbxLONG:
+ *p->pLong = ImpGetLong( p ); break;
+ case SbxBYREF | SbxULONG:
+ *p->pULong = ImpGetULong( p ); break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = ImpGetSingle( p ); break;
+ case SbxBYREF | SbxDATE:
+ *p->pDouble = ImpGetDate( p ); break;
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = ImpGetDouble( p ); break;
+ case SbxBYREF | SbxCURRENCY:
+ *p->pLong64 = ImpGetCurrency( p ); break;
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+ delete pTmp;
+}
+
+// Convert string to an array of bytes, preserving unicode (2bytes per character)
+SbxArray* StringToByteArray(const ::rtl::OUString& rStr)
+{
+ sal_Int32 nArraySize = rStr.getLength() * 2;
+ const sal_Unicode* pSrc = rStr.getStr();
+ SbxDimArray* pArray = new SbxDimArray(SbxBYTE);
+ bool bIncIndex = ( IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
+ if( nArraySize )
+ {
+ if( bIncIndex )
+ pArray->AddDim32( 1, nArraySize );
+ else
+ pArray->AddDim32( 0, nArraySize-1 );
+ }
+ else
+ {
+ pArray->unoAddDim( 0, -1 );
+ }
+
+ for( USHORT i=0; i< nArraySize; i++)
+ {
+ SbxVariable* pNew = new SbxVariable( SbxBYTE );
+ BYTE aByte = static_cast< BYTE >( i%2 ? ((*pSrc) >> 8) & 0xff : (*pSrc) & 0xff );
+ pNew->PutByte( aByte );
+ pNew->SetFlag( SBX_WRITE );
+ pArray->Put( pNew, i );
+ if( i%2 )
+ pSrc++;
+ }
+ return pArray;
+}
+
+// Convert an array of bytes to string (2bytes per character)
+::rtl::OUString ByteArrayToString(SbxArray* pArr)
+{
+ USHORT nCount = pArr->Count();
+ OUStringBuffer aStrBuf;
+ sal_Unicode aChar = 0;
+ for( USHORT i = 0 ; i < nCount ; i++ )
+ {
+ sal_Unicode aTempChar = pArr->Get(i)->GetByte();
+ if( i%2 )
+ {
+ aChar = (aTempChar << 8 ) | aChar;
+ aStrBuf.append(aChar);
+ aChar = 0;
+ }
+ else
+ {
+ aChar = aTempChar;
+ }
+ }
+
+ if( nCount%2 )
+ {
+ aStrBuf.append(aChar);
+ }
+
+ return aStrBuf.makeStringAndClear();
+}
diff --git a/basic/source/sbx/sbxuint.cxx b/basic/source/sbx/sbxuint.cxx
new file mode 100644
index 000000000000..5b75a24d6d26
--- /dev/null
+++ b/basic/source/sbx/sbxuint.cxx
@@ -0,0 +1,331 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#include <basic/sbx.hxx>
+#include "sbxconv.hxx"
+
+UINT16 ImpGetUShort( const SbxValues* p )
+{
+ SbxValues aTmp;
+ UINT16 nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar;
+ break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ if( p->nInteger < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = p->nInteger;
+ break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort;
+ break;
+ case SbxLONG:
+ if( p->nLong > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXUINT;
+ }
+ else if( p->nLong < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT16) p->nLong;
+ break;
+ case SbxULONG:
+ if( p->nULong > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXUINT;
+ }
+ else
+ nRes = (UINT16) p->nULong;
+ break;
+ case SbxSALINT64:
+ if( p->nInt64 > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXUINT;
+ }
+ else if( p->nInt64 < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT16) p->nInt64;
+ break;
+ case SbxSALUINT64:
+ if( p->uInt64 > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXUINT;
+ }
+ else
+ nRes = (UINT16) p->uInt64;
+ break;
+ case SbxSINGLE:
+ if( p->nSingle > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXUINT;
+ }
+ else if( p->nSingle < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT16) ( p->nSingle + 0.5 );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else if( p->eType == SbxDECIMAL )
+ {
+ dVal = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( dVal );
+ }
+ else
+ dVal = p->nDouble;
+
+ if( dVal > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXUINT;
+ }
+ else if( dVal < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT16) ( dVal + 0.5 );
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ nRes = 0;
+ else
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXUINT;
+ }
+ else if( d < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT16) ( d + 0.5 );
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetUShort();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ nRes = *p->pUShort; break;
+
+ // ab hier wird getestet
+ case SbxBYREF | SbxCHAR:
+ aTmp.nChar = *p->pChar; goto ref;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ aTmp.nInteger = *p->pInteger; goto ref;
+ case SbxBYREF | SbxLONG:
+ aTmp.nLong = *p->pLong; goto ref;
+ case SbxBYREF | SbxULONG:
+ aTmp.nULong = *p->pULong; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutUShort( SbxValues* p, UINT16 n )
+{
+ SbxValues aTmp;
+
+start:
+ switch( +p->eType )
+ {
+ case SbxERROR:
+ case SbxUSHORT:
+ p->nUShort = n; break;
+ case SbxLONG:
+ p->nLong = n; break;
+ case SbxULONG:
+ p->nULong = n; break;
+ case SbxSINGLE:
+ p->nSingle = n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxSALUINT64:
+ p->uInt64 = n; break;
+ case SbxULONG64:
+ p->nULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxLONG64:
+ p->nLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxCURRENCY:
+ p->nLong64 = ImpDoubleToCurrency( (double)n ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ ImpCreateDecimal( p )->setUInt( n );
+ break;
+
+ // Tests ab hier
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger;
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ p->pOUString = new ::rtl::OUString;
+ ImpCvtNum( (double) n, 0, *p->pOUString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutUShort( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ *p->pUShort = n; break;
+ case SbxBYREF | SbxLONG:
+ *p->pLong = n; break;
+ case SbxBYREF | SbxULONG:
+ *p->pULong = n; break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = n; break;
+ case SbxBYREF | SbxULONG64:
+ *p->pULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxBYREF | SbxLONG64:
+ *p->pLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxBYREF | SbxCURRENCY:
+ *p->pLong64 = ImpDoubleToCurrency( (double)n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
diff --git a/basic/source/sbx/sbxulng.cxx b/basic/source/sbx/sbxulng.cxx
new file mode 100644
index 000000000000..e0f6f3fa421d
--- /dev/null
+++ b/basic/source/sbx/sbxulng.cxx
@@ -0,0 +1,321 @@
+/*************************************************************************
+ *
+ * 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/errcode.hxx>
+#include <basic/sbx.hxx>
+#include "sbxconv.hxx"
+
+UINT32 ImpGetULong( const SbxValues* p )
+{
+ SbxValues aTmp;
+ UINT32 nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar;
+ break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ if( p->nInteger < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = p->nInteger;
+ break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort;
+ break;
+ case SbxLONG:
+ if( p->nLong < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = p->nLong;
+ break;
+ case SbxULONG:
+ nRes = p->nULong; break;
+ case SbxSINGLE:
+ if( p->nSingle > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXULNG;
+ }
+ else if( p->nSingle < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT32) ( p->nSingle + 0.5 );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxSALINT64:
+ case SbxSALUINT64:
+ case SbxCURRENCY:
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else if( p->eType == SbxSALINT64 )
+ dVal = static_cast< double >(p->nInt64);
+ else if( p->eType == SbxSALUINT64 )
+ dVal = ImpSalUInt64ToDouble( p->uInt64 );
+ else if( p->eType == SbxDECIMAL )
+ {
+ dVal = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( dVal );
+ }
+ else
+ dVal = p->nDouble;
+
+ if( dVal > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXULNG;
+ }
+ else if( dVal < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT32) ( dVal + 0.5 );
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ nRes = 0;
+ else
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXULNG;
+ }
+ else if( d < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT32) ( d + 0.5 );
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetULong();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ nRes = *p->pUShort; break;
+ case SbxBYREF | SbxULONG:
+ nRes = *p->pULong; break;
+
+ // Tests ab hier
+ case SbxBYREF | SbxCHAR:
+ aTmp.nChar = *p->pChar; goto ref;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ aTmp.nInteger = *p->pInteger; goto ref;
+ case SbxBYREF | SbxLONG:
+ aTmp.nLong = *p->pLong; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutULong( SbxValues* p, UINT32 n )
+{
+ SbxValues aTmp;
+start:
+ switch( +p->eType )
+ {
+ case SbxULONG:
+ p->nULong = n; break;
+ case SbxSINGLE:
+ p->nSingle = (float) n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxSALUINT64:
+ p->uInt64 = n; break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ ImpCreateDecimal( p )->setULong( n );
+ break;
+
+ // Tests ab hier
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxUINT:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxLONG:
+ aTmp.pLong = &p->nLong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxULONG64:
+ aTmp.pULong64 = &p->nULong64; goto direct;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ aTmp.pLong64 = &p->nLong64; goto direct;
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pOUString )
+ p->pOUString = new ::rtl::OUString;
+ ImpCvtNum( (double) n, 0, *p->pOUString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutULong( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
+ }
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ if( n > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
+ }
+ *p->pLong = (INT32) n; break;
+ case SbxBYREF | SbxULONG:
+ *p->pULong = n; break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = n; break;
+ case SbxBYREF | SbxCURRENCY:
+ double d;
+ if( n > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); d = SbxMAXCURR;
+ }
+ else
+ {
+ d = n;
+ }
+ *p->pLong64 = ImpDoubleToCurrency( n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
diff --git a/basic/source/sbx/sbxvals.cxx b/basic/source/sbx/sbxvals.cxx
new file mode 100644
index 000000000000..e63a352879ed
--- /dev/null
+++ b/basic/source/sbx/sbxvals.cxx
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * 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"
+
+#define _TLBIGINT_INT64
+#include <tools/bigint.hxx>
+#include <basic/sbx.hxx>
+
+///////////////////////////// BigInt/Currency //////////////////////////////
+
+SbxValues::SbxValues( const BigInt &rBig ) : eType(SbxCURRENCY)
+{
+ rBig.INT64( &nLong64 );
+}
+
+//TODO: BigInt is TOOLS_DLLPUBLIC, and its four member functions only declared
+// and defined within basic (#define _TLBIGINT_INT64) are a bad hack that causes
+// "warning C4273: 'function' : inconsistent dll linkage" on MSC; this whole
+// mess should be cleaned up properly (e.g., by completely removing Sbx[U]INT64
+// and using sal_[u]Int64 instead):
+#if defined _MSC_VER
+#pragma warning(disable: 4273)
+#endif
+
+BOOL BigInt::INT64( SbxINT64 *p ) const
+{
+ if( bIsBig ) {
+ if( nLen > 4 || (nNum[3] & 0x8000) )
+ return FALSE;
+
+ p->nLow = ((UINT32)nNum[1] << 16) | (UINT32)nNum[0];
+ p->nHigh = ((UINT32)nNum[3] << 16) | (UINT32)nNum[2];
+ if( bIsNeg )
+ p->CHS();
+ }
+ else
+ p->Set( (INT32)nVal );
+
+ return TRUE;
+}
+
+BigInt::BigInt( const SbxINT64 &r )
+{
+ BigInt a10000 = 0x10000;
+
+ *this = r.nHigh;
+ if( r.nHigh )
+ *this *= a10000;
+ *this += (USHORT)(r.nLow >> 16);
+ *this *= a10000;
+ *this += (USHORT)r.nLow;
+}
+
+BOOL BigInt::UINT64( SbxUINT64 *p ) const
+{
+ if( bIsBig ) {
+ if( bIsNeg || nLen > 4 )
+ return FALSE;
+
+ p->nLow = ((UINT32)nNum[1] << 16) | (UINT32)nNum[0];
+ p->nHigh = ((UINT32)nNum[3] << 16) | (UINT32)nNum[2];
+ }
+ else {
+ if( nVal < 0 )
+ return FALSE;
+
+ p->Set( (UINT32)nVal );
+ }
+
+ return TRUE;
+}
+
+BigInt::BigInt( const SbxUINT64 &r )
+{
+ BigInt a10000 = 0x10000;
+
+ *this = BigInt(r.nHigh);
+ if( r.nHigh )
+ *this *= a10000;
+ *this += (USHORT)(r.nLow >> 16);
+ *this *= a10000;
+ *this += (USHORT)r.nLow;
+}
diff --git a/basic/source/sbx/sbxvalue.cxx b/basic/source/sbx/sbxvalue.cxx
new file mode 100644
index 000000000000..4ea4836b701b
--- /dev/null
+++ b/basic/source/sbx/sbxvalue.cxx
@@ -0,0 +1,1858 @@
+/*************************************************************************
+ *
+ * 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"
+
+#define _TLBIGINT_INT64
+#include <tools/bigint.hxx>
+#include <tools/stream.hxx>
+
+#include <basic/sbx.hxx>
+#include "sbxconv.hxx"
+#include <math.h>
+#include "runtime.hxx"
+// AB 29.10.99 Unicode
+#ifndef _USE_NO_NAMESPACE
+using namespace rtl;
+#endif
+
+
+TYPEINIT1(SbxValue,SbxBase)
+
+/////////////////////////// SbxINT64 /////////////////////////////////////
+SbxINT64 &SbxINT64::operator -= ( const SbxINT64 &r )
+{
+ BigInt b( *this );
+ b -= BigInt( r );
+ b.INT64( this );
+ return *this;
+}
+SbxINT64 &SbxINT64::operator += ( const SbxINT64 &r )
+{
+ BigInt b( *this );
+ b += BigInt( r );
+ b.INT64( this );
+ return *this;
+}
+SbxINT64 &SbxINT64::operator *= ( const SbxINT64 &r )
+{
+ BigInt b( *this );
+ b *= BigInt( r );
+ b.INT64( this );
+ return *this;
+}
+SbxINT64 &SbxINT64::operator %= ( const SbxINT64 &r )
+{
+ BigInt b( *this );
+ b %= BigInt( r );
+ b.INT64( this );
+ return *this;
+}
+SbxINT64 &SbxINT64::operator /= ( const SbxINT64 &r )
+{
+ BigInt b( *this );
+ b /= BigInt( r );
+ b.INT64( this );
+ return *this;
+}
+SbxINT64 &SbxINT64::operator &= ( const SbxINT64 &r )
+{
+ nHigh &= r.nHigh;
+ nLow &= r.nLow;
+ return *this;
+}
+SbxINT64 &SbxINT64::operator |= ( const SbxINT64 &r )
+{
+ nHigh |= r.nHigh;
+ nLow |= r.nLow;
+ return *this;
+}
+SbxINT64 &SbxINT64::operator ^= ( const SbxINT64 &r )
+{
+ nHigh ^= r.nHigh;
+ nLow ^= r.nLow;
+ return *this;
+}
+
+SbxINT64 operator - ( const SbxINT64 &l, const SbxINT64 &r )
+{
+ SbxINT64 a(l);
+ a -= r;
+ return a;
+}
+SbxINT64 operator + ( const SbxINT64 &l, const SbxINT64 &r )
+{
+ SbxINT64 a(l);
+ a += r;
+ return a;
+}
+SbxINT64 operator / ( const SbxINT64 &l, const SbxINT64 &r )
+{
+ SbxINT64 a(l);
+ a /= r;
+ return a;
+}
+SbxINT64 operator % ( const SbxINT64 &l, const SbxINT64 &r )
+{
+ SbxINT64 a(l);
+ a %= r;
+ return a;
+}
+SbxINT64 operator * ( const SbxINT64 &l, const SbxINT64 &r )
+{
+ SbxINT64 a(l);
+ a *= r;
+ return a;
+}
+SbxINT64 operator & ( const SbxINT64 &l, const SbxINT64 &r )
+{
+ SbxINT64 a;
+ a.nHigh = r.nHigh & l.nHigh;
+ a.nLow = r.nLow & l.nLow;
+ return a;
+}
+SbxINT64 operator | ( const SbxINT64 &l, const SbxINT64 &r )
+{
+ SbxINT64 a;
+ a.nHigh = r.nHigh | l.nHigh;
+ a.nLow = r.nLow | l.nLow;
+ return a;
+}
+SbxINT64 operator ^ ( const SbxINT64 &r, const SbxINT64 &l )
+{
+ SbxINT64 a;
+ a.nHigh = r.nHigh ^ l.nHigh;
+ a.nLow = r.nLow ^ l.nLow;
+ return a;
+}
+
+SbxINT64 operator - ( const SbxINT64 &r )
+{
+ SbxINT64 a( r );
+ a.CHS();
+ return a;
+}
+SbxINT64 operator ~ ( const SbxINT64 &r )
+{
+ SbxINT64 a;
+ a.nHigh = ~r.nHigh;
+ a.nLow = ~r.nLow;
+ return a;
+}
+
+SbxUINT64 &SbxUINT64::operator %= ( const SbxUINT64 &r )
+{
+ BigInt b( *this );
+ b %= BigInt( r );
+ b.UINT64( this );
+ return *this;
+}
+SbxUINT64 &SbxUINT64::operator /= ( const SbxUINT64 &r )
+{
+ BigInt b( *this );
+ b /= BigInt( r );
+ b.UINT64( this );
+ return *this;
+}
+/////////////////////////// Fehlerbehandlung /////////////////////////////
+
+#ifdef _USED
+// NOCH NACHZUBAUEN!
+
+// Das Default-Handling setzt nur den Fehlercode.
+
+#ifndef WNT
+#if defined ( UNX )
+int matherr( struct exception* p )
+#else
+int matherr( struct _exception* p )
+#endif
+{
+ switch( p->type )
+ {
+#if defined ( UNX )
+ case OVERFLOW: SbxBase::SetError( SbxERR_OVERFLOW ); break;
+#else
+ case _OVERFLOW: SbxBase::SetError( SbxERR_OVERFLOW ); break;
+#endif
+ default: SbxBase::SetError( SbxERR_NOTIMP ); break;
+ }
+ return TRUE;
+}
+#endif
+
+#endif // _USED
+
+
+///////////////////////////// Konstruktoren //////////////////////////////
+
+SbxValue::SbxValue() : SbxBase()
+{
+ aData.eType = SbxEMPTY;
+}
+
+SbxValue::SbxValue( SbxDataType t, void* p ) : SbxBase()
+{
+ int n = t & 0x0FFF;
+ if( p )
+ n |= SbxBYREF;
+ if( n == SbxVARIANT )
+ n = SbxEMPTY;
+ else
+ SetFlag( SBX_FIXED );
+ if( p )
+ switch( t & 0x0FFF )
+ {
+ case SbxINTEGER: n |= SbxBYREF; aData.pInteger = (INT16*) p; break;
+ case SbxULONG64: n |= SbxBYREF; aData.pULong64 = (SbxUINT64*) p; break;
+ case SbxLONG64:
+ case SbxCURRENCY: n |= SbxBYREF; aData.pLong64 = (SbxINT64*) p; break;
+ case SbxLONG: n |= SbxBYREF; aData.pLong = (INT32*) p; break;
+ case SbxSINGLE: n |= SbxBYREF; aData.pSingle = (float*) p; break;
+ case SbxDATE:
+ case SbxDOUBLE: n |= SbxBYREF; aData.pDouble = (double*) p; break;
+ case SbxSTRING: n |= SbxBYREF; aData.pOUString = (::rtl::OUString*) p; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ case SbxBOOL: n |= SbxBYREF; aData.pUShort = (UINT16*) p; break;
+ case SbxULONG: n |= SbxBYREF; aData.pULong = (UINT32*) p; break;
+ case SbxCHAR: n |= SbxBYREF; aData.pChar = (xub_Unicode*) p; break;
+ case SbxBYTE: n |= SbxBYREF; aData.pByte = (BYTE*) p; break;
+ case SbxINT: n |= SbxBYREF; aData.pInt = (int*) p; break;
+ case SbxOBJECT:
+ aData.pObj = (SbxBase*) p;
+ if( p )
+ aData.pObj->AddRef();
+ break;
+ case SbxDECIMAL:
+ aData.pDecimal = (SbxDecimal*) p;
+ if( p )
+ aData.pDecimal->addRef();
+ break;
+ default:
+ DBG_ASSERT( !this, "Angabe eines Pointers unzulaessig" );
+ n = SbxNULL;
+ }
+ else
+ memset( &aData, 0, sizeof( SbxValues ) );
+ aData.eType = SbxDataType( n );
+}
+
+SbxValue::SbxValue( const SbxValue& r )
+ : SvRefBase( r ), SbxBase( r )
+{
+ if( !r.CanRead() )
+ {
+ SetError( SbxERR_PROP_WRITEONLY );
+ if( !IsFixed() )
+ aData.eType = SbxNULL;
+ }
+ else
+ {
+ ((SbxValue*) &r)->Broadcast( SBX_HINT_DATAWANTED );
+ aData = r.aData;
+ // Pointer kopieren, Referenzen inkrementieren
+ switch( aData.eType )
+ {
+ case SbxSTRING:
+ if( aData.pOUString )
+ aData.pOUString = new ::rtl::OUString( *aData.pOUString );
+ break;
+ case SbxOBJECT:
+ if( aData.pObj )
+ aData.pObj->AddRef();
+ break;
+ case SbxDECIMAL:
+ if( aData.pDecimal )
+ aData.pDecimal->addRef();
+ break;
+ default: break;
+ }
+ }
+}
+
+SbxValue& SbxValue::operator=( const SbxValue& r )
+{
+ if( &r != this )
+ {
+ if( !CanWrite() )
+ SetError( SbxERR_PROP_READONLY );
+ else
+ {
+ // string -> byte array
+ if( IsFixed() && (aData.eType == SbxOBJECT)
+ && aData.pObj && ( aData.pObj->GetType() == (SbxARRAY | SbxBYTE) )
+ && (r.aData.eType == SbxSTRING) )
+ {
+ ::rtl::OUString aStr = r.GetString();
+ SbxArray* pArr = StringToByteArray(aStr);
+ PutObject(pArr);
+ return *this;
+ }
+ // byte array -> string
+ if( r.IsFixed() && (r.aData.eType == SbxOBJECT)
+ && r.aData.pObj && ( r.aData.pObj->GetType() == (SbxARRAY | SbxBYTE) )
+ && (aData.eType == SbxSTRING) )
+ {
+ SbxBase* pObj = r.GetObject();
+ SbxArray* pArr = PTR_CAST(SbxArray, pObj);
+ if( pArr )
+ {
+ ::rtl::OUString aStr = ByteArrayToString( pArr );
+ PutString(aStr);
+ return *this;
+ }
+ }
+ // Den Inhalt der Variablen auslesen
+ SbxValues aNew;
+ if( IsFixed() )
+ // fest: dann muss der Typ stimmen
+ aNew.eType = aData.eType;
+ else if( r.IsFixed() )
+ // Quelle fest: Typ uebernehmen
+ aNew.eType = SbxDataType( r.aData.eType & 0x0FFF );
+ else
+ // beides Variant: dann isses egal
+ aNew.eType = SbxVARIANT;
+ if( r.Get( aNew ) )
+ Put( aNew );
+ }
+ }
+ return *this;
+}
+
+SbxValue::~SbxValue()
+{
+#ifndef C50
+ Broadcast( SBX_HINT_DYING );
+ SetFlag( SBX_WRITE );
+ SbxValue::Clear();
+#else
+ // Provisorischer Fix fuer Solaris 5.0 Compiler Bug
+ // bei Nutzung virtueller Vererbung. Virtuelle Calls
+ // im Destruktor vermeiden. Statt Clear() zu rufen
+ // moegliche Objekt-Referenzen direkt freigeben.
+ if( aData.eType == SbxOBJECT )
+ {
+ if( aData.pObj && aData.pObj != this )
+ {
+ HACK(nicht bei Parent-Prop - sonst CyclicRef)
+ SbxVariable *pThisVar = PTR_CAST(SbxVariable, this);
+ BOOL bParentProp = pThisVar && 5345 ==
+ ( (INT16) ( pThisVar->GetUserData() & 0xFFFF ) );
+ if ( !bParentProp )
+ aData.pObj->ReleaseRef();
+ }
+ }
+ else if( aData.eType == SbxDECIMAL )
+ {
+ releaseDecimalPtr( aData.pDecimal );
+ }
+#endif
+}
+
+void SbxValue::Clear()
+{
+ switch( aData.eType )
+ {
+ case SbxNULL:
+ case SbxEMPTY:
+ case SbxVOID:
+ break;
+ case SbxSTRING:
+ delete aData.pOUString; aData.pOUString = NULL;
+ break;
+ case SbxOBJECT:
+ if( aData.pObj )
+ {
+ if( aData.pObj != this )
+ {
+ HACK(nicht bei Parent-Prop - sonst CyclicRef)
+ SbxVariable *pThisVar = PTR_CAST(SbxVariable, this);
+ BOOL bParentProp = pThisVar && 5345 ==
+ ( (INT16) ( pThisVar->GetUserData() & 0xFFFF ) );
+ if ( !bParentProp )
+ aData.pObj->ReleaseRef();
+ }
+ aData.pObj = NULL;
+ }
+ break;
+ case SbxDECIMAL:
+ if( aData.eType == SbxDECIMAL )
+ releaseDecimalPtr( aData.pDecimal );
+ break;
+ case SbxDATAOBJECT:
+ aData.pData = NULL; break;
+ default:
+ {
+ SbxValues aEmpty;
+ memset( &aEmpty, 0, sizeof( SbxValues ) );
+ aEmpty.eType = GetType();
+ Put( aEmpty );
+ }
+ }
+}
+
+// Dummy
+
+void SbxValue::Broadcast( ULONG )
+{}
+
+//////////////////////////// Daten auslesen //////////////////////////////
+
+// Ermitteln der "richtigen" Variablen. Falls es ein Objekt ist, wird
+// entweder das Objekt selbst oder dessen Default-Property angesprochen.
+// Falls die Variable eine Variable oder ein Objekt enthaelt, wird
+// dieses angesprochen.
+
+SbxValue* SbxValue::TheRealValue() const
+{
+ return TheRealValue( TRUE );
+}
+
+// #55226 Zusaetzliche Info transportieren
+SbxValue* SbxValue::TheRealValue( BOOL bObjInObjError ) const
+{
+ SbxValue* p = (SbxValue*) this;
+ for( ;; )
+ {
+ SbxDataType t = SbxDataType( p->aData.eType & 0x0FFF );
+ if( t == SbxOBJECT )
+ {
+ // Der Block enthaelt ein Objekt oder eine Variable
+ SbxObject* pObj = PTR_CAST(SbxObject,p->aData.pObj);
+ if( pObj )
+ {
+ // Hat das Objekt eine Default-Property?
+ SbxVariable* pDflt = pObj->GetDfltProperty();
+
+ // Falls dies ein Objekt ist und sich selbst enthaelt,
+ // koennen wir nicht darauf zugreifen
+ // #55226# Die alte Bedingung, um einen Fehler zu setzen,
+ // ist nicht richtig, da z.B. eine ganz normale Variant-
+ // Variable mit Objekt davon betroffen sein kann, wenn ein
+ // anderer Wert zugewiesen werden soll. Daher mit Flag.
+ if( bObjInObjError && !pDflt &&
+ ((SbxValue*) pObj)->aData.eType == SbxOBJECT &&
+ ((SbxValue*) pObj)->aData.pObj == pObj )
+ {
+ SetError( SbxERR_BAD_PROP_VALUE );
+ p = NULL;
+ }
+ else if( pDflt )
+ p = pDflt;
+ /* ALT:
+ else
+ p = pDflt ? pDflt : (SbxVariable*) pObj;
+ */
+ break;
+ }
+ // Haben wir ein Array?
+ SbxArray* pArray = PTR_CAST(SbxArray,p->aData.pObj);
+ if( pArray )
+ {
+ // Ggf. Parameter holen
+ SbxArray* pPar = NULL;
+ SbxVariable* pVar = PTR_CAST(SbxVariable,p);
+ if( pVar )
+ pPar = pVar->GetParameters();
+ if( pPar )
+ {
+ // Haben wir ein dimensioniertes Array?
+ SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,p->aData.pObj);
+ if( pDimArray )
+ p = pDimArray->Get( pPar );
+ else
+ p = pArray->Get( pPar->Get( 1 )->GetInteger() );
+ break;
+ }
+ }
+ // Sonst einen SbxValue annehmen
+ SbxValue* pVal = PTR_CAST(SbxValue,p->aData.pObj);
+ if( pVal )
+ p = pVal;
+ else
+ break;
+ }
+ else
+ break;
+ }
+ return p;
+}
+
+BOOL SbxValue::Get( SbxValues& rRes ) const
+{
+ BOOL bRes = FALSE;
+ SbxError eOld = GetError();
+ if( eOld != SbxERR_OK )
+ ResetError();
+ if( !CanRead() )
+ {
+ SetError( SbxERR_PROP_WRITEONLY );
+ rRes.pObj = NULL;
+ }
+ else
+ {
+ // Falls nach einem Objekt oder einem VARIANT gefragt wird, nicht
+ // die wahren Werte suchen
+ SbxValue* p = (SbxValue*) this;
+ if( rRes.eType != SbxOBJECT && rRes.eType != SbxVARIANT )
+ p = TheRealValue();
+ if( p )
+ {
+ p->Broadcast( SBX_HINT_DATAWANTED );
+ switch( rRes.eType )
+ {
+ case SbxEMPTY:
+ case SbxVOID:
+ case SbxNULL: break;
+ case SbxVARIANT: rRes = p->aData; break;
+ case SbxINTEGER: rRes.nInteger = ImpGetInteger( &p->aData ); break;
+ case SbxLONG: rRes.nLong = ImpGetLong( &p->aData ); break;
+ case SbxSALINT64: rRes.nInt64 = ImpGetInt64( &p->aData ); break;
+ case SbxSALUINT64: rRes.uInt64 = ImpGetUInt64( &p->aData ); break;
+ case SbxSINGLE: rRes.nSingle = ImpGetSingle( &p->aData ); break;
+ case SbxDOUBLE: rRes.nDouble = ImpGetDouble( &p->aData ); break;
+ case SbxCURRENCY:rRes.nLong64 = ImpGetCurrency( &p->aData ); break;
+ case SbxDECIMAL: rRes.pDecimal = ImpGetDecimal( &p->aData ); break;
+ case SbxDATE: rRes.nDouble = ImpGetDate( &p->aData ); break;
+ case SbxBOOL:
+ rRes.nUShort = sal::static_int_cast< UINT16 >(
+ ImpGetBool( &p->aData ) );
+ break;
+ case SbxCHAR: rRes.nChar = ImpGetChar( &p->aData ); break;
+ case SbxBYTE: rRes.nByte = ImpGetByte( &p->aData ); break;
+ case SbxUSHORT: rRes.nUShort = ImpGetUShort( &p->aData ); break;
+ case SbxULONG: rRes.nULong = ImpGetULong( &p->aData ); break;
+ case SbxLPSTR:
+ case SbxSTRING: p->aPic = ImpGetString( &p->aData );
+ rRes.pOUString = &p->aPic; break;
+ case SbxCoreSTRING: p->aPic = ImpGetCoreString( &p->aData );
+ rRes.pOUString = &p->aPic; break;
+ case SbxINT:
+#if SAL_TYPES_SIZEOFINT == 2
+ rRes.nInt = (int) ImpGetInteger( &p->aData );
+#else
+ rRes.nInt = (int) ImpGetLong( &p->aData );
+#endif
+ break;
+ case SbxUINT:
+#if SAL_TYPES_SIZEOFINT == 2
+ rRes.nUInt = (int) ImpGetUShort( &p->aData );
+#else
+ rRes.nUInt = (int) ImpGetULong( &p->aData );
+#endif
+ break;
+ case SbxOBJECT:
+ if( p->aData.eType == SbxOBJECT )
+ rRes.pObj = p->aData.pObj;
+ else
+ {
+ SetError( SbxERR_NO_OBJECT );
+ rRes.pObj = NULL;
+ }
+ break;
+ default:
+ if( p->aData.eType == rRes.eType )
+ rRes = p->aData;
+ else
+ {
+ SetError( SbxERR_CONVERSION );
+ rRes.pObj = NULL;
+ }
+ }
+ }
+ else
+ {
+ // Objekt enthielt sich selbst
+ SbxDataType eTemp = rRes.eType;
+ memset( &rRes, 0, sizeof( SbxValues ) );
+ rRes.eType = eTemp;
+ }
+ }
+ if( !IsError() )
+ {
+ bRes = TRUE;
+ if( eOld != SbxERR_OK )
+ SetError( eOld );
+ }
+ return bRes;
+}
+
+BOOL SbxValue::GetNoBroadcast( SbxValues& rRes )
+{
+ USHORT nFlags_ = GetFlags();
+ SetFlag( SBX_NO_BROADCAST );
+ BOOL bRes = Get( rRes );
+ SetFlags( nFlags_ );
+ return bRes;
+}
+
+const XubString& SbxValue::GetString() const
+{
+ SbxValues aRes;
+ aRes.eType = SbxSTRING;
+ if( Get( aRes ) )
+ ((SbxValue*) this)->aToolString = *aRes.pOUString;
+ else
+ ((SbxValue*) this)->aToolString.Erase();
+
+ return aToolString;
+}
+
+const XubString& SbxValue::GetCoreString() const
+{
+ SbxValues aRes;
+ aRes.eType = SbxCoreSTRING;
+ if( Get( aRes ) )
+ ((SbxValue*) this)->aToolString = *aRes.pOUString;
+ else
+ ((SbxValue*) this)->aToolString.Erase();
+
+ return aToolString;
+}
+
+::rtl::OUString SbxValue::GetOUString() const
+{
+ ::rtl::OUString aResult;
+ SbxValues aRes;
+ aRes.eType = SbxSTRING;
+ if( Get( aRes ) )
+ aResult = *aRes.pOUString;
+
+ return aResult;
+}
+
+BOOL SbxValue::HasObject() const
+{
+ ErrCode eErr = GetError();
+ SbxValues aRes;
+ aRes.eType = SbxOBJECT;
+ Get( aRes );
+ SetError( eErr );
+ return 0 != aRes.pObj;
+}
+
+BOOL SbxValue::GetBool() const
+{
+ SbxValues aRes;
+ aRes.eType = SbxBOOL;
+ Get( aRes );
+ return BOOL( aRes.nUShort != 0 );
+}
+
+#define GET( g, e, t, m ) \
+t SbxValue::g() const { SbxValues aRes(e); Get( aRes ); return aRes.m; }
+
+GET( GetByte, SbxBYTE, BYTE, nByte )
+GET( GetChar, SbxCHAR, xub_Unicode, nChar )
+GET( GetCurrency, SbxCURRENCY, SbxINT64, nLong64 )
+GET( GetDate, SbxDATE, double, nDouble )
+GET( GetData, SbxDATAOBJECT, void*, pData )
+GET( GetDouble, SbxDOUBLE, double, nDouble )
+GET( GetErr, SbxERROR, UINT16, nUShort )
+GET( GetInt, SbxINT, int, nInt )
+GET( GetInteger, SbxINTEGER, INT16, nInteger )
+GET( GetLong, SbxLONG, INT32, nLong )
+GET( GetLong64, SbxLONG64, SbxINT64, nLong64 )
+GET( GetObject, SbxOBJECT, SbxBase*, pObj )
+GET( GetSingle, SbxSINGLE, float, nSingle )
+GET( GetULong, SbxULONG, UINT32, nULong )
+GET( GetULong64, SbxULONG64, SbxUINT64, nULong64 )
+GET( GetUShort, SbxUSHORT, UINT16, nUShort )
+GET( GetInt64, SbxSALINT64, sal_Int64, nInt64 )
+GET( GetUInt64, SbxSALUINT64, sal_uInt64, uInt64 )
+GET( GetDecimal, SbxDECIMAL, SbxDecimal*, pDecimal )
+
+
+//////////////////////////// Daten schreiben /////////////////////////////
+
+BOOL SbxValue::Put( const SbxValues& rVal )
+{
+ BOOL bRes = FALSE;
+ SbxError eOld = GetError();
+ if( eOld != SbxERR_OK )
+ ResetError();
+ if( !CanWrite() )
+ SetError( SbxERR_PROP_READONLY );
+ else if( rVal.eType & 0xF000 )
+ SetError( SbxERR_NOTIMP );
+ else
+ {
+ // Falls nach einem Objekt gefragt wird, nicht
+ // die wahren Werte suchen
+ SbxValue* p = this;
+ if( rVal.eType != SbxOBJECT )
+ p = TheRealValue( FALSE ); // #55226 Hier keinen Fehler erlauben
+ if( p )
+ {
+ if( !p->CanWrite() )
+ SetError( SbxERR_PROP_READONLY );
+ else if( p->IsFixed() || p->SetType( (SbxDataType) ( rVal.eType & 0x0FFF ) ) )
+ switch( rVal.eType & 0x0FFF )
+ {
+ case SbxEMPTY:
+ case SbxVOID:
+ case SbxNULL: break;
+ case SbxINTEGER: ImpPutInteger( &p->aData, rVal.nInteger ); break;
+ case SbxLONG: ImpPutLong( &p->aData, rVal.nLong ); break;
+ case SbxSALINT64: ImpPutInt64( &p->aData, rVal.nInt64 ); break;
+ case SbxSALUINT64: ImpPutUInt64( &p->aData, rVal.uInt64 ); break;
+ case SbxSINGLE: ImpPutSingle( &p->aData, rVal.nSingle ); break;
+ case SbxDOUBLE: ImpPutDouble( &p->aData, rVal.nDouble ); break;
+ case SbxCURRENCY: ImpPutCurrency( &p->aData, rVal.nLong64 ); break;
+ case SbxDECIMAL: ImpPutDecimal( &p->aData, rVal.pDecimal ); break;
+ case SbxDATE: ImpPutDate( &p->aData, rVal.nDouble ); break;
+ case SbxBOOL: ImpPutBool( &p->aData, rVal.nInteger ); break;
+ case SbxCHAR: ImpPutChar( &p->aData, rVal.nChar ); break;
+ case SbxBYTE: ImpPutByte( &p->aData, rVal.nByte ); break;
+ case SbxUSHORT: ImpPutUShort( &p->aData, rVal.nUShort ); break;
+ case SbxULONG: ImpPutULong( &p->aData, rVal.nULong ); break;
+ case SbxLPSTR:
+ case SbxSTRING: ImpPutString( &p->aData, rVal.pOUString ); break;
+ case SbxINT:
+#if SAL_TYPES_SIZEOFINT == 2
+ ImpPutInteger( &p->aData, (INT16) rVal.nInt );
+#else
+ ImpPutLong( &p->aData, (INT32) rVal.nInt );
+#endif
+ break;
+ case SbxUINT:
+#if SAL_TYPES_SIZEOFINT == 2
+ ImpPutUShort( &p->aData, (UINT16) rVal.nUInt );
+#else
+ ImpPutULong( &p->aData, (UINT32) rVal.nUInt );
+#endif
+ break;
+ case SbxOBJECT:
+ if( !p->IsFixed() || p->aData.eType == SbxOBJECT )
+ {
+ // ist schon drin
+ if( p->aData.eType == SbxOBJECT && p->aData.pObj == rVal.pObj )
+ break;
+
+ // Nur den Werteteil loeschen!
+ p->SbxValue::Clear();
+
+ // eingentliche Zuweisung
+ p->aData.pObj = rVal.pObj;
+
+ // ggf. Ref-Count mitzaehlen
+ if( p->aData.pObj && p->aData.pObj != p )
+ {
+ if ( p != this )
+ {
+ DBG_ERROR( "TheRealValue" );
+ }
+ HACK(nicht bei Parent-Prop - sonst CyclicRef)
+ SbxVariable *pThisVar = PTR_CAST(SbxVariable, this);
+ BOOL bParentProp = pThisVar && 5345 ==
+ ( (INT16) ( pThisVar->GetUserData() & 0xFFFF ) );
+ if ( !bParentProp )
+ p->aData.pObj->AddRef();
+ }
+ }
+ else
+ SetError( SbxERR_CONVERSION );
+ break;
+ default:
+ if( p->aData.eType == rVal.eType )
+ p->aData = rVal;
+ else
+ {
+ SetError( SbxERR_CONVERSION );
+ if( !p->IsFixed() )
+ p->aData.eType = SbxNULL;
+ }
+ }
+ if( !IsError() )
+ {
+ p->SetModified( TRUE );
+ p->Broadcast( SBX_HINT_DATACHANGED );
+ if( eOld != SbxERR_OK )
+ SetError( eOld );
+ bRes = TRUE;
+ }
+ }
+ }
+ return bRes;
+}
+
+// AB, 28.3.96:
+// Methode, um bei speziellen Typen eine Vorbehandlung des Strings
+// durchzufuehren. Insbesondere erforderlich fuer BASIC-IDE, damit
+// die Ausgaben im Watch-Fenster mit PutStringExt zurueckgeschrieben
+// werden koennen, wenn Floats mit ',' als Dezimaltrenner oder BOOLs
+// explizit mit "TRUE" oder "FALSE" angegeben werden.
+// Implementierung in ImpConvStringExt (SBXSCAN.CXX)
+BOOL SbxValue::PutStringExt( const ::rtl::OUString& r )
+{
+ // Kopieren, bei Unicode gleich konvertieren
+ ::rtl::OUString aStr( r );
+
+ // Eigenen Typ bestimmen (nicht wie in Put() mit TheRealValue(),
+ // Objekte werden sowieso nicht behandelt)
+ SbxDataType eTargetType = SbxDataType( aData.eType & 0x0FFF );
+
+ // Source-Value basteln
+ SbxValues aRes;
+ aRes.eType = SbxSTRING;
+
+ // Nur, wenn wirklich was konvertiert wurde, Kopie nehmen,
+ // sonst Original (Unicode bleibt erhalten)
+ BOOL bRet;
+ if( ImpConvStringExt( aStr, eTargetType ) )
+ aRes.pOUString = (::rtl::OUString*)&aStr;
+ else
+ aRes.pOUString = (::rtl::OUString*)&r;
+
+ // #34939: Bei Strings. die eine Zahl enthalten und wenn this einen
+ // Num-Typ hat, Fixed-Flag setzen, damit der Typ nicht veraendert wird
+ USHORT nFlags_ = GetFlags();
+ if( ( eTargetType >= SbxINTEGER && eTargetType <= SbxCURRENCY ) ||
+ ( eTargetType >= SbxCHAR && eTargetType <= SbxUINT ) ||
+ eTargetType == SbxBOOL )
+ {
+ SbxValue aVal;
+ aVal.Put( aRes );
+ if( aVal.IsNumeric() )
+ SetFlag( SBX_FIXED );
+ }
+
+ Put( aRes );
+ bRet = BOOL( !IsError() );
+
+ // Falls das mit dem FIXED einen Error gegeben hat, zuruecksetzen
+ // (UI-Aktion sollte keinen Error ergeben, sondern nur scheitern)
+ if( !bRet )
+ ResetError();
+
+ SetFlags( nFlags_ );
+ return bRet;
+}
+
+BOOL SbxValue::PutString( const xub_Unicode* p )
+{
+ ::rtl::OUString aVal( p );
+ SbxValues aRes;
+ aRes.eType = SbxSTRING;
+ aRes.pOUString = &aVal;
+ Put( aRes );
+ return BOOL( !IsError() );
+}
+
+BOOL SbxValue::PutBool( BOOL b )
+{
+ SbxValues aRes;
+ aRes.eType = SbxBOOL;
+ aRes.nUShort = sal::static_int_cast< UINT16 >(b ? SbxTRUE : SbxFALSE);
+ Put( aRes );
+ return BOOL( !IsError() );
+}
+
+BOOL SbxValue::PutEmpty()
+{
+ BOOL bRet = SetType( SbxEMPTY );
+ SetModified( TRUE );
+ return bRet;
+}
+
+BOOL SbxValue::PutNull()
+{
+ BOOL bRet = SetType( SbxNULL );
+ if( bRet )
+ SetModified( TRUE );
+ return bRet;
+}
+
+
+// Special decimal methods
+BOOL SbxValue::PutDecimal( com::sun::star::bridge::oleautomation::Decimal& rAutomationDec )
+{
+ SbxValue::Clear();
+ aData.pDecimal = new SbxDecimal( rAutomationDec );
+ aData.pDecimal->addRef();
+ aData.eType = SbxDECIMAL;
+ return TRUE;
+}
+
+BOOL SbxValue::fillAutomationDecimal
+ ( com::sun::star::bridge::oleautomation::Decimal& rAutomationDec )
+{
+ SbxDecimal* pDecimal = GetDecimal();
+ if( pDecimal != NULL )
+ {
+ pDecimal->fillAutomationDecimal( rAutomationDec );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+BOOL SbxValue::PutpChar( const xub_Unicode* p )
+{
+ ::rtl::OUString aVal( p );
+ SbxValues aRes;
+ aRes.eType = SbxLPSTR;
+ aRes.pOUString = &aVal;
+ Put( aRes );
+ return BOOL( !IsError() );
+}
+
+BOOL SbxValue::PutString( const ::rtl::OUString& r )
+{
+ SbxValues aRes;
+ aRes.eType = SbxSTRING;
+ aRes.pOUString = (::rtl::OUString*) &r;
+ Put( aRes );
+ return BOOL( !IsError() );
+}
+
+
+#define PUT( p, e, t, m ) \
+BOOL SbxValue::p( t n ) \
+{ SbxValues aRes(e); aRes.m = n; Put( aRes ); return BOOL( !IsError() ); }
+
+PUT( PutByte, SbxBYTE, BYTE, nByte )
+PUT( PutChar, SbxCHAR, xub_Unicode, nChar )
+PUT( PutCurrency, SbxCURRENCY, const SbxINT64&, nLong64 )
+PUT( PutDate, SbxDATE, double, nDouble )
+PUT( PutData, SbxDATAOBJECT, void*, pData )
+PUT( PutDouble, SbxDOUBLE, double, nDouble )
+PUT( PutErr, SbxERROR, UINT16, nUShort )
+PUT( PutInt, SbxINT, int, nInt )
+PUT( PutInteger, SbxINTEGER, INT16, nInteger )
+PUT( PutLong, SbxLONG, INT32, nLong )
+PUT( PutLong64, SbxLONG64, const SbxINT64&, nLong64 )
+PUT( PutObject, SbxOBJECT, SbxBase*, pObj )
+PUT( PutSingle, SbxSINGLE, float, nSingle )
+PUT( PutULong, SbxULONG, UINT32, nULong )
+PUT( PutULong64, SbxULONG64, const SbxUINT64&, nULong64 )
+PUT( PutUShort, SbxUSHORT, UINT16, nUShort )
+PUT( PutInt64, SbxSALINT64, sal_Int64, nInt64 )
+PUT( PutUInt64, SbxSALUINT64, sal_uInt64, uInt64 )
+PUT( PutDecimal, SbxDECIMAL, SbxDecimal*, pDecimal )
+
+
+////////////////////////// Setzen des Datentyps ///////////////////////////
+
+BOOL SbxValue::IsFixed() const
+{
+ return ( (GetFlags() & SBX_FIXED) | (aData.eType & SbxBYREF) ) != 0;
+}
+
+// Eine Variable ist numerisch, wenn sie EMPTY oder wirklich numerisch ist
+// oder einen vollstaendig konvertierbaren String enthaelt
+
+// #41692, fuer RTL und Basic-Core getrennt implementieren
+BOOL SbxValue::IsNumeric() const
+{
+ return ImpIsNumeric( /*bOnlyIntntl*/FALSE );
+}
+
+BOOL SbxValue::IsNumericRTL() const
+{
+ return ImpIsNumeric( /*bOnlyIntntl*/TRUE );
+}
+
+BOOL SbxValue::ImpIsNumeric( BOOL bOnlyIntntl ) const
+{
+
+ if( !CanRead() )
+ {
+ SetError( SbxERR_PROP_WRITEONLY ); return FALSE;
+ }
+ // Downcast pruefen!!!
+ if( this->ISA(SbxVariable) )
+ ((SbxVariable*)this)->Broadcast( SBX_HINT_DATAWANTED );
+ SbxDataType t = GetType();
+ if( t == SbxSTRING )
+ {
+ if( aData.pOUString )
+ {
+ ::rtl::OUString s( *aData.pOUString );
+ double n;
+ SbxDataType t2;
+ USHORT nLen = 0;
+ if( ImpScan( s, n, t2, &nLen, /*bAllowIntntl*/FALSE, bOnlyIntntl ) == SbxERR_OK )
+ return BOOL( nLen == s.getLength() );
+ }
+ return FALSE;
+ }
+ else
+ return BOOL( t == SbxEMPTY
+ || ( t >= SbxINTEGER && t <= SbxCURRENCY )
+ || ( t >= SbxCHAR && t <= SbxUINT ) );
+}
+
+SbxClassType SbxValue::GetClass() const
+{
+ return SbxCLASS_VALUE;
+}
+
+SbxDataType SbxValue::GetType() const
+{
+ return SbxDataType( aData.eType & 0x0FFF );
+}
+
+SbxDataType SbxValue::GetFullType() const
+{
+ return aData.eType;
+}
+
+BOOL SbxValue::SetType( SbxDataType t )
+{
+ DBG_ASSERT( !( t & 0xF000 ), "Setzen von BYREF|ARRAY verboten!" );
+ if( ( t == SbxEMPTY && aData.eType == SbxVOID )
+ || ( aData.eType == SbxEMPTY && t == SbxVOID ) )
+ return TRUE;
+ if( ( t & 0x0FFF ) == SbxVARIANT )
+ {
+ // Versuch, den Datentyp auf Variant zu setzen
+ ResetFlag( SBX_FIXED );
+ if( IsFixed() )
+ {
+ SetError( SbxERR_CONVERSION ); return FALSE;
+ }
+ t = SbxEMPTY;
+ }
+ if( ( t & 0x0FFF ) != ( aData.eType & 0x0FFF ) )
+ {
+ if( !CanWrite() || IsFixed() )
+ {
+ SetError( SbxERR_CONVERSION ); return FALSE;
+ }
+ else
+ {
+ // Eventuelle Objekte freigeben
+ switch( aData.eType )
+ {
+ case SbxSTRING:
+ delete aData.pOUString;
+ break;
+ case SbxOBJECT:
+ if( aData.pObj && aData.pObj != this )
+ {
+ HACK(nicht bei Parent-Prop - sonst CyclicRef)
+ SbxVariable *pThisVar = PTR_CAST(SbxVariable, this);
+ UINT16 nSlotId = pThisVar
+ ? ( (INT16) ( pThisVar->GetUserData() & 0xFFFF ) )
+ : 0;
+ DBG_ASSERT( nSlotId != 5345 || pThisVar->GetName() == UniString::CreateFromAscii( "Parent" ),
+ "SID_PARENTOBJECT heisst nicht 'Parent'" );
+ BOOL bParentProp = 5345 == nSlotId;
+ if ( !bParentProp )
+ aData.pObj->ReleaseRef();
+ }
+ break;
+ default: break;
+ }
+ // Das klappt immer, da auch die Float-Repraesentationen 0 sind.
+ memset( &aData, 0, sizeof( SbxValues ) );
+ aData.eType = t;
+ }
+ }
+ return TRUE;
+}
+
+BOOL SbxValue::Convert( SbxDataType eTo )
+{
+ eTo = SbxDataType( eTo & 0x0FFF );
+ if( ( aData.eType & 0x0FFF ) == eTo )
+ return TRUE;
+ if( !CanWrite() )
+ return FALSE;
+ if( eTo == SbxVARIANT )
+ {
+ // Versuch, den Datentyp auf Variant zu setzen
+ ResetFlag( SBX_FIXED );
+ if( IsFixed() )
+ {
+ SetError( SbxERR_CONVERSION ); return FALSE;
+ }
+ else
+ return TRUE;
+ }
+ // Convert from Null geht niemals. Einmal Null, immer Null!
+ if( aData.eType == SbxNULL )
+ {
+ SetError( SbxERR_CONVERSION ); return FALSE;
+ }
+
+ // Konversion der Daten:
+ SbxValues aNew;
+ aNew.eType = eTo;
+ if( Get( aNew ) )
+ {
+ // Der Datentyp konnte konvertiert werden. Bei Fixed-Elementen
+ // ist hier Ende, da die Daten nicht uebernommen zu werden brauchen
+ if( !IsFixed() )
+ {
+ SetType( eTo );
+ Put( aNew );
+ SetModified( TRUE );
+ }
+ Broadcast( SBX_HINT_CONVERTED );
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+////////////////////////////////// Rechnen /////////////////////////////////
+
+BOOL SbxValue::Compute( SbxOperator eOp, const SbxValue& rOp )
+{
+ bool bVBAInterop = SbiRuntime::isVBAEnabled();
+
+ SbxDataType eThisType = GetType();
+ SbxDataType eOpType = rOp.GetType();
+ SbxError eOld = GetError();
+ if( eOld != SbxERR_OK )
+ ResetError();
+ if( !CanWrite() )
+ SetError( SbxERR_PROP_READONLY );
+ else if( !rOp.CanRead() )
+ SetError( SbxERR_PROP_WRITEONLY );
+ // Sonderregel 1: Ist ein Operand Null, ist das Ergebnis Null
+ else if( eThisType == SbxNULL || eOpType == SbxNULL )
+ SetType( SbxNULL );
+ // Sonderregel 2: Ist ein Operand Empty, ist das Ergebnis der 2. Operand
+ else if( eThisType == SbxEMPTY
+ && !bVBAInterop
+ )
+ *this = rOp;
+ // 13.2.96: Nicht schon vor Get auf SbxEMPTY pruefen
+ else
+ {
+ SbxValues aL, aR;
+ bool bDecimal = false;
+ if( bVBAInterop && ( ( eThisType == SbxSTRING && eOpType != SbxSTRING ) ||
+ ( eThisType != SbxSTRING && eOpType == SbxSTRING ) ) &&
+ ( eOp == SbxMUL || eOp == SbxDIV || eOp == SbxPLUS || eOp == SbxMINUS ) )
+ {
+ goto Lbl_OpIsDouble;
+ }
+ else if( eThisType == SbxSTRING || eOp == SbxCAT || ( bVBAInterop && ( eOpType == SbxSTRING ) && ( eOp == SbxPLUS ) ) )
+ {
+ if( eOp == SbxCAT || eOp == SbxPLUS )
+ {
+ // AB 5.11.1999, OUString beruecksichtigen
+ aL.eType = aR.eType = SbxSTRING;
+ rOp.Get( aR );
+ // AB 8.12.1999, #70399: Hier wieder GetType() rufen, Get() kann Typ aendern!
+ if( rOp.GetType() == SbxEMPTY )
+ goto Lbl_OpIsEmpty;
+ Get( aL );
+
+ // #30576: Erstmal testen, ob Wandlung geklappt hat
+ if( aL.pOUString != NULL && aR.pOUString != NULL )
+ {
+ *aL.pOUString += *aR.pOUString;
+ }
+ // Nicht einmal Left OK?
+ else if( aL.pOUString == NULL )
+ {
+ aL.pOUString = new ::rtl::OUString();
+ }
+ Put( aL );
+ }
+ else
+ SetError( SbxERR_CONVERSION );
+ }
+ else if( eOpType == SbxSTRING && rOp.IsFixed() )
+ { // Numerisch: rechts darf kein String stehen
+ SetError( SbxERR_CONVERSION );
+ }
+ else if( ( eOp >= SbxIDIV && eOp <= SbxNOT ) || eOp == SbxMOD )
+ {
+ if( GetType() == eOpType )
+ {
+ if( GetType() == SbxULONG64
+ || GetType() == SbxLONG64
+ || GetType() == SbxCURRENCY
+ || GetType() == SbxULONG )
+ aL.eType = aR.eType = GetType();
+// else if( GetType() == SbxDouble || GetType() == SbxSingle )
+// aL.eType = aR.eType = SbxLONG64;
+ else
+ aL.eType = aR.eType = SbxLONG;
+ }
+ else if( GetType() == SbxCURRENCY || eOpType == SbxCURRENCY
+ || GetType() == SbxULONG64 || eOpType == SbxULONG64
+ || GetType() == SbxLONG64 || eOpType == SbxLONG64 )
+ aL.eType = aR.eType = SbxLONG64;
+// else if( GetType() == SbxDouble || rOP.GetType() == SbxDouble
+// || GetType() == SbxSingle || rOP.GetType() == SbxSingle )
+// aL.eType = aR.eType = SbxLONG64;
+ else
+ aL.eType = aR.eType = SbxLONG;
+
+ if( rOp.Get( aR ) )
+ {
+ if( rOp.GetType() == SbxEMPTY )
+ {
+ if ( !bVBAInterop || ( bVBAInterop && ( eOp != SbxNOT ) ) )
+ goto Lbl_OpIsEmpty;
+ }
+ if( Get( aL ) ) switch( eOp )
+ {
+ case SbxIDIV:
+ if( aL.eType == SbxCURRENCY )
+ aL.eType = SbxLONG64;
+ if( aL.eType == SbxLONG64 )
+ if( !aR.nLong64 ) SetError( SbxERR_ZERODIV );
+ else aL.nLong64 /= aR.nLong64;
+ else if( aL.eType == SbxULONG64 )
+ if( !aR.nULong64 ) SetError( SbxERR_ZERODIV );
+ else aL.nULong64 /= aR.nULong64;
+ else if( aL.eType == SbxLONG )
+ if( !aR.nLong ) SetError( SbxERR_ZERODIV );
+ else aL.nLong /= aR.nLong;
+ else
+ if( !aR.nULong ) SetError( SbxERR_ZERODIV );
+ else aL.nULong /= aR.nULong;
+ break;
+ case SbxMOD:
+ if( aL.eType == SbxCURRENCY )
+ aL.eType = SbxLONG64;
+ if( aL.eType == SbxLONG64 )
+ if( !aR.nLong64 ) SetError( SbxERR_ZERODIV );
+ else aL.nLong64 %= aR.nLong64;
+ else if( aL.eType == SbxULONG64 )
+ if( !aR.nULong64 ) SetError( SbxERR_ZERODIV );
+ else aL.nULong64 %= aR.nULong64;
+ else if( aL.eType == SbxLONG )
+ if( !aR.nLong ) SetError( SbxERR_ZERODIV );
+ else aL.nLong %= aR.nLong;
+ else
+ if( !aR.nULong ) SetError( SbxERR_ZERODIV );
+ else aL.nULong %= aR.nULong;
+ break;
+ case SbxAND:
+ if( aL.eType != SbxLONG && aL.eType != SbxULONG )
+ aL.nLong64 &= aR.nLong64;
+ else
+ aL.nLong &= aR.nLong;
+ break;
+ case SbxOR:
+ if( aL.eType != SbxLONG && aL.eType != SbxULONG )
+ aL.nLong64 |= aR.nLong64;
+ else
+ aL.nLong |= aR.nLong;
+ break;
+ case SbxXOR:
+ if( aL.eType != SbxLONG && aL.eType != SbxULONG )
+ aL.nLong64 ^= aR.nLong64;
+ else
+ aL.nLong ^= aR.nLong;
+ break;
+ case SbxEQV:
+ if( aL.eType != SbxLONG && aL.eType != SbxULONG )
+ aL.nLong64 = (aL.nLong64 & aR.nLong64) | (~aL.nLong64 & ~aR.nLong64);
+ else
+ aL.nLong = (aL.nLong & aR.nLong) | (~aL.nLong & ~aR.nLong);
+ break;
+ case SbxIMP:
+ if( aL.eType != SbxLONG && aL.eType != SbxULONG )
+ aL.nLong64 = ~aL.nLong64 | aR.nLong64;
+ else
+ aL.nLong = ~aL.nLong | aR.nLong;
+ break;
+ case SbxNOT:
+ if( aL.eType != SbxLONG && aL.eType != SbxULONG )
+ aL.nLong64 = ~aL.nLong64;
+ else
+ aL.nLong = ~aL.nLong;
+ break;
+ default: break;
+ }
+ }
+ }
+ else if( ( GetType() == SbxDECIMAL || rOp.GetType() == SbxDECIMAL ) &&
+ ( eOp == SbxMUL || eOp == SbxDIV || eOp == SbxPLUS || eOp == SbxMINUS || eOp == SbxNEG ) )
+ {
+ aL.eType = aR.eType = SbxDECIMAL;
+ bDecimal = true;
+ if( rOp.Get( aR ) )
+ {
+ if( rOp.GetType() == SbxEMPTY )
+ {
+ releaseDecimalPtr( aL.pDecimal );
+ goto Lbl_OpIsEmpty;
+ }
+ if( Get( aL ) )
+ {
+ if( aL.pDecimal && aR.pDecimal )
+ {
+ bool bOk = true;
+ switch( eOp )
+ {
+ case SbxMUL:
+ bOk = ( *(aL.pDecimal) *= *(aR.pDecimal) );
+ break;
+ case SbxDIV:
+ if( aR.pDecimal->isZero() )
+ SetError( SbxERR_ZERODIV );
+ else
+ bOk = ( *(aL.pDecimal) /= *(aR.pDecimal) );
+ break;
+ case SbxPLUS:
+ bOk = ( *(aL.pDecimal) += *(aR.pDecimal) );
+ break;
+ case SbxMINUS:
+ bOk = ( *(aL.pDecimal) -= *(aR.pDecimal) );
+ break;
+ case SbxNEG:
+ bOk = ( aL.pDecimal->neg() );
+ break;
+ default:
+ SetError( SbxERR_NOTIMP );
+ }
+ if( !bOk )
+ SetError( SbxERR_OVERFLOW );
+ }
+ else
+ {
+ SetError( SbxERR_CONVERSION );
+ }
+ }
+ }
+ }
+ else if( GetType() == SbxCURRENCY || rOp.GetType() == SbxCURRENCY )
+ {
+ aL.eType = SbxCURRENCY;
+ aR.eType = SbxCURRENCY;
+
+ if( rOp.Get( aR ) )
+ {
+ static BigInt n10K( 10000 );
+
+ if( rOp.GetType() == SbxEMPTY )
+ goto Lbl_OpIsEmpty;
+
+ if( Get( aL ) ) switch( eOp )
+ {
+ case SbxMUL:
+ {
+ // #i20704 Implement directly
+ BigInt b1( aL.nLong64 );
+ BigInt b2( aR.nLong64 );
+ b1 *= b2;
+ b1 /= n10K;
+ double d = double( b1 ) / 10000.0;
+ if( d > SbxMAXCURR || d < SbxMINCURR )
+ SetError( SbxERR_OVERFLOW );
+ else
+ b1.INT64( &aL.nLong64 );
+ break;
+ }
+ case SbxDIV:
+ if( !aR.nLong64 )
+ {
+ SetError( SbxERR_ZERODIV );
+ }
+ else
+ {
+ // #i20704 Implement directly
+ BigInt b1( aL.nLong64 );
+ BigInt b2( aR.nLong64 );
+ b1 *= n10K;
+ b1 /= b2;
+ double d = double( b1 ) / 10000.0;
+ if( d > SbxMAXCURR || d < SbxMINCURR )
+ SetError( SbxERR_OVERFLOW );
+ else
+ b1.INT64( &aL.nLong64 );
+ }
+ break;
+ case SbxPLUS:
+ aL.nLong64 += aR.nLong64; break;
+ case SbxMINUS:
+ aL.nLong64 -= aR.nLong64; break;
+ case SbxNEG:
+ aL.nLong64 = -aL.nLong64; break;
+ default:
+ SetError( SbxERR_NOTIMP );
+ }
+ }
+ }
+ else
+Lbl_OpIsDouble:
+ { // Andere Operatoren
+ aL.eType = aR.eType = SbxDOUBLE;
+ if( rOp.Get( aR ) )
+ {
+ if( rOp.GetType() == SbxEMPTY )
+ {
+ if ( !bVBAInterop || ( bVBAInterop && ( eOp != SbxNEG ) ) )
+ goto Lbl_OpIsEmpty;
+ }
+ if( Get( aL ) )
+ {
+ switch( eOp )
+ {
+ case SbxEXP:
+ aL.nDouble = pow( aL.nDouble, aR.nDouble );
+ break;
+ case SbxMUL:
+ aL.nDouble *= aR.nDouble; break;
+ case SbxDIV:
+ if( !aR.nDouble ) SetError( SbxERR_ZERODIV );
+ else aL.nDouble /= aR.nDouble; break;
+ case SbxPLUS:
+ aL.nDouble += aR.nDouble; break;
+ case SbxMINUS:
+ aL.nDouble -= aR.nDouble; break;
+ case SbxNEG:
+ aL.nDouble = -aL.nDouble; break;
+ default:
+ SetError( SbxERR_NOTIMP );
+ }
+
+ // #45465 Date braucht bei + eine Spezial-Behandlung
+ if( eOp == SbxPLUS && (GetType() == SbxDATE || rOp.GetType() == SbxDATE ) )
+ aL.eType = SbxDATE;
+ }
+ }
+
+ }
+ if( !IsError() )
+ Put( aL );
+ if( bDecimal )
+ {
+ releaseDecimalPtr( aL.pDecimal );
+ releaseDecimalPtr( aR.pDecimal );
+ }
+ }
+Lbl_OpIsEmpty:
+
+ BOOL bRes = BOOL( !IsError() );
+ if( bRes && eOld != SbxERR_OK )
+ SetError( eOld );
+ return bRes;
+}
+
+// Die Vergleichs-Routine liefert TRUE oder FALSE.
+
+BOOL SbxValue::Compare( SbxOperator eOp, const SbxValue& rOp ) const
+{
+ bool bVBAInterop = SbiRuntime::isVBAEnabled();
+
+ BOOL bRes = FALSE;
+ SbxError eOld = GetError();
+ if( eOld != SbxERR_OK )
+ ResetError();
+ if( !CanRead() || !rOp.CanRead() )
+ SetError( SbxERR_PROP_WRITEONLY );
+ else if( GetType() == SbxNULL && rOp.GetType() == SbxNULL && !bVBAInterop )
+ {
+ bRes = TRUE;
+ }
+ else if( GetType() == SbxEMPTY && rOp.GetType() == SbxEMPTY )
+ bRes = !bVBAInterop ? TRUE : ( eOp == SbxEQ ? TRUE : FALSE );
+ // Sonderregel 1: Ist ein Operand Null, ist das Ergebnis FALSE
+ else if( GetType() == SbxNULL || rOp.GetType() == SbxNULL )
+ bRes = FALSE;
+ // Sonderregel 2: Wenn beide Variant sind und einer ist numerisch,
+ // und der andere ein String, ist num < str
+ else if( !IsFixed() && !rOp.IsFixed()
+ && ( rOp.GetType() == SbxSTRING && GetType() != SbxSTRING && IsNumeric() ) && !bVBAInterop
+ )
+ bRes = BOOL( eOp == SbxLT || eOp == SbxLE || eOp == SbxNE );
+ else if( !IsFixed() && !rOp.IsFixed()
+ && ( GetType() == SbxSTRING && rOp.GetType() != SbxSTRING && rOp.IsNumeric() )
+&& !bVBAInterop
+ )
+ bRes = BOOL( eOp == SbxGT || eOp == SbxGE || eOp == SbxNE );
+ else
+ {
+ SbxValues aL, aR;
+ // Wenn einer der Operanden ein String ist,
+ // findet ein Stringvergleich statt
+ if( GetType() == SbxSTRING || rOp.GetType() == SbxSTRING )
+ {
+ aL.eType = aR.eType = SbxSTRING;
+ if( Get( aL ) && rOp.Get( aR ) ) switch( eOp )
+ {
+ case SbxEQ:
+ bRes = BOOL( *aL.pOUString == *aR.pOUString ); break;
+ case SbxNE:
+ bRes = BOOL( *aL.pOUString != *aR.pOUString ); break;
+ case SbxLT:
+ bRes = BOOL( *aL.pOUString < *aR.pOUString ); break;
+ case SbxGT:
+ bRes = BOOL( *aL.pOUString > *aR.pOUString ); break;
+ case SbxLE:
+ bRes = BOOL( *aL.pOUString <= *aR.pOUString ); break;
+ case SbxGE:
+ bRes = BOOL( *aL.pOUString >= *aR.pOUString ); break;
+ default:
+ SetError( SbxERR_NOTIMP );
+ }
+ }
+ // AB 19.12.95: Wenn SbxSINGLE beteiligt, auf SINGLE konvertieren,
+ // sonst gibt es numerische Fehler
+ else if( GetType() == SbxSINGLE || rOp.GetType() == SbxSINGLE )
+ {
+ aL.eType = aR.eType = SbxSINGLE;
+ if( Get( aL ) && rOp.Get( aR ) )
+ switch( eOp )
+ {
+ case SbxEQ:
+ bRes = BOOL( aL.nSingle == aR.nSingle ); break;
+ case SbxNE:
+ bRes = BOOL( aL.nSingle != aR.nSingle ); break;
+ case SbxLT:
+ bRes = BOOL( aL.nSingle < aR.nSingle ); break;
+ case SbxGT:
+ bRes = BOOL( aL.nSingle > aR.nSingle ); break;
+ case SbxLE:
+ bRes = BOOL( aL.nSingle <= aR.nSingle ); break;
+ case SbxGE:
+ bRes = BOOL( aL.nSingle >= aR.nSingle ); break;
+ default:
+ SetError( SbxERR_NOTIMP );
+ }
+ }
+ else if( GetType() == SbxDECIMAL && rOp.GetType() == SbxDECIMAL )
+ {
+ aL.eType = aR.eType = SbxDECIMAL;
+ Get( aL );
+ rOp.Get( aR );
+ if( aL.pDecimal && aR.pDecimal )
+ {
+ SbxDecimal::CmpResult eRes = compare( *aL.pDecimal, *aR.pDecimal );
+ switch( eOp )
+ {
+ case SbxEQ:
+ bRes = BOOL( eRes == SbxDecimal::EQ ); break;
+ case SbxNE:
+ bRes = BOOL( eRes != SbxDecimal::EQ ); break;
+ case SbxLT:
+ bRes = BOOL( eRes == SbxDecimal::LT ); break;
+ case SbxGT:
+ bRes = BOOL( eRes == SbxDecimal::GT ); break;
+ case SbxLE:
+ bRes = BOOL( eRes != SbxDecimal::GT ); break;
+ case SbxGE:
+ bRes = BOOL( eRes != SbxDecimal::LT ); break;
+ default:
+ SetError( SbxERR_NOTIMP );
+ }
+ }
+ else
+ {
+ SetError( SbxERR_CONVERSION );
+ }
+ releaseDecimalPtr( aL.pDecimal );
+ releaseDecimalPtr( aR.pDecimal );
+ }
+ // Alles andere auf SbxDOUBLE-Basis vergleichen
+ else
+ {
+ aL.eType = aR.eType = SbxDOUBLE;
+ //if( Get( aL ) && rOp.Get( aR ) )
+ bool bGetL = Get( aL );
+ bool bGetR = rOp.Get( aR );
+ if( bGetL && bGetR )
+ switch( eOp )
+ {
+ case SbxEQ:
+ bRes = BOOL( aL.nDouble == aR.nDouble ); break;
+ case SbxNE:
+ bRes = BOOL( aL.nDouble != aR.nDouble ); break;
+ case SbxLT:
+ bRes = BOOL( aL.nDouble < aR.nDouble ); break;
+ case SbxGT:
+ bRes = BOOL( aL.nDouble > aR.nDouble ); break;
+ case SbxLE:
+ bRes = BOOL( aL.nDouble <= aR.nDouble ); break;
+ case SbxGE:
+ bRes = BOOL( aL.nDouble >= aR.nDouble ); break;
+ default:
+ SetError( SbxERR_NOTIMP );
+ }
+ // at least one value was got
+ // if this is VBA then a conversion error for one
+ // side will yield a false result of an equality test
+ else if ( bGetR || bGetL )
+ {
+ if ( bVBAInterop && eOp == SbxEQ && GetError() == SbxERR_CONVERSION )
+ {
+ ResetError();
+ bRes = FALSE;
+ }
+ }
+ }
+ }
+ if( eOld != SbxERR_OK )
+ SetError( eOld );
+ return bRes;
+}
+
+///////////////////////////// Lesen/Schreiben ////////////////////////////
+
+BOOL SbxValue::LoadData( SvStream& r, USHORT )
+{
+ SbxValue::Clear();
+ UINT16 nType;
+ r >> nType;
+ aData.eType = SbxDataType( nType );
+ switch( nType )
+ {
+ case SbxBOOL:
+ case SbxINTEGER:
+ r >> aData.nInteger; break;
+ case SbxLONG:
+ r >> aData.nLong; break;
+ case SbxSINGLE:
+ {
+ // Floats als ASCII
+ XubString aVal;
+ r.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US );
+ double d;
+ SbxDataType t;
+ if( ImpScan( aVal, d, t, NULL ) != SbxERR_OK || t == SbxDOUBLE )
+ {
+ aData.nSingle = 0.0F;
+ return FALSE;
+ }
+ aData.nSingle = (float) d;
+ break;
+ }
+ case SbxDATE:
+ case SbxDOUBLE:
+ {
+ // Floats als ASCII
+ XubString aVal;
+ r.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US );
+ SbxDataType t;
+ if( ImpScan( aVal, aData.nDouble, t, NULL ) != SbxERR_OK )
+ {
+ aData.nDouble = 0.0;
+ return FALSE;
+ }
+ break;
+ }
+ case SbxULONG64:
+ {
+ r >> aData.nULong64.nHigh >> aData.nULong64.nLow;
+ break;
+ }
+ case SbxLONG64:
+ case SbxCURRENCY:
+ {
+ r >> aData.nLong64.nHigh >> aData.nLong64.nLow;
+ break;
+ }
+ case SbxSTRING:
+ {
+ XubString aVal;
+ r.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US );
+ if( aVal.Len() )
+ aData.pOUString = new ::rtl::OUString( aVal );
+ else
+ aData.pOUString = NULL; // JSM 22.09.1995
+ break;
+ }
+ case SbxERROR:
+ case SbxUSHORT:
+ r >> aData.nUShort; break;
+ case SbxOBJECT:
+ {
+ BYTE nMode;
+ r >> nMode;
+ switch( nMode )
+ {
+ case 0:
+ aData.pObj = NULL;
+ break;
+ case 1:
+ aData.pObj = SbxBase::Load( r );
+ return BOOL( aData.pObj != NULL );
+ case 2:
+ aData.pObj = this;
+ break;
+ }
+ break;
+ }
+ case SbxCHAR:
+ {
+ char c;
+ r >> c;
+ aData.nChar = c;
+ break;
+ }
+ case SbxBYTE:
+ r >> aData.nByte; break;
+ case SbxULONG:
+ r >> aData.nULong; break;
+ case SbxINT:
+ {
+ BYTE n;
+ r >> n;
+ // Passt der Int auf diesem System?
+ if( n > SAL_TYPES_SIZEOFINT )
+ r >> aData.nLong, aData.eType = SbxLONG;
+ else
+ r >> aData.nInt;
+ break;
+ }
+ case SbxUINT:
+ {
+ BYTE n;
+ r >> n;
+ // Passt der UInt auf diesem System?
+ if( n > SAL_TYPES_SIZEOFINT )
+ r >> aData.nULong, aData.eType = SbxULONG;
+ else
+ r >> (sal_uInt32&)aData.nUInt;
+ break;
+ }
+ case SbxEMPTY:
+ case SbxNULL:
+ case SbxVOID:
+ break;
+ case SbxDATAOBJECT:
+ r >> aData.nLong;
+ break;
+ // #78919 For backwards compatibility
+ case SbxWSTRING:
+ case SbxWCHAR:
+ break;
+ default:
+ memset (&aData,0,sizeof(aData));
+ ResetFlag(SBX_FIXED);
+ aData.eType = SbxNULL;
+ DBG_ASSERT( !this, "Nicht unterstuetzer Datentyp geladen" );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL SbxValue::StoreData( SvStream& r ) const
+{
+ UINT16 nType = sal::static_int_cast< UINT16 >(aData.eType);
+ r << nType;
+ switch( nType & 0x0FFF )
+ {
+ case SbxBOOL:
+ case SbxINTEGER:
+ r << aData.nInteger; break;
+ case SbxLONG:
+ r << aData.nLong; break;
+ case SbxDATE:
+ // #49935: Als double speichern, sonst Fehler beim Einlesen
+ ((SbxValue*)this)->aData.eType = (SbxDataType)( ( nType & 0xF000 ) | SbxDOUBLE );
+ r.WriteByteString( GetCoreString(), RTL_TEXTENCODING_ASCII_US );
+ ((SbxValue*)this)->aData.eType = (SbxDataType)nType;
+ break;
+ case SbxSINGLE:
+ case SbxDOUBLE:
+ r.WriteByteString( GetCoreString(), RTL_TEXTENCODING_ASCII_US );
+ break;
+ case SbxULONG64:
+ {
+ r << aData.nULong64.nHigh << aData.nULong64.nLow;
+ break;
+ }
+ case SbxLONG64:
+ case SbxCURRENCY:
+ {
+ r << aData.nLong64.nHigh << aData.nLong64.nLow;
+ break;
+ }
+ case SbxSTRING:
+ if( aData.pOUString )
+ {
+ r.WriteByteString( *aData.pOUString, RTL_TEXTENCODING_ASCII_US );
+ }
+ else
+ {
+ String aEmpty;
+ r.WriteByteString( aEmpty, RTL_TEXTENCODING_ASCII_US );
+ }
+ break;
+ case SbxERROR:
+ case SbxUSHORT:
+ r << aData.nUShort; break;
+ case SbxOBJECT:
+ // sich selbst als Objektptr speichern geht nicht!
+ if( aData.pObj )
+ {
+ if( PTR_CAST(SbxValue,aData.pObj) != this )
+ {
+ r << (BYTE) 1;
+ return aData.pObj->Store( r );
+ }
+ else
+ r << (BYTE) 2;
+ }
+ else
+ r << (BYTE) 0;
+ break;
+ case SbxCHAR:
+ {
+ char c = sal::static_int_cast< char >(aData.nChar);
+ r << c;
+ break;
+ }
+ case SbxBYTE:
+ r << aData.nByte; break;
+ case SbxULONG:
+ r << aData.nULong; break;
+ case SbxINT:
+ {
+ BYTE n = SAL_TYPES_SIZEOFINT;
+ r << n << (sal_Int32)aData.nInt;
+ break;
+ }
+ case SbxUINT:
+ {
+ BYTE n = SAL_TYPES_SIZEOFINT;
+ r << n << (sal_uInt32)aData.nUInt;
+ break;
+ }
+ case SbxEMPTY:
+ case SbxNULL:
+ case SbxVOID:
+ break;
+ case SbxDATAOBJECT:
+ r << aData.nLong;
+ break;
+ // #78919 For backwards compatibility
+ case SbxWSTRING:
+ case SbxWCHAR:
+ break;
+ default:
+ DBG_ASSERT( !this, "Speichern eines nicht unterstuetzten Datentyps" );
+ return FALSE;
+ }
+ return TRUE;
+}
+
diff --git a/basic/source/sbx/sbxvar.cxx b/basic/source/sbx/sbxvar.cxx
new file mode 100644
index 000000000000..58e3c1ae92c2
--- /dev/null
+++ b/basic/source/sbx/sbxvar.cxx
@@ -0,0 +1,644 @@
+/*************************************************************************
+ *
+ * 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 "svl/brdcst.hxx"
+
+#include <basic/sbx.hxx>
+#include <basic/sbxbase.hxx>
+#include "sbxres.hxx"
+#include "sbxconv.hxx"
+#include <math.h>
+#include <ctype.h>
+
+#include "com/sun/star/uno/XInterface.hpp"
+using namespace com::sun::star::uno;
+
+///////////////////////////// SbxVariable //////////////////////////////
+
+TYPEINIT1(SbxVariable,SbxValue)
+TYPEINIT1(SbxHint,SfxSimpleHint)
+
+extern UINT32 nVarCreator; // in SBXBASE.CXX, fuer LoadData()
+#ifdef DBG_UTIL
+static ULONG nVar = 0;
+#endif
+
+///////////////////////////// SbxVariableImpl ////////////////////////////
+
+class SbxVariableImpl
+{
+ friend class SbxVariable;
+ String m_aDeclareClassName;
+ Reference< XInterface > m_xComListener;
+
+ SbxVariableImpl( void )
+ {}
+ SbxVariableImpl( const SbxVariableImpl& r )
+ : m_aDeclareClassName( r.m_aDeclareClassName )
+ , m_xComListener( r.m_xComListener )
+ {}
+};
+
+
+///////////////////////////// Konstruktoren //////////////////////////////
+
+SbxVariable::SbxVariable() : SbxValue()
+{
+ mpSbxVariableImpl = NULL;
+ pCst = NULL;
+ pParent = NULL;
+ nUserData = 0;
+ nHash = 0;
+#ifdef DBG_UTIL
+ DbgOutf( "SbxVariable::Ctor %lx=%ld", (void*)this, ++nVar );
+ GetSbxData_Impl()->aVars.Insert( this, LIST_APPEND );
+#endif
+}
+
+SbxVariable::SbxVariable( const SbxVariable& r )
+ : SvRefBase( r ), SbxValue( r ), mpPar( r.mpPar ), pInfo( r.pInfo )
+{
+ mpSbxVariableImpl = NULL;
+ if( r.mpSbxVariableImpl != NULL )
+ mpSbxVariableImpl = new SbxVariableImpl( *r.mpSbxVariableImpl );
+ pCst = NULL;
+ if( r.CanRead() )
+ {
+ pParent = r.pParent;
+ nUserData = r.nUserData;
+ maName = r.maName;
+ nHash = r.nHash;
+ }
+ else
+ {
+ pParent = NULL;
+ nUserData = 0;
+ nHash = 0;
+ }
+#ifdef DBG_UTIL
+ static sal_Char const aCellsStr[] = "Cells";
+ if ( maName.EqualsAscii( aCellsStr ) )
+ maName.AssignAscii( aCellsStr, sizeof( aCellsStr )-1 );
+ DbgOutf( "SbxVariable::Ctor %lx=%ld", (void*)this, ++nVar );
+ GetSbxData_Impl()->aVars.Insert( this, LIST_APPEND );
+#endif
+}
+
+SbxVariable::SbxVariable( SbxDataType t, void* p ) : SbxValue( t, p )
+{
+ mpSbxVariableImpl = NULL;
+ pCst = NULL;
+ pParent = NULL;
+ nUserData = 0;
+ nHash = 0;
+#ifdef DBG_UTIL
+ DbgOutf( "SbxVariable::Ctor %lx=%ld", (void*)this, ++nVar );
+ GetSbxData_Impl()->aVars.Insert( this, LIST_APPEND );
+#endif
+}
+
+SbxVariable::~SbxVariable()
+{
+#ifdef DBG_UTIL
+ ByteString aBStr( (const UniString&)maName, RTL_TEXTENCODING_ASCII_US );
+ DbgOutf( "SbxVariable::Dtor %lx (%s)", (void*)this, aBStr.GetBuffer() );
+ static sal_Char const aCellsStr[] = "Cells";
+ if ( maName.EqualsAscii( aCellsStr ) )
+ maName.AssignAscii( aCellsStr, sizeof( aCellsStr )-1 );
+ GetSbxData_Impl()->aVars.Remove( this );
+#endif
+ delete mpSbxVariableImpl;
+ delete pCst;
+}
+
+////////////////////////////// Broadcasting //////////////////////////////
+
+SfxBroadcaster& SbxVariable::GetBroadcaster()
+{
+ if( !pCst )
+ pCst = new SfxBroadcaster;
+ return *pCst;
+}
+
+// Eines Tages kann man vielleicht den Parameter 0 schleifen,
+// dann entfaellt die Kopiererei...
+
+void SbxVariable::Broadcast( ULONG 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;
+ // Weitere Broadcasts verhindern
+ SfxBroadcaster* pSave = pCst;
+ pCst = NULL;
+ USHORT nSaveFlags = GetFlags();
+ SetFlag( SBX_READWRITE );
+ if( mpPar.Is() )
+ // this, als Element 0 eintragen, aber den Parent nicht umsetzen!
+ mpPar->GetRef( 0 ) = this;
+ pSave->Broadcast( SbxHint( nHintId, this ) );
+ delete pCst; // wer weiss schon, auf welche Gedanken mancher kommt?
+ pCst = pSave;
+ SetFlags( nSaveFlags );
+ }
+}
+
+SbxInfo* SbxVariable::GetInfo()
+{
+ if( !pInfo )
+ {
+ Broadcast( SBX_HINT_INFOWANTED );
+ if( pInfo.Is() )
+ SetModified( TRUE );
+ }
+ return pInfo;
+}
+
+void SbxVariable::SetInfo( SbxInfo* p )
+{
+ pInfo = p;
+}
+
+void SbxVariable::SetParameters( SbxArray* p )
+{
+ mpPar = p;
+}
+
+
+/////////////////////////// Name der Variablen ///////////////////////////
+
+void SbxVariable::SetName( const XubString& rName )
+{
+ maName = rName;
+ nHash = MakeHashCode( rName );
+}
+
+const XubString& SbxVariable::GetName( SbxNameType t ) const
+{
+ static char cSuffixes[] = " %&!#@ $";
+ if( t == SbxNAME_NONE )
+ return maName;
+ // Parameter-Infos anfordern (nicht fuer Objekte)
+ ((SbxVariable*)this)->GetInfo();
+ // Nix anfuegen, wenn einfache Property (keine leeren Klammern)
+ if( !pInfo
+ || ( !pInfo->aParams.Count() && GetClass() == SbxCLASS_PROPERTY ) )
+ return maName;
+ xub_Unicode cType = ' ';
+ XubString aTmp( maName );
+ // Kurzer Typ? Dann holen, evtl. ist dieser 0.
+ SbxDataType et = GetType();
+ if( t == SbxNAME_SHORT_TYPES )
+ {
+ if( et <= SbxSTRING )
+ cType = cSuffixes[ et ];
+ if( cType != ' ' )
+ aTmp += cType;
+ }
+ aTmp += '(';
+ for( USHORT i = 0; i < pInfo->aParams.Count(); i++ )
+ {
+ const SbxParamInfo* q = pInfo->aParams.GetObject( i );
+ int nt = q->eType & 0x0FFF;
+ if( i )
+ aTmp += ',';
+ if( q->nFlags & SBX_OPTIONAL )
+ aTmp += String( SbxRes( STRING_OPTIONAL ) );
+ if( q->eType & SbxBYREF )
+ aTmp += String( SbxRes( STRING_BYREF ) );
+ aTmp += q->aName;
+ cType = ' ';
+ // Kurzer Typ? Dann holen, evtl. ist dieser 0.
+ if( t == SbxNAME_SHORT_TYPES )
+ {
+ if( nt <= SbxSTRING )
+ cType = cSuffixes[ nt ];
+ }
+ if( cType != ' ' )
+ {
+ aTmp += cType;
+ if( q->eType & SbxARRAY )
+ aTmp.AppendAscii( "()" );
+ }
+ else
+ {
+ if( q->eType & SbxARRAY )
+ aTmp.AppendAscii( "()" );
+ // langer Typ?
+ if( t != SbxNAME_SHORT )
+ {
+ aTmp += String( SbxRes( STRING_AS ) );
+ if( nt < 32 )
+ aTmp += String( SbxRes(
+ sal::static_int_cast< USHORT >( STRING_TYPES + nt ) ) );
+ else
+ aTmp += String( SbxRes( STRING_ANY ) );
+ }
+ }
+ }
+ aTmp += ')';
+ // Langer Typ? Dann holen
+ if( t == SbxNAME_LONG_TYPES && et != SbxEMPTY )
+ {
+ aTmp += String( SbxRes( STRING_AS ) );
+ if( et < 32 )
+ aTmp += String( SbxRes(
+ sal::static_int_cast< USHORT >( STRING_TYPES + et ) ) );
+ else
+ aTmp += String( SbxRes( STRING_ANY ) );
+ }
+ ((SbxVariable*) this)->aToolString = aTmp;
+ return aToolString;
+}
+
+// Einen simplen Hashcode erzeugen: Es werden die ersten 6 Zeichen gewertet.
+
+USHORT SbxVariable::MakeHashCode( const XubString& rName )
+{
+ USHORT n = 0;
+ USHORT nLen = rName.Len();
+ if( nLen > 6 )
+ nLen = 6;
+ const xub_Unicode* p = rName.GetBuffer();
+ while( nLen-- )
+ {
+ BYTE c = (BYTE)*p;
+ p++;
+ // Falls wir ein Schweinezeichen haben, abbrechen!!
+ if( c >= 0x80 )
+ return 0;
+ n = sal::static_int_cast< USHORT >( ( n << 3 ) + toupper( c ) );
+ }
+ return n;
+}
+
+////////////////////////////// Operatoren ////////////////////////////////
+
+SbxVariable& SbxVariable::operator=( const SbxVariable& r )
+{
+ SbxValue::operator=( r );
+ delete mpSbxVariableImpl;
+ if( r.mpSbxVariableImpl != NULL )
+ mpSbxVariableImpl = new SbxVariableImpl( *r.mpSbxVariableImpl );
+ else
+ mpSbxVariableImpl = NULL;
+ return *this;
+}
+
+//////////////////////////////// Konversion ////////////////////////////////
+
+SbxDataType SbxVariable::GetType() const
+{
+ if( aData.eType == SbxOBJECT )
+ return aData.pObj ? aData.pObj->GetType() : SbxOBJECT;
+ else if( aData.eType == SbxVARIANT )
+ return aData.pObj ? aData.pObj->GetType() : SbxVARIANT;
+ else
+ return aData.eType;
+}
+
+SbxClassType SbxVariable::GetClass() const
+{
+ return SbxCLASS_VARIABLE;
+}
+
+void SbxVariable::SetModified( BOOL b )
+{
+ if( IsSet( SBX_NO_MODIFY ) )
+ return;
+ SbxBase::SetModified( b );
+ if( pParent && pParent != this ) //??? HotFix: Rekursion raus MM
+ pParent->SetModified( b );
+}
+
+void SbxVariable::SetParent( SbxObject* p )
+{
+#ifdef DBG_UTIL
+ // wird der Parent eines SbxObjects gesetzt?
+ if ( p && ISA(SbxObject) )
+ {
+ // dann mu\s dieses auch Child vom neuen Parent sein
+ BOOL bFound = FALSE;
+ SbxArray *pChilds = p->GetObjects();
+ if ( pChilds )
+ {
+ for ( USHORT nIdx = 0; !bFound && nIdx < pChilds->Count(); ++nIdx )
+ bFound = ( this == pChilds->Get(nIdx) );
+ }
+ if ( !bFound )
+ {
+ String aMsg = String::CreateFromAscii( "dangling: [" );
+ aMsg += GetName();
+ aMsg.AppendAscii( "].SetParent([" );
+ aMsg += p->GetName();
+ aMsg.AppendAscii( "])" );
+ ByteString aBStr( (const UniString&)aMsg, RTL_TEXTENCODING_ASCII_US );
+ DbgOut( aBStr.GetBuffer(), DBG_OUT_WARNING, __FILE__, __LINE__);
+ }
+ }
+#endif
+
+ pParent = p;
+}
+
+SbxVariableImpl* SbxVariable::getImpl( void )
+{
+ if( mpSbxVariableImpl == NULL )
+ mpSbxVariableImpl = new SbxVariableImpl();
+ return mpSbxVariableImpl;
+}
+
+const String& SbxVariable::GetDeclareClassName( void )
+{
+ SbxVariableImpl* pImpl = getImpl();
+ return pImpl->m_aDeclareClassName;
+}
+
+void SbxVariable::SetDeclareClassName( const String& rDeclareClassName )
+{
+ SbxVariableImpl* pImpl = getImpl();
+ pImpl->m_aDeclareClassName = rDeclareClassName;
+}
+
+void SbxVariable::SetComListener( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xComListener )
+{
+ SbxVariableImpl* pImpl = getImpl();
+ pImpl->m_xComListener = xComListener;
+}
+
+
+////////////////////////////// Laden/Speichern /////////////////////////////
+
+BOOL SbxVariable::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ UINT16 nType;
+ BYTE cMark;
+ rStrm >> cMark;
+ if( cMark == 0xFF )
+ {
+ if( !SbxValue::LoadData( rStrm, nVer ) )
+ return FALSE;
+ rStrm.ReadByteString( maName, RTL_TEXTENCODING_ASCII_US );
+ UINT32 nTemp;
+ rStrm >> nTemp;
+ nUserData = nTemp;
+ }
+ else
+ {
+ rStrm.SeekRel( -1L );
+ rStrm >> nType;
+ rStrm.ReadByteString( maName, RTL_TEXTENCODING_ASCII_US );
+ UINT32 nTemp;
+ rStrm >> nTemp;
+ nUserData = nTemp;
+ // Korrektur: Alte Methoden haben statt SbxNULL jetzt SbxEMPTY
+ if( nType == SbxNULL && GetClass() == SbxCLASS_METHOD )
+ nType = SbxEMPTY;
+ SbxValues aTmp;
+ String aTmpString;
+ ::rtl::OUString aVal;
+ aTmp.eType = aData.eType = (SbxDataType) nType;
+ aTmp.pOUString = &aVal;
+ switch( nType )
+ {
+ case SbxBOOL:
+ case SbxERROR:
+ case SbxINTEGER:
+ rStrm >> aTmp.nInteger; break;
+ case SbxLONG:
+ rStrm >> aTmp.nLong; break;
+ case SbxSINGLE:
+ {
+ // Floats als ASCII
+ rStrm.ReadByteString( aTmpString, RTL_TEXTENCODING_ASCII_US );
+ double d;
+ SbxDataType t;
+ if( ImpScan( aTmpString, d, t, NULL ) != SbxERR_OK || t == SbxDOUBLE )
+ {
+ aTmp.nSingle = 0;
+ return FALSE;
+ }
+ aTmp.nSingle = (float) d;
+ break;
+ }
+ case SbxDATE:
+ case SbxDOUBLE:
+ {
+ // Floats als ASCII
+ rStrm.ReadByteString( aTmpString, RTL_TEXTENCODING_ASCII_US );
+ SbxDataType t;
+ if( ImpScan( aTmpString, aTmp.nDouble, t, NULL ) != SbxERR_OK )
+ {
+ aTmp.nDouble = 0;
+ return FALSE;
+ }
+ break;
+ }
+ case SbxSTRING:
+ rStrm.ReadByteString( aTmpString, RTL_TEXTENCODING_ASCII_US );
+ aVal = aTmpString;
+ break;
+ case SbxEMPTY:
+ case SbxNULL:
+ break;
+ default:
+ aData.eType = SbxNULL;
+ DBG_ASSERT( !this, "Nicht unterstuetzer Datentyp geladen" );
+ return FALSE;
+ }
+ // Wert putten
+ if( nType != SbxNULL && nType != SbxEMPTY && !Put( aTmp ) )
+ return FALSE;
+ }
+ rStrm >> cMark;
+ // cMark ist auch eine Versionsnummer!
+ // 1: initial version
+ // 2: mit nUserData
+ if( cMark )
+ {
+ if( cMark > 2 )
+ return FALSE;
+ pInfo = new SbxInfo;
+ pInfo->LoadData( rStrm, (USHORT) cMark );
+ }
+ // Privatdaten nur laden, wenn es eine SbxVariable ist
+ if( GetClass() == SbxCLASS_VARIABLE && !LoadPrivateData( rStrm, nVer ) )
+ return FALSE;
+ ((SbxVariable*) this)->Broadcast( SBX_HINT_DATACHANGED );
+ nHash = MakeHashCode( maName );
+ SetModified( TRUE );
+ return TRUE;
+}
+
+BOOL SbxVariable::StoreData( SvStream& rStrm ) const
+{
+ rStrm << (BYTE) 0xFF; // Marker
+ BOOL bValStore;
+ if( this->IsA( TYPE(SbxMethod) ) )
+ {
+ // #50200 Verhindern, dass Objekte, die zur Laufzeit als Return-Wert
+ // in der Methode als Value gespeichert sind, mit gespeichert werden
+ SbxVariable* pThis = (SbxVariable*)this;
+ USHORT nSaveFlags = GetFlags();
+ pThis->SetFlag( SBX_WRITE );
+ pThis->SbxValue::Clear();
+ pThis->SetFlags( nSaveFlags );
+
+ // Damit die Methode in keinem Fall ausgefuehrt wird!
+ // CAST, um const zu umgehen!
+ pThis->SetFlag( SBX_NO_BROADCAST );
+ bValStore = SbxValue::StoreData( rStrm );
+ pThis->ResetFlag( SBX_NO_BROADCAST );
+ }
+ else
+ bValStore = SbxValue::StoreData( rStrm );
+ if( !bValStore )
+ return FALSE;
+ // if( !SbxValue::StoreData( rStrm ) )
+ // return FALSE;
+ rStrm.WriteByteString( maName, RTL_TEXTENCODING_ASCII_US );
+ rStrm << (UINT32)nUserData;
+ if( pInfo.Is() )
+ {
+ rStrm << (BYTE) 2; // Version 2: mit UserData!
+ pInfo->StoreData( rStrm );
+ }
+ else
+ rStrm << (BYTE) 0;
+ // Privatdaten nur speichern, wenn es eine SbxVariable ist
+ if( GetClass() == SbxCLASS_VARIABLE )
+ return StorePrivateData( rStrm );
+ else
+ return TRUE;
+}
+
+////////////////////////////// SbxInfo ///////////////////////////////////
+
+SbxInfo::SbxInfo() : aHelpFile(), nHelpId( 0 ), aParams()
+{}
+
+SbxInfo::SbxInfo( const String& r, UINT32 n )
+ : aHelpFile( r ), nHelpId( n ), aParams()
+{}
+
+////////////////////////////// SbxAlias //////////////////////////////////
+
+SbxAlias::SbxAlias( const XubString& rName, SbxVariable* p )
+ : SbxVariable(), xAlias( p )
+{
+ SetName( rName );
+ SetFlags( p->GetFlags() );
+ SetFlag( SBX_DONTSTORE );
+ aData.eType = p->GetType();
+ StartListening( p->GetBroadcaster() );
+}
+
+SbxAlias::SbxAlias( const SbxAlias& r )
+ : SvRefBase( r ), SbxVariable( r ),
+ SfxListener( r ), xAlias( r.xAlias )
+{}
+
+SbxAlias& SbxAlias::operator=( const SbxAlias& r )
+{
+ xAlias = r.xAlias;
+ return *this;
+}
+
+SbxAlias::~SbxAlias()
+{
+ if( xAlias.Is() )
+ EndListening( xAlias->GetBroadcaster() );
+}
+
+void SbxAlias::Broadcast( ULONG nHt )
+{
+ if( xAlias.Is() && StaticIsEnabledBroadcasting() )
+ {
+ xAlias->SetParameters( GetParameters() );
+ if( nHt == SBX_HINT_DATAWANTED )
+ SbxVariable::operator=( *xAlias );
+ else if( nHt == SBX_HINT_DATACHANGED || nHt == SBX_HINT_CONVERTED )
+ *xAlias = *this;
+ else if( nHt == SBX_HINT_INFOWANTED )
+ {
+ xAlias->Broadcast( nHt );
+ pInfo = xAlias->GetInfo();
+ }
+ }
+}
+
+void SbxAlias::SFX_NOTIFY( SfxBroadcaster&, const TypeId&,
+ const SfxHint& rHint, const TypeId& )
+{
+ const SbxHint* p = PTR_CAST(SbxHint,&rHint);
+ if( p && p->GetId() == SBX_HINT_DYING )
+ {
+ xAlias.Clear();
+ // Alias loeschen?
+ if( pParent )
+ pParent->Remove( this );
+ }
+}
+
+void SbxVariable::Dump( SvStream& rStrm, BOOL bFill )
+{
+ ByteString aBNameStr( (const UniString&)GetName( SbxNAME_SHORT_TYPES ), RTL_TEXTENCODING_ASCII_US );
+ rStrm << "Variable( "
+ << ByteString::CreateFromInt64( (ULONG) this ).GetBuffer() << "=="
+ << aBNameStr.GetBuffer();
+ ByteString aBParentNameStr( (const UniString&)GetParent()->GetName(), RTL_TEXTENCODING_ASCII_US );
+ if ( GetParent() )
+ rStrm << " in parent '" << aBParentNameStr.GetBuffer() << "'";
+ else
+ rStrm << " no parent";
+ rStrm << " ) ";
+
+ // bei Object-Vars auch das Object ausgeben
+ if ( GetValues_Impl().eType == SbxOBJECT &&
+ GetValues_Impl().pObj &&
+ GetValues_Impl().pObj != this &&
+ GetValues_Impl().pObj != GetParent() )
+ {
+ rStrm << " contains ";
+ ((SbxObject*) GetValues_Impl().pObj)->Dump( rStrm, bFill );
+ }
+ else
+ rStrm << endl;
+}
+
diff --git a/basic/source/uno/dlgcont.cxx b/basic/source/uno/dlgcont.cxx
new file mode 100644
index 000000000000..004b61fbf198
--- /dev/null
+++ b/basic/source/uno/dlgcont.cxx
@@ -0,0 +1,658 @@
+/*************************************************************************
+ *
+ * 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 <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#include "com/sun/star/resource/XStringResourceWithStorage.hpp"
+#include "com/sun/star/resource/XStringResourceWithLocation.hpp"
+#include "dlgcont.hxx"
+#include "sbmodule.hxx"
+#include <comphelper/processfactory.hxx>
+#include <unotools/streamwrap.hxx>
+#include <osl/mutex.hxx>
+
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <unotools/pathoptions.hxx>
+#include <xmlscript/xmldlg_imexp.hxx>
+#include <cppuhelper/factory.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svtools/ehdl.hxx>
+
+
+namespace basic
+{
+
+using namespace com::sun::star::document;
+using namespace com::sun::star::container;
+using namespace com::sun::star::io;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::script;
+using namespace com::sun::star::xml::sax;
+using namespace com::sun::star;
+using namespace cppu;
+using namespace rtl;
+using namespace osl;
+
+using com::sun::star::uno::Reference;
+
+//============================================================================
+// Implementation class SfxDialogLibraryContainer
+
+const sal_Char* SAL_CALL SfxDialogLibraryContainer::getInfoFileName() const { return "dialog"; }
+const sal_Char* SAL_CALL SfxDialogLibraryContainer::getOldInfoFileName() const { return "dialogs"; }
+const sal_Char* SAL_CALL SfxDialogLibraryContainer::getLibElementFileExtension() const { return "xdl"; }
+const sal_Char* SAL_CALL SfxDialogLibraryContainer::getLibrariesDir() const { return "Dialogs"; }
+
+// Ctor for service
+SfxDialogLibraryContainer::SfxDialogLibraryContainer( void )
+{
+ // all initialisation has to be done
+ // by calling XInitialization::initialize
+}
+
+SfxDialogLibraryContainer::SfxDialogLibraryContainer( const uno::Reference< embed::XStorage >& xStorage )
+{
+ init( OUString(), xStorage );
+}
+
+// Methods to get library instances of the correct type
+SfxLibrary* SfxDialogLibraryContainer::implCreateLibrary( const ::rtl::OUString& aName )
+{
+ SfxLibrary* pRet = new SfxDialogLibrary( maModifiable, aName, mxMSF, mxSFI, this );
+ return pRet;
+}
+
+SfxLibrary* SfxDialogLibraryContainer::implCreateLibraryLink
+ ( const ::rtl::OUString& aName, const OUString& aLibInfoFileURL,
+ const OUString& StorageURL, sal_Bool ReadOnly )
+{
+ SfxLibrary* pRet = new SfxDialogLibrary
+ ( maModifiable, aName, mxMSF, mxSFI, aLibInfoFileURL, StorageURL, ReadOnly, this );
+ return pRet;
+}
+
+Any SAL_CALL SfxDialogLibraryContainer::createEmptyLibraryElement( void )
+{
+ Reference< XInputStreamProvider > xISP;
+ Any aRetAny;
+ aRetAny <<= xISP;
+ return aRetAny;
+}
+
+bool SAL_CALL SfxDialogLibraryContainer::isLibraryElementValid( Any aElement ) const
+{
+ return SfxDialogLibrary::containsValidDialog( aElement );
+}
+
+bool writeOasis2OOoLibraryElement(
+ Reference< XInputStream > xInput, Reference< XOutputStream > xOutput )
+{
+ Reference< XMultiServiceFactory > xMSF(
+ comphelper::getProcessServiceFactory() );
+
+ Reference< XComponentContext > xContext;
+ Reference< beans::XPropertySet > xProps( xMSF, UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ OSL_VERIFY( xProps->getPropertyValue(
+ OUString::createFromAscii(("DefaultContext")) ) >>= xContext );
+
+ Reference< lang::XMultiComponentFactory > xSMgr(
+ xContext->getServiceManager() );
+
+ if (! xSMgr.is())
+ {
+ return FALSE;
+ }
+
+ Reference< xml::sax::XParser > xParser(
+ xSMgr->createInstanceWithContext(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.xml.sax.Parser" ) ),
+ xContext ),
+ UNO_QUERY );
+
+ Reference< xml::sax::XExtendedDocumentHandler > xWriter(
+ xSMgr->createInstanceWithContext(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.xml.sax.Writer" ) ),
+ xContext ),
+ UNO_QUERY );
+
+ Reference< io::XActiveDataSource > xSource( xWriter, UNO_QUERY );
+ xSource->setOutputStream( xOutput );
+
+ if ( !xParser.is() || !xWriter.is() )
+ {
+ return FALSE;
+ }
+
+ Sequence<Any> aArgs( 1 );
+ aArgs[0] <<= xWriter;
+
+ Reference< xml::sax::XDocumentHandler > xHandler(
+ xSMgr->createInstanceWithArgumentsAndContext(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.Oasis2OOoTransformer" ) ),
+ aArgs, xContext ),
+ UNO_QUERY );
+
+ xParser->setDocumentHandler( xHandler );
+
+ xml::sax::InputSource source;
+ source.aInputStream = xInput;
+ source.sSystemId = OUString::createFromAscii( "virtual file" );
+
+ xParser->parseStream( source );
+
+ return TRUE;
+}
+
+void SAL_CALL SfxDialogLibraryContainer::writeLibraryElement
+(
+ const Reference < XNameContainer >& xLib,
+ const OUString& aElementName,
+ const Reference< XOutputStream >& xOutput
+)
+ throw(Exception)
+{
+ Any aElement = xLib->getByName( aElementName );
+ Reference< XInputStreamProvider > xISP;
+ aElement >>= xISP;
+ if( !xISP.is() )
+ return;
+
+ Reference< XInputStream > xInput( xISP->createInputStream() );
+
+ bool bComplete = FALSE;
+ if ( mbOasis2OOoFormat )
+ {
+ bComplete = writeOasis2OOoLibraryElement( xInput, xOutput );
+ }
+
+ if ( bComplete == FALSE )
+ {
+ Sequence< sal_Int8 > bytes;
+ sal_Int32 nRead = xInput->readBytes( bytes, xInput->available() );
+ for (;;)
+ {
+ if( nRead )
+ xOutput->writeBytes( bytes );
+
+ nRead = xInput->readBytes( bytes, 1024 );
+ if (! nRead)
+ break;
+ }
+ }
+ xInput->closeInput();
+}
+
+void SfxDialogLibraryContainer::storeLibrariesToStorage( const uno::Reference< embed::XStorage >& xStorage ) throw ( RuntimeException )
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ mbOasis2OOoFormat = sal_False;
+
+ if ( mxStorage.is() && xStorage.is() )
+ {
+ try
+ {
+ long nSource = SotStorage::GetVersion( mxStorage );
+ long nTarget = SotStorage::GetVersion( xStorage );
+
+ if ( nSource == SOFFICE_FILEFORMAT_CURRENT &&
+ nTarget != SOFFICE_FILEFORMAT_CURRENT )
+ {
+ mbOasis2OOoFormat = sal_True;
+ }
+ }
+ catch ( Exception& )
+ {
+ // if we cannot get the version then the
+ // Oasis2OOoTransformer will not be used
+ OSL_ASSERT(FALSE);
+ }
+ }
+
+ SfxLibraryContainer::storeLibrariesToStorage( xStorage );
+
+ mbOasis2OOoFormat = sal_False;
+}
+
+
+Any SAL_CALL SfxDialogLibraryContainer::importLibraryElement
+ ( const Reference < XNameContainer >& /*xLib*/,
+ const OUString& /*aElementName */, const OUString& aFile,
+ const uno::Reference< io::XInputStream >& xElementStream )
+{
+ Any aRetAny;
+
+ // TODO: Member because later it will be a component
+ //Reference< XMultiServiceFactory > xMSF( comphelper::getProcessServiceFactory() );
+ //if( !xMSF.is() )
+ //{
+ // OSL_ENSURE( 0, "### couln't get ProcessServiceFactory\n" );
+ // return aRetAny;
+ //}
+
+ Reference< XParser > xParser( mxMSF->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY );
+ if( !xParser.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create sax parser component\n" );
+ return aRetAny;
+ }
+
+ Reference< XNameContainer > xDialogModel( mxMSF->createInstance
+ ( OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlDialogModel" ) ) ), UNO_QUERY );
+ if( !xDialogModel.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create com.sun.star.awt.UnoControlDialogModel component\n" );
+ return aRetAny;
+ }
+
+ // Read from storage?
+ sal_Bool bStorage = xElementStream.is();
+ Reference< XInputStream > xInput;
+
+ if( bStorage )
+ {
+ xInput = xElementStream;
+ }
+ else
+ {
+ try
+ {
+ xInput = mxSFI->openFileRead( aFile );
+ }
+ catch( Exception& )
+ //catch( Exception& e )
+ {
+ // TODO:
+ //throw WrappedTargetException( e );
+ }
+ }
+ if( !xInput.is() )
+ return aRetAny;
+
+ Reference< XComponentContext > xContext;
+ Reference< beans::XPropertySet > xProps( mxMSF, UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ OSL_VERIFY( xProps->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")) ) >>= xContext );
+
+ InputSource source;
+ source.aInputStream = xInput;
+ source.sSystemId = aFile;
+
+ try {
+ // start parsing
+ xParser->setDocumentHandler( ::xmlscript::importDialogModel( xDialogModel, xContext ) );
+ xParser->parseStream( source );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( 0, "Parsing error\n" );
+ SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFile );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ return aRetAny;
+ }
+
+ // Create InputStream, TODO: Implement own InputStreamProvider
+ // to avoid creating the DialogModel here!
+ Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext );
+ aRetAny <<= xISP;
+ return aRetAny;
+}
+
+void SAL_CALL SfxDialogLibraryContainer::importFromOldStorage( const OUString& )
+{
+ // Nothing to do here, old dialogs cannot be imported
+}
+
+SfxLibraryContainer* SfxDialogLibraryContainer::createInstanceImpl( void )
+{
+ return new SfxDialogLibraryContainer();
+}
+
+
+static OUString aResourceFileNameBase = OUString::createFromAscii( "DialogStrings" );
+static OUString aResourceFileCommentBase = OUString::createFromAscii( "# Strings for Dialog Library " );
+
+// Resource handling
+Reference< ::com::sun::star::resource::XStringResourcePersistence >
+ SfxDialogLibraryContainer::implCreateStringResource( SfxDialogLibrary* pDialogLibrary )
+{
+ Reference< resource::XStringResourcePersistence > xRet;
+ OUString aLibName = pDialogLibrary->getName();
+ bool bReadOnly = pDialogLibrary->mbReadOnly;
+
+ // get ui locale
+ ::com::sun ::star::lang::Locale aLocale = Application::GetSettings().GetUILocale();
+
+ OUString aComment = aResourceFileCommentBase;
+ aComment += aLibName;
+
+ sal_Bool bStorage = mxStorage.is();
+ if( bStorage )
+ {
+ Sequence<Any> aArgs( 5 );
+ aArgs[1] <<= bReadOnly;
+ aArgs[2] <<= aLocale;
+ aArgs[3] <<= aResourceFileNameBase;
+ aArgs[4] <<= aComment;
+
+ // TODO: Ctor
+ xRet = Reference< resource::XStringResourcePersistence >( mxMSF->createInstance
+ ( OUString::createFromAscii( "com.sun.star.resource.StringResourceWithStorage" ) ), UNO_QUERY );
+
+ uno::Reference< embed::XStorage > xLibrariesStor;
+ uno::Reference< embed::XStorage > xLibraryStor;
+ try {
+ xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
+ // TODO: Should be READWRITE with new storage concept using store() instead of storeTo()
+ if ( !xLibrariesStor.is() )
+ throw uno::RuntimeException();
+
+ xLibraryStor = xLibrariesStor->openStorageElement( aLibName, embed::ElementModes::READ );
+ // TODO: Should be READWRITE with new storage concept using store() instead of storeTo()
+ if ( !xLibraryStor.is() )
+ throw uno::RuntimeException();
+
+ aArgs[0] <<= xLibraryStor;
+ }
+ catch( uno::Exception& )
+ {
+ // TODO: Error handling?
+ return xRet;
+ }
+
+ // TODO: Ctor
+ if( xRet.is() )
+ {
+ Reference< XInitialization > xInit( xRet, UNO_QUERY );
+ if( xInit.is() )
+ xInit->initialize( aArgs );
+ }
+ }
+ else
+ {
+ Sequence<Any> aArgs( 6 );
+
+ OUString aLocation = createAppLibraryFolder( pDialogLibrary, aLibName );
+ aArgs[0] <<= aLocation;
+ aArgs[1] <<= bReadOnly;
+ aArgs[2] <<= aLocale;
+ aArgs[3] <<= aResourceFileNameBase;
+ aArgs[4] <<= aComment;
+
+ // TODO: Real handler?
+ Reference< task::XInteractionHandler > xDummyHandler;
+ aArgs[5] <<= xDummyHandler;
+
+ // TODO: Ctor
+ xRet = Reference< resource::XStringResourcePersistence >( mxMSF->createInstance
+ ( OUString::createFromAscii( "com.sun.star.resource.StringResourceWithLocation" ) ), UNO_QUERY );
+
+ // TODO: Ctor
+ if( xRet.is() )
+ {
+ Reference< XInitialization > xInit( xRet, UNO_QUERY );
+ if( xInit.is() )
+ xInit->initialize( aArgs );
+ }
+ }
+
+ return xRet;
+}
+
+void SfxDialogLibraryContainer::onNewRootStorage()
+{
+ // the library container is not modified, go through the libraries and check whether they are modified
+ Sequence< OUString > aNames = maNameContainer.getElementNames();
+ const OUString* pNames = aNames.getConstArray();
+ sal_Int32 nNameCount = aNames.getLength();
+
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aName = pNames[ i ];
+ SfxDialogLibrary* pDialogLibrary = static_cast<SfxDialogLibrary*>( getImplLib( aName ) );
+
+ Reference< resource::XStringResourcePersistence > xStringResourcePersistence =
+ pDialogLibrary->getStringResourcePersistence();
+
+ if( xStringResourcePersistence.is() )
+ {
+ Reference< embed::XStorage > xLibrariesStor;
+ Reference< embed::XStorage > xLibraryStor;
+ try {
+ xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READWRITE );
+ if ( !xLibrariesStor.is() )
+ throw uno::RuntimeException();
+
+ OUString aLibName = pDialogLibrary->getName();
+ xLibraryStor = xLibrariesStor->openStorageElement( aLibName, embed::ElementModes::READWRITE );
+ if ( !xLibraryStor.is() )
+ throw uno::RuntimeException();
+
+ Reference< resource::XStringResourceWithStorage >
+ xStringResourceWithStorage( xStringResourcePersistence, UNO_QUERY );
+ if( xStringResourceWithStorage.is() )
+ xStringResourceWithStorage->setStorage( xLibraryStor );
+ }
+ catch( uno::Exception& )
+ {
+ // TODO: Error handling?
+ }
+ }
+ }
+}
+
+
+//============================================================================
+// Service
+
+void createRegistryInfo_SfxDialogLibraryContainer()
+{
+ static OAutoRegistration< SfxDialogLibraryContainer > aAutoRegistration;
+}
+
+::rtl::OUString SAL_CALL SfxDialogLibraryContainer::getImplementationName( ) throw (RuntimeException)
+{
+ return getImplementationName_static();
+}
+
+Sequence< ::rtl::OUString > SAL_CALL SfxDialogLibraryContainer::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ return getSupportedServiceNames_static();
+}
+
+Sequence< OUString > SfxDialogLibraryContainer::getSupportedServiceNames_static()
+{
+ Sequence< OUString > aServiceNames( 2 );
+ aServiceNames[0] = OUString::createFromAscii( "com.sun.star.script.DocumentDialogLibraryContainer" );
+ // plus, for compatibility:
+ aServiceNames[1] = OUString::createFromAscii( "com.sun.star.script.DialogLibraryContainer" );
+ return aServiceNames;
+}
+
+OUString SfxDialogLibraryContainer::getImplementationName_static()
+{
+ static OUString aImplName;
+ static sal_Bool bNeedsInit = sal_True;
+
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if( bNeedsInit )
+ {
+ aImplName = OUString::createFromAscii( "com.sun.star.comp.sfx2.DialogLibraryContainer" );
+ bNeedsInit = sal_False;
+ }
+ return aImplName;
+}
+
+Reference< XInterface > SAL_CALL SfxDialogLibraryContainer::Create( const Reference< XComponentContext >& ) throw( Exception )
+{
+ Reference< XInterface > xRet =
+ static_cast< XInterface* >( static_cast< OWeakObject* >(new SfxDialogLibraryContainer()) );
+ return xRet;
+}
+
+
+//============================================================================
+// Implementation class SfxDialogLibrary
+
+// Ctor
+SfxDialogLibrary::SfxDialogLibrary( ModifiableHelper& _rModifiable,
+ const ::rtl::OUString& aName,
+ const Reference< XMultiServiceFactory >& xMSF,
+ const Reference< XSimpleFileAccess >& xSFI,
+ SfxDialogLibraryContainer* pParent )
+ : SfxLibrary( _rModifiable, getCppuType( (const Reference< XInputStreamProvider > *)0 ), xMSF, xSFI )
+ , m_pParent( pParent )
+ , m_aName( aName )
+{
+}
+
+SfxDialogLibrary::SfxDialogLibrary( ModifiableHelper& _rModifiable,
+ const ::rtl::OUString& aName,
+ const Reference< XMultiServiceFactory >& xMSF,
+ const Reference< XSimpleFileAccess >& xSFI,
+ const OUString& aLibInfoFileURL,
+ const OUString& aStorageURL,
+ sal_Bool ReadOnly,
+ SfxDialogLibraryContainer* pParent )
+ : SfxLibrary( _rModifiable, getCppuType( (const Reference< XInputStreamProvider > *)0 ),
+ xMSF, xSFI, aLibInfoFileURL, aStorageURL, ReadOnly)
+ , m_pParent( pParent )
+ , m_aName( aName )
+{
+}
+
+IMPLEMENT_FORWARD_XINTERFACE2( SfxDialogLibrary, SfxLibrary, SfxDialogLibrary_BASE );
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( SfxDialogLibrary, SfxLibrary, SfxDialogLibrary_BASE );
+
+// Provide modify state including resources
+sal_Bool SfxDialogLibrary::isModified( void )
+{
+ sal_Bool bRet = implIsModified();
+
+ if( !bRet && m_xStringResourcePersistence.is() )
+ bRet = m_xStringResourcePersistence->isModified();
+ // else: Resources not accessed so far -> not modified
+
+ return bRet;
+}
+
+void SfxDialogLibrary::storeResources( void )
+{
+ if( m_xStringResourcePersistence.is() )
+ m_xStringResourcePersistence->store();
+}
+
+void SfxDialogLibrary::storeResourcesAsURL
+ ( const ::rtl::OUString& URL, const ::rtl::OUString& NewName )
+{
+ OUString aComment = aResourceFileCommentBase;
+ m_aName = NewName;
+ aComment += m_aName;
+
+ if( m_xStringResourcePersistence.is() )
+ {
+ m_xStringResourcePersistence->setComment( aComment );
+
+ Reference< resource::XStringResourceWithLocation >
+ xStringResourceWithLocation( m_xStringResourcePersistence, UNO_QUERY );
+ if( xStringResourceWithLocation.is() )
+ xStringResourceWithLocation->storeAsURL( URL );
+ }
+}
+
+void SfxDialogLibrary::storeResourcesToURL( const OUString& URL,
+ const Reference< task::XInteractionHandler >& xHandler )
+{
+ OUString aComment = aResourceFileCommentBase;
+ aComment += m_aName;
+
+ if( m_xStringResourcePersistence.is() )
+ {
+ m_xStringResourcePersistence->storeToURL
+ ( URL, aResourceFileNameBase, aComment, xHandler );
+ }
+}
+
+void SfxDialogLibrary::storeResourcesToStorage( const ::com::sun::star::uno::Reference
+ < ::com::sun::star::embed::XStorage >& xStorage )
+{
+ OUString aComment = aResourceFileCommentBase;
+ aComment += m_aName;
+
+ if( m_xStringResourcePersistence.is() )
+ {
+ m_xStringResourcePersistence->storeToStorage
+ ( xStorage, aResourceFileNameBase, aComment );
+ }
+}
+
+
+// XStringResourceSupplier
+Reference< resource::XStringResourceResolver >
+ SAL_CALL SfxDialogLibrary::getStringResource( ) throw (RuntimeException)
+{
+ if( !m_xStringResourcePersistence.is() )
+ m_xStringResourcePersistence = m_pParent->implCreateStringResource( this );
+
+ Reference< resource::XStringResourceResolver > xRet( m_xStringResourcePersistence, UNO_QUERY );
+ return xRet;
+}
+
+bool SfxDialogLibrary::containsValidDialog( const ::com::sun::star::uno::Any& aElement )
+{
+ Reference< XInputStreamProvider > xISP;
+ aElement >>= xISP;
+ return xISP.is();
+}
+
+bool SAL_CALL SfxDialogLibrary::isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const
+{
+ return SfxDialogLibrary::containsValidDialog( aElement );
+}
+
+}
+//============================================================================
+
diff --git a/basic/source/uno/makefile.mk b/basic/source/uno/makefile.mk
new file mode 100644
index 000000000000..52e7f7004c4d
--- /dev/null
+++ b/basic/source/uno/makefile.mk
@@ -0,0 +1,49 @@
+#*************************************************************************
+#
+# 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=uno
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ------------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+SLOFILES= \
+ $(SLO)$/namecont.obj \
+ $(SLO)$/scriptcont.obj \
+ $(SLO)$/dlgcont.obj \
+ $(SLO)$/sbmodule.obj \
+ $(SLO)$/sbservices.obj \
+ $(SLO)$/modsizeexceeded.obj
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/basic/source/uno/modsizeexceeded.cxx b/basic/source/uno/modsizeexceeded.cxx
new file mode 100644
index 000000000000..408b0f3f8dd4
--- /dev/null
+++ b/basic/source/uno/modsizeexceeded.cxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * 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 "modsizeexceeded.hxx"
+
+#include <framework/interaction.hxx>
+#include <com/sun/star/script/ModuleSizeExceededRequest.hpp>
+
+using namespace com::sun::star;
+using namespace cppu;
+using namespace rtl;
+using namespace osl;
+
+ModuleSizeExceeded::ModuleSizeExceeded( const uno::Sequence< ::rtl::OUString >& sModules )
+{
+ script::ModuleSizeExceededRequest aReq;
+ aReq.Names = sModules;
+
+ m_aRequest <<= aReq;
+
+ m_xAbort.set( uno::Reference< task::XInteractionAbort >(new framework::ContinuationAbort), uno::UNO_QUERY );
+ m_xApprove.set( uno::Reference< task::XInteractionApprove >(new framework::ContinuationApprove ), uno::UNO_QUERY );
+ m_lContinuations.realloc( 2 );
+ m_lContinuations[0] = m_xApprove;
+ m_lContinuations[1] = m_xAbort;
+}
+
+sal_Bool
+ModuleSizeExceeded::isAbort() const
+{
+ framework::ContinuationAbort* pBase = static_cast< framework::ContinuationAbort* >( m_xAbort.get() );
+ return pBase->isSelected();
+}
+
+sal_Bool
+ModuleSizeExceeded::isApprove() const
+{
+ framework::ContinuationApprove* pBase = static_cast< framework::ContinuationApprove* >( m_xApprove.get() );
+ return pBase->isSelected();
+}
+
+
diff --git a/basic/source/uno/namecont.cxx b/basic/source/uno/namecont.cxx
new file mode 100644
index 000000000000..c31aed1f8ef7
--- /dev/null
+++ b/basic/source/uno/namecont.cxx
@@ -0,0 +1,3506 @@
+/*************************************************************************
+ *
+ * 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 <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <vcl/svapp.hxx>
+#include <vos/mutex.hxx>
+#ifndef __RSC //autogen
+#include <tools/errinf.hxx>
+#endif
+#include <osl/mutex.hxx>
+#include <vos/diagnose.hxx>
+#include <rtl/uri.hxx>
+#include <rtl/strbuf.hxx>
+#include <comphelper/processfactory.hxx>
+#ifndef INCLUDED_COMPHELPER_ANYTOSTRING_HXX
+#include <comphelper/anytostring.hxx>
+#endif
+
+#include "namecont.hxx"
+#include <basic/basicmanagerrepository.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/urlobj.hxx>
+#include <unotools/streamwrap.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svtools/ehdl.hxx>
+#include <basic/basmgr.hxx>
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/DeploymentException.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/script/LibraryNotLoadedException.hpp>
+#include "com/sun/star/deployment/ExtensionManager.hpp"
+#include <comphelper/storagehelper.hxx>
+#ifndef _RTL_USTRING_HXX_
+#include <comphelper/anytostring.hxx>
+#endif
+#include <cppuhelper/exc_hlp.hxx>
+#include <basic/sbmod.hxx>
+
+namespace basic
+{
+
+using namespace com::sun::star::document;
+using namespace com::sun::star::container;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::io;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::script;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::xml::sax;
+using namespace com::sun::star::util;
+using namespace com::sun::star::task;
+using namespace com::sun::star::embed;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::deployment;
+using namespace com::sun::star;
+using namespace cppu;
+using namespace rtl;
+using namespace osl;
+
+using com::sun::star::uno::Reference;
+
+// #i34411: Flag for error handling during migration
+static bool GbMigrationSuppressErrors = false;
+
+//============================================================================
+// Implementation class NameContainer
+
+// Methods XElementAccess
+Type NameContainer::getElementType()
+ throw(RuntimeException)
+{
+ return mType;
+}
+
+sal_Bool NameContainer::hasElements()
+ throw(RuntimeException)
+{
+ sal_Bool bRet = (mnElementCount > 0);
+ return bRet;
+}
+
+// Methods XNameAccess
+Any NameContainer::getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ NameContainerNameMap::iterator aIt = mHashMap.find( aName );
+ if( aIt == mHashMap.end() )
+ {
+ throw NoSuchElementException();
+ }
+ sal_Int32 iHashResult = (*aIt).second;
+ Any aRetAny = mValues.getConstArray()[ iHashResult ];
+ return aRetAny;
+}
+
+Sequence< OUString > NameContainer::getElementNames()
+ throw(RuntimeException)
+{
+ return mNames;
+}
+
+sal_Bool NameContainer::hasByName( const OUString& aName )
+ throw(RuntimeException)
+{
+ NameContainerNameMap::iterator aIt = mHashMap.find( aName );
+ sal_Bool bRet = ( aIt != mHashMap.end() );
+ return bRet;
+}
+
+
+// Methods XNameReplace
+void NameContainer::replaceByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ Type aAnyType = aElement.getValueType();
+ if( mType != aAnyType )
+ throw IllegalArgumentException();
+
+ NameContainerNameMap::iterator aIt = mHashMap.find( aName );
+ if( aIt == mHashMap.end() )
+ {
+ throw NoSuchElementException();
+ }
+ sal_Int32 iHashResult = (*aIt).second;
+ Any aOldElement = mValues.getConstArray()[ iHashResult ];
+ mValues.getArray()[ iHashResult ] = aElement;
+
+
+ // Fire event
+ ContainerEvent aEvent;
+ aEvent.Source = mpxEventSource;
+ aEvent.Accessor <<= aName;
+ aEvent.Element = aElement;
+ aEvent.ReplacedElement = aOldElement;
+
+ OInterfaceIteratorHelper aIterator( maListenerContainer );
+ while( aIterator.hasMoreElements() )
+ {
+ Reference< XInterface > xIface = aIterator.next();
+ Reference< XContainerListener > xListener( xIface, UNO_QUERY );
+ try
+ {
+ xListener->elementReplaced( aEvent );
+ }
+ catch(RuntimeException&)
+ {
+ aIterator.remove();
+ }
+ }
+}
+
+
+// Methods XNameContainer
+void NameContainer::insertByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ Type aAnyType = aElement.getValueType();
+ if( mType != aAnyType )
+ throw IllegalArgumentException();
+
+ NameContainerNameMap::iterator aIt = mHashMap.find( aName );
+ if( aIt != mHashMap.end() )
+ {
+ throw ElementExistException();
+ }
+
+ sal_Int32 nCount = mNames.getLength();
+ mNames.realloc( nCount + 1 );
+ mValues.realloc( nCount + 1 );
+ mNames.getArray()[ nCount ] = aName;
+ mValues.getArray()[ nCount ] = aElement;
+
+ mHashMap[ aName ] = nCount;
+ mnElementCount++;
+
+
+ // Fire event
+ ContainerEvent aEvent;
+ aEvent.Source = mpxEventSource;
+ aEvent.Accessor <<= aName;
+ aEvent.Element = aElement;
+
+ OInterfaceIteratorHelper aIterator( maListenerContainer );
+ while( aIterator.hasMoreElements() )
+ {
+ Reference< XInterface > xIface = aIterator.next();
+ Reference< XContainerListener > xListener( xIface, UNO_QUERY );
+ try
+ {
+ xListener->elementInserted( aEvent );
+ }
+ catch(RuntimeException&)
+ {
+ aIterator.remove();
+ }
+ }
+}
+
+void NameContainer::removeByName( const OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ NameContainerNameMap::iterator aIt = mHashMap.find( Name );
+ if( aIt == mHashMap.end() )
+ {
+ throw NoSuchElementException();
+ }
+
+ sal_Int32 iHashResult = (*aIt).second;
+ Any aOldElement = mValues.getConstArray()[ iHashResult ];
+ mHashMap.erase( aIt );
+ sal_Int32 iLast = mNames.getLength() - 1;
+ if( iLast != iHashResult )
+ {
+ OUString* pNames = mNames.getArray();
+ Any* pValues = mValues.getArray();
+ pNames[ iHashResult ] = pNames[ iLast ];
+ pValues[ iHashResult ] = pValues[ iLast ];
+ mHashMap[ pNames[ iHashResult ] ] = iHashResult;
+ }
+ mNames.realloc( iLast );
+ mValues.realloc( iLast );
+ mnElementCount--;
+
+
+ // Fire event
+ ContainerEvent aEvent;
+ aEvent.Source = mpxEventSource;
+ aEvent.Accessor <<= Name;
+ aEvent.Element = aOldElement;
+
+ OInterfaceIteratorHelper aIterator( maListenerContainer );
+ while( aIterator.hasMoreElements() )
+ {
+ Reference< XInterface > xIface = aIterator.next();
+ Reference< XContainerListener > xListener( xIface, UNO_QUERY );
+ try
+ {
+ xListener->elementRemoved( aEvent );
+ }
+ catch(RuntimeException&)
+ {
+ aIterator.remove();
+ }
+ }
+}
+
+
+// Methods XContainer
+void SAL_CALL NameContainer::addContainerListener( const Reference< XContainerListener >& xListener )
+ throw (RuntimeException)
+{
+ if( !xListener.is() )
+ throw RuntimeException();
+ Reference< XInterface > xIface( xListener, UNO_QUERY );
+ maListenerContainer.addInterface( xIface );
+}
+
+void SAL_CALL NameContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
+ throw (RuntimeException)
+{
+ if( !xListener.is() )
+ throw RuntimeException();
+ Reference< XInterface > xIface( xListener, UNO_QUERY );
+ maListenerContainer.removeInterface( xIface );
+}
+
+//============================================================================
+// ModifiableHelper
+
+void ModifiableHelper::setModified( sal_Bool _bModified )
+{
+ if ( _bModified == mbModified )
+ return;
+ mbModified = _bModified;
+
+ if ( m_aModifyListeners.getLength() == 0 )
+ return;
+
+ EventObject aModifyEvent( m_rEventSource );
+ m_aModifyListeners.notifyEach( &XModifyListener::modified, aModifyEvent );
+}
+
+//============================================================================
+
+// Implementation class SfxLibraryContainer
+DBG_NAME( SfxLibraryContainer )
+
+// Ctor
+SfxLibraryContainer::SfxLibraryContainer( void )
+ : LibraryContainerHelper( maMutex )
+ , mbVBACompat( sal_False )
+ , maModifiable( *this, maMutex )
+ , maNameContainer( getCppuType( (Reference< XNameAccess >*) NULL ) )
+ , mbOldInfoFormat( sal_False )
+ , mbOasis2OOoFormat( sal_False )
+ , mpBasMgr( NULL )
+ , mbOwnBasMgr( sal_False )
+{
+ DBG_CTOR( SfxLibraryContainer, NULL );
+
+ mxMSF = comphelper::getProcessServiceFactory();
+ if( !mxMSF.is() )
+ {
+ OSL_ENSURE( 0, "### couln't get ProcessServiceFactory\n" );
+ }
+
+ mxSFI = Reference< XSimpleFileAccess >( mxMSF->createInstance
+ ( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
+ if( !mxSFI.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create SimpleFileAccess component\n" );
+ }
+
+ mxStringSubstitution = Reference< XStringSubstitution >( mxMSF->createInstance
+ ( OUString::createFromAscii( "com.sun.star.util.PathSubstitution" ) ), UNO_QUERY );
+ if( !mxStringSubstitution.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create PathSubstitution component\n" );
+ }
+}
+
+SfxLibraryContainer::~SfxLibraryContainer()
+{
+ if( mbOwnBasMgr )
+ BasicManager::LegacyDeleteBasicManager( mpBasMgr );
+ DBG_DTOR( SfxLibraryContainer, NULL );
+}
+
+void SfxLibraryContainer::checkDisposed() const
+{
+ if ( isDisposed() )
+ throw DisposedException( ::rtl::OUString(), *const_cast< SfxLibraryContainer* >( this ) );
+}
+
+void SfxLibraryContainer::enterMethod()
+{
+ maMutex.acquire();
+ checkDisposed();
+}
+
+void SfxLibraryContainer::leaveMethod()
+{
+ maMutex.release();
+}
+
+BasicManager* SfxLibraryContainer::getBasicManager( void )
+{
+ if ( mpBasMgr )
+ return mpBasMgr;
+
+ Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
+ OSL_ENSURE( xDocument.is(), "SfxLibraryContainer::getBasicManager: cannot obtain a BasicManager without document!" );
+ if ( xDocument.is() )
+ mpBasMgr = BasicManagerRepository::getDocumentBasicManager( xDocument );
+
+ return mpBasMgr;
+}
+
+// Methods XStorageBasedLibraryContainer
+Reference< XStorage > SAL_CALL SfxLibraryContainer::getRootStorage() throw (RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ return mxStorage;
+}
+
+void SAL_CALL SfxLibraryContainer::setRootStorage( const Reference< XStorage >& _rxRootStorage ) throw (IllegalArgumentException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ if ( !_rxRootStorage.is() )
+ throw IllegalArgumentException();
+
+ mxStorage = _rxRootStorage;
+ onNewRootStorage();
+}
+
+void SAL_CALL SfxLibraryContainer::storeLibrariesToStorage( const Reference< XStorage >& _rxRootStorage ) throw (IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ if ( !_rxRootStorage.is() )
+ throw IllegalArgumentException();
+
+ try
+ {
+ storeLibraries_Impl( _rxRootStorage, sal_True );
+ }
+ catch( const Exception& )
+ {
+ throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
+ }
+}
+
+
+// Methods XModifiable
+sal_Bool SfxLibraryContainer::isModified() throw (RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ if ( maModifiable.isModified() )
+ return sal_True;
+
+ // the library container is not modified, go through the libraries and check whether they are modified
+ Sequence< OUString > aNames = maNameContainer.getElementNames();
+ const OUString* pNames = aNames.getConstArray();
+ sal_Int32 nNameCount = aNames.getLength();
+
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aName = pNames[ i ];
+ SfxLibrary* pImplLib = getImplLib( aName );
+ if( pImplLib->isModified() )
+ {
+ if ( aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Standard") ) ) )
+ {
+ // this is a workaround that has to be implemented because
+ // empty standard library should stay marked as modified
+ // but should not be treated as modified while it is empty
+ if ( pImplLib->hasElements() )
+ return sal_True;
+ }
+ else
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+void SAL_CALL SfxLibraryContainer::setModified( sal_Bool _bModified ) throw (PropertyVetoException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ maModifiable.setModified( _bModified );
+}
+
+void SAL_CALL SfxLibraryContainer::addModifyListener( const Reference< XModifyListener >& _rxListener ) throw (RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ maModifiable.addModifyListener( _rxListener );
+}
+
+void SAL_CALL SfxLibraryContainer::removeModifyListener( const Reference< XModifyListener >& _rxListener ) throw (RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ maModifiable.removeModifyListener( _rxListener );
+}
+
+// Methods XPersistentLibraryContainer
+Any SAL_CALL SfxLibraryContainer::getRootLocation() throw (RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ return makeAny( getRootStorage() );
+}
+
+::rtl::OUString SAL_CALL SfxLibraryContainer::getContainerLocationName() throw (RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ return maLibrariesDir;
+}
+
+void SAL_CALL SfxLibraryContainer::storeLibraries( ) throw (WrappedTargetException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ try
+ {
+ storeLibraries_Impl( mxStorage, mxStorage.is() );
+ // we need to store *all* libraries if and only if we are based on a storage:
+ // in this case, storeLibraries_Impl will remove the source storage, after loading
+ // all libraries, so we need to force them to be stored, again
+ }
+ catch( const Exception& )
+ {
+ throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
+ }
+}
+
+static void checkAndCopyFileImpl( const INetURLObject& rSourceFolderInetObj,
+ const INetURLObject& rTargetFolderInetObj,
+ const OUString& rCheckFileName,
+ const OUString& rCheckExtension,
+ Reference< XSimpleFileAccess > xSFI )
+{
+ INetURLObject aTargetFolderInetObj( rTargetFolderInetObj );
+ aTargetFolderInetObj.insertName( rCheckFileName, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ aTargetFolderInetObj.setExtension( rCheckExtension );
+ OUString aTargetFile = aTargetFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ if( !xSFI->exists( aTargetFile ) )
+ {
+ INetURLObject aSourceFolderInetObj( rSourceFolderInetObj );
+ aSourceFolderInetObj.insertName( rCheckFileName, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ aSourceFolderInetObj.setExtension( rCheckExtension );
+ OUString aSourceFile = aSourceFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ xSFI->copy( aSourceFile, aTargetFile );
+ }
+}
+
+static void createVariableURL( OUString& rStr, const OUString& rLibName,
+ const OUString& rInfoFileName, bool bUser )
+{
+ if( bUser )
+ rStr = OUString::createFromAscii( "$(USER)/basic/" );
+ else
+ rStr = OUString::createFromAscii( "$(INST)/share/basic/" );
+
+ rStr += rLibName;
+ rStr += OUString::createFromAscii( "/" );
+ rStr += rInfoFileName;
+ rStr += OUString::createFromAscii( ".xlb/" );
+}
+
+sal_Bool SfxLibraryContainer::init( const OUString& rInitialDocumentURL, const uno::Reference< embed::XStorage >& rxInitialStorage )
+{
+ // this might be called from within the ctor, and the impl_init might (indirectly) create
+ // an UNO reference to ourself.
+ // Ensure that we're not destroyed while we're in here
+ osl_incrementInterlockedCount( &m_refCount );
+ sal_Bool bSuccess = init_Impl( rInitialDocumentURL, rxInitialStorage );
+ osl_decrementInterlockedCount( &m_refCount );
+
+ return bSuccess;
+}
+
+sal_Bool SfxLibraryContainer::init_Impl(
+ const OUString& rInitialDocumentURL, const uno::Reference< embed::XStorage >& rxInitialStorage )
+{
+ uno::Reference< embed::XStorage > xStorage = rxInitialStorage;
+
+ maInitialDocumentURL = rInitialDocumentURL;
+ maInfoFileName = OUString::createFromAscii( getInfoFileName() );
+ maOldInfoFileName = OUString::createFromAscii( getOldInfoFileName() );
+ maLibElementFileExtension = OUString::createFromAscii( getLibElementFileExtension() );
+ maLibrariesDir = OUString::createFromAscii( getLibrariesDir() );
+
+ meInitMode = DEFAULT;
+ INetURLObject aInitUrlInetObj( maInitialDocumentURL );
+ OUString aInitFileName = aInitUrlInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ if( aInitFileName.getLength() )
+ {
+ // We need a BasicManager to avoid problems
+ StarBASIC* pBas = new StarBASIC();
+ mpBasMgr = new BasicManager( pBas );
+ mbOwnBasMgr = sal_True;
+
+ OUString aExtension = aInitUrlInetObj.getExtension();
+ if( aExtension.compareToAscii( "xlc" ) == COMPARE_EQUAL )
+ {
+ meInitMode = CONTAINER_INIT_FILE;
+ INetURLObject aLibPathInetObj( aInitUrlInetObj );
+ aLibPathInetObj.removeSegment();
+ maLibraryPath = aLibPathInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ else if( aExtension.compareToAscii( "xlb" ) == COMPARE_EQUAL )
+ {
+ meInitMode = LIBRARY_INIT_FILE;
+ uno::Reference< embed::XStorage > xDummyStor;
+ ::xmlscript::LibDescriptor aLibDesc;
+ sal_Bool bReadIndexFile = implLoadLibraryIndexFile( NULL, aLibDesc, xDummyStor, aInitFileName );
+ return bReadIndexFile;
+ }
+ else
+ {
+ // Decide between old and new document
+ sal_Bool bOldStorage = SotStorage::IsOLEStorage( aInitFileName );
+ if ( bOldStorage )
+ {
+ meInitMode = OLD_BASIC_STORAGE;
+ importFromOldStorage( aInitFileName );
+ return sal_True;
+ }
+ else
+ {
+ meInitMode = OFFICE_DOCUMENT;
+ try
+ {
+ xStorage = ::comphelper::OStorageHelper::GetStorageFromURL( aInitFileName, embed::ElementModes::READ );
+ }
+ catch ( uno::Exception& )
+ {
+ // TODO: error handling
+ }
+ }
+ }
+ }
+ else
+ {
+ // Default pathes
+ maLibraryPath = SvtPathOptions().GetBasicPath();
+ }
+
+ Reference< XParser > xParser( mxMSF->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY );
+ if( !xParser.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create sax parser component\n" );
+ return sal_False;
+ }
+
+ uno::Reference< io::XInputStream > xInput;
+
+ mxStorage = xStorage;
+ sal_Bool bStorage = mxStorage.is();
+
+
+ // #110009: Scope to force the StorageRefs to be destructed and
+ // so the streams to be closed before the preload operation
+ {
+ // #110009
+
+ uno::Reference< embed::XStorage > xLibrariesStor;
+ String aFileName;
+
+ int nPassCount = 1;
+ if( !bStorage && meInitMode == DEFAULT )
+ nPassCount = 2;
+ for( int nPass = 0 ; nPass < nPassCount ; nPass++ )
+ {
+ if( bStorage )
+ {
+ OSL_ENSURE( meInitMode == DEFAULT || meInitMode == OFFICE_DOCUMENT,
+ "### Wrong InitMode for document\n" );
+ try
+ {
+ uno::Reference< io::XStream > xStream;
+ xLibrariesStor = xStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
+ //if ( !xLibrariesStor.is() )
+ // TODO: the method must either return a storage or throw an exception
+ //throw uno::RuntimeException();
+
+ if ( xLibrariesStor.is() )
+ {
+ aFileName = maInfoFileName;
+ aFileName += String( RTL_CONSTASCII_USTRINGPARAM("-lc.xml") );
+
+ try
+ {
+ xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
+ }
+ catch( uno::Exception& )
+ {}
+
+ if( !xStream.is() )
+ {
+ mbOldInfoFormat = true;
+
+ // Check old version
+ aFileName = maOldInfoFileName;
+ aFileName += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
+
+ try
+ {
+ xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
+ }
+ catch( uno::Exception& )
+ {}
+
+ if( !xStream.is() )
+ {
+ // Check for EA2 document version with wrong extensions
+ aFileName = maOldInfoFileName;
+ aFileName += String( RTL_CONSTASCII_USTRINGPARAM(".xli") );
+ xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
+ }
+ }
+ }
+
+ if ( xStream.is() )
+ xInput = xStream->getInputStream();
+ }
+ catch( uno::Exception& )
+ {
+ // TODO: error handling?
+ }
+ }
+ else
+ {
+ INetURLObject* pLibInfoInetObj = NULL;
+ if( meInitMode == CONTAINER_INIT_FILE )
+ {
+ aFileName = aInitFileName;
+ }
+ else
+ {
+ if( nPass == 1 )
+ pLibInfoInetObj = new INetURLObject( String(maLibraryPath).GetToken(0) );
+ else
+ pLibInfoInetObj = new INetURLObject( String(maLibraryPath).GetToken(1) );
+ pLibInfoInetObj->insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ pLibInfoInetObj->setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlc") ) );
+ aFileName = pLibInfoInetObj->GetMainURL( INetURLObject::NO_DECODE );
+ }
+
+ try
+ {
+ xInput = mxSFI->openFileRead( aFileName );
+ }
+ catch( Exception& )
+ {
+ xInput.clear();
+ if( nPass == 0 )
+ {
+ SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFileName );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+ }
+
+ // Old variant?
+ if( !xInput.is() && nPass == 0 )
+ {
+ INetURLObject aLibInfoInetObj( String(maLibraryPath).GetToken(1) );
+ aLibInfoInetObj.insertName( maOldInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aLibInfoInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xli") ) );
+ aFileName = aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ try
+ {
+ xInput = mxSFI->openFileRead( aFileName );
+ mbOldInfoFormat = true;
+ }
+ catch( Exception& )
+ {
+ xInput.clear();
+ SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFileName );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+ }
+
+ delete pLibInfoInetObj;
+ }
+
+ if( xInput.is() )
+ {
+ InputSource source;
+ source.aInputStream = xInput;
+ source.sSystemId = aFileName;
+
+ // start parsing
+ ::xmlscript::LibDescriptorArray* pLibArray = new ::xmlscript::LibDescriptorArray();
+
+ try
+ {
+ xParser->setDocumentHandler( ::xmlscript::importLibraryContainer( pLibArray ) );
+ xParser->parseStream( source );
+ }
+ catch ( xml::sax::SAXException& e )
+ {
+ (void) e; // avoid warning
+ OSL_ENSURE( 0, OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ return sal_False;
+ }
+ catch ( io::IOException& e )
+ {
+ (void) e; // avoid warning
+ OSL_ENSURE( 0, OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ return sal_False;
+ }
+
+ sal_Int32 nLibCount = pLibArray->mnLibCount;
+ for( sal_Int32 i = 0 ; i < nLibCount ; i++ )
+ {
+ ::xmlscript::LibDescriptor& rLib = pLibArray->mpLibs[i];
+
+ // Check storage URL
+ OUString aStorageURL = rLib.aStorageURL;
+ if( !bStorage && !aStorageURL.getLength() && nPass == 0 )
+ {
+ String aLibraryPath;
+ if( meInitMode == CONTAINER_INIT_FILE )
+ aLibraryPath = maLibraryPath;
+ else
+ aLibraryPath = String(maLibraryPath).GetToken(1);
+ INetURLObject aInetObj( aLibraryPath );
+
+ aInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ if( mxSFI->isFolder( aLibDirPath ) )
+ {
+ createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, true );
+ maModifiable.setModified( sal_True );
+ }
+ else if( rLib.bLink )
+ {
+ // Check "share" path
+ INetURLObject aShareInetObj( String(maLibraryPath).GetToken(0) );
+ aShareInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ OUString aShareLibDirPath = aShareInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ if( mxSFI->isFolder( aShareLibDirPath ) )
+ {
+ createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, false );
+ maModifiable.setModified( sal_True );
+ }
+ else
+ {
+ // #i25537: Ignore lib if library folder does not really exist
+ continue;
+ }
+ }
+ }
+
+ OUString aLibName = rLib.aName;
+
+ // If the same library name is used by the shared and the
+ // user lib container index files the user file wins
+ if( nPass == 1 && hasByName( aLibName ) )
+ continue;
+
+ SfxLibrary* pImplLib;
+ if( rLib.bLink )
+ {
+ Reference< XNameAccess > xLib =
+ createLibraryLink( aLibName, rLib.aStorageURL, rLib.bReadOnly );
+ pImplLib = static_cast< SfxLibrary* >( xLib.get() );
+ }
+ else
+ {
+ Reference< XNameContainer > xLib = createLibrary( aLibName );
+ pImplLib = static_cast< SfxLibrary* >( xLib.get() );
+ pImplLib->mbLoaded = sal_False;
+ pImplLib->mbReadOnly = rLib.bReadOnly;
+ if( !bStorage )
+ checkStorageURL( rLib.aStorageURL, pImplLib->maLibInfoFileURL,
+ pImplLib->maStorageURL, pImplLib->maUnexpandedStorageURL );
+ }
+ maModifiable.setModified( sal_False );
+
+ // Read library info files
+ if( !mbOldInfoFormat )
+ {
+ uno::Reference< embed::XStorage > xLibraryStor;
+ if( !pImplLib->mbInitialised && bStorage )
+ {
+ try {
+ xLibraryStor = xLibrariesStor->openStorageElement( rLib.aName,
+ embed::ElementModes::READ );
+ }
+ catch( uno::Exception& )
+ {
+ #if OSL_DEBUG_LEVEL > 0
+ Any aError( ::cppu::getCaughtException() );
+ ::rtl::OStringBuffer aMessage;
+ aMessage.append( "couln't open sub storage for library '" );
+ aMessage.append( ::rtl::OUStringToOString( rLib.aName, osl_getThreadTextEncoding() ) );
+ aMessage.append( "'.\n\nException:" );
+ aMessage.append( ::rtl::OUStringToOString( ::comphelper::anyToString( aError ), osl_getThreadTextEncoding() ) );
+ OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
+ #endif
+ }
+ }
+
+ // Link is already initialised in createLibraryLink()
+ if( !pImplLib->mbInitialised && (!bStorage || xLibraryStor.is()) )
+ {
+ OUString aIndexFileName;
+ sal_Bool bLoaded = implLoadLibraryIndexFile( pImplLib, rLib, xLibraryStor, aIndexFileName );
+ if( bLoaded && aLibName != rLib.aName )
+ {
+ OSL_ENSURE( 0, "Different library names in library"
+ " container and library info files!\n" );
+ }
+ if( GbMigrationSuppressErrors && !bLoaded )
+ removeLibrary( aLibName );
+ }
+ }
+ else if( !bStorage )
+ {
+ // Write new index file immediately because otherwise
+ // the library elements will be lost when storing into
+ // the new info format
+ uno::Reference< embed::XStorage > xTmpStorage;
+ implStoreLibraryIndexFile( pImplLib, rLib, xTmpStorage );
+ }
+
+ implImportLibDescriptor( pImplLib, rLib );
+
+ if( nPass == 1 )
+ {
+ pImplLib->mbSharedIndexFile = sal_True;
+ pImplLib->mbReadOnly = sal_True;
+ }
+ }
+
+ // Keep flag for documents to force writing the new index files
+ if( !bStorage )
+ mbOldInfoFormat = sal_False;
+
+ delete pLibArray;
+ }
+ // Only in the first pass it's an error when no index file is found
+ else if( nPass == 0 )
+ {
+ return sal_False;
+ }
+ }
+
+ // #110009: END Scope to force the StorageRefs to be destructed
+ }
+ // #110009
+
+ if( !bStorage && meInitMode == DEFAULT )
+ {
+ try
+ {
+ implScanExtensions();
+ }
+ catch( uno::Exception& )
+ {
+ // TODO: error handling?
+ OSL_ASSERT( "Cannot access extensions!" );
+ }
+ }
+
+ // #110009 Preload?
+ {
+ Sequence< OUString > aNames = maNameContainer.getElementNames();
+ const OUString* pNames = aNames.getConstArray();
+ sal_Int32 nNameCount = aNames.getLength();
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aName = pNames[ i ];
+ SfxLibrary* pImplLib = getImplLib( aName );
+ if( pImplLib->mbPreload )
+ loadLibrary( aName );
+ }
+ }
+
+ // #118803# upgrade installation 7.0 -> 8.0
+ if( meInitMode == DEFAULT )
+ {
+ INetURLObject aUserBasicInetObj( String(maLibraryPath).GetToken(1) );
+ OUString aStandardStr( RTL_CONSTASCII_USTRINGPARAM("Standard") );
+
+ static char strPrevFolderName_1[] = "__basic_80";
+ static char strPrevFolderName_2[] = "__basic_80_2";
+ INetURLObject aPrevUserBasicInetObj_1( aUserBasicInetObj );
+ aPrevUserBasicInetObj_1.removeSegment();
+ INetURLObject aPrevUserBasicInetObj_2 = aPrevUserBasicInetObj_1;
+ aPrevUserBasicInetObj_1.Append( strPrevFolderName_1 );
+ aPrevUserBasicInetObj_2.Append( strPrevFolderName_2 );
+
+ // #i93163
+ bool bCleanUp = false;
+ try
+ {
+ INetURLObject aPrevUserBasicInetObj = aPrevUserBasicInetObj_1;
+ String aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ bool bSecondTime = false;
+ if( mxSFI->isFolder( aPrevFolder ) )
+ {
+ // #110101 Check if Standard folder exists and is complete
+ INetURLObject aUserBasicStandardInetObj( aUserBasicInetObj );
+ aUserBasicStandardInetObj.insertName( aStandardStr, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ INetURLObject aPrevUserBasicStandardInetObj( aPrevUserBasicInetObj );
+ aPrevUserBasicStandardInetObj.insertName( aStandardStr, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ OUString aPrevStandardFolder = aPrevUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ if( mxSFI->isFolder( aPrevStandardFolder ) )
+ {
+ OUString aXlbExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
+ OUString aCheckFileName;
+
+ // Check if script.xlb exists
+ aCheckFileName = OUString( RTL_CONSTASCII_USTRINGPARAM("script") );
+ checkAndCopyFileImpl( aUserBasicStandardInetObj,
+ aPrevUserBasicStandardInetObj,
+ aCheckFileName, aXlbExtension, mxSFI );
+
+ // Check if dialog.xlb exists
+ aCheckFileName = OUString( RTL_CONSTASCII_USTRINGPARAM("dialog") );
+ checkAndCopyFileImpl( aUserBasicStandardInetObj,
+ aPrevUserBasicStandardInetObj,
+ aCheckFileName, aXlbExtension, mxSFI );
+
+ // Check if module1.xba exists
+ OUString aXbaExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xba") ) );
+ aCheckFileName = OUString( RTL_CONSTASCII_USTRINGPARAM("Module1") );
+ checkAndCopyFileImpl( aUserBasicStandardInetObj,
+ aPrevUserBasicStandardInetObj,
+ aCheckFileName, aXbaExtension, mxSFI );
+ }
+ else
+ {
+ String aStandardFolder = aUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ mxSFI->copy( aStandardFolder, aPrevStandardFolder );
+ }
+
+ String aPrevCopyToFolder = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::NO_DECODE );
+ mxSFI->copy( aPrevFolder, aPrevCopyToFolder );
+ }
+ else
+ {
+ bSecondTime = true;
+ aPrevUserBasicInetObj = aPrevUserBasicInetObj_2;
+ aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ if( mxSFI->isFolder( aPrevFolder ) )
+ {
+ SfxLibraryContainer* pPrevCont = createInstanceImpl();
+ Reference< XInterface > xRef = static_cast< XInterface* >( static_cast< OWeakObject* >(pPrevCont) );
+
+ // Rename previous basic folder to make storage URLs correct during initialisation
+ String aFolderUserBasic = aUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ INetURLObject aUserBasicTmpInetObj( aUserBasicInetObj );
+ aUserBasicTmpInetObj.removeSegment();
+ aUserBasicTmpInetObj.Append( "__basic_tmp" );
+ String aFolderTmp = aUserBasicTmpInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ mxSFI->move( aFolderUserBasic, aFolderTmp );
+ try
+ {
+ mxSFI->move( aPrevFolder, aFolderUserBasic );
+ }
+ catch( Exception& )
+ {
+ // Move back user/basic folder
+ try
+ {
+ mxSFI->kill( aFolderUserBasic );
+ }
+ catch( Exception& )
+ {}
+ mxSFI->move( aFolderTmp, aFolderUserBasic );
+ throw;
+ }
+
+ INetURLObject aPrevUserBasicLibInfoInetObj( aUserBasicInetObj );
+ aPrevUserBasicLibInfoInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ aPrevUserBasicLibInfoInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlc") ) );
+ OUString aLibInfoFileName = aPrevUserBasicLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ Sequence<Any> aInitSeq( 1 );
+ aInitSeq.getArray()[0] <<= aLibInfoFileName;
+ GbMigrationSuppressErrors = true;
+ pPrevCont->initialize( aInitSeq );
+ GbMigrationSuppressErrors = false;
+
+ // Rename folders back
+ mxSFI->move( aFolderUserBasic, aPrevFolder );
+ mxSFI->move( aFolderTmp, aFolderUserBasic );
+
+ OUString aUserSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE" );
+ OUString aSharedSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE" );
+ OUString aBundledSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$BUNDLED_EXTENSIONS" );
+ OUString aInstSearchStr = OUString::createFromAscii( "$(INST)" );
+
+ Sequence< OUString > aNames = pPrevCont->getElementNames();
+ const OUString* pNames = aNames.getConstArray();
+ sal_Int32 nNameCount = aNames.getLength();
+
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aLibName = pNames[ i ];
+ if( hasByName( aLibName ) )
+ {
+ if( aLibName == aStandardStr )
+ {
+ SfxLibrary* pImplLib = getImplLib( aStandardStr );
+ INetURLObject aStandardFolderInetObj( pImplLib->maStorageURL );
+ String aStandardFolder = pImplLib->maStorageURL;
+ mxSFI->kill( aStandardFolder );
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ SfxLibrary* pImplLib = pPrevCont->getImplLib( aLibName );
+ if( pImplLib->mbLink )
+ {
+ OUString aStorageURL = pImplLib->maUnexpandedStorageURL;
+ bool bCreateLink = true;
+ if( aStorageURL.indexOf( aUserSearchStr ) != -1 ||
+ aStorageURL.indexOf( aSharedSearchStr ) != -1 ||
+ aStorageURL.indexOf( aBundledSearchStr ) != -1 ||
+ aStorageURL.indexOf( aInstSearchStr ) != -1 )
+ {
+ bCreateLink = false;
+ }
+ if( bCreateLink )
+ createLibraryLink( aLibName, pImplLib->maStorageURL, pImplLib->mbReadOnly );
+ }
+ else
+ {
+ // Move folder if not already done
+ INetURLObject aUserBasicLibFolderInetObj( aUserBasicInetObj );
+ aUserBasicLibFolderInetObj.Append( aLibName );
+ String aLibFolder = aUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ INetURLObject aPrevUserBasicLibFolderInetObj( aPrevUserBasicInetObj );
+ aPrevUserBasicLibFolderInetObj.Append( aLibName );
+ String aPrevLibFolder = aPrevUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if( mxSFI->isFolder( aPrevLibFolder ) && !mxSFI->isFolder( aLibFolder ) )
+ mxSFI->move( aPrevLibFolder, aLibFolder );
+
+ if( aLibName == aStandardStr )
+ maNameContainer.removeByName( aLibName );
+
+ // Create library
+ Reference< XNameContainer > xLib = createLibrary( aLibName );
+ SfxLibrary* pNewLib = static_cast< SfxLibrary* >( xLib.get() );
+ pNewLib->mbLoaded = false;
+ pNewLib->implSetModified( sal_False );
+ checkStorageURL( aLibFolder, pNewLib->maLibInfoFileURL,
+ pNewLib->maStorageURL, pNewLib->maUnexpandedStorageURL );
+
+ uno::Reference< embed::XStorage > xDummyStor;
+ ::xmlscript::LibDescriptor aLibDesc;
+ /*sal_Bool bReadIndexFile =*/ implLoadLibraryIndexFile
+ ( pNewLib, aLibDesc, xDummyStor, pNewLib->maLibInfoFileURL );
+ implImportLibDescriptor( pNewLib, aLibDesc );
+ }
+ }
+ mxSFI->kill( aPrevFolder );
+ }
+ }
+ catch( Exception& )
+ {
+ bCleanUp = true;
+ }
+
+ // #i93163
+ if( bCleanUp )
+ {
+ DBG_ERROR( "Upgrade of Basic installation failed somehow" );
+
+ static char strErrorSavFolderName[] = "__basic_80_err";
+ INetURLObject aPrevUserBasicInetObj_Err( aUserBasicInetObj );
+ aPrevUserBasicInetObj_Err.removeSegment();
+ aPrevUserBasicInetObj_Err.Append( strErrorSavFolderName );
+ String aPrevFolder_Err = aPrevUserBasicInetObj_Err.GetMainURL( INetURLObject::NO_DECODE );
+
+ bool bSaved = false;
+ try
+ {
+ String aPrevFolder_1 = aPrevUserBasicInetObj_1.GetMainURL( INetURLObject::NO_DECODE );
+ if( mxSFI->isFolder( aPrevFolder_1 ) )
+ {
+ mxSFI->move( aPrevFolder_1, aPrevFolder_Err );
+ bSaved = true;
+ }
+ }
+ catch( Exception& )
+ {}
+ try
+ {
+ String aPrevFolder_2 = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::NO_DECODE );
+ if( !bSaved && mxSFI->isFolder( aPrevFolder_2 ) )
+ mxSFI->move( aPrevFolder_2, aPrevFolder_Err );
+ else
+ mxSFI->kill( aPrevFolder_2 );
+ }
+ catch( Exception& )
+ {}
+ }
+ }
+
+ return sal_True;
+}
+
+void SfxLibraryContainer::implScanExtensions( void )
+{
+ ScriptExtensionIterator aScriptIt;
+ rtl::OUString aLibURL;
+
+ bool bPureDialogLib = false;
+ while( (aLibURL = aScriptIt.nextBasicOrDialogLibrary( bPureDialogLib )).getLength() > 0 )
+ {
+ if( bPureDialogLib && maInfoFileName.equalsAscii( "script" ) )
+ continue;
+
+ // Extract lib name
+ sal_Int32 nLen = aLibURL.getLength();
+ sal_Int32 indexLastSlash = aLibURL.lastIndexOf( '/' );
+ sal_Int32 nReduceCopy = 0;
+ if( indexLastSlash == nLen - 1 )
+ {
+ nReduceCopy = 1;
+ indexLastSlash = aLibURL.lastIndexOf( '/', nLen - 1 );
+ }
+
+ OUString aLibName = aLibURL.copy( indexLastSlash + 1, nLen - indexLastSlash - nReduceCopy - 1 );
+
+ // If a library of the same exists the existing library wins
+ if( hasByName( aLibName ) )
+ continue;
+
+ // Add index file to URL
+ OUString aIndexFileURL = aLibURL;
+ if( nReduceCopy == 0 )
+ aIndexFileURL += OUString::createFromAscii( "/" );
+ aIndexFileURL += maInfoFileName;
+ aIndexFileURL += OUString::createFromAscii( ".xlb" );
+
+ // Create link
+ const bool bReadOnly = false;
+ Reference< XNameAccess > xLib =
+ createLibraryLink( aLibName, aIndexFileURL, bReadOnly );
+ }
+}
+
+// Handle maLibInfoFileURL and maStorageURL correctly
+void SfxLibraryContainer::checkStorageURL( const OUString& aSourceURL,
+ OUString& aLibInfoFileURL, OUString& aStorageURL, OUString& aUnexpandedStorageURL )
+{
+ OUString aExpandedSourceURL = expand_url( aSourceURL );
+ if( aExpandedSourceURL != aSourceURL )
+ aUnexpandedStorageURL = aSourceURL;
+
+ INetURLObject aInetObj( aExpandedSourceURL );
+ OUString aExtension = aInetObj.getExtension();
+ if( aExtension.compareToAscii( "xlb" ) == COMPARE_EQUAL )
+ {
+ // URL to xlb file
+ aLibInfoFileURL = aExpandedSourceURL;
+ aInetObj.removeSegment();
+ aStorageURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ else
+ {
+ // URL to library folder
+ aStorageURL = aExpandedSourceURL;
+ aInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
+ aLibInfoFileURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+}
+
+SfxLibrary* SfxLibraryContainer::getImplLib( const String& rLibraryName )
+{
+ Any aLibAny = maNameContainer.getByName( rLibraryName ) ;
+ Reference< XNameAccess > xNameAccess;
+ aLibAny >>= xNameAccess;
+ SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
+ return pImplLib;
+}
+
+
+// Storing with password encryption
+
+// Empty implementation, avoids unneccesary implementation in dlgcont.cxx
+sal_Bool SfxLibraryContainer::implStorePasswordLibrary(
+ SfxLibrary*,
+ const OUString&,
+ const uno::Reference< embed::XStorage >&, const uno::Reference< task::XInteractionHandler >& )
+{
+ return sal_False;
+}
+
+sal_Bool SfxLibraryContainer::implStorePasswordLibrary(
+ SfxLibrary* /*pLib*/,
+ const ::rtl::OUString& /*aName*/,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& /*xStorage*/,
+ const ::rtl::OUString& /*aTargetURL*/,
+ const Reference< XSimpleFileAccess > /*xToUseSFI*/,
+ const uno::Reference< task::XInteractionHandler >& )
+{
+ return sal_False;
+}
+
+sal_Bool SfxLibraryContainer::implLoadPasswordLibrary(
+ SfxLibrary* /*pLib*/,
+ const OUString& /*Name*/,
+ sal_Bool /*bVerifyPasswordOnly*/ )
+throw(WrappedTargetException, RuntimeException)
+{
+ return sal_True;
+}
+
+
+
+#define EXPAND_PROTOCOL "vnd.sun.star.expand"
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+OUString SfxLibraryContainer::createAppLibraryFolder
+ ( SfxLibrary* pLib, const OUString& aName )
+{
+ OUString aLibDirPath = pLib->maStorageURL;
+ if( !aLibDirPath.getLength() )
+ {
+ INetURLObject aInetObj( String(maLibraryPath).GetToken(1) );
+ aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ checkStorageURL( aInetObj.GetMainURL( INetURLObject::NO_DECODE ), pLib->maLibInfoFileURL,
+ pLib->maStorageURL, pLib->maUnexpandedStorageURL );
+ aLibDirPath = pLib->maStorageURL;
+ }
+
+ if( !mxSFI->isFolder( aLibDirPath ) )
+ {
+ try
+ {
+ mxSFI->createFolder( aLibDirPath );
+ }
+ catch( Exception& )
+ {}
+ }
+
+ return aLibDirPath;
+}
+
+// Storing
+void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
+ const OUString& aName, const uno::Reference< embed::XStorage >& xStorage )
+{
+ OUString aDummyLocation;
+ Reference< XSimpleFileAccess > xDummySFA;
+ Reference< XInteractionHandler > xDummyHandler;
+ implStoreLibrary( pLib, aName, xStorage, aDummyLocation, xDummySFA, xDummyHandler );
+}
+
+// New variant for library export
+void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
+ const OUString& aName, const uno::Reference< embed::XStorage >& xStorage,
+ const ::rtl::OUString& aTargetURL, Reference< XSimpleFileAccess > xToUseSFI,
+ const Reference< XInteractionHandler >& xHandler )
+{
+ sal_Bool bLink = pLib->mbLink;
+ sal_Bool bStorage = xStorage.is() && !bLink;
+
+ Sequence< OUString > aElementNames = pLib->getElementNames();
+ sal_Int32 nNameCount = aElementNames.getLength();
+ const OUString* pNames = aElementNames.getConstArray();
+
+ if( bStorage )
+ {
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aElementName = pNames[ i ];
+
+ OUString aStreamName = aElementName;
+ aStreamName += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
+
+ /*Any aElement = pLib->getByName( aElementName );*/
+ if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
+ {
+ #if OSL_DEBUG_LEVEL > 0
+ ::rtl::OStringBuffer aMessage;
+ aMessage.append( "invalid library element '" );
+ aMessage.append( ::rtl::OUStringToOString( aElementName, osl_getThreadTextEncoding() ) );
+ aMessage.append( "'." );
+ OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
+ #endif
+ continue;
+ }
+ try {
+ uno::Reference< io::XStream > xElementStream = xStorage->openStreamElement(
+ aStreamName,
+ embed::ElementModes::READWRITE );
+ //if ( !xElementStream.is() )
+ // throw uno::RuntimeException(); // TODO: method must either return the stream or throw an exception
+
+ String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
+ OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
+
+ uno::Reference< beans::XPropertySet > xProps( xElementStream, uno::UNO_QUERY );
+ OSL_ENSURE( xProps.is(), "The StorageStream must implement XPropertySet interface!\n" );
+ //if ( !xProps.is() ) //TODO
+ // throw uno::RuntimeException();
+
+ if ( xProps.is() )
+ {
+ xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
+
+ // #87671 Allow encryption
+//REMOVE aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Encrypted") );
+ aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
+ xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );
+
+ Reference< XOutputStream > xOutput = xElementStream->getOutputStream();
+ Reference< XNameContainer > xLib( pLib );
+ writeLibraryElement( xLib, aElementName, xOutput );
+ // writeLibraryElement closes the stream
+ // xOutput->closeOutput();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Problem during storing of library!\n" );
+ // TODO: error handling?
+ }
+ }
+
+ pLib->storeResourcesToStorage( xStorage );
+ }
+ else
+ {
+ // Export?
+ bool bExport = aTargetURL.getLength();
+ try
+ {
+ Reference< XSimpleFileAccess > xSFI = mxSFI;
+ if( xToUseSFI.is() )
+ xSFI = xToUseSFI;
+
+ OUString aLibDirPath;
+ if( bExport )
+ {
+ INetURLObject aInetObj( aTargetURL );
+ aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if( !xSFI->isFolder( aLibDirPath ) )
+ xSFI->createFolder( aLibDirPath );
+
+ pLib->storeResourcesToURL( aLibDirPath, xHandler );
+ }
+ else
+ {
+ aLibDirPath = createAppLibraryFolder( pLib, aName );
+ pLib->storeResources();
+ }
+
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aElementName = pNames[ i ];
+
+ INetURLObject aElementInetObj( aLibDirPath );
+ aElementInetObj.insertName( aElementName, sal_False,
+ INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aElementInetObj.setExtension( maLibElementFileExtension );
+ String aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ /*Any aElement = pLib->getByName( aElementName );*/
+ if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
+ {
+ #if OSL_DEBUG_LEVEL > 0
+ ::rtl::OStringBuffer aMessage;
+ aMessage.append( "invalid library element '" );
+ aMessage.append( ::rtl::OUStringToOString( aElementName, osl_getThreadTextEncoding() ) );
+ aMessage.append( "'." );
+ OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
+ #endif
+ continue;
+ }
+
+ // TODO: Check modified
+ try
+ {
+ if( xSFI->exists( aElementPath ) )
+ xSFI->kill( aElementPath );
+ Reference< XOutputStream > xOutput = xSFI->openFileWrite( aElementPath );
+ Reference< XNameContainer > xLib( pLib );
+ writeLibraryElement( xLib, aElementName, xOutput );
+ xOutput->closeOutput();
+ }
+ catch( Exception& )
+ {
+ if( bExport )
+ throw;
+
+ SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aElementPath );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ if( bExport )
+ throw;
+ }
+ }
+}
+
+void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
+ const ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage )
+{
+ OUString aDummyLocation;
+ Reference< XSimpleFileAccess > xDummySFA;
+ implStoreLibraryIndexFile( pLib, rLib, xStorage, aDummyLocation, xDummySFA );
+}
+
+// New variant for library export
+void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
+ const ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage,
+ const ::rtl::OUString& aTargetURL, Reference< XSimpleFileAccess > xToUseSFI )
+{
+ // Create sax writer
+ Reference< XExtendedDocumentHandler > xHandler(
+ mxMSF->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") ) ), UNO_QUERY );
+ if( !xHandler.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create sax-writer component\n" );
+ return;
+ }
+
+ sal_Bool bLink = pLib->mbLink;
+ sal_Bool bStorage = xStorage.is() && !bLink;
+
+ // Write info file
+ uno::Reference< io::XOutputStream > xOut;
+ uno::Reference< io::XStream > xInfoStream;
+ if( bStorage )
+ {
+ OUString aStreamName( maInfoFileName );
+ aStreamName += String( RTL_CONSTASCII_USTRINGPARAM("-lb.xml") );
+
+ try {
+ xInfoStream = xStorage->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
+ OSL_ENSURE( xInfoStream.is(), "No stream!\n" );
+ uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
+ //if ( !xProps.is() )
+ // throw uno::RuntimeException(); // TODO
+
+ if ( xProps.is() )
+ {
+ String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
+ OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
+ xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
+
+ // #87671 Allow encryption
+//REMOVE aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Encrypted") );
+ aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
+ xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );
+
+ xOut = xInfoStream->getOutputStream();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Problem during storing of library index file!\n" );
+ // TODO: error handling?
+ }
+ }
+ else
+ {
+ // Export?
+ bool bExport = aTargetURL.getLength();
+ Reference< XSimpleFileAccess > xSFI = mxSFI;
+ if( xToUseSFI.is() )
+ xSFI = xToUseSFI;
+
+ OUString aLibInfoPath;
+ if( bExport )
+ {
+ INetURLObject aInetObj( aTargetURL );
+ aInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ if( !xSFI->isFolder( aLibDirPath ) )
+ xSFI->createFolder( aLibDirPath );
+
+ aInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
+ aLibInfoPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ else
+ {
+ createAppLibraryFolder( pLib, rLib.aName );
+ aLibInfoPath = pLib->maLibInfoFileURL;
+ }
+
+ try
+ {
+ if( xSFI->exists( aLibInfoPath ) )
+ xSFI->kill( aLibInfoPath );
+ xOut = xSFI->openFileWrite( aLibInfoPath );
+ }
+ catch( Exception& )
+ {
+ if( bExport )
+ throw;
+
+ SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+ }
+ if( !xOut.is() )
+ {
+ OSL_ENSURE( 0, "### couln't open output stream\n" );
+ return;
+ }
+
+ Reference< XActiveDataSource > xSource( xHandler, UNO_QUERY );
+ xSource->setOutputStream( xOut );
+
+ xmlscript::exportLibrary( xHandler, rLib );
+}
+
+
+sal_Bool SfxLibraryContainer::implLoadLibraryIndexFile( SfxLibrary* pLib,
+ ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage, const OUString& aIndexFileName )
+{
+ Reference< XParser > xParser( mxMSF->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY );
+ if( !xParser.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create sax parser component\n" );
+ return sal_False;
+ }
+
+ sal_Bool bLink = sal_False;
+ sal_Bool bStorage = sal_False;
+ if( pLib )
+ {
+ bLink = pLib->mbLink;
+ bStorage = xStorage.is() && !bLink;
+ }
+
+ // Read info file
+ uno::Reference< io::XInputStream > xInput;
+ String aLibInfoPath;
+ if( bStorage )
+ {
+ aLibInfoPath = maInfoFileName;
+ aLibInfoPath += String( RTL_CONSTASCII_USTRINGPARAM("-lb.xml") );
+
+ try {
+ uno::Reference< io::XStream > xInfoStream =
+ xStorage->openStreamElement( aLibInfoPath, embed::ElementModes::READ );
+ xInput = xInfoStream->getInputStream();
+ }
+ catch( uno::Exception& )
+ {}
+ }
+ else
+ {
+ // Create Input stream
+ //String aLibInfoPath; // attention: THIS PROBLEM MUST BE REVIEWED BY SCRIPTING OWNER!!!
+
+ if( pLib )
+ {
+ createAppLibraryFolder( pLib, rLib.aName );
+ aLibInfoPath = pLib->maLibInfoFileURL;
+ }
+ else
+ aLibInfoPath = aIndexFileName;
+
+ try
+ {
+ xInput = mxSFI->openFileRead( aLibInfoPath );
+ }
+ catch( Exception& )
+ {
+ xInput.clear();
+ if( !GbMigrationSuppressErrors )
+ {
+ SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+ }
+ }
+ if( !xInput.is() )
+ {
+ // OSL_ENSURE( 0, "### couln't open input stream\n" );
+ return sal_False;
+ }
+
+ InputSource source;
+ source.aInputStream = xInput;
+ source.sSystemId = aLibInfoPath;
+
+ // start parsing
+ try {
+ xParser->setDocumentHandler( ::xmlscript::importLibrary( rLib ) );
+ xParser->parseStream( source );
+ }
+ catch( Exception& )
+ {
+ // throw WrappedTargetException( OUString::createFromAscii( "parsing error!\n" ),
+ // Reference< XInterface >(),
+ // makeAny( e ) );
+ OSL_ENSURE( 0, "Parsing error\n" );
+ SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ return sal_False;
+ }
+
+ if( !pLib )
+ {
+ Reference< XNameContainer > xLib = createLibrary( rLib.aName );
+ pLib = static_cast< SfxLibrary* >( xLib.get() );
+ pLib->mbLoaded = sal_False;
+ rLib.aStorageURL = aIndexFileName;
+ checkStorageURL( rLib.aStorageURL, pLib->maLibInfoFileURL, pLib->maStorageURL,
+ pLib->maUnexpandedStorageURL );
+
+ implImportLibDescriptor( pLib, rLib );
+ }
+
+ return sal_True;
+}
+
+void SfxLibraryContainer::implImportLibDescriptor
+ ( SfxLibrary* pLib, ::xmlscript::LibDescriptor& rLib )
+{
+ if( !pLib->mbInitialised )
+ {
+ sal_Int32 nElementCount = rLib.aElementNames.getLength();
+ const OUString* pElementNames = rLib.aElementNames.getConstArray();
+ Any aDummyElement = createEmptyLibraryElement();
+ for( sal_Int32 i = 0 ; i < nElementCount ; i++ )
+ {
+ pLib->maNameContainer.insertByName( pElementNames[i], aDummyElement );
+ }
+ pLib->mbPasswordProtected = rLib.bPasswordProtected;
+ pLib->mbReadOnly = rLib.bReadOnly;
+ pLib->mbPreload = rLib.bPreload;
+ pLib->implSetModified( sal_False );
+
+ pLib->mbInitialised = sal_True;
+ }
+}
+
+
+// Methods of new XLibraryStorage interface?
+void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XStorage >& i_rStorage, sal_Bool bComplete )
+{
+ const Sequence< OUString > aNames = maNameContainer.getElementNames();
+ sal_Int32 nNameCount = aNames.getLength();
+ const OUString* pName = aNames.getConstArray();
+ const OUString* pNamesEnd = aNames.getConstArray() + nNameCount;
+
+ // Don't count libs from shared index file
+ sal_Int32 nLibsToSave = nNameCount;
+ for( ; pName != pNamesEnd; ++pName )
+ {
+ SfxLibrary* pImplLib = getImplLib( *pName );
+ if( pImplLib->mbSharedIndexFile || pImplLib->mbExtension )
+ nLibsToSave--;
+ }
+ if( !nLibsToSave )
+ return;
+
+ ::xmlscript::LibDescriptorArray* pLibArray = new ::xmlscript::LibDescriptorArray( nLibsToSave );
+
+ // Write to storage?
+ sal_Bool bStorage = i_rStorage.is();
+ uno::Reference< embed::XStorage > xSourceLibrariesStor;
+ uno::Reference< embed::XStorage > xTargetLibrariesStor;
+ ::rtl::OUString sTempTargetStorName;
+ const bool bInplaceStorage = bStorage && ( i_rStorage == mxStorage );
+ if ( bStorage )
+ {
+ // Don't write if only empty standard lib exists
+ if ( ( nNameCount == 1 ) && ( aNames[0].equalsAscii( "Standard" ) ) )
+ {
+ Any aLibAny = maNameContainer.getByName( aNames[0] );
+ Reference< XNameAccess > xNameAccess;
+ aLibAny >>= xNameAccess;
+ if ( !xNameAccess->hasElements() )
+ return;
+ }
+
+ // create the empty target storage
+ try
+ {
+ ::rtl::OUString sTargetLibrariesStoreName;
+ if ( bInplaceStorage )
+ {
+ // create a temporary target storage
+ const ::rtl::OUStringBuffer aTempTargetNameBase = maLibrariesDir + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_temp_" ) );
+ sal_Int32 index = 0;
+ do
+ {
+ ::rtl::OUStringBuffer aTempTargetName( aTempTargetNameBase );
+ aTempTargetName.append( index++ );
+
+ sTargetLibrariesStoreName = aTempTargetName.makeStringAndClear();
+ if ( !i_rStorage->hasByName( sTargetLibrariesStoreName ) )
+ break;
+ }
+ while ( true );
+ sTempTargetStorName = sTargetLibrariesStoreName;
+ }
+ else
+ {
+ sTargetLibrariesStoreName = maLibrariesDir;
+ if ( i_rStorage->hasByName( sTargetLibrariesStoreName ) )
+ i_rStorage->removeElement( sTargetLibrariesStoreName );
+ }
+
+ xTargetLibrariesStor.set( i_rStorage->openStorageElement( sTargetLibrariesStoreName, embed::ElementModes::READWRITE ), UNO_QUERY_THROW );
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ return;
+ }
+
+ // open the source storage which might be used to copy yet-unmodified libraries
+ try
+ {
+ if ( mxStorage->hasByName( maLibrariesDir ) )
+ xSourceLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, bInplaceStorage ? embed::ElementModes::READWRITE : embed::ElementModes::READ );
+ else if ( bInplaceStorage )
+ xSourceLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READWRITE );
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ return;
+ }
+ }
+
+ int iArray = 0;
+ pName = aNames.getConstArray();
+ ::xmlscript::LibDescriptor aLibDescriptorForExtensionLibs;
+ for( ; pName != pNamesEnd; ++pName )
+ {
+ SfxLibrary* pImplLib = getImplLib( *pName );
+ if( pImplLib->mbSharedIndexFile )
+ continue;
+ const bool bExtensionLib = pImplLib->mbExtension;
+ ::xmlscript::LibDescriptor& rLib = bExtensionLib ?
+ aLibDescriptorForExtensionLibs : pLibArray->mpLibs[iArray];
+ if( !bExtensionLib )
+ iArray++;
+ rLib.aName = *pName;
+
+ rLib.bLink = pImplLib->mbLink;
+ if( !bStorage || pImplLib->mbLink )
+ {
+ rLib.aStorageURL = ( pImplLib->maUnexpandedStorageURL.getLength() ) ?
+ pImplLib->maUnexpandedStorageURL : pImplLib->maLibInfoFileURL;
+ }
+ rLib.bReadOnly = pImplLib->mbReadOnly;
+ rLib.bPreload = pImplLib->mbPreload;
+ rLib.bPasswordProtected = pImplLib->mbPasswordProtected;
+ rLib.aElementNames = pImplLib->getElementNames();
+
+ if( pImplLib->implIsModified() || bComplete )
+ {
+ // Can we simply copy the storage?
+ if( !mbOldInfoFormat && !pImplLib->implIsModified() && !mbOasis2OOoFormat && xSourceLibrariesStor.is() )
+ {
+ try
+ {
+ xSourceLibrariesStor->copyElementTo( rLib.aName, xTargetLibrariesStor, rLib.aName );
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ // TODO: error handling?
+ }
+ }
+ else
+ {
+ uno::Reference< embed::XStorage > xLibraryStor;
+ if( bStorage )
+ {
+ try
+ {
+ xLibraryStor = xTargetLibrariesStor->openStorageElement(
+ rLib.aName,
+ embed::ElementModes::READWRITE );
+ }
+ catch( uno::Exception& )
+ {
+ #if OSL_DEBUG_LEVEL > 0
+ Any aError( ::cppu::getCaughtException() );
+ ::rtl::OStringBuffer aMessage;
+ aMessage.append( "couln't create sub storage for library '" );
+ aMessage.append( ::rtl::OUStringToOString( rLib.aName, osl_getThreadTextEncoding() ) );
+ aMessage.append( "'.\n\nException:" );
+ aMessage.append( ::rtl::OUStringToOString( ::comphelper::anyToString( aError ), osl_getThreadTextEncoding() ) );
+ OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
+ #endif
+ return;
+ }
+ }
+
+ // Maybe lib is not loaded?!
+ if( bComplete )
+ loadLibrary( rLib.aName );
+
+ if( pImplLib->mbPasswordProtected )
+ implStorePasswordLibrary( pImplLib, rLib.aName, xLibraryStor, uno::Reference< task::XInteractionHandler >() );
+ // TODO: Check return value
+ else
+ implStoreLibrary( pImplLib, rLib.aName, xLibraryStor );
+
+ implStoreLibraryIndexFile( pImplLib, rLib, xLibraryStor );
+ if( bStorage )
+ {
+ try
+ {
+ uno::Reference< embed::XTransactedObject > xTransact( xLibraryStor, uno::UNO_QUERY_THROW );
+ xTransact->commit();
+ }
+ catch( uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ // TODO: error handling
+ }
+ }
+ }
+
+ maModifiable.setModified( sal_True );
+ pImplLib->implSetModified( sal_False );
+ }
+
+ // For container info ReadOnly refers to mbReadOnlyLink
+ rLib.bReadOnly = pImplLib->mbReadOnlyLink;
+ }
+
+ // if we did an in-place save into a storage (i.e. a save into the storage we were already based on),
+ // then we need to clean up the temporary storage we used for this
+ if ( bInplaceStorage && sTempTargetStorName.getLength() )
+ {
+ OSL_ENSURE( xSourceLibrariesStor.is(), "SfxLibrariesContainer::storeLibraries_impl: unexpected: we should have a source storage here!" );
+ try
+ {
+ // for this, we first remove everything from the source storage, then copy the complete content
+ // from the temporary target storage. From then on, what used to be the "source storage" becomes
+ // the "targt storage" for all subsequent operations.
+
+ // (We cannot simply remove the storage, denoted by maLibrariesDir, from i_rStorage - there might be
+ // open references to it.)
+
+ if ( xSourceLibrariesStor.is() )
+ {
+ // remove
+ const Sequence< ::rtl::OUString > aRemoveNames( xSourceLibrariesStor->getElementNames() );
+ for ( const ::rtl::OUString* pRemoveName = aRemoveNames.getConstArray();
+ pRemoveName != aRemoveNames.getConstArray() + aRemoveNames.getLength();
+ ++pRemoveName
+ )
+ {
+ xSourceLibrariesStor->removeElement( *pRemoveName );
+ }
+
+ // copy
+ const Sequence< ::rtl::OUString > aCopyNames( xTargetLibrariesStor->getElementNames() );
+ for ( const ::rtl::OUString* pCopyName = aCopyNames.getConstArray();
+ pCopyName != aCopyNames.getConstArray() + aCopyNames.getLength();
+ ++pCopyName
+ )
+ {
+ xTargetLibrariesStor->copyElementTo( *pCopyName, xSourceLibrariesStor, *pCopyName );
+ }
+ }
+
+ // close and remove temp target
+ xTargetLibrariesStor->dispose();
+ i_rStorage->removeElement( sTempTargetStorName );
+ xTargetLibrariesStor.clear();
+ sTempTargetStorName = ::rtl::OUString();
+
+ // adjust target
+ xTargetLibrariesStor = xSourceLibrariesStor;
+ xSourceLibrariesStor.clear();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ if( !mbOldInfoFormat && !maModifiable.isModified() )
+ return;
+ maModifiable.setModified( sal_False );
+ mbOldInfoFormat = sal_False;
+
+ // Write library container info
+ // Create sax writer
+ Reference< XExtendedDocumentHandler > xHandler(
+ mxMSF->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") ) ), UNO_QUERY );
+ if( !xHandler.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create sax-writer component\n" );
+ return;
+ }
+
+ // Write info file
+ uno::Reference< io::XOutputStream > xOut;
+ uno::Reference< io::XStream > xInfoStream;
+ if( bStorage )
+ {
+ OUString aStreamName( maInfoFileName );
+ aStreamName += String( RTL_CONSTASCII_USTRINGPARAM("-lc.xml") );
+
+ try {
+ xInfoStream = xTargetLibrariesStor->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
+ uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
+ OSL_ENSURE ( xProps.is(), "The stream must implement XPropertySet!\n" );
+ if ( !xProps.is() )
+ throw uno::RuntimeException();
+
+ String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
+ OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
+ xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
+
+ // #87671 Allow encryption
+ aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("UseCommonStoragePasswordEncryption") );
+ xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );
+
+ xOut = xInfoStream->getOutputStream();
+ }
+ catch( uno::Exception& )
+ {
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+ }
+ else
+ {
+ // Create Output stream
+ INetURLObject aLibInfoInetObj( String(maLibraryPath).GetToken(1) );
+ aLibInfoInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aLibInfoInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlc") ) );
+ String aLibInfoPath( aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ try
+ {
+ if( mxSFI->exists( aLibInfoPath ) )
+ mxSFI->kill( aLibInfoPath );
+ xOut = mxSFI->openFileWrite( aLibInfoPath );
+ }
+ catch( Exception& )
+ {
+ xOut.clear();
+ SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+
+ }
+ if( !xOut.is() )
+ {
+ OSL_ENSURE( 0, "### couln't open output stream\n" );
+ return;
+ }
+
+ Reference< XActiveDataSource > xSource( xHandler, UNO_QUERY );
+ xSource->setOutputStream( xOut );
+
+ try
+ {
+ xmlscript::exportLibraryContainer( xHandler, pLibArray );
+ if ( bStorage )
+ {
+ uno::Reference< embed::XTransactedObject > xTransact( xTargetLibrariesStor, uno::UNO_QUERY );
+ OSL_ENSURE( xTransact.is(), "The storage must implement XTransactedObject!\n" );
+ if ( !xTransact.is() )
+ throw uno::RuntimeException();
+
+ xTransact->commit();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Problem during storing of libraries!\n" );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+
+ delete pLibArray;
+}
+
+
+// Methods XElementAccess
+Type SAL_CALL SfxLibraryContainer::getElementType()
+ throw(RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ return maNameContainer.getElementType();
+}
+
+sal_Bool SfxLibraryContainer::hasElements()
+ throw(RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ sal_Bool bRet = maNameContainer.hasElements();
+ return bRet;
+}
+
+// Methods XNameAccess
+Any SfxLibraryContainer::getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ Any aRetAny = maNameContainer.getByName( aName ) ;
+ return aRetAny;
+}
+
+Sequence< OUString > SfxLibraryContainer::getElementNames()
+ throw(RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ return maNameContainer.getElementNames();
+}
+
+sal_Bool SfxLibraryContainer::hasByName( const OUString& aName )
+ throw(RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ return maNameContainer.hasByName( aName ) ;
+}
+
+// Methods XLibraryContainer
+Reference< XNameContainer > SAL_CALL SfxLibraryContainer::createLibrary( const OUString& Name )
+ throw(IllegalArgumentException, ElementExistException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ SfxLibrary* pNewLib = implCreateLibrary( Name );
+ pNewLib->maLibElementFileExtension = maLibElementFileExtension;
+
+ createVariableURL( pNewLib->maUnexpandedStorageURL, Name, maInfoFileName, true );
+
+ Reference< XNameAccess > xNameAccess = static_cast< XNameAccess* >( pNewLib );
+ Any aElement;
+ aElement <<= xNameAccess;
+ maNameContainer.insertByName( Name, aElement );
+ maModifiable.setModified( sal_True );
+ Reference< XNameContainer > xRet( xNameAccess, UNO_QUERY );
+ return xRet;
+}
+
+Reference< XNameAccess > SAL_CALL SfxLibraryContainer::createLibraryLink
+ ( const OUString& Name, const OUString& StorageURL, sal_Bool ReadOnly )
+ throw(IllegalArgumentException, ElementExistException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ // TODO: Check other reasons to force ReadOnly status
+ //if( !ReadOnly )
+ //{
+ //}
+
+ OUString aLibInfoFileURL;
+ OUString aLibDirURL;
+ OUString aUnexpandedStorageURL;
+ checkStorageURL( StorageURL, aLibInfoFileURL, aLibDirURL, aUnexpandedStorageURL );
+
+
+ SfxLibrary* pNewLib = implCreateLibraryLink( Name, aLibInfoFileURL, aLibDirURL, ReadOnly );
+ pNewLib->maLibElementFileExtension = maLibElementFileExtension;
+ pNewLib->maUnexpandedStorageURL = aUnexpandedStorageURL;
+ pNewLib->maOrignialStorageURL = StorageURL;
+
+ OUString aInitFileName;
+ uno::Reference< embed::XStorage > xDummyStor;
+ ::xmlscript::LibDescriptor aLibDesc;
+ /*sal_Bool bReadIndexFile = */implLoadLibraryIndexFile( pNewLib, aLibDesc, xDummyStor, aInitFileName );
+ implImportLibDescriptor( pNewLib, aLibDesc );
+
+ Reference< XNameAccess > xRet = static_cast< XNameAccess* >( pNewLib );
+ Any aElement;
+ aElement <<= xRet;
+ maNameContainer.insertByName( Name, aElement );
+ maModifiable.setModified( sal_True );
+
+ OUString aUserSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE" );
+ OUString aSharedSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE" );
+ OUString aBundledSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$BUNDLED_EXTENSIONS" );
+ if( StorageURL.indexOf( aUserSearchStr ) != -1 )
+ {
+ pNewLib->mbExtension = sal_True;
+ }
+ else if( StorageURL.indexOf( aSharedSearchStr ) != -1 || StorageURL.indexOf( aBundledSearchStr ) != -1 )
+ {
+ pNewLib->mbExtension = sal_True;
+ pNewLib->mbReadOnly = sal_True;
+ }
+
+ return xRet;
+}
+
+void SAL_CALL SfxLibraryContainer::removeLibrary( const OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ // Get and hold library before removing
+ Any aLibAny = maNameContainer.getByName( Name ) ;
+ Reference< XNameAccess > xNameAccess;
+ aLibAny >>= xNameAccess;
+ SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
+ if( pImplLib->mbReadOnly && !pImplLib->mbLink )
+ throw IllegalArgumentException();
+
+ // Remove from container
+ maNameContainer.removeByName( Name );
+ maModifiable.setModified( sal_True );
+
+ // Delete library files, but not for linked libraries
+ if( !pImplLib->mbLink )
+ {
+ if( mxStorage.is() )
+ return;
+ if( xNameAccess->hasElements() )
+ {
+ Sequence< OUString > aNames = pImplLib->getElementNames();
+ sal_Int32 nNameCount = aNames.getLength();
+ const OUString* pNames = aNames.getConstArray();
+ for( sal_Int32 i = 0 ; i < nNameCount ; ++i, ++pNames )
+ {
+ pImplLib->removeElementWithoutChecks( *pNames, SfxLibrary::LibraryContainerAccess() );
+ }
+ }
+
+ // Delete index file
+ createAppLibraryFolder( pImplLib, Name );
+ String aLibInfoPath = pImplLib->maLibInfoFileURL;
+ try
+ {
+ if( mxSFI->exists( aLibInfoPath ) )
+ mxSFI->kill( aLibInfoPath );
+ }
+ catch( Exception& ) {}
+
+ // Delete folder if empty
+ INetURLObject aInetObj( String(maLibraryPath).GetToken(1) );
+ aInetObj.insertName( Name, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ try
+ {
+ if( mxSFI->isFolder( aLibDirPath ) )
+ {
+ Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
+ sal_Int32 nCount = aContentSeq.getLength();
+ if( !nCount )
+ mxSFI->kill( aLibDirPath );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ }
+}
+
+sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLoaded( const OUString& Name )
+ throw(NoSuchElementException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ SfxLibrary* pImplLib = getImplLib( Name );
+ sal_Bool bRet = pImplLib->mbLoaded;
+ return bRet;
+}
+
+
+void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ Any aLibAny = maNameContainer.getByName( Name ) ;
+ Reference< XNameAccess > xNameAccess;
+ aLibAny >>= xNameAccess;
+ SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
+
+ sal_Bool bLoaded = pImplLib->mbLoaded;
+ pImplLib->mbLoaded = sal_True;
+ if( !bLoaded && xNameAccess->hasElements() )
+ {
+ if( pImplLib->mbPasswordProtected )
+ {
+ implLoadPasswordLibrary( pImplLib, Name );
+ return;
+ }
+
+ sal_Bool bLink = pImplLib->mbLink;
+ sal_Bool bStorage = mxStorage.is() && !bLink;
+
+ uno::Reference< embed::XStorage > xLibrariesStor;
+ uno::Reference< embed::XStorage > xLibraryStor;
+ if( bStorage )
+ {
+ try {
+ xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
+ OSL_ENSURE( xLibrariesStor.is(), "The method must either throw exception or return a storage!\n" );
+ if ( !xLibrariesStor.is() )
+ throw uno::RuntimeException();
+
+ xLibraryStor = xLibrariesStor->openStorageElement( Name, embed::ElementModes::READ );
+ OSL_ENSURE( xLibraryStor.is(), "The method must either throw exception or return a storage!\n" );
+ if ( !xLibrariesStor.is() )
+ throw uno::RuntimeException();
+ }
+ catch( uno::Exception& )
+ {
+ #if OSL_DEBUG_LEVEL > 0
+ Any aError( ::cppu::getCaughtException() );
+ ::rtl::OStringBuffer aMessage;
+ aMessage.append( "couln't open sub storage for library '" );
+ aMessage.append( ::rtl::OUStringToOString( Name, osl_getThreadTextEncoding() ) );
+ aMessage.append( "'.\n\nException:" );
+ aMessage.append( ::rtl::OUStringToOString( ::comphelper::anyToString( aError ), osl_getThreadTextEncoding() ) );
+ OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
+ #endif
+ return;
+ }
+ }
+
+ Sequence< OUString > aNames = pImplLib->getElementNames();
+ sal_Int32 nNameCount = aNames.getLength();
+ const OUString* pNames = aNames.getConstArray();
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aElementName = pNames[ i ];
+
+ OUString aFile;
+ uno::Reference< io::XInputStream > xInStream;
+
+ if( bStorage )
+ {
+ uno::Reference< io::XStream > xElementStream;
+
+ aFile = aElementName;
+ aFile += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
+
+ try {
+ xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
+ } catch( uno::Exception& )
+ {}
+
+ if( !xElementStream.is() )
+ {
+ // Check for EA2 document version with wrong extensions
+ aFile = aElementName;
+ aFile += String( RTL_CONSTASCII_USTRINGPARAM(".") );
+ aFile += maLibElementFileExtension;
+ try {
+ xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
+ } catch( uno::Exception& )
+ {}
+ }
+
+ if ( xElementStream.is() )
+ xInStream = xElementStream->getInputStream();
+
+ if ( !xInStream.is() )
+ {
+ #if OSL_DEBUG_LEVEL > 0
+ ::rtl::OStringBuffer aMessage;
+ aMessage.append( "couln't open library element stream - attempted to open library '" );
+ aMessage.append( ::rtl::OUStringToOString( Name, osl_getThreadTextEncoding() ) );
+ aMessage.append( "'." );
+ OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
+ #endif
+ return;
+ }
+ }
+ else
+ {
+ String aLibDirPath = pImplLib->maStorageURL;
+ INetURLObject aElementInetObj( aLibDirPath );
+ aElementInetObj.insertName( aElementName, sal_False,
+ INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aElementInetObj.setExtension( maLibElementFileExtension );
+ aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+
+ Reference< XNameContainer > xLib( pImplLib );
+ Any aAny = importLibraryElement( xLib, aElementName,
+ aFile, xInStream );
+ if( pImplLib->hasByName( aElementName ) )
+ {
+ if( aAny.hasValue() )
+ pImplLib->maNameContainer.replaceByName( aElementName, aAny );
+ }
+ else
+ {
+ pImplLib->maNameContainer.insertByName( aElementName, aAny );
+ }
+ }
+
+ pImplLib->implSetModified( sal_False );
+ }
+}
+
+// Methods XLibraryContainer2
+sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLink( const OUString& Name )
+ throw (NoSuchElementException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ SfxLibrary* pImplLib = getImplLib( Name );
+ sal_Bool bRet = pImplLib->mbLink;
+ return bRet;
+}
+
+OUString SAL_CALL SfxLibraryContainer::getLibraryLinkURL( const OUString& Name )
+ throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ SfxLibrary* pImplLib = getImplLib( Name );
+ sal_Bool bLink = pImplLib->mbLink;
+ if( !bLink )
+ throw IllegalArgumentException();
+ OUString aRetStr = pImplLib->maLibInfoFileURL;
+ return aRetStr;
+}
+
+sal_Bool SAL_CALL SfxLibraryContainer::isLibraryReadOnly( const OUString& Name )
+ throw (NoSuchElementException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ SfxLibrary* pImplLib = getImplLib( Name );
+ sal_Bool bRet = pImplLib->mbReadOnly || (pImplLib->mbLink && pImplLib->mbReadOnlyLink);
+ return bRet;
+}
+
+void SAL_CALL SfxLibraryContainer::setLibraryReadOnly( const OUString& Name, sal_Bool bReadOnly )
+ throw (NoSuchElementException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ SfxLibrary* pImplLib = getImplLib( Name );
+ if( pImplLib->mbLink )
+ {
+ if( pImplLib->mbReadOnlyLink != bReadOnly )
+ {
+ pImplLib->mbReadOnlyLink = bReadOnly;
+ pImplLib->implSetModified( sal_True );
+ maModifiable.setModified( sal_True );
+ }
+ }
+ else
+ {
+ if( pImplLib->mbReadOnly != bReadOnly )
+ {
+ pImplLib->mbReadOnly = bReadOnly;
+ pImplLib->implSetModified( sal_True );
+ }
+ }
+}
+
+void SAL_CALL SfxLibraryContainer::renameLibrary( const OUString& Name, const OUString& NewName )
+ throw (NoSuchElementException, ElementExistException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ if( maNameContainer.hasByName( NewName ) )
+ throw ElementExistException();
+
+ // Get and hold library before removing
+ Any aLibAny = maNameContainer.getByName( Name ) ;
+
+ // #i24094 Maybe lib is not loaded!
+ Reference< XNameAccess > xNameAccess;
+ aLibAny >>= xNameAccess;
+ SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
+ if( pImplLib->mbPasswordProtected && !pImplLib->mbPasswordVerified )
+ return; // Lib with unverified password cannot be renamed
+ loadLibrary( Name );
+
+ // Remove from container
+ maNameContainer.removeByName( Name );
+ maModifiable.setModified( sal_True );
+
+ // Rename library folder, but not for linked libraries
+ bool bMovedSuccessful = true;
+
+ // Rename files
+ sal_Bool bStorage = mxStorage.is();
+ if( !bStorage && !pImplLib->mbLink )
+ {
+ bMovedSuccessful = false;
+
+ OUString aLibDirPath = pImplLib->maStorageURL;
+
+ INetURLObject aDestInetObj( String(maLibraryPath).GetToken(1) );
+ aDestInetObj.insertName( NewName, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ OUString aDestDirPath = aDestInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ // Store new URL
+ OUString aLibInfoFileURL = pImplLib->maLibInfoFileURL;
+ checkStorageURL( aDestDirPath, pImplLib->maLibInfoFileURL, pImplLib->maStorageURL,
+ pImplLib->maUnexpandedStorageURL );
+
+ try
+ {
+ if( mxSFI->isFolder( aLibDirPath ) )
+ {
+ if( !mxSFI->isFolder( aDestDirPath ) )
+ mxSFI->createFolder( aDestDirPath );
+
+ // Move index file
+ try
+ {
+ if( mxSFI->exists( pImplLib->maLibInfoFileURL ) )
+ mxSFI->kill( pImplLib->maLibInfoFileURL );
+ mxSFI->move( aLibInfoFileURL, pImplLib->maLibInfoFileURL );
+ }
+ catch( Exception& )
+ {
+ }
+
+ Sequence< OUString > aElementNames = xNameAccess->getElementNames();
+ sal_Int32 nNameCount = aElementNames.getLength();
+ const OUString* pNames = aElementNames.getConstArray();
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aElementName = pNames[ i ];
+
+ INetURLObject aElementInetObj( aLibDirPath );
+ aElementInetObj.insertName( aElementName, sal_False,
+ INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aElementInetObj.setExtension( maLibElementFileExtension );
+ String aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ INetURLObject aElementDestInetObj( aDestDirPath );
+ aElementDestInetObj.insertName( aElementName, sal_False,
+ INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aElementDestInetObj.setExtension( maLibElementFileExtension );
+ String aDestElementPath( aElementDestInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ try
+ {
+ if( mxSFI->exists( aDestElementPath ) )
+ mxSFI->kill( aDestElementPath );
+ mxSFI->move( aElementPath, aDestElementPath );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ pImplLib->storeResourcesAsURL( aDestDirPath, NewName );
+
+ // Delete folder if empty
+ Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
+ sal_Int32 nCount = aContentSeq.getLength();
+ if( !nCount )
+ {
+ mxSFI->kill( aLibDirPath );
+ }
+
+ bMovedSuccessful = true;
+ pImplLib->implSetModified( sal_True );
+ }
+ }
+ catch( Exception& )
+ {
+ // Restore old library
+ maNameContainer.insertByName( Name, aLibAny ) ;
+ }
+ }
+
+ if( bStorage && !pImplLib->mbLink )
+ pImplLib->implSetModified( sal_True );
+
+ if( bMovedSuccessful )
+ maNameContainer.insertByName( NewName, aLibAny ) ;
+
+}
+
+
+// Methods XInitialization
+void SAL_CALL SfxLibraryContainer::initialize( const Sequence< Any >& _rArguments )
+ throw (Exception, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ sal_Int32 nArgCount = _rArguments.getLength();
+ if ( nArgCount == 1 )
+ {
+ OUString sInitialDocumentURL;
+ Reference< XStorageBasedDocument > xDocument;
+ if ( _rArguments[0] >>= sInitialDocumentURL )
+ {
+ initializeFromDocumentURL( sInitialDocumentURL );
+ return;
+ }
+
+ if ( _rArguments[0] >>= xDocument )
+ {
+ initializeFromDocument( xDocument );
+ return;
+ }
+ }
+
+ throw IllegalArgumentException();
+}
+
+void SAL_CALL SfxLibraryContainer::initializeFromDocumentURL( const ::rtl::OUString& _rInitialDocumentURL )
+{
+ init( _rInitialDocumentURL, NULL );
+}
+
+void SAL_CALL SfxLibraryContainer::initializeFromDocument( const Reference< XStorageBasedDocument >& _rxDocument )
+{
+ // check whether this is a valid OfficeDocument, and obtain the document's root storage
+ Reference< XStorage > xDocStorage;
+ try
+ {
+ Reference< XServiceInfo > xSI( _rxDocument, UNO_QUERY_THROW );
+ if ( xSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.OfficeDocument" ) ) ) )
+ xDocStorage.set( _rxDocument->getDocumentStorage(), UNO_QUERY_THROW );
+
+ Reference< XModel > xDocument( _rxDocument, UNO_QUERY_THROW );
+ Reference< XComponent > xDocComponent( _rxDocument, UNO_QUERY_THROW );
+
+ mxOwnerDocument = xDocument;
+ startComponentListening( xDocComponent );
+ }
+ catch( const Exception& ) { }
+
+ if ( !xDocStorage.is() )
+ throw IllegalArgumentException();
+
+ init( OUString(), xDocStorage );
+}
+
+// OEventListenerAdapter
+void SfxLibraryContainer::_disposing( const EventObject& _rSource )
+{
+#if OSL_DEBUG_LEVEL > 0
+ Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
+ OSL_ENSURE( ( xDocument == _rSource.Source ) && xDocument.is(), "SfxLibraryContainer::_disposing: where does this come from?" );
+#else
+ (void)_rSource;
+#endif
+ dispose();
+}
+
+// OComponentHelper
+void SAL_CALL SfxLibraryContainer::disposing()
+{
+ stopAllComponentListening();
+ mxOwnerDocument = WeakReference< XModel >();
+}
+
+// Methods XLibraryContainerPassword
+sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordProtected( const OUString& )
+ throw (NoSuchElementException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ return sal_False;
+}
+
+sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordVerified( const OUString& )
+ throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ throw IllegalArgumentException();
+}
+
+sal_Bool SAL_CALL SfxLibraryContainer::verifyLibraryPassword
+ ( const OUString&, const OUString& )
+ throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ throw IllegalArgumentException();
+}
+
+void SAL_CALL SfxLibraryContainer::changeLibraryPassword(
+ const OUString&, const OUString&, const OUString& )
+ throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ throw IllegalArgumentException();
+}
+
+// Methods XContainer
+void SAL_CALL SfxLibraryContainer::addContainerListener( const Reference< XContainerListener >& xListener )
+ throw (RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
+ maNameContainer.addContainerListener( xListener );
+}
+
+void SAL_CALL SfxLibraryContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
+ throw (RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ maNameContainer.removeContainerListener( xListener );
+}
+
+// Methods XLibraryContainerExport
+void SAL_CALL SfxLibraryContainer::exportLibrary( const OUString& Name, const OUString& URL,
+ const Reference< XInteractionHandler >& Handler )
+ throw ( uno::Exception, NoSuchElementException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ SfxLibrary* pImplLib = getImplLib( Name );
+
+ Reference< XSimpleFileAccess > xToUseSFI;
+ if( Handler.is() )
+ {
+ xToUseSFI = Reference< XSimpleFileAccess >( mxMSF->createInstance
+ ( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
+ if( xToUseSFI.is() )
+ xToUseSFI->setInteractionHandler( Handler );
+ }
+
+ // Maybe lib is not loaded?!
+ loadLibrary( Name );
+
+ uno::Reference< ::com::sun::star::embed::XStorage > xDummyStor;
+ if( pImplLib->mbPasswordProtected )
+ implStorePasswordLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
+ else
+ implStoreLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
+
+ ::xmlscript::LibDescriptor aLibDesc;
+ aLibDesc.aName = Name;
+ aLibDesc.bLink = false; // Link status gets lost?
+ aLibDesc.bReadOnly = pImplLib->mbReadOnly;
+ aLibDesc.bPreload = false; // Preload status gets lost?
+ aLibDesc.bPasswordProtected = pImplLib->mbPasswordProtected;
+ aLibDesc.aElementNames = pImplLib->getElementNames();
+
+ implStoreLibraryIndexFile( pImplLib, aLibDesc, xDummyStor, URL, xToUseSFI );
+}
+
+OUString SfxLibraryContainer::expand_url( const OUString& url )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (0 == url.compareToAscii( RTL_CONSTASCII_STRINGPARAM(EXPAND_PROTOCOL ":") ))
+ {
+ if( !mxMacroExpander.is() )
+ {
+ Reference< XPropertySet > xProps( mxMSF, UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ if( xProps.is() )
+ {
+ Reference< XComponentContext > xContext;
+ xProps->getPropertyValue(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext;
+ OSL_ASSERT( xContext.is() );
+ if( xContext.is() )
+ {
+ Reference< util::XMacroExpander > xExpander;
+ xContext->getValueByName(
+ OUSTR("/singletons/com.sun.star.util.theMacroExpander") ) >>= xExpander;
+ if(! xExpander.is())
+ {
+ throw uno::DeploymentException(
+ OUSTR("no macro expander singleton available!"), Reference< XInterface >() );
+ }
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !mxMacroExpander.is() )
+ {
+ mxMacroExpander = xExpander;
+ }
+ }
+ }
+ }
+
+ if( !mxMacroExpander.is() )
+ return url;
+
+ // cut protocol
+ OUString macro( url.copy( sizeof (EXPAND_PROTOCOL ":") -1 ) );
+ // decode uric class chars
+ macro = Uri::decode( macro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ // expand macro string
+ OUString ret( mxMacroExpander->expandMacros( macro ) );
+ return ret;
+ }
+ else if( mxStringSubstitution.is() )
+ {
+ OUString ret( mxStringSubstitution->substituteVariables( url, false ) );
+ return ret;
+ }
+ else
+ {
+ return url;
+ }
+}
+
+//XLibraryContainer3
+OUString SAL_CALL SfxLibraryContainer::getOriginalLibraryLinkURL( const OUString& Name )
+ throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ SfxLibrary* pImplLib = getImplLib( Name );
+ sal_Bool bLink = pImplLib->mbLink;
+ if( !bLink )
+ throw IllegalArgumentException();
+ OUString aRetStr = pImplLib->maOrignialStorageURL;
+ return aRetStr;
+}
+
+
+// XVBACompatibility
+::sal_Bool SAL_CALL SfxLibraryContainer::getVBACompatibilityMode() throw (RuntimeException)
+{
+ return mbVBACompat;
+}
+
+void SAL_CALL SfxLibraryContainer::setVBACompatibilityMode( ::sal_Bool _vbacompatmodeon ) throw (RuntimeException)
+{
+ BasicManager* pBasMgr = getBasicManager();
+ if( pBasMgr )
+ {
+ // get the standard library
+ String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
+ if ( pBasMgr->GetName().Len() )
+ aLibName = pBasMgr->GetName();
+
+ StarBASIC* pBasic = pBasMgr->GetLib( aLibName );
+ if( pBasic )
+ pBasic->SetVBAEnabled( _vbacompatmodeon );
+ }
+ mbVBACompat = _vbacompatmodeon;
+}
+
+// Methods XServiceInfo
+::sal_Bool SAL_CALL SfxLibraryContainer::supportsService( const ::rtl::OUString& _rServiceName )
+ throw (RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ Sequence< OUString > aSupportedServices( getSupportedServiceNames() );
+ const OUString* pSupportedServices = aSupportedServices.getConstArray();
+ for ( sal_Int32 i=0; i<aSupportedServices.getLength(); ++i, ++pSupportedServices )
+ if ( *pSupportedServices == _rServiceName )
+ return sal_True;
+ return sal_False;
+}
+
+//============================================================================
+
+// Implementation class SfxLibrary
+
+// Ctor
+SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
+ const Reference< XMultiServiceFactory >& xMSF, const Reference< XSimpleFileAccess >& xSFI )
+ : OComponentHelper( m_aMutex )
+ , mxMSF( xMSF )
+ , mxSFI( xSFI )
+ , mrModifiable( _rModifiable )
+ , maNameContainer( aType )
+ , mbLoaded( sal_True )
+ , mbIsModified( sal_True )
+ , mbInitialised( sal_False )
+ , mbLink( sal_False )
+ , mbReadOnly( sal_False )
+ , mbReadOnlyLink( sal_False )
+ , mbPreload( sal_False )
+ , mbPasswordProtected( sal_False )
+ , mbPasswordVerified( sal_False )
+ , mbDoc50Password( sal_False )
+ , mbSharedIndexFile( sal_False )
+ , mbExtension( sal_False )
+{
+}
+
+SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
+ const Reference< XMultiServiceFactory >& xMSF, const Reference< XSimpleFileAccess >& xSFI,
+ const OUString& aLibInfoFileURL, const OUString& aStorageURL, sal_Bool ReadOnly )
+ : OComponentHelper( m_aMutex )
+ , mxMSF( xMSF )
+ , mxSFI( xSFI )
+ , mrModifiable( _rModifiable )
+ , maNameContainer( aType )
+ , mbLoaded( sal_False )
+ , mbIsModified( sal_True )
+ , mbInitialised( sal_False )
+ , maLibInfoFileURL( aLibInfoFileURL )
+ , maStorageURL( aStorageURL )
+ , mbLink( sal_True )
+ , mbReadOnly( sal_False )
+ , mbReadOnlyLink( ReadOnly )
+ , mbPreload( sal_False )
+ , mbPasswordProtected( sal_False )
+ , mbPasswordVerified( sal_False )
+ , mbDoc50Password( sal_False )
+ , mbSharedIndexFile( sal_False )
+ , mbExtension( sal_False )
+{
+}
+
+void SfxLibrary::implSetModified( sal_Bool _bIsModified )
+{
+ if ( mbIsModified == _bIsModified )
+ return;
+ mbIsModified = _bIsModified;
+ if ( mbIsModified )
+ mrModifiable.setModified( sal_True );
+}
+
+// Methods XInterface
+Any SAL_CALL SfxLibrary::queryInterface( const Type& rType )
+ throw( RuntimeException )
+{
+ Any aRet;
+
+ /*
+ if( mbReadOnly )
+ {
+ aRet = Any( ::cppu::queryInterface( rType,
+ static_cast< XContainer * >( this ),
+ static_cast< XNameAccess * >( this ) ) );
+ }
+ else
+ {
+ */
+ aRet = Any( ::cppu::queryInterface( rType,
+ static_cast< XContainer * >( this ),
+ static_cast< XNameContainer * >( this ),
+ static_cast< XNameAccess * >( this ) ) );
+ //}
+ if( !aRet.hasValue() )
+ aRet = OComponentHelper::queryInterface( rType );
+ return aRet;
+}
+
+// Methods XElementAccess
+Type SfxLibrary::getElementType()
+ throw(RuntimeException)
+{
+ return maNameContainer.getElementType();
+}
+
+sal_Bool SfxLibrary::hasElements()
+ throw(RuntimeException)
+{
+ sal_Bool bRet = maNameContainer.hasElements();
+ return bRet;
+}
+
+// Methods XNameAccess
+Any SfxLibrary::getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ impl_checkLoaded();
+
+ Any aRetAny = maNameContainer.getByName( aName ) ;
+ return aRetAny;
+}
+
+Sequence< OUString > SfxLibrary::getElementNames()
+ throw(RuntimeException)
+{
+ return maNameContainer.getElementNames();
+}
+
+sal_Bool SfxLibrary::hasByName( const OUString& aName )
+ throw(RuntimeException)
+{
+ sal_Bool bRet = maNameContainer.hasByName( aName );
+ return bRet;
+}
+
+void SfxLibrary::impl_checkReadOnly()
+{
+ if( mbReadOnly || (mbLink && mbReadOnlyLink) )
+ throw IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Library is readonly." ) ),
+ // TODO: resource
+ *this, 0
+ );
+}
+
+void SfxLibrary::impl_checkLoaded()
+{
+ if ( !mbLoaded )
+ throw WrappedTargetException(
+ ::rtl::OUString(),
+ *this,
+ makeAny( LibraryNotLoadedException(
+ ::rtl::OUString(),
+ *this
+ ) )
+ );
+}
+
+// Methods XNameReplace
+void SfxLibrary::replaceByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ impl_checkReadOnly();
+ impl_checkLoaded();
+
+ OSL_ENSURE( isLibraryElementValid( aElement ), "SfxLibrary::replaceByName: replacing element is invalid!" );
+
+ maNameContainer.replaceByName( aName, aElement );
+ implSetModified( sal_True );
+}
+
+
+// Methods XNameContainer
+void SfxLibrary::insertByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ impl_checkReadOnly();
+ impl_checkLoaded();
+
+ OSL_ENSURE( isLibraryElementValid( aElement ), "SfxLibrary::insertByName: to-be-inserted element is invalid!" );
+
+ maNameContainer.insertByName( aName, aElement );
+ implSetModified( sal_True );
+}
+
+void SfxLibrary::impl_removeWithoutChecks( const ::rtl::OUString& _rElementName )
+{
+ maNameContainer.removeByName( _rElementName );
+ implSetModified( sal_True );
+
+ // Remove element file
+ if( maStorageURL.getLength() )
+ {
+ INetURLObject aElementInetObj( maStorageURL );
+ aElementInetObj.insertName( _rElementName, sal_False,
+ INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aElementInetObj.setExtension( maLibElementFileExtension );
+ OUString aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ try
+ {
+ if( mxSFI->exists( aFile ) )
+ mxSFI->kill( aFile );
+ }
+ catch( Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+}
+
+void SfxLibrary::removeByName( const OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ impl_checkReadOnly();
+ impl_checkLoaded();
+ impl_removeWithoutChecks( Name );
+}
+
+// XTypeProvider
+Sequence< Type > SfxLibrary::getTypes()
+ throw( RuntimeException )
+{
+ static OTypeCollection * s_pTypes_NameContainer = 0;
+ {
+ if( !s_pTypes_NameContainer )
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if( !s_pTypes_NameContainer )
+ {
+ static OTypeCollection s_aTypes_NameContainer(
+ ::getCppuType( (const Reference< XNameContainer > *)0 ),
+ ::getCppuType( (const Reference< XContainer > *)0 ),
+ OComponentHelper::getTypes() );
+ s_pTypes_NameContainer = &s_aTypes_NameContainer;
+ }
+ }
+ return s_pTypes_NameContainer->getTypes();
+ }
+}
+
+
+Sequence< sal_Int8 > SfxLibrary::getImplementationId()
+ throw( RuntimeException )
+{
+ static OImplementationId * s_pId_NameContainer = 0;
+ {
+ if( !s_pId_NameContainer )
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if( !s_pId_NameContainer )
+ {
+ static OImplementationId s_aId_NameContainer;
+ s_pId_NameContainer = &s_aId_NameContainer;
+ }
+ }
+ return s_pId_NameContainer->getImplementationId();
+ }
+}
+
+
+//============================================================================
+
+// Methods XContainer
+void SAL_CALL SfxLibrary::addContainerListener( const Reference< XContainerListener >& xListener )
+ throw (RuntimeException)
+{
+ maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
+ maNameContainer.addContainerListener( xListener );
+}
+
+void SAL_CALL SfxLibrary::removeContainerListener( const Reference< XContainerListener >& xListener )
+ throw (RuntimeException)
+{
+ maNameContainer.removeContainerListener( xListener );
+}
+
+
+//============================================================================
+// Implementation class ScriptExtensionIterator
+
+static rtl::OUString aBasicLibMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.basic-library" ) );
+static rtl::OUString aDialogLibMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.dialog-library" ) );
+
+ScriptExtensionIterator::ScriptExtensionIterator( void )
+ : m_eState( USER_EXTENSIONS )
+ , m_bUserPackagesLoaded( false )
+ , m_bSharedPackagesLoaded( false )
+ , m_bBundledPackagesLoaded( false )
+ , m_iUserPackage( 0 )
+ , m_iSharedPackage( 0 )
+ , m_iBundledPackage( 0 )
+ , m_pScriptSubPackageIterator( NULL )
+{
+ 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") ) ) >>= m_xContext;
+ OSL_ASSERT( m_xContext.is() );
+ }
+ if( !m_xContext.is() )
+ {
+ throw RuntimeException(
+ ::rtl::OUString::createFromAscii( "ScriptExtensionIterator::init(), no XComponentContext" ),
+ Reference< XInterface >() );
+ }
+}
+
+rtl::OUString ScriptExtensionIterator::nextBasicOrDialogLibrary( bool& rbPureDialogLib )
+{
+ rtl::OUString aRetLib;
+
+ while( !aRetLib.getLength() && m_eState != END_REACHED )
+ {
+ switch( m_eState )
+ {
+ case USER_EXTENSIONS:
+ {
+ Reference< deployment::XPackage > xScriptPackage =
+ implGetNextUserScriptPackage( rbPureDialogLib );
+ if( !xScriptPackage.is() )
+ break;
+
+ aRetLib = xScriptPackage->getURL();
+ break;
+ }
+
+ case SHARED_EXTENSIONS:
+ {
+ Reference< deployment::XPackage > xScriptPackage =
+ implGetNextSharedScriptPackage( rbPureDialogLib );
+ if( !xScriptPackage.is() )
+ break;
+
+ aRetLib = xScriptPackage->getURL();
+ break;
+ }
+ case BUNDLED_EXTENSIONS:
+ {
+ Reference< deployment::XPackage > xScriptPackage =
+ implGetNextBundledScriptPackage( rbPureDialogLib );
+ if( !xScriptPackage.is() )
+ break;
+
+ aRetLib = xScriptPackage->getURL();
+ break;
+ }
+ case END_REACHED:
+ VOS_ENSURE( false, "ScriptExtensionIterator::nextBasicOrDialogLibrary(): Invalid case END_REACHED" );
+ break;
+ }
+ }
+
+ return aRetLib;
+}
+
+ScriptSubPackageIterator::ScriptSubPackageIterator( Reference< deployment::XPackage > xMainPackage )
+ : m_xMainPackage( xMainPackage )
+ , m_bIsValid( false )
+ , m_bIsBundle( false )
+ , m_nSubPkgCount( 0 )
+ , m_iNextSubPkg( 0 )
+{
+ Reference< deployment::XPackage > xScriptPackage;
+ if( !m_xMainPackage.is() )
+ return;
+
+ // Check if parent package is registered
+ beans::Optional< beans::Ambiguous<sal_Bool> > option( m_xMainPackage->isRegistered
+ ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
+ bool bRegistered = false;
+ if( option.IsPresent )
+ {
+ beans::Ambiguous<sal_Bool> const & reg = option.Value;
+ if( !reg.IsAmbiguous && reg.Value )
+ bRegistered = true;
+ }
+ if( bRegistered )
+ {
+ m_bIsValid = true;
+ if( m_xMainPackage->isBundle() )
+ {
+ m_bIsBundle = true;
+ m_aSubPkgSeq = m_xMainPackage->getBundle
+ ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() );
+ m_nSubPkgCount = m_aSubPkgSeq.getLength();
+ }
+ }
+}
+
+Reference< deployment::XPackage > ScriptSubPackageIterator::getNextScriptSubPackage
+ ( bool& rbPureDialogLib )
+{
+ rbPureDialogLib = false;
+
+ Reference< deployment::XPackage > xScriptPackage;
+ if( !m_bIsValid )
+ return xScriptPackage;
+
+ if( m_bIsBundle )
+ {
+ const Reference< deployment::XPackage >* pSeq = m_aSubPkgSeq.getConstArray();
+ sal_Int32 iPkg;
+ for( iPkg = m_iNextSubPkg ; iPkg < m_nSubPkgCount ; ++iPkg )
+ {
+ const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
+ xScriptPackage = implDetectScriptPackage( xSubPkg, rbPureDialogLib );
+ if( xScriptPackage.is() )
+ break;
+ }
+ m_iNextSubPkg = iPkg + 1;
+ }
+ else
+ {
+ xScriptPackage = implDetectScriptPackage( m_xMainPackage, rbPureDialogLib );
+ m_bIsValid = false; // No more script packages
+ }
+
+ return xScriptPackage;
+}
+
+Reference< deployment::XPackage > ScriptSubPackageIterator::implDetectScriptPackage
+ ( const Reference< deployment::XPackage > xPackage, bool& rbPureDialogLib )
+{
+ Reference< deployment::XPackage > xScriptPackage;
+
+ if( xPackage.is() )
+ {
+ const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType();
+ rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
+ if( aMediaType.equals( aBasicLibMediaType ) )
+ {
+ xScriptPackage = xPackage;
+ }
+ else if( aMediaType.equals( aDialogLibMediaType ) )
+ {
+ rbPureDialogLib = true;
+ xScriptPackage = xPackage;
+ }
+ }
+
+ return xScriptPackage;
+}
+
+Reference< deployment::XPackage > ScriptExtensionIterator::implGetScriptPackageFromPackage
+ ( const Reference< deployment::XPackage > xPackage, bool& rbPureDialogLib )
+{
+ rbPureDialogLib = false;
+
+ Reference< deployment::XPackage > xScriptPackage;
+ if( !xPackage.is() )
+ return xScriptPackage;
+
+ // Check if parent package is registered
+ beans::Optional< beans::Ambiguous<sal_Bool> > option( xPackage->isRegistered
+ ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
+ bool bRegistered = false;
+ if( option.IsPresent )
+ {
+ beans::Ambiguous<sal_Bool> const & reg = option.Value;
+ if( !reg.IsAmbiguous && reg.Value )
+ bRegistered = true;
+ }
+ if( bRegistered )
+ {
+ if( xPackage->isBundle() )
+ {
+ Sequence< Reference< deployment::XPackage > > aPkgSeq = xPackage->getBundle
+ ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() );
+ sal_Int32 nPkgCount = aPkgSeq.getLength();
+ const Reference< deployment::XPackage >* pSeq = aPkgSeq.getConstArray();
+ for( sal_Int32 iPkg = 0 ; iPkg < nPkgCount ; ++iPkg )
+ {
+ const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
+ const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xSubPkg->getPackageType();
+ rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
+ if( aMediaType.equals( aBasicLibMediaType ) )
+ {
+ xScriptPackage = xSubPkg;
+ break;
+ }
+ else if( aMediaType.equals( aDialogLibMediaType ) )
+ {
+ rbPureDialogLib = true;
+ xScriptPackage = xSubPkg;
+ break;
+ }
+ }
+ }
+ else
+ {
+ const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType();
+ rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
+ if( aMediaType.equals( aBasicLibMediaType ) )
+ {
+ xScriptPackage = xPackage;
+ }
+ else if( aMediaType.equals( aDialogLibMediaType ) )
+ {
+ rbPureDialogLib = true;
+ xScriptPackage = xPackage;
+ }
+ }
+ }
+
+ return xScriptPackage;
+}
+
+Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextUserScriptPackage
+ ( bool& rbPureDialogLib )
+{
+ Reference< deployment::XPackage > xScriptPackage;
+
+ if( !m_bUserPackagesLoaded )
+ {
+ try
+ {
+ Reference< XExtensionManager > xManager =
+ ExtensionManager::get( m_xContext );
+ m_aUserPackagesSeq = xManager->getDeployedExtensions
+ (rtl::OUString::createFromAscii("user"),
+ Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
+ }
+ catch( com::sun::star::uno::DeploymentException& )
+ {
+ // Special Office installations may not contain deployment code
+ m_eState = END_REACHED;
+ return xScriptPackage;
+ }
+
+ m_bUserPackagesLoaded = true;
+ }
+
+ if( m_iUserPackage == m_aUserPackagesSeq.getLength() )
+ {
+ m_eState = SHARED_EXTENSIONS; // Later: SHARED_MODULE
+ }
+ else
+ {
+ if( m_pScriptSubPackageIterator == NULL )
+ {
+ const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray();
+ Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage ];
+ VOS_ENSURE( xPackage.is(), "ScriptExtensionIterator::implGetNextUserScriptPackage(): Invalid package" );
+ m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
+ }
+
+ if( m_pScriptSubPackageIterator != NULL )
+ {
+ xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
+ if( !xScriptPackage.is() )
+ {
+ delete m_pScriptSubPackageIterator;
+ m_pScriptSubPackageIterator = NULL;
+ m_iUserPackage++;
+ }
+ }
+ }
+
+ return xScriptPackage;
+}
+
+Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextSharedScriptPackage
+ ( bool& rbPureDialogLib )
+{
+ Reference< deployment::XPackage > xScriptPackage;
+
+ if( !m_bSharedPackagesLoaded )
+ {
+ try
+ {
+ Reference< XExtensionManager > xSharedManager =
+ ExtensionManager::get( m_xContext );
+ m_aSharedPackagesSeq = xSharedManager->getDeployedExtensions
+ (rtl::OUString::createFromAscii("shared"),
+ Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
+ }
+ catch( com::sun::star::uno::DeploymentException& )
+ {
+ // Special Office installations may not contain deployment code
+ return xScriptPackage;
+ }
+
+ m_bSharedPackagesLoaded = true;
+ }
+
+ if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() )
+ {
+ m_eState = BUNDLED_EXTENSIONS;
+ }
+ else
+ {
+ if( m_pScriptSubPackageIterator == NULL )
+ {
+ const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray();
+ Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage ];
+ VOS_ENSURE( xPackage.is(), "ScriptExtensionIterator::implGetNextSharedScriptPackage(): Invalid package" );
+ m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
+ }
+
+ if( m_pScriptSubPackageIterator != NULL )
+ {
+ xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
+ if( !xScriptPackage.is() )
+ {
+ delete m_pScriptSubPackageIterator;
+ m_pScriptSubPackageIterator = NULL;
+ m_iSharedPackage++;
+ }
+ }
+ }
+
+ return xScriptPackage;
+}
+
+Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextBundledScriptPackage
+ ( bool& rbPureDialogLib )
+{
+ Reference< deployment::XPackage > xScriptPackage;
+
+ if( !m_bBundledPackagesLoaded )
+ {
+ try
+ {
+ Reference< XExtensionManager > xManager =
+ ExtensionManager::get( m_xContext );
+ m_aBundledPackagesSeq = xManager->getDeployedExtensions
+ (rtl::OUString::createFromAscii("bundled"),
+ Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
+ }
+ catch( com::sun::star::uno::DeploymentException& )
+ {
+ // Special Office installations may not contain deployment code
+ return xScriptPackage;
+ }
+
+ m_bBundledPackagesLoaded = true;
+ }
+
+ if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() )
+ {
+ m_eState = END_REACHED;
+ }
+ else
+ {
+ if( m_pScriptSubPackageIterator == NULL )
+ {
+ const Reference< deployment::XPackage >* pBundledPackages = m_aBundledPackagesSeq.getConstArray();
+ Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage ];
+ VOS_ENSURE( xPackage.is(), "ScriptExtensionIterator::implGetNextBundledScriptPackage(): Invalid package" );
+ m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
+ }
+
+ if( m_pScriptSubPackageIterator != NULL )
+ {
+ xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
+ if( !xScriptPackage.is() )
+ {
+ delete m_pScriptSubPackageIterator;
+ m_pScriptSubPackageIterator = NULL;
+ m_iBundledPackage++;
+ }
+ }
+ }
+
+ return xScriptPackage;
+}
+
+} // namespace basic
diff --git a/basic/source/uno/sbmodule.cxx b/basic/source/uno/sbmodule.cxx
new file mode 100644
index 000000000000..db9383a019b5
--- /dev/null
+++ b/basic/source/uno/sbmodule.cxx
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * 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 "sbmodule.hxx"
+#include <rtl/instance.hxx>
+
+//........................................................................
+namespace basic
+{
+//........................................................................
+
+ IMPLEMENT_COMPONENT_MODULE( BasicModule );
+
+//........................................................................
+} // namespace basic
+//........................................................................
+
+
diff --git a/basic/source/uno/sbmodule.hxx b/basic/source/uno/sbmodule.hxx
new file mode 100644
index 000000000000..459dac691896
--- /dev/null
+++ b/basic/source/uno/sbmodule.hxx
@@ -0,0 +1,45 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef SBMODULE_HXX
+#define SBMODULE_HXX
+
+#include <comphelper/componentmodule.hxx>
+
+//........................................................................
+namespace basic
+{
+//........................................................................
+
+ DECLARE_COMPONENT_MODULE( BasicModule, BasicModuleClient )
+
+//........................................................................
+} // namespace basic
+//........................................................................
+
+#endif // SBMODULE_HXX
+
diff --git a/basic/source/uno/sbservices.cxx b/basic/source/uno/sbservices.cxx
new file mode 100644
index 000000000000..7a1a4fd2d1cb
--- /dev/null
+++ b/basic/source/uno/sbservices.cxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * 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 "sbmodule.hxx"
+
+/** === begin UNO includes === **/
+/** === end UNO includes === **/
+
+//........................................................................
+namespace basic
+{
+//........................................................................
+
+ //--------------------------------------------------------------------
+ extern void createRegistryInfo_SfxDialogLibraryContainer();
+ extern void createRegistryInfo_SfxScriptLibraryContainer();
+
+ static void initializeModule()
+ {
+ static bool bInitialized( false );
+ if ( !bInitialized )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !bInitialized )
+ {
+ createRegistryInfo_SfxDialogLibraryContainer();
+ createRegistryInfo_SfxScriptLibraryContainer();
+ }
+ }
+ }
+
+//........................................................................
+} // namespace basic
+//........................................................................
+
+IMPLEMENT_COMPONENT_LIBRARY_API( ::basic::BasicModule, ::basic::initializeModule )
+
diff --git a/basic/source/uno/scriptcont.cxx b/basic/source/uno/scriptcont.cxx
new file mode 100644
index 000000000000..f7091d1c1a0b
--- /dev/null
+++ b/basic/source/uno/scriptcont.cxx
@@ -0,0 +1,1328 @@
+/*************************************************************************
+ *
+ * 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 "scriptcont.hxx"
+#include "sbmodule.hxx"
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XEncryptionProtectedSource.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/task/ErrorCodeIOException.hpp>
+#include <com/sun/star/script/ModuleType.hpp>
+#include <comphelper/processfactory.hxx>
+#ifndef _COMPHELPER_STORAGEHELPER_HXX_
+#include <comphelper/storagehelper.hxx>
+#endif
+#include <unotools/streamwrap.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <osl/mutex.hxx>
+#include <rtl/digest.h>
+#include <rtl/strbuf.hxx>
+
+// For password functionality
+#include <tools/urlobj.hxx>
+
+
+#include <unotools/pathoptions.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svtools/ehdl.hxx>
+#include <basic/basmgr.hxx>
+#include <basic/sbmod.hxx>
+#include <basic/basicmanagerrepository.hxx>
+#include "modsizeexceeded.hxx"
+#include <xmlscript/xmlmod_imexp.hxx>
+#include <cppuhelper/factory.hxx>
+#include <com/sun/star/util/VetoException.hpp>
+
+namespace basic
+{
+
+using namespace com::sun::star::document;
+using namespace com::sun::star::container;
+using namespace com::sun::star::io;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::script;
+using namespace com::sun::star::xml::sax;
+using namespace com::sun::star;
+using namespace cppu;
+using namespace rtl;
+using namespace osl;
+
+using com::sun::star::uno::Reference;
+
+//============================================================================
+// Implementation class SfxScriptLibraryContainer
+
+const sal_Char* SAL_CALL SfxScriptLibraryContainer::getInfoFileName() const { return "script"; }
+const sal_Char* SAL_CALL SfxScriptLibraryContainer::getOldInfoFileName() const { return "script"; }
+const sal_Char* SAL_CALL SfxScriptLibraryContainer::getLibElementFileExtension() const { return "xba"; }
+const sal_Char* SAL_CALL SfxScriptLibraryContainer::getLibrariesDir() const { return "Basic"; }
+
+// OldBasicPassword interface
+void SfxScriptLibraryContainer::setLibraryPassword
+ ( const String& rLibraryName, const String& rPassword )
+{
+ try
+ {
+ SfxLibrary* pImplLib = getImplLib( rLibraryName );
+ if( rPassword.Len() )
+ {
+ pImplLib->mbDoc50Password = sal_True;
+ pImplLib->mbPasswordProtected = sal_True;
+ pImplLib->maPassword = rPassword;
+ }
+ }
+ catch( NoSuchElementException& ) {}
+}
+
+String SfxScriptLibraryContainer::getLibraryPassword( const String& rLibraryName )
+{
+ SfxLibrary* pImplLib = getImplLib( rLibraryName );
+ String aPassword;
+ if( pImplLib->mbPasswordVerified )
+ aPassword = pImplLib->maPassword;
+ return aPassword;
+}
+
+void SfxScriptLibraryContainer::clearLibraryPassword( const String& rLibraryName )
+{
+ try
+ {
+ SfxLibrary* pImplLib = getImplLib( rLibraryName );
+ pImplLib->mbDoc50Password = sal_False;
+ pImplLib->mbPasswordProtected = sal_False;
+ pImplLib->maPassword = OUString();
+ }
+ catch( NoSuchElementException& ) {}
+}
+
+sal_Bool SfxScriptLibraryContainer::hasLibraryPassword( const String& rLibraryName )
+{
+ SfxLibrary* pImplLib = getImplLib( rLibraryName );
+ return pImplLib->mbPasswordProtected;
+}
+
+
+// Ctor for service
+SfxScriptLibraryContainer::SfxScriptLibraryContainer( void )
+ :maScriptLanguage( RTL_CONSTASCII_USTRINGPARAM( "StarBasic" ) )
+{
+ // all initialisation has to be done
+ // by calling XInitialization::initialize
+}
+
+SfxScriptLibraryContainer::SfxScriptLibraryContainer( const uno::Reference< embed::XStorage >& xStorage )
+ :maScriptLanguage( RTL_CONSTASCII_USTRINGPARAM( "StarBasic" ) )
+{
+ init( OUString(), xStorage );
+}
+
+// Methods to get library instances of the correct type
+SfxLibrary* SfxScriptLibraryContainer::implCreateLibrary( const OUString& aName )
+{
+ (void)aName; // Only needed for SfxDialogLibrary
+ SfxLibrary* pRet = new SfxScriptLibrary( maModifiable, mxMSF, mxSFI );
+ return pRet;
+}
+
+SfxLibrary* SfxScriptLibraryContainer::implCreateLibraryLink
+ ( const OUString& aName, const OUString& aLibInfoFileURL,
+ const OUString& StorageURL, sal_Bool ReadOnly )
+{
+ (void)aName; // Only needed for SfxDialogLibrary
+ SfxLibrary* pRet =
+ new SfxScriptLibrary
+ ( maModifiable, mxMSF, mxSFI, aLibInfoFileURL, StorageURL, ReadOnly );
+ return pRet;
+}
+
+Any SAL_CALL SfxScriptLibraryContainer::createEmptyLibraryElement( void )
+{
+ OUString aMod;
+ Any aRetAny;
+ aRetAny <<= aMod;
+ return aRetAny;
+}
+
+bool SAL_CALL SfxScriptLibraryContainer::isLibraryElementValid( Any aElement ) const
+{
+ return SfxScriptLibrary::containsValidModule( aElement );
+}
+
+void SAL_CALL SfxScriptLibraryContainer::writeLibraryElement
+(
+ const Reference < XNameContainer >& xLib,
+ const OUString& aElementName,
+ const Reference< XOutputStream >& xOutput
+)
+ throw(Exception)
+{
+ // Create sax writer
+ Reference< XExtendedDocumentHandler > xHandler(
+ mxMSF->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") ) ), UNO_QUERY );
+ if( !xHandler.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create sax-writer component\n" );
+ return;
+ }
+
+ Reference< XTruncate > xTruncate( xOutput, UNO_QUERY );
+ OSL_ENSURE( xTruncate.is(), "Currently only the streams that can be truncated are expected!" );
+ if ( xTruncate.is() )
+ xTruncate->truncate();
+
+ Reference< XActiveDataSource > xSource( xHandler, UNO_QUERY );
+ xSource->setOutputStream( xOutput );
+
+ xmlscript::ModuleDescriptor aMod;
+ aMod.aName = aElementName;
+ aMod.aLanguage = maScriptLanguage;
+ Any aElement = xLib->getByName( aElementName );
+ aElement >>= aMod.aCode;
+
+ Reference< script::vba::XVBAModuleInfo > xModInfo( xLib, UNO_QUERY );
+ if( xModInfo.is() && xModInfo->hasModuleInfo( aElementName ) )
+ {
+ script::ModuleInfo aModInfo = xModInfo->getModuleInfo( aElementName );
+ switch( aModInfo.ModuleType )
+ {
+ case ModuleType::NORMAL:
+ aMod.aModuleType = OUString( RTL_CONSTASCII_USTRINGPARAM("normal") );
+ break;
+ case ModuleType::CLASS:
+ aMod.aModuleType = OUString( RTL_CONSTASCII_USTRINGPARAM("class") );
+ break;
+ case ModuleType::FORM:
+ aMod.aModuleType = OUString( RTL_CONSTASCII_USTRINGPARAM("form") );
+ break;
+ case ModuleType::DOCUMENT:
+ aMod.aModuleType = OUString( RTL_CONSTASCII_USTRINGPARAM("document") );
+ break;
+ case ModuleType::UNKNOWN:
+ // nothing
+ break;
+ }
+ }
+
+ xmlscript::exportScriptModule( xHandler, aMod );
+}
+
+
+Any SAL_CALL SfxScriptLibraryContainer::importLibraryElement
+ ( const Reference < XNameContainer >& xLib,
+ const OUString& aElementName, const OUString& aFile,
+ const uno::Reference< io::XInputStream >& xInStream )
+{
+ Any aRetAny;
+
+ Reference< XParser > xParser( mxMSF->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY );
+ if( !xParser.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create sax parser component\n" );
+ return aRetAny;
+ }
+
+
+ // Read from storage?
+ sal_Bool bStorage = xInStream.is();
+ Reference< XInputStream > xInput;
+
+ if( bStorage )
+ {
+ xInput = xInStream;
+ }
+ else
+ {
+ try
+ {
+ xInput = mxSFI->openFileRead( aFile );
+ }
+ catch( Exception& )
+ //catch( Exception& e )
+ {
+ // TODO:
+ //throw WrappedTargetException( e );
+ }
+ }
+
+ if( !xInput.is() )
+ return aRetAny;
+
+ InputSource source;
+ source.aInputStream = xInput;
+ source.sSystemId = aFile;
+
+ // start parsing
+ xmlscript::ModuleDescriptor aMod;
+
+ try
+ {
+ xParser->setDocumentHandler( ::xmlscript::importScriptModule( aMod ) );
+ xParser->parseStream( source );
+ }
+ catch( Exception& )
+ {
+ SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFile );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+
+ aRetAny <<= aMod.aCode;
+
+ // TODO: Check language
+ // aMod.aLanguage
+ // aMod.aName ignored
+ if( aMod.aModuleType.getLength() > 0 )
+ {
+ if( !getVBACompatibilityMode() )
+ {
+ setVBACompatibilityMode( sal_True );
+
+ Any aGlobs;
+ Sequence< Any > aArgs(1);
+ Reference<frame::XModel > xModel( mxOwnerDocument );
+ aArgs[ 0 ] <<= xModel;
+
+ BasicManager* pBasicMgr = getBasicManager();
+ if( pBasicMgr )
+ {
+ aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.Globals" ) ), aArgs );
+ pBasicMgr->SetGlobalUNOConstant( "VBAGlobals", aGlobs );
+ }
+ pBasicMgr = BasicManagerRepository::getApplicationBasicManager( sal_False );
+ if( pBasicMgr )
+ pBasicMgr->SetGlobalUNOConstant( "ThisExcelDoc", aArgs[0] );
+ }
+
+ script::ModuleInfo aModInfo;
+ aModInfo.ModuleType = ModuleType::UNKNOWN;
+ if( aMod.aModuleType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("normal") ))
+ {
+ aModInfo.ModuleType = ModuleType::NORMAL;
+ }
+ else if( aMod.aModuleType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("class") ))
+ {
+ aModInfo.ModuleType = ModuleType::CLASS;
+ }
+ else if( aMod.aModuleType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("form") ))
+ {
+ aModInfo.ModuleType = ModuleType::FORM;
+ aModInfo.ModuleObject = mxOwnerDocument;
+ }
+ else if( aMod.aModuleType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("document") ))
+ {
+ aModInfo.ModuleType = ModuleType::DOCUMENT;
+ Reference<frame::XModel > xModel( mxOwnerDocument );
+ Reference< XMultiServiceFactory> xSF( xModel, UNO_QUERY);
+ Reference< container::XNameAccess > xVBACodeNameAccess;
+ if( xSF.is() )
+ {
+ try
+ {
+ xVBACodeNameAccess.set( xSF->createInstance(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "ooo.vba.VBAObjectModuleObjectProvider"))),
+ UNO_QUERY );
+ }
+ catch(uno::Exception&) {}
+ }
+ if( xVBACodeNameAccess.is() )
+ {
+ try
+ {
+ aModInfo.ModuleObject.set( xVBACodeNameAccess->getByName( aElementName), uno::UNO_QUERY );
+ }
+ catch(uno::Exception&)
+ {
+ OSL_TRACE("Failed to get documument object for %s", rtl::OUStringToOString( aElementName, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+ }
+
+ Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, UNO_QUERY );
+ if( xVBAModuleInfo.is() )
+ {
+ if( xVBAModuleInfo->hasModuleInfo( aElementName ) )
+ xVBAModuleInfo->removeModuleInfo( aElementName );
+ xVBAModuleInfo->insertModuleInfo( aElementName, aModInfo );
+ }
+ }
+
+ return aRetAny;
+}
+
+SfxLibraryContainer* SfxScriptLibraryContainer::createInstanceImpl( void )
+{
+ return new SfxScriptLibraryContainer();
+}
+
+void SAL_CALL SfxScriptLibraryContainer::importFromOldStorage( const ::rtl::OUString& aFile )
+{
+ // TODO: move loading from old storage to binary filters?
+ SotStorageRef xStorage = new SotStorage( sal_False, aFile );
+ if( xStorage.Is() && xStorage->GetError() == ERRCODE_NONE )
+ {
+ // We need a BasicManager to avoid problems
+ // StarBASIC* pBas = new StarBASIC();
+ BasicManager* pBasicManager = new BasicManager( *(SotStorage*)xStorage, aFile );
+
+ // Set info
+ LibraryContainerInfo aInfo( this, NULL, static_cast< OldBasicPassword* >( this ) );
+ pBasicManager->SetLibraryContainerInfo( aInfo );
+
+ // Now the libraries should be copied to this SfxScriptLibraryContainer
+ BasicManager::LegacyDeleteBasicManager( pBasicManager );
+ }
+}
+
+
+// Storing with password encryption
+
+// Methods XLibraryContainerPassword
+sal_Bool SAL_CALL SfxScriptLibraryContainer::isLibraryPasswordProtected( const OUString& Name )
+ throw (NoSuchElementException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ SfxLibrary* pImplLib = getImplLib( Name );
+ sal_Bool bRet = pImplLib->mbPasswordProtected;
+ return bRet;
+}
+
+sal_Bool SAL_CALL SfxScriptLibraryContainer::isLibraryPasswordVerified( const OUString& Name )
+ throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ SfxLibrary* pImplLib = getImplLib( Name );
+ if( !pImplLib->mbPasswordProtected )
+ throw IllegalArgumentException();
+ sal_Bool bRet = pImplLib->mbPasswordVerified;
+ return bRet;
+}
+
+sal_Bool SAL_CALL SfxScriptLibraryContainer::verifyLibraryPassword
+ ( const OUString& Name, const OUString& Password )
+ throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ SfxLibrary* pImplLib = getImplLib( Name );
+ if( !pImplLib->mbPasswordProtected || pImplLib->mbPasswordVerified )
+ throw IllegalArgumentException();
+
+ // Test password
+ sal_Bool bSuccess = sal_False;
+ if( pImplLib->mbDoc50Password )
+ {
+ bSuccess = ( Password == pImplLib->maPassword );
+ if( bSuccess )
+ pImplLib->mbPasswordVerified = sal_True;
+ }
+ else
+ {
+ pImplLib->maPassword = Password;
+ bSuccess = implLoadPasswordLibrary( pImplLib, Name, sal_True );
+ if( bSuccess )
+ {
+ // The library gets modified by verifiying the password, because other-
+ // wise for saving the storage would be copied and that doesn't work
+ // with mtg's storages when the password is verified
+ pImplLib->implSetModified( sal_True );
+ pImplLib->mbPasswordVerified = sal_True;
+
+ // Reload library to get source
+ if( pImplLib->mbLoaded )
+ implLoadPasswordLibrary( pImplLib, Name );
+ }
+ }
+ return bSuccess;
+}
+
+void SAL_CALL SfxScriptLibraryContainer::changeLibraryPassword( const OUString& Name,
+ const OUString& OldPassword, const OUString& NewPassword )
+ throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+{
+ LibraryContainerMethodGuard aGuard( *this );
+ SfxLibrary* pImplLib = getImplLib( Name );
+ if( OldPassword == NewPassword )
+ return;
+
+ sal_Bool bOldPassword = ( OldPassword.getLength() > 0 );
+ sal_Bool bNewPassword = ( NewPassword.getLength() > 0 );
+ sal_Bool bStorage = mxStorage.is() && !pImplLib->mbLink;
+
+ if( pImplLib->mbReadOnly || (bOldPassword && !pImplLib->mbPasswordProtected) )
+ throw IllegalArgumentException();
+
+ // Library must be loaded
+ loadLibrary( Name );
+
+ sal_Bool bKillCryptedFiles = sal_False;
+ sal_Bool bKillUncryptedFiles = sal_False;
+
+ // Remove or change password?
+ if( bOldPassword )
+ {
+ if( isLibraryPasswordVerified( Name ) )
+ {
+ if( pImplLib->maPassword != OldPassword )
+ throw IllegalArgumentException();
+ }
+ else
+ {
+ if( !verifyLibraryPassword( Name, OldPassword ) )
+ throw IllegalArgumentException();
+
+ // Reload library to get source
+ // Should be done in verifyLibraryPassword loadLibrary( Name );
+ }
+
+ if( !bNewPassword )
+ {
+ pImplLib->mbPasswordProtected = sal_False;
+ pImplLib->mbPasswordVerified = sal_False;
+ pImplLib->maPassword = OUString();
+
+ maModifiable.setModified( sal_True );
+ pImplLib->implSetModified( sal_True );
+
+ if( !bStorage && !pImplLib->mbDoc50Password )
+ {
+ // Store application basic uncrypted
+ uno::Reference< embed::XStorage > xStorage;
+ storeLibraries_Impl( xStorage, sal_False );
+ bKillCryptedFiles = sal_True;
+ }
+ }
+ }
+
+ // Set new password?
+ if( bNewPassword )
+ {
+ pImplLib->mbPasswordProtected = sal_True;
+ pImplLib->mbPasswordVerified = sal_True;
+ pImplLib->maPassword = NewPassword;
+
+ maModifiable.setModified( sal_True );
+ pImplLib->implSetModified( sal_True );
+
+ if( !bStorage && !pImplLib->mbDoc50Password )
+ {
+ // Store applictaion basic crypted
+ uno::Reference< embed::XStorage > xStorage;
+ storeLibraries_Impl( xStorage, sal_False );
+ bKillUncryptedFiles = sal_True;
+ }
+ }
+
+ if( bKillCryptedFiles || bKillUncryptedFiles )
+ {
+ Sequence< OUString > aElementNames = pImplLib->getElementNames();
+ sal_Int32 nNameCount = aElementNames.getLength();
+ const OUString* pNames = aElementNames.getConstArray();
+ OUString aLibDirPath = createAppLibraryFolder( pImplLib, Name );
+ try
+ {
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aElementName = pNames[ i ];
+
+ INetURLObject aElementInetObj( aLibDirPath );
+ aElementInetObj.insertName( aElementName, sal_False,
+ INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ if( bKillUncryptedFiles )
+ aElementInetObj.setExtension( maLibElementFileExtension );
+ else
+ aElementInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("pba") ) );
+ String aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ if( mxSFI->exists( aElementPath ) )
+ mxSFI->kill( aElementPath );
+ }
+ }
+ catch( Exception& ) {}
+ }
+}
+
+
+void setStreamKey( uno::Reference< io::XStream > xStream, const ::rtl::OUString& aPass )
+{
+ uno::Reference< embed::XEncryptionProtectedSource > xEncrStream( xStream, uno::UNO_QUERY );
+ if ( xEncrStream.is() )
+ xEncrStream->setEncryptionPassword( aPass );
+}
+
+
+// Impl methods
+sal_Bool SfxScriptLibraryContainer::implStorePasswordLibrary( SfxLibrary* pLib,
+ const ::rtl::OUString& aName, const uno::Reference< embed::XStorage >& xStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler )
+{
+ OUString aDummyLocation;
+ Reference< XSimpleFileAccess > xDummySFA;
+ return implStorePasswordLibrary( pLib, aName, xStorage, aDummyLocation, xDummySFA, xHandler );
+}
+
+sal_Bool SfxScriptLibraryContainer::implStorePasswordLibrary( SfxLibrary* pLib, const ::rtl::OUString& aName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage,
+ const ::rtl::OUString& aTargetURL, const Reference< XSimpleFileAccess > xToUseSFI, const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler )
+{
+ bool bExport = aTargetURL.getLength();
+
+ BasicManager* pBasicMgr = getBasicManager();
+ OSL_ENSURE( pBasicMgr, "SfxScriptLibraryContainer::implStorePasswordLibrary: cannot do this without a BasicManager!" );
+ if ( !pBasicMgr )
+ return sal_False;
+
+ // Only need to handle the export case here,
+ // save/saveas etc are handled in sfxbasemodel::storeSelf &
+ // sfxbasemodel::impl_store
+ uno::Sequence<rtl::OUString> aNames;
+ if ( bExport && pBasicMgr->LegacyPsswdBinaryLimitExceeded(aNames) )
+ {
+ if ( xHandler.is() )
+ {
+ ModuleSizeExceeded* pReq = new ModuleSizeExceeded( aNames );
+ uno::Reference< task::XInteractionRequest > xReq( pReq );
+ xHandler->handle( xReq );
+ if ( pReq->isAbort() )
+ throw util::VetoException();
+ }
+ }
+
+ StarBASIC* pBasicLib = pBasicMgr->GetLib( aName );
+ if( !pBasicLib )
+ return sal_False;
+
+ Sequence< OUString > aElementNames = pLib->getElementNames();
+ sal_Int32 nNameCount = aElementNames.getLength();
+ const OUString* pNames = aElementNames.getConstArray();
+
+ sal_Bool bLink = pLib->mbLink;
+ sal_Bool bStorage = xStorage.is() && !bLink;
+ if( bStorage )
+ {
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aElementName = pNames[ i ];
+
+ // Write binary image stream
+ SbModule* pMod = pBasicLib->FindModule( aElementName );
+ if( pMod )
+ {
+ //OUString aCodeStreamName( RTL_CONSTASCII_USTRINGPARAM("code.bin") );
+ OUString aCodeStreamName = aElementName;
+ aCodeStreamName += String( RTL_CONSTASCII_USTRINGPARAM(".bin") );
+
+ try {
+ uno::Reference< io::XStream > xCodeStream = xStorage->openStreamElement(
+ aCodeStreamName,
+ embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
+
+ if ( !xCodeStream.is() )
+ throw uno::RuntimeException();
+
+ SvMemoryStream aMemStream;
+ /*BOOL bStore = */pMod->StoreBinaryData( aMemStream );
+
+ sal_Int32 nSize = (sal_Int32)aMemStream.Tell();
+ Sequence< sal_Int8 > aBinSeq( nSize );
+ sal_Int8* pData = aBinSeq.getArray();
+ ::rtl_copyMemory( pData, aMemStream.GetData(), nSize );
+
+ Reference< XOutputStream > xOut = xCodeStream->getOutputStream();
+ if ( !xOut.is() )
+ throw io::IOException(); // access denied because the stream is readonly
+
+ xOut->writeBytes( aBinSeq );
+ xOut->closeOutput();
+ }
+ catch( uno::Exception& )
+ {
+ // TODO: handle error
+ }
+ }
+
+ if( pLib->mbPasswordVerified || pLib->mbDoc50Password )
+ {
+ /*Any aElement = pLib->getByName( aElementName );*/
+ if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
+ {
+ #if OSL_DEBUG_LEVEL > 0
+ ::rtl::OStringBuffer aMessage;
+ aMessage.append( "invalid library element '" );
+ aMessage.append( ::rtl::OUStringToOString( aElementName, osl_getThreadTextEncoding() ) );
+ aMessage.append( "'." );
+ OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
+ #endif
+ continue;
+ }
+
+ OUString aSourceStreamName = aElementName;
+ aSourceStreamName += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
+
+ try {
+ uno::Reference< io::XStream > xSourceStream = xStorage->openStreamElement(
+ aSourceStreamName,
+ embed::ElementModes::READWRITE );
+ uno::Reference< beans::XPropertySet > xProps( xSourceStream, uno::UNO_QUERY );
+ if ( !xProps.is() )
+ throw uno::RuntimeException();
+
+ String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
+ OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
+ xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
+
+ // Set encryption key
+ setStreamKey( xSourceStream, pLib->maPassword );
+
+ Reference< XOutputStream > xOutput = xSourceStream->getOutputStream();
+ Reference< XNameContainer > xLib( pLib );
+ writeLibraryElement( xLib, aElementName, xOutput );
+ // writeLibraryElement should have the stream already closed
+ // xOutput->closeOutput();
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Problem on storing of password library!\n" );
+ // TODO: error handling
+ }
+ }
+ else // !mbPasswordVerified
+ {
+ // TODO
+ // What to do if not verified?! In any case it's already loaded here
+ }
+ }
+
+ }
+ // Application libraries have only to be saved if the password
+ // is verified because otherwise they can't be modified
+ else if( pLib->mbPasswordVerified || bExport )
+ {
+ try
+ {
+ Reference< XSimpleFileAccess > xSFI = mxSFI;
+ if( xToUseSFI.is() )
+ xSFI = xToUseSFI;
+
+ OUString aLibDirPath;
+ if( bExport )
+ {
+ INetURLObject aInetObj( aTargetURL );
+ aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if( !xSFI->isFolder( aLibDirPath ) )
+ xSFI->createFolder( aLibDirPath );
+ }
+ else
+ {
+ aLibDirPath = createAppLibraryFolder( pLib, aName );
+ }
+
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aElementName = pNames[ i ];
+
+ INetURLObject aElementInetObj( aLibDirPath );
+ aElementInetObj.insertName( aElementName, sal_False,
+ INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aElementInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("pba") ) );
+ String aElementPath = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ /*Any aElement = pLib->getByName( aElementName );*/
+ if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
+ {
+ #if OSL_DEBUG_LEVEL > 0
+ ::rtl::OStringBuffer aMessage;
+ aMessage.append( "invalid library element '" );
+ aMessage.append( ::rtl::OUStringToOString( aElementName, osl_getThreadTextEncoding() ) );
+ aMessage.append( "'." );
+ OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
+ #endif
+ continue;
+ }
+
+ try
+ {
+ uno::Reference< embed::XStorage > xElementRootStorage =
+ ::comphelper::OStorageHelper::GetStorageFromURL(
+ aElementPath,
+ embed::ElementModes::READWRITE );
+ if ( !xElementRootStorage.is() )
+ throw uno::RuntimeException();
+
+ // Write binary image stream
+ SbModule* pMod = pBasicLib->FindModule( aElementName );
+ if( pMod )
+ {
+ OUString aCodeStreamName( RTL_CONSTASCII_USTRINGPARAM("code.bin") );
+
+ uno::Reference< io::XStream > xCodeStream = xElementRootStorage->openStreamElement(
+ aCodeStreamName,
+ embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE );
+
+ SvMemoryStream aMemStream;
+ /*BOOL bStore = */pMod->StoreBinaryData( aMemStream );
+
+ sal_Int32 nSize = (sal_Int32)aMemStream.Tell();
+ Sequence< sal_Int8 > aBinSeq( nSize );
+ sal_Int8* pData = aBinSeq.getArray();
+ ::rtl_copyMemory( pData, aMemStream.GetData(), nSize );
+
+ Reference< XOutputStream > xOut = xCodeStream->getOutputStream();
+ if ( xOut.is() )
+ {
+ xOut->writeBytes( aBinSeq );
+ xOut->closeOutput();
+ }
+ }
+
+ // Write encrypted source stream
+ OUString aSourceStreamName( RTL_CONSTASCII_USTRINGPARAM("source.xml") );
+
+ uno::Reference< io::XStream > xSourceStream;
+ try
+ {
+ xSourceStream = xElementRootStorage->openStreamElement(
+ aSourceStreamName,
+ embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE );
+
+ // #87671 Allow encryption
+ uno::Reference< embed::XEncryptionProtectedSource > xEncr( xSourceStream, uno::UNO_QUERY );
+ OSL_ENSURE( xEncr.is(),
+ "StorageStream opened for writing must implement XEncryptionProtectedSource!\n" );
+ if ( !xEncr.is() )
+ throw uno::RuntimeException();
+ xEncr->setEncryptionPassword( pLib->maPassword );
+ }
+ catch( ::com::sun::star::packages::WrongPasswordException& )
+ {
+ xSourceStream = xElementRootStorage->openEncryptedStreamElement(
+ aSourceStreamName,
+ embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE,
+ pLib->maPassword );
+ }
+
+ uno::Reference< beans::XPropertySet > xProps( xSourceStream, uno::UNO_QUERY );
+ if ( !xProps.is() )
+ throw uno::RuntimeException();
+ String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
+ OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
+ xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
+
+ Reference< XOutputStream > xOut = xSourceStream->getOutputStream();
+ Reference< XNameContainer > xLib( pLib );
+ writeLibraryElement( xLib, aElementName, xOut );
+ // i50568: sax writer already closes stream
+ // xOut->closeOutput();
+
+ uno::Reference< embed::XTransactedObject > xTransact( xElementRootStorage, uno::UNO_QUERY );
+ OSL_ENSURE( xTransact.is(), "The storage must implement XTransactedObject!\n" );
+ if ( !xTransact.is() )
+ throw uno::RuntimeException();
+
+ xTransact->commit();
+ }
+ catch( uno::Exception& )
+ {
+ // TODO: handle error
+ }
+
+ // Storage Dtor commits too, that makes problems
+ // xElementRootStorage->Commit();
+ }
+ }
+ catch( Exception& )
+ {
+ //throw e;
+ }
+ }
+ return sal_True;
+}
+
+sal_Bool SfxScriptLibraryContainer::implLoadPasswordLibrary
+ ( SfxLibrary* pLib, const OUString& Name, sal_Bool bVerifyPasswordOnly )
+ throw(WrappedTargetException, RuntimeException)
+{
+ sal_Bool bRet = sal_True;
+
+ sal_Bool bLink = pLib->mbLink;
+ sal_Bool bStorage = mxStorage.is() && !bLink;
+
+ // Already loaded? Then only verifiedPassword can change something
+ SfxScriptLibrary* pScriptLib = static_cast< SfxScriptLibrary* >( pLib );
+ if( pScriptLib->mbLoaded )
+ {
+ if( pScriptLib->mbLoadedBinary && !bVerifyPasswordOnly &&
+ (pScriptLib->mbLoadedSource || !pLib->mbPasswordVerified) )
+ return sal_False;
+ }
+
+ StarBASIC* pBasicLib = NULL;
+ sal_Bool bLoadBinary = sal_False;
+ if( !pScriptLib->mbLoadedBinary && !bVerifyPasswordOnly && !pLib->mbPasswordVerified )
+ {
+ BasicManager* pBasicMgr = getBasicManager();
+ OSL_ENSURE( pBasicMgr, "SfxScriptLibraryContainer::implLoadPasswordLibrary: cannot do this without a BasicManager!" );
+ sal_Bool bLoaded = pScriptLib->mbLoaded;
+ pScriptLib->mbLoaded = sal_True; // Necessary to get lib
+ pBasicLib = pBasicMgr ? pBasicMgr->GetLib( Name ) : NULL;
+ pScriptLib->mbLoaded = bLoaded; // Restore flag
+ if( !pBasicLib )
+ return sal_False;
+
+ bLoadBinary = sal_True;
+ pScriptLib->mbLoadedBinary = sal_True;
+ }
+
+ sal_Bool bLoadSource = sal_False;
+ if( !pScriptLib->mbLoadedSource && pLib->mbPasswordVerified && !bVerifyPasswordOnly )
+ {
+ bLoadSource = sal_True;
+ pScriptLib->mbLoadedSource = sal_True;
+ }
+
+ Sequence< OUString > aElementNames = pLib->getElementNames();
+ sal_Int32 nNameCount = aElementNames.getLength();
+ const OUString* pNames = aElementNames.getConstArray();
+
+ if( bStorage )
+ {
+ uno::Reference< embed::XStorage > xLibrariesStor;
+ uno::Reference< embed::XStorage > xLibraryStor;
+ if( bStorage )
+ {
+ try {
+ xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
+ if ( !xLibrariesStor.is() )
+ throw uno::RuntimeException();
+
+ xLibraryStor = xLibrariesStor->openStorageElement( Name, embed::ElementModes::READ );
+ if ( !xLibraryStor.is() )
+ throw uno::RuntimeException();
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( 0, "### couln't open sub storage for library\n" );
+ return sal_False;
+ }
+ }
+
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aElementName = pNames[ i ];
+
+ // Load binary
+ if( bLoadBinary )
+ {
+ SbModule* pMod = pBasicLib->FindModule( aElementName );
+ if( !pMod )
+ {
+ pMod = pBasicLib->MakeModule( aElementName, String() );
+ pBasicLib->SetModified( FALSE );
+ }
+
+ //OUString aCodeStreamName( RTL_CONSTASCII_USTRINGPARAM("code.bin") );
+ OUString aCodeStreamName= aElementName;
+ aCodeStreamName += String( RTL_CONSTASCII_USTRINGPARAM(".bin") );
+
+ try {
+ uno::Reference< io::XStream > xCodeStream = xLibraryStor->openStreamElement(
+ aCodeStreamName,
+ embed::ElementModes::READ );
+ if ( !xCodeStream.is() )
+ throw uno::RuntimeException();
+
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xCodeStream );
+ if ( !pStream || pStream->GetError() )
+ {
+ sal_Int32 nError = pStream ? pStream->GetError() : ERRCODE_IO_GENERAL;
+ delete pStream;
+ throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), nError );
+ }
+
+ /*BOOL bRet = */pMod->LoadBinaryData( *pStream );
+ // TODO: Check return value
+
+ delete pStream;
+ }
+ catch( uno::Exception& )
+ {
+ // TODO: error handling
+ }
+ }
+
+ // Load source
+ if( bLoadSource || bVerifyPasswordOnly )
+ {
+ // Access encrypted source stream
+ OUString aSourceStreamName = aElementName;
+ aSourceStreamName += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
+
+ try {
+ uno::Reference< io::XStream > xSourceStream = xLibraryStor->openEncryptedStreamElement(
+ aSourceStreamName,
+ embed::ElementModes::READ,
+ pLib->maPassword );
+ if ( !xSourceStream.is() )
+ throw uno::RuntimeException();
+
+ // if this point is reached then the password is correct
+ if ( !bVerifyPasswordOnly )
+ {
+ uno::Reference< io::XInputStream > xInStream = xSourceStream->getInputStream();
+ if ( !xInStream.is() )
+ throw io::IOException(); // read access denied, seems to be impossible
+
+ Reference< XNameContainer > xLib( pLib );
+ Any aAny = importLibraryElement( xLib,
+ aElementName, aSourceStreamName,
+ xInStream );
+ if( pLib->hasByName( aElementName ) )
+ {
+ if( aAny.hasValue() )
+ pLib->maNameContainer.replaceByName( aElementName, aAny );
+ }
+ else
+ {
+ pLib->maNameContainer.insertByName( aElementName, aAny );
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ bRet = sal_False;
+ }
+ }
+ }
+ }
+ else
+ {
+ try
+ {
+ OUString aLibDirPath = createAppLibraryFolder( pLib, Name );
+
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aElementName = pNames[ i ];
+
+ INetURLObject aElementInetObj( aLibDirPath );
+ aElementInetObj.insertName( aElementName, sal_False,
+ INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aElementInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("pba") ) );
+ String aElementPath = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ uno::Reference< embed::XStorage > xElementRootStorage;
+ try {
+ xElementRootStorage = ::comphelper::OStorageHelper::GetStorageFromURL(
+ aElementPath,
+ embed::ElementModes::READ );
+ } catch( uno::Exception& )
+ {
+ // TODO: error handling
+ }
+
+ if ( xElementRootStorage.is() )
+ {
+ // Load binary
+ if( bLoadBinary )
+ {
+ SbModule* pMod = pBasicLib->FindModule( aElementName );
+ if( !pMod )
+ {
+ pMod = pBasicLib->MakeModule( aElementName, String() );
+ pBasicLib->SetModified( FALSE );
+ }
+
+ try {
+ OUString aCodeStreamName( RTL_CONSTASCII_USTRINGPARAM("code.bin") );
+ uno::Reference< io::XStream > xCodeStream = xElementRootStorage->openStreamElement(
+ aCodeStreamName,
+ embed::ElementModes::READ );
+
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xCodeStream );
+ if ( !pStream || pStream->GetError() )
+ {
+ sal_Int32 nError = pStream ? pStream->GetError() : ERRCODE_IO_GENERAL;
+ delete pStream;
+ throw task::ErrorCodeIOException( ::rtl::OUString(),
+ uno::Reference< uno::XInterface >(),
+ nError );
+ }
+
+ /*BOOL bRet = */pMod->LoadBinaryData( *pStream );
+ // TODO: Check return value
+
+ delete pStream;
+ }
+ catch( uno::Exception& )
+ {
+ // TODO: error handling
+ }
+ }
+
+ // Load source
+ if( bLoadSource || bVerifyPasswordOnly )
+ {
+ // Access encrypted source stream
+ OUString aSourceStreamName( RTL_CONSTASCII_USTRINGPARAM("source.xml") );
+ try {
+ uno::Reference< io::XStream > xSourceStream = xElementRootStorage->openEncryptedStreamElement(
+ aSourceStreamName,
+ embed::ElementModes::READ,
+ pLib->maPassword );
+ if ( !xSourceStream.is() )
+ throw uno::RuntimeException();
+
+ if ( !bVerifyPasswordOnly )
+ {
+ uno::Reference< io::XInputStream > xInStream = xSourceStream->getInputStream();
+ if ( !xInStream.is() )
+ throw io::IOException(); // read access denied, seems to be impossible
+
+ Reference< XNameContainer > xLib( pLib );
+ Any aAny = importLibraryElement( xLib,
+ aElementName,
+ aSourceStreamName,
+ xInStream );
+ if( pLib->hasByName( aElementName ) )
+ {
+ if( aAny.hasValue() )
+ pLib->maNameContainer.replaceByName( aElementName, aAny );
+ }
+ else
+ {
+ pLib->maNameContainer.insertByName( aElementName, aAny );
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ bRet = sal_False;
+ }
+ }
+ }
+ }
+
+ }
+ catch( Exception& )
+ {
+ // TODO
+ //throw e;
+ }
+ }
+
+//REMOVE // If the password is verified the library must remain modified, because
+//REMOVE // otherwise for saving the storage would be copied and that doesn't work
+//REMOVE // with mtg's storages when the password is verified
+//REMOVE if( !pLib->mbPasswordVerified )
+//REMOVE pLib->mbModified = sal_False;
+ return bRet;
+}
+
+
+void SfxScriptLibraryContainer::onNewRootStorage()
+{
+}
+
+//============================================================================
+// Service
+void createRegistryInfo_SfxScriptLibraryContainer()
+{
+ static OAutoRegistration< SfxScriptLibraryContainer > aAutoRegistration;
+}
+
+::rtl::OUString SAL_CALL SfxScriptLibraryContainer::getImplementationName( ) throw (RuntimeException)
+{
+ return getImplementationName_static();
+}
+
+Sequence< ::rtl::OUString > SAL_CALL SfxScriptLibraryContainer::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ return getSupportedServiceNames_static();
+}
+
+Sequence< OUString > SfxScriptLibraryContainer::getSupportedServiceNames_static()
+{
+ Sequence< OUString > aServiceNames( 2 );
+ aServiceNames[0] = OUString::createFromAscii( "com.sun.star.script.DocumentScriptLibraryContainer" );
+ // plus, for compatibility:
+ aServiceNames[1] = OUString::createFromAscii( "com.sun.star.script.ScriptLibraryContainer" );
+ return aServiceNames;
+}
+
+OUString SfxScriptLibraryContainer::getImplementationName_static()
+{
+ static OUString aImplName;
+ static sal_Bool bNeedsInit = sal_True;
+
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if( bNeedsInit )
+ {
+ aImplName = OUString::createFromAscii( "com.sun.star.comp.sfx2.ScriptLibraryContainer" );
+ bNeedsInit = sal_False;
+ }
+ return aImplName;
+}
+
+Reference< XInterface > SAL_CALL SfxScriptLibraryContainer::Create
+ ( const Reference< XComponentContext >& )
+ throw( Exception )
+{
+ Reference< XInterface > xRet =
+ static_cast< XInterface* >( static_cast< OWeakObject* >(new SfxScriptLibraryContainer()) );
+ return xRet;
+}
+
+//============================================================================
+// Implementation class SfxScriptLibrary
+
+// Ctor
+SfxScriptLibrary::SfxScriptLibrary( ModifiableHelper& _rModifiable,
+ const Reference< XMultiServiceFactory >& xMSF,
+ const Reference< XSimpleFileAccess >& xSFI )
+ : SfxLibrary( _rModifiable, getCppuType( (const OUString *)0 ), xMSF, xSFI )
+ , mbLoadedSource( sal_False )
+ , mbLoadedBinary( sal_False )
+{
+}
+
+SfxScriptLibrary::SfxScriptLibrary( ModifiableHelper& _rModifiable,
+ const Reference< XMultiServiceFactory >& xMSF,
+ const Reference< XSimpleFileAccess >& xSFI,
+ const OUString& aLibInfoFileURL,
+ const OUString& aStorageURL,
+ sal_Bool ReadOnly )
+ : SfxLibrary( _rModifiable, getCppuType( (const OUString *)0 ), xMSF, xSFI,
+ aLibInfoFileURL, aStorageURL, ReadOnly)
+ , mbLoadedSource( sal_False )
+ , mbLoadedBinary( sal_False )
+{
+}
+
+// Provide modify state including resources
+sal_Bool SfxScriptLibrary::isModified( void )
+{
+ return implIsModified(); // No resources
+}
+
+void SfxScriptLibrary::storeResources( void )
+{
+ // No resources
+}
+
+void SfxScriptLibrary::storeResourcesToURL( const ::rtl::OUString& URL,
+ const Reference< task::XInteractionHandler >& Handler )
+{
+ (void)URL;
+ (void)Handler;
+}
+
+void SfxScriptLibrary::storeResourcesAsURL
+ ( const ::rtl::OUString& URL, const ::rtl::OUString& NewName )
+{
+ (void)URL;
+ (void)NewName;
+}
+
+void SfxScriptLibrary::storeResourcesToStorage( const ::com::sun::star::uno::Reference
+ < ::com::sun::star::embed::XStorage >& xStorage )
+{
+ // No resources
+ (void)xStorage;
+}
+
+bool SfxScriptLibrary::containsValidModule( const Any& aElement )
+{
+ OUString sModuleText;
+ aElement >>= sModuleText;
+ return ( sModuleText.getLength() > 0 );
+}
+
+bool SAL_CALL SfxScriptLibrary::isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const
+{
+ return SfxScriptLibrary::containsValidModule( aElement );
+}
+
+IMPLEMENT_FORWARD_XINTERFACE2( SfxScriptLibrary, SfxLibrary, SfxScriptLibrary_BASE );
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( SfxScriptLibrary, SfxLibrary, SfxScriptLibrary_BASE );
+
+script::ModuleInfo SAL_CALL
+SfxScriptLibrary::getModuleInfo( const ::rtl::OUString& ModuleName ) throw (NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ if ( !hasModuleInfo( ModuleName ) )
+ throw NoSuchElementException();
+ return mModuleInfos[ ModuleName ];
+}
+
+sal_Bool SAL_CALL
+SfxScriptLibrary::hasModuleInfo( const ::rtl::OUString& ModuleName ) throw (RuntimeException)
+{
+ sal_Bool bRes = sal_False;
+ ModuleInfoMap::iterator it = mModuleInfos.find( ModuleName );
+
+ if ( it != mModuleInfos.end() )
+ bRes = sal_True;
+
+ return bRes;
+}
+
+void SAL_CALL SfxScriptLibrary::insertModuleInfo( const ::rtl::OUString& ModuleName, const script::ModuleInfo& ModuleInfo ) throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ if ( hasModuleInfo( ModuleName ) )
+ throw ElementExistException();
+ mModuleInfos[ ModuleName ] = ModuleInfo;
+}
+
+void SAL_CALL SfxScriptLibrary::removeModuleInfo( const ::rtl::OUString& ModuleName ) throw (NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ // #FIXME add NoSuchElementException to the spec
+ if ( !hasModuleInfo( ModuleName ) )
+ throw NoSuchElementException();
+ mModuleInfos.erase( mModuleInfos.find( ModuleName ) );
+}
+
+
+//============================================================================
+
+} // namespace basic
diff --git a/basic/util/makefile.mk b/basic/util/makefile.mk
new file mode 100644
index 000000000000..629586f0441c
--- /dev/null
+++ b/basic/util/makefile.mk
@@ -0,0 +1,146 @@
+#*************************************************************************
+#
+# 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=sb
+#basic.hid generieren
+GEN_HID=TRUE
+
+# --- Settings ---------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Allgemein ---------------------------------------------------
+
+LIB1TARGET=$(SLB)$/sb.lib
+LIB1FILES= \
+ $(SLB)$/basicmgr.lib \
+ $(SLB)$/classes.lib \
+ $(SLB)$/comp.lib \
+ $(SLB)$/uno.lib \
+ $(SLB)$/runtime.lib \
+ $(SLB)$/sbx.lib
+
+SHL1TARGET= sb$(DLLPOSTFIX)
+SHL1IMPLIB= basic
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(TOOLSLIB) \
+ $(SVTOOLLIB) \
+ $(SVLLIB) \
+ $(VCLLIB) \
+ $(VOSLIB) \
+ $(SALLIB) \
+ $(SALHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(SOTLIB) \
+ $(VOSLIB) \
+ $(XMLSCRIPTLIB)
+
+.IF "$(SOLAR_JAVA)" != "TRUE"
+SHL1STDLIBS+=$(SJLIB)
+.ENDIF
+
+.IF "$(GUI)"=="WNT"
+SHL1STDLIBS+= \
+ $(UWINAPILIB) \
+ $(OLEAUT32LIB)
+.ENDIF # WNT
+
+.IF "$(GUI)" != "UNX"
+.IF "$(COM)" != "GCC"
+SHL1OBJS= \
+ $(SLO)$/sb.obj
+.ENDIF
+.ENDIF
+
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1LIBS= $(SLB)$/sb.lib
+
+DEF1NAME =$(SHL1TARGET)
+DEF1DEPN = \
+ $(MISC)$/$(SHL1TARGET).flt
+
+DEFLIB1NAME =sb
+DEF1DES =StarBasic
+
+
+RES1TARGET=$(PRJNAME)
+SRS1FILES= \
+ $(SRS)$/classes.srs \
+ $(SRS)$/sbx.srs
+
+# --- TESTTOOL IDE ------------------------------------------------------
+# The resources are linked here
+
+RESLIB1NAME=stt
+RESLIB1IMAGES=$(PRJ)$/res
+RESLIB1SRSFILES= \
+ $(SRS)$/app.srs
+
+RESLIB2NAME=sb
+RESLIB2IMAGES=$(PRJ)$/res
+RESLIB2SRSFILES= \
+ $(SRS)$/classes.srs \
+ $(SRS)$/sbx.srs
+########## remove sbx.srx (and this line) when issue i53795 is fixed
+
+# --- Targets -----------------------------------------------------------
+
+.INCLUDE : target.mk
+
+#-------------------------------------------------------------------------
+# Windows NT
+#-------------------------------------------------------------------------
+#
+# default targets aus target.mk
+#
+
+# --- Basic-Filter-Datei ---
+
+$(MISC)$/$(SHL1TARGET).flt: makefile.mk
+ @echo ------------------------------
+ @echo Making: $@
+ @echo WEP > $@
+ @echo LIBMAIN >> $@
+ @echo LibMain >> $@
+ @echo Sbi >> $@
+ @echo SvRTL >> $@
+ @echo SbRtl_ >> $@
+ @echo exception >> $@
+ @echo bad_alloc >> $@
+ @echo __CT >> $@
+
+$(SRS)$/basic.srs:
+ $(TYPE) $(SRS)$/classes.srs + $(SRS)$/runtime.srs + $(SRS)$/sbx.srs > $@
+
+
diff --git a/basic/win/res/basic.ico b/basic/win/res/basic.ico
new file mode 100644
index 000000000000..c453a0fa988f
--- /dev/null
+++ b/basic/win/res/basic.ico
Binary files differ
diff --git a/basic/win/res/testtool.ico b/basic/win/res/testtool.ico
new file mode 100644
index 000000000000..db880c8678a7
--- /dev/null
+++ b/basic/win/res/testtool.ico
Binary files differ
diff --git a/basic/win/res/work.ico b/basic/win/res/work.ico
new file mode 100644
index 000000000000..43e3b5b3df03
--- /dev/null
+++ b/basic/win/res/work.ico
Binary files differ
diff --git a/basic/workben/basmgr.src b/basic/workben/basmgr.src
new file mode 100644
index 000000000000..f89c719c2399
--- /dev/null
+++ b/basic/workben/basmgr.src
@@ -0,0 +1,31 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#pragma CHARSET_IBMPC
+
+String 300 {
+ Text = "Dummy";
+};
diff --git a/basic/workben/makefile.mk b/basic/workben/makefile.mk
new file mode 100644
index 000000000000..6ec2a9971b9e
--- /dev/null
+++ b/basic/workben/makefile.mk
@@ -0,0 +1,89 @@
+#*************************************************************************
+#
+# 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=miniapp
+TARGETTYPE=GUI
+
+# --- Settings ---------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- SBASIC IDE --------------------------------------------------------
+
+APP1TARGET=$(PRJNAME)app
+APP1STDLIBS= \
+ $(SALLIB) \
+ $(TOOLSLIB) \
+ $(UNOTOOLSLIB) \
+ $(SVTOOLLIB) \
+ $(SVLLIB) \
+ $(VCLLIB) \
+ $(COMPHELPERLIB) \
+ $(UCBHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SJLIB) \
+ $(SOTLIB) \
+ $(VOSLIB)
+
+#.IF "$(GUI)"=="WNT" || "$(COM)"=="GCC"
+#APP1STDLIBS+=$(CPPULIB)
+#.ENDIF
+#.IF "$(GUI)"=="UNX"
+#APP1STDLIBS+= \
+# $(VOSLIB) \
+# $(SALLIB)
+#.ENDIF
+
+.IF "$(GUI)"!="OS2"
+APP1LIBS= \
+ $(LB)$/basic.lib
+.ENDIF
+APP1LIBS+= \
+ $(LB)$/app.lib \
+ $(LB)$/sample.lib
+.IF "$(GUI)"=="UNX" || "$(GUI)"=="OS2"
+APP1STDLIBS+= \
+ $(BASICLIB)
+.ENDIF
+
+
+APP1DEPN= $(L)$/itools.lib $(SVLIBDEPEND) $(LB)$/basic.lib $(LB)$/app.lib $(LB)$/sample.lib
+
+APP1OBJS = $(OBJ)$/ttbasic.obj
+
+.IF "$(GUI)" != "UNX"
+APP1OBJS+= \
+ $(OBJ)$/app.obj \
+ $(SLO)$/sbintern.obj
+.ENDIF
+
+.INCLUDE : target.mk
+
diff --git a/basic/workben/mgrtest.cxx b/basic/workben/mgrtest.cxx
new file mode 100644
index 000000000000..c56506d7ae31
--- /dev/null
+++ b/basic/workben/mgrtest.cxx
@@ -0,0 +1,591 @@
+/*************************************************************************
+ *
+ * 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 <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/toolbox.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/sound.hxx>
+#include <basic/basmgr.hxx>
+#include <basic/sbx.hxx>
+#include <basic/sbmod.hxx>
+#include <basic/basrdll.hxx>
+
+//#include <sv.hxx>
+//#include <basic.hxx>
+//#include <sostor.hxx>
+
+// Defines for ToolBox-Id's
+#define TB_NEW 1
+#define TB_OPENSTORAGE 2
+#define TB_SAVESTORAGE 3
+#define TB_ORG 4
+#define TB_CREATELIB1 10
+#define TB_CREATELIB2 11
+#define TB_CREATELIB3 12
+#define TB_LOADLIB1 20
+#define TB_LOADLIB2 21
+#define TB_LOADLIB3 22
+#define TB_STORELIBX 30
+#define TB_UNLOADX 31
+#define TB_LOADX 32
+#define TB_EXECX 33
+#define TB_REMOVEX 34
+#define TB_REMOVEDELX 35
+
+#define TB_LIB0 40
+#define TB_LIB1 41
+#define TB_LIB2 42
+#define TB_LIB3 43
+
+const char* pLib1Str = "Lib1";
+const char* pLib2Str = "Lib2";
+const char* pLib3Str = "Lib3";
+
+// Test-Application
+class TestApp : public Application
+{
+public:
+ virtual void Main( void );
+ virtual void Main( int, char*[] );
+};
+
+// Test-Window with a ToolBox to choose a test from
+// and the typically used virtual methods
+class TestWindow : public WorkWindow
+{
+private:
+ ToolBox aToolBox;
+ BasicManager* pBasMgr;
+
+ void CheckError();
+ USHORT nLibX;
+ DECL_LINK( BasicErrorHdl, StarBASIC * );
+
+
+public:
+ TestWindow();
+ ~TestWindow();
+
+ virtual void Paint( const Rectangle& );
+ virtual void Resize();
+ virtual void KeyInput( const KeyEvent& rKeyEvt );
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+
+ DECL_LINK( TBSelect, ToolBox * );
+ void UpdateToolBox();
+ void ShowInfo();
+};
+
+TestWindow::~TestWindow()
+{
+}
+
+TestWindow::TestWindow() :
+ WorkWindow( NULL, WB_APP | WB_STDWORK | WB_3DLOOK | WB_CLIPCHILDREN ) ,
+ aToolBox( this, WinBits( WB_BORDER | WB_3DLOOK | WB_SCROLL | WB_LINESPACING ) )
+{
+ nLibX = 0;
+
+ aToolBox.SetButtonType( BUTTON_TEXT );
+ aToolBox.SetLineCount( 2 );
+ aToolBox.SetPosPixel( Point( 0, 0 ) );
+ aToolBox.SetSelectHdl( LINK( this, TestWindow, TBSelect ) );
+
+ Font aFont;
+ aFont.SetName( "Helv" );
+ aFont.SetSize( Size( 0, 6 ) );
+ aFont.SetPitch( PITCH_VARIABLE );
+ aFont.SetFamily( FAMILY_SWISS );
+ aFont.SetTransparent( TRUE );
+ aFont.SetAlign( ALIGN_TOP );
+ aToolBox.SetFont( aFont );
+ SetFont( aFont );
+
+ aToolBox.InsertItem( TB_NEW, "New" );
+ aToolBox.SetHelpText( TB_NEW, "New BasicManager" );
+ aToolBox.InsertItem( TB_OPENSTORAGE, "Load" );
+ aToolBox.SetHelpText( TB_OPENSTORAGE, "Load Storage D:\\MYSTORE.SVS" );
+ aToolBox.InsertItem( TB_SAVESTORAGE, "Save" );
+ aToolBox.SetHelpText( TB_SAVESTORAGE, "Save Storage D:\\MYSTORE.SVS" );
+
+ aToolBox.InsertSeparator();
+
+ aToolBox.InsertItem( TB_ORG, "Verwalten" );
+ aToolBox.SetHelpText( TB_ORG, "Libaries verwalten" );
+
+ aToolBox.InsertSeparator();
+
+ aToolBox.InsertItem( TB_LIB0, "0" );
+ aToolBox.SetHelpText( TB_LIB0, "Aktuelle Lib: STANDARD" );
+ aToolBox.InsertItem( TB_LIB1, "1" );
+ aToolBox.SetHelpText( TB_LIB1, "Aktuelle Lib: 1" );
+ aToolBox.InsertItem( TB_LIB2, "2" );
+ aToolBox.SetHelpText( TB_LIB2, "Aktuelle Lib: 2" );
+ aToolBox.InsertItem( TB_LIB3, "3" );
+ aToolBox.SetHelpText( TB_LIB3, "Aktuelle Lib: 3" );
+
+ aToolBox.InsertBreak();
+ aToolBox.InsertItem( TB_CREATELIB1, "CreateLib1" );
+ aToolBox.SetHelpText( TB_CREATELIB1, "Create Libary LIB1" );
+ aToolBox.InsertItem( TB_CREATELIB2, "CreateLib2" );
+ aToolBox.SetHelpText( TB_CREATELIB2, "Create Libary LIB2" );
+ aToolBox.InsertItem( TB_CREATELIB3, "CreateLib3" );
+ aToolBox.SetHelpText( TB_CREATELIB3, "Create Libary LIB3" );
+
+ aToolBox.InsertSeparator();
+ aToolBox.InsertItem( TB_LOADLIB1, "LoadLib1" );
+ aToolBox.SetHelpText( TB_LOADLIB1, "Load Libary LIB1" );
+ aToolBox.InsertItem( TB_LOADLIB2, "LoadLib2" );
+ aToolBox.SetHelpText( TB_LOADLIB2, "Load Libary LIB2" );
+ aToolBox.InsertItem( TB_LOADLIB3, "LoadLib3" );
+ aToolBox.SetHelpText( TB_LOADLIB3, "Load Libary LIB3" );
+
+ aToolBox.InsertSeparator();
+ aToolBox.InsertItem( TB_STORELIBX, "StoreLibX" );
+ aToolBox.SetHelpText( TB_STORELIBX, "Store Libary LIBX" );
+ aToolBox.InsertItem( TB_UNLOADX, "UnloadX" );
+ aToolBox.SetHelpText( TB_UNLOADX, "Unload Libary LIBX" );
+ aToolBox.InsertItem( TB_LOADX, "LoadX" );
+ aToolBox.SetHelpText( TB_LOADX, "Load Libary LIBX" );
+ aToolBox.InsertItem( TB_EXECX, "ExecX" );
+ aToolBox.SetHelpText( TB_EXECX, "Execute 'Libary' LIBX" );
+ aToolBox.InsertItem( TB_REMOVEX, "RemoveX" );
+ aToolBox.SetHelpText( TB_REMOVEX, "Remove Libary LIBX" );
+ aToolBox.InsertItem( TB_REMOVEDELX, "RemDelX" );
+ aToolBox.SetHelpText( TB_REMOVEDELX, "Remove and delete Libary LIBX" );
+
+ pBasMgr = 0;
+
+ Show();
+ UpdateToolBox();
+ aToolBox.Show();
+}
+void TestWindow::ShowInfo()
+{
+ Invalidate();
+ Update();
+ long nH = GetTextSize( "X" ).Height();
+ if ( pBasMgr )
+ {
+ Point aPos( 10, aToolBox.GetSizePixel().Height()+5 );
+ for ( USHORT nLib = 0; nLib < pBasMgr->GetLibCount(); nLib++ )
+ {
+ String aOutStr( nLib );
+ aOutStr +=": ";
+ StarBASIC* pL = pBasMgr->GetLib( nLib );
+ aOutStr += '[';
+ aOutStr += pBasMgr->GetLibName( nLib );
+ aOutStr += "]<";
+ if ( pL )
+ aOutStr += pL->GetName();
+ else
+ aOutStr += "NoLoaded";
+ aOutStr += ">, Storage='";
+ aOutStr += pBasMgr->GetLibStorageName( nLib );
+ aOutStr += "', bLoaded=";
+ aOutStr += (USHORT)pBasMgr->IsLibLoaded( nLib );
+ DrawText( aPos, aOutStr );
+ aPos.Y() += nH;
+ }
+ }
+}
+
+void TestWindow::UpdateToolBox()
+{
+ // View of some buttons as checked or disabled if
+ // wished by tests
+ aToolBox.EnableItem( TB_ORG, (BOOL)(ULONG)pBasMgr );
+
+ aToolBox.EnableItem( TB_CREATELIB1, (BOOL)(ULONG)pBasMgr );
+ aToolBox.EnableItem( TB_CREATELIB2, (BOOL)(ULONG)pBasMgr );
+ aToolBox.EnableItem( TB_CREATELIB3, (BOOL)(ULONG)pBasMgr );
+
+ aToolBox.EnableItem( TB_LOADLIB1, (BOOL)(ULONG)pBasMgr );
+ aToolBox.EnableItem( TB_LOADLIB2, (BOOL)(ULONG)pBasMgr );
+ aToolBox.EnableItem( TB_LOADLIB3, (BOOL)(ULONG)pBasMgr );
+
+ aToolBox.EnableItem( TB_STORELIBX, (BOOL)(ULONG)pBasMgr );
+ aToolBox.EnableItem( TB_EXECX, (BOOL)(ULONG)pBasMgr );
+ aToolBox.EnableItem( TB_UNLOADX, (BOOL)(ULONG)pBasMgr );
+ aToolBox.EnableItem( TB_LOADX, (BOOL)(ULONG)pBasMgr );
+ aToolBox.EnableItem( TB_REMOVEX, (BOOL)(ULONG)pBasMgr );
+ aToolBox.EnableItem( TB_REMOVEDELX, (BOOL)(ULONG)pBasMgr );
+
+ aToolBox.CheckItem( TB_LIB0, nLibX == 0 );
+ aToolBox.CheckItem( TB_LIB1, nLibX == 1 );
+ aToolBox.CheckItem( TB_LIB2, nLibX == 2 );
+ aToolBox.CheckItem( TB_LIB3, nLibX == 3 );
+}
+
+IMPL_LINK( TestWindow, TBSelect, ToolBox *, p )
+{
+ USHORT nId = aToolBox.GetCurItemId();
+ BOOL bChecked = aToolBox.IsItemChecked( nId );
+ switch ( nId )
+ {
+ case TB_NEW:
+ {
+ delete pBasMgr;
+ pBasMgr = new BasicManager( new StarBASIC );
+ pBasMgr->SetStorageName( "d:\\mystore.svs" );
+ }
+ break;
+ case TB_OPENSTORAGE:
+ {
+ delete pBasMgr;
+ SvStorageRef xStorage = new SvStorage( "d:\\mystore.svs", STREAM_READ | STREAM_SHARE_DENYWRITE );
+ DBG_ASSERT( xStorage.Is(), "Kein Storage!" );
+ pBasMgr = new BasicManager( *xStorage );
+ }
+ break;
+ case TB_SAVESTORAGE:
+ {
+ if ( pBasMgr)
+ {
+ SvStorageRef xStorage = new SvStorage( "d:\\mystore.svs" );
+ DBG_ASSERT( xStorage.Is(), "Kein Storage!" );
+ pBasMgr->Store( *xStorage );
+ }
+ }
+ break;
+ case TB_ORG:
+ {
+ if ( pBasMgr)
+ {
+ InfoBox( 0, "Organisieren..." ).Execute();
+ }
+ }
+ break;
+ case TB_CREATELIB1:
+ {
+ if ( pBasMgr )
+ {
+ USHORT nLib = pBasMgr->GetLibId( pBasMgr->CreateLib( pLib1Str ) );
+ if ( nLib != LIB_NOTFOUND )
+ {
+ pBasMgr->SetLibStorageName( nLib, "d:\\mystore.svs" );
+ StarBASIC* pLib = pBasMgr->GetLib( pLib1Str );
+ DBG_ASSERT( pLib, "Lib?!" );
+ String aSource( "Sub SubInLib1Mod1\nprint\"XXX\"\nEnd Sub");
+ SbModule* pM = pLib->MakeModule( "ModLib1", aSource );
+ DBG_ASSERT( pM, "Modul?" );
+ pLib->Compile( pM );
+ }
+ else
+ InfoBox( 0, "CreateLibary fehlgeschlagen..." ).Execute();
+ }
+ }
+ break;
+ case TB_CREATELIB2:
+ {
+ if ( pBasMgr )
+ {
+ USHORT nLib = pBasMgr->GetLibId( pBasMgr->CreateLib( pLib2Str ) );
+ if ( nLib != LIB_NOTFOUND )
+ {
+ pBasMgr->SetLibStorageName( nLib, "d:\\mystore.svs" );
+ StarBASIC* pLib = pBasMgr->GetLib( pLib2Str );
+ DBG_ASSERT( pLib, "Lib?!" );
+ SbModule* pM = pLib->MakeModule( "ModuleLib2", "Sub SubInLib2\n print \"Tralala\" \nEnd Sub\n" );
+ pLib->Compile( pM );
+ }
+ else
+ InfoBox( 0, "CreateLibary fehlgeschlagen..." ).Execute();
+ }
+ }
+ break;
+ case TB_CREATELIB3:
+ {
+ if ( pBasMgr )
+ {
+ // liegt in einem anderen Storage !!!
+ USHORT nLib = pBasMgr->GetLibId( pBasMgr->CreateLib( pLib3Str ) );
+ if ( nLib != LIB_NOTFOUND )
+ {
+ pBasMgr->SetLibStorageName( nLib, "d:\\mystore2.svs" );
+ StarBASIC* pLib = pBasMgr->GetLib( pLib3Str );
+ DBG_ASSERT( pLib, "Lib?!" );
+ SbModule* pM = pLib->MakeModule( "ModuleLib2", "Sub XYZInLib3\n print \"?!\" \nEnd Sub\n" );
+ pLib->Compile( pM );
+ }
+ else
+ InfoBox( 0, "CreateLibary fehlgeschlagen..." ).Execute();
+ }
+ }
+ break;
+ case TB_LOADLIB1:
+ {
+ if ( pBasMgr )
+ {
+ SvStorageRef xStorage = new SvStorage( "d:\\mystore.svs" );
+ if ( !pBasMgr->AddLib( *xStorage, pLib1Str, FALSE ) )
+ Sound::Beep();
+ }
+ }
+ break;
+ case TB_LOADLIB2:
+ {
+ if ( pBasMgr )
+ {
+ SvStorageRef xStorage = new SvStorage( "d:\\mystore.svs" );
+ if ( !pBasMgr->AddLib( *xStorage, pLib2Str, FALSE ) )
+ Sound::Beep();
+ }
+ }
+ break;
+ case TB_LOADLIB3:
+ {
+ if ( pBasMgr )
+ {
+ // liegt in einem anderen Storage !!!
+ SvStorageRef xStorage = new SvStorage( "d:\\mystore2.svs" );
+ if ( !pBasMgr->AddLib( *xStorage, pLib3Str, FALSE ) )
+ Sound::Beep();
+ }
+ }
+ break;
+ case TB_STORELIBX:
+ {
+ if ( pBasMgr )
+ pBasMgr->StoreLib( nLibX );
+ }
+ break;
+ case TB_UNLOADX:
+ {
+ if ( pBasMgr )
+ pBasMgr->UnloadLib( nLibX );
+ }
+ break;
+ case TB_LOADX:
+ {
+ if ( pBasMgr )
+ pBasMgr->LoadLib( nLibX );
+ }
+ break;
+ case TB_REMOVEX:
+ {
+ if ( pBasMgr )
+ pBasMgr->RemoveLib( nLibX, FALSE );
+ }
+ break;
+ case TB_REMOVEDELX:
+ {
+ if ( pBasMgr )
+ pBasMgr->RemoveLib( nLibX, TRUE );
+ }
+ break;
+ case TB_EXECX:
+ {
+ if ( pBasMgr )
+ {
+ StarBASIC* pBasic = pBasMgr->GetLib( nLibX );
+ if ( pBasic && pBasic->GetModules()->Count() )
+ {
+ pBasic->SetErrorHdl( LINK( this, TestWindow, BasicErrorHdl ) );
+
+ SbModule* pMod = (SbModule*)pBasic->GetModules()->Get( 0 );
+ if ( pMod && pMod->GetMethods()->Count() )
+ pMod->GetMethods()->Get(0)->GetInteger();
+ }
+ }
+ }
+ break;
+
+ case TB_LIB0: nLibX = 0;
+ break;
+ case TB_LIB1: nLibX = 1;
+ break;
+ case TB_LIB2: nLibX = 2;
+ break;
+ case TB_LIB3: nLibX = 3;
+ break;
+ }
+
+ UpdateToolBox();
+ CheckError();
+ ShowInfo();
+ return 0;
+}
+
+void TestWindow::CheckError()
+{
+ if ( pBasMgr )
+ {
+ BasicError* pError = pBasMgr->GetFirstError();
+ while ( pError )
+ {
+ String aErrorStr;
+ String aReasonStr;
+ switch ( pError->GetErrorId() )
+ {
+ case BASERR_ID_STDLIBOPEN:
+ aErrorStr = "Standard-Lib konnte nicht geoffnet werden.";
+ break;
+ case BASERR_ID_STDLIBSAVE:
+ aErrorStr = "Standard-Lib konnte nicht gespeichert werden.";
+ break;
+ case BASERR_ID_LIBLOAD:
+ aErrorStr = "Lib konnte nicht geoffnet werden.";
+ break;
+ case BASERR_ID_LIBCREATE:
+ aErrorStr = "Lib konnte nicht erzeugt werden.";
+ break;
+ case BASERR_ID_LIBSAVE:
+ aErrorStr = "Lib konnte nicht gespeichert werden.";
+ break;
+ case BASERR_ID_MGROPEN:
+ aErrorStr = "Manager konnte nicht geladen werden.";
+ break;
+ case BASERR_ID_MGRSAVE:
+ aErrorStr = "Manager konnte nicht gespeichert werden.";
+ break;
+ case BASERR_ID_UNLOADLIB:
+ aErrorStr = "Libary konnte nicht entladen werden.";
+ break;
+ case BASERR_ID_REMOVELIB:
+ aErrorStr = "Libary konnte nicht entfernt werden.";
+ break;
+ default:
+ aErrorStr = "Unbekannter Fehler!";
+ }
+
+ switch ( pError->GetReason() )
+ {
+ case BASERR_REASON_OPENSTORAGE:
+ aReasonStr = "Der Storage konnte nicht geoeffnet werden";
+ break;
+ case BASERR_REASON_OPENLIBSTORAGE:
+ aReasonStr = "Der Lib-Storage konnte nicht geoeffnet werden";
+ break;
+ case BASERR_REASON_OPENMGRSTREAM:
+ aReasonStr = "Der Manager-Stream konnte nicht geoeffnet werden";
+ break;
+ case BASERR_REASON_OPENLIBSTREAM:
+ aReasonStr = "Der Basic-Stream konnte nicht geoeffnet werden";
+ break;
+ case BASERR_REASON_STDLIB:
+ aReasonStr = "STANDARD-Lib";
+ break;
+ case BASERR_REASON_BASICLOADERROR:
+ aReasonStr = "Fehler beim Laden des Basics";
+ default:
+ aReasonStr = " - ";
+ }
+
+ String aErr( aErrorStr );
+ aErr += "\nGrund: ";
+ aErr += aReasonStr;
+ InfoBox( 0, aErr ).Execute();
+
+ pError = pBasMgr->GetNextError();
+ }
+ pBasMgr->ClearErrors();
+ }
+}
+
+void __EXPORT TestWindow::Paint( const Rectangle& rRec )
+{
+}
+
+void __EXPORT TestWindow::Resize()
+{
+ Size aTBSz = aToolBox.CalcWindowSizePixel();
+ aToolBox.SetSizePixel( Size( GetOutputSizePixel().Width(), aTBSz.Height()) );
+ Invalidate();
+ ShowInfo();
+}
+
+void __EXPORT TestWindow::KeyInput( const KeyEvent& rKEvt )
+{
+ char nCharCode = rKEvt.GetCharCode();
+ USHORT nCode = rKEvt.GetKeyCode().GetCode();
+
+ // Nur bei Alt-Return
+ if ( ( nCode == KEY_RETURN ) && rKEvt.GetKeyCode().IsMod2() )
+ ;
+ else
+ WorkWindow::KeyInput( rKEvt );
+
+ UpdateToolBox();
+}
+
+void __EXPORT TestWindow::MouseMove( const MouseEvent& rMEvt )
+{
+}
+
+void __EXPORT TestWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ ShowInfo();
+}
+
+void __EXPORT TestWindow::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ UpdateToolBox();
+}
+
+IMPL_LINK( TestWindow, BasicErrorHdl, StarBASIC *, pBasic )
+{
+ String aErrorText( pBasic->GetErrorText() );
+
+ String aErrorTextPrefix;
+ if( pBasic->IsCompilerError() )
+ {
+ aErrorTextPrefix = "Compilererror: ";
+ }
+ else
+ {
+ aErrorTextPrefix = "Runtimeerror: ";
+ aErrorTextPrefix += pBasic->GetErrorCode();
+ aErrorTextPrefix += " ";
+ }
+
+ InfoBox( 0, String( aErrorTextPrefix + aErrorText ) ).Execute();
+ return 0;
+}
+
+void __EXPORT TestApp::Main( void )
+{
+ Main( 0, NULL );
+}
+
+void __EXPORT TestApp::Main( int, char*[] )
+{
+ BasicDLL aBasiDLL;
+ SvFactory::Init();
+ EnableSVLook();
+ TestWindow aWindow;
+ Execute();
+ SvFactory::DeInit();
+}
+
+
+TestApp aTestApp;