summaryrefslogtreecommitdiff
path: root/filter/source/msfilter/svxmsbas.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'filter/source/msfilter/svxmsbas.cxx')
-rw-r--r--filter/source/msfilter/svxmsbas.cxx406
1 files changed, 406 insertions, 0 deletions
diff --git a/filter/source/msfilter/svxmsbas.cxx b/filter/source/msfilter/svxmsbas.cxx
new file mode 100644
index 000000000000..02370dd75c92
--- /dev/null
+++ b/filter/source/msfilter/svxmsbas.cxx
@@ -0,0 +1,406 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: svxmsbas.cxx,v $
+ * $Revision: 1.24 $
+ *
+ * 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_filter.hxx"
+
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+#include <tools/debug.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/app.hxx>
+#include <basic/basmgr.hxx>
+#include <basic/sbmod.hxx>
+#include <svx/svxerr.hxx>
+#include <filter/msfilter/svxmsbas.hxx>
+#include <msvbasic.hxx>
+#include <filter/msfilter/msocximex.hxx>
+#include <sot/storinfo.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+using namespace com::sun::star::beans;
+using namespace com::sun::star::io;
+using namespace com::sun::star::awt;
+#include <comphelper/storagehelper.hxx>
+
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/script/XLibraryContainer.hpp>
+using namespace com::sun::star::container;
+using namespace com::sun::star::script;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star;
+
+using rtl::OUString;
+
+int SvxImportMSVBasic::Import( const String& rStorageName,
+ const String &rSubStorageName,
+ BOOL bAsComment, BOOL bStripped )
+{
+ int nRet = 0;
+ if( bImport && ImportCode_Impl( rStorageName, rSubStorageName,
+ bAsComment, bStripped ))
+ nRet |= 1;
+
+ if (bImport)
+ ImportForms_Impl(rStorageName, rSubStorageName);
+
+ if( bCopy && CopyStorage_Impl( rStorageName, rSubStorageName ))
+ nRet |= 2;
+
+ return nRet;
+}
+
+bool SvxImportMSVBasic::ImportForms_Impl(const String& rStorageName,
+ const String& rSubStorageName)
+{
+ SvStorageRef xVBAStg(xRoot->OpenSotStorage(rStorageName,
+ STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYALL));
+ if (!xVBAStg.Is() || xVBAStg->GetError())
+ return false;
+
+ std::vector<String> aUserForms;
+ SvStorageInfoList aContents;
+ xVBAStg->FillInfoList(&aContents);
+ for (USHORT nI = 0; nI < aContents.Count(); ++nI)
+ {
+ SvStorageInfo& rInfo = aContents.GetObject(nI);
+ if (!rInfo.IsStream() && rInfo.GetName() != rSubStorageName)
+ aUserForms.push_back(rInfo.GetName());
+ }
+
+ if (aUserForms.empty())
+ return false;
+
+ bool bRet = true;
+ SFX_APP()->EnterBasicCall();
+ try
+ {
+ Reference<XMultiServiceFactory> xSF(comphelper::getProcessServiceFactory());
+
+ Reference<XComponentContext> xContext;
+ Reference<XPropertySet> xProps(xSF, UNO_QUERY);
+ xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")) ) >>= xContext;
+
+
+ Reference<XLibraryContainer> xLibContainer = rDocSh.GetDialogContainer();
+ DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );
+
+ String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
+ Reference<XNameContainer> xLib;
+ if (xLibContainer.is())
+ {
+ if( !xLibContainer->hasByName(aLibName))
+ xLibContainer->createLibrary(aLibName);
+
+ Any aLibAny = xLibContainer->getByName( aLibName );
+ aLibAny >>= xLib;
+ }
+
+ if(xLib.is())
+ {
+ typedef std::vector<String>::iterator myIter;
+ myIter aEnd = aUserForms.end();
+ for (myIter aIter = aUserForms.begin(); aIter != aEnd; ++aIter)
+ {
+ SvStorageRef xForm (xVBAStg->OpenSotStorage(*aIter,
+ STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYALL));
+
+ if (!xForm.Is() || xForm->GetError())
+ continue;
+
+ SvStorageStreamRef xFrame = xForm->OpenSotStream(
+ String( RTL_CONSTASCII_USTRINGPARAM( "\3VBFrame" ) ),
+ STREAM_STD_READ | STREAM_NOCREATE);
+
+ if (!xFrame.Is() || xFrame->GetError())
+ continue;
+
+ SvStorageStreamRef xTypes = xForm->OpenSotStream(
+ String( 'f' ), STREAM_STD_READ | STREAM_NOCREATE);
+
+ if (!xTypes.Is() || xTypes->GetError())
+ continue;
+
+ //<UserForm Name=""><VBFrame></VBFrame>"
+ String sData;
+ String sLine;
+ while(xFrame->ReadByteStringLine(sLine, RTL_TEXTENCODING_MS_1252))
+ {
+ sData += sLine;
+ sData += '\n';
+ }
+ sData.ConvertLineEnd();
+
+ Reference<container::XNameContainer> xDialog(
+ xSF->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.awt.UnoControlDialogModel"))), uno::UNO_QUERY);
+
+ OCX_UserForm aForm(xVBAStg, *aIter, *aIter, xDialog, xSF );
+ aForm.pDocSh = &rDocSh;
+ sal_Bool bOk = aForm.Read(xTypes);
+ DBG_ASSERT(bOk, "Had unexpected content, not risking this module");
+ if (bOk)
+ aForm.Import(xLib);
+ }
+ }
+ }
+ catch(...)
+ {
+ DBG_ERRORFILE( "SvxImportMSVBasic::ImportForms_Impl - any exception caught" );
+ //bRet = false;
+ }
+ SFX_APP()->LeaveBasicCall();
+ return bRet;
+}
+
+
+BOOL SvxImportMSVBasic::CopyStorage_Impl( const String& rStorageName,
+ const String& rSubStorageName)
+{
+ BOOL bValidStg = FALSE;
+ {
+ SvStorageRef xVBAStg( xRoot->OpenSotStorage( rStorageName,
+ STREAM_READWRITE | STREAM_NOCREATE |
+ STREAM_SHARE_DENYALL ));
+ if( xVBAStg.Is() && !xVBAStg->GetError() )
+ {
+ SvStorageRef xVBASubStg( xVBAStg->OpenSotStorage( rSubStorageName,
+ STREAM_READWRITE | STREAM_NOCREATE |
+ STREAM_SHARE_DENYALL ));
+ if( xVBASubStg.Is() && !xVBASubStg->GetError() )
+ {
+ // then we will copy these storages into the (temporary) storage of the document
+ bValidStg = TRUE;
+ }
+ }
+ }
+
+ if( bValidStg )
+ {
+ String aDstStgName( GetMSBasicStorageName() );
+ SotStorageRef xDst = SotStorage::OpenOLEStorage( rDocSh.GetStorage(), aDstStgName, STREAM_READWRITE | STREAM_TRUNC );
+ SotStorageRef xSrc = xRoot->OpenSotStorage( rStorageName, STREAM_STD_READ );
+
+ // TODO/LATER: should we commit the storage?
+ xSrc->CopyTo( xDst );
+ xDst->Commit();
+ ErrCode nError = xDst->GetError();
+ if ( nError == ERRCODE_NONE )
+ nError = xSrc->GetError();
+ if ( nError != ERRCODE_NONE )
+ xRoot->SetError( nError );
+ else
+ bValidStg = TRUE;
+ }
+
+ return bValidStg;
+}
+
+BOOL SvxImportMSVBasic::ImportCode_Impl( const String& rStorageName,
+ const String &rSubStorageName,
+ BOOL bAsComment, BOOL bStripped )
+{
+ BOOL bRet = FALSE;
+ VBA_Impl aVBA( *xRoot, bAsComment );
+ if( aVBA.Open(rStorageName,rSubStorageName) )
+ {
+ SFX_APP()->EnterBasicCall();
+ Reference<XLibraryContainer> xLibContainer = rDocSh.GetBasicContainer();
+ DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );
+
+ UINT16 nStreamCount = aVBA.GetNoStreams();
+ Reference<XNameContainer> xLib;
+ if( xLibContainer.is() && nStreamCount )
+ {
+ String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
+ if( !xLibContainer->hasByName( aLibName ) )
+ xLibContainer->createLibrary( aLibName );
+
+ Any aLibAny = xLibContainer->getByName( aLibName );
+ aLibAny >>= xLib;
+ }
+ if( xLib.is() )
+ {
+ for( UINT16 i=0; i<nStreamCount;i++)
+ {
+ StringArray aDecompressed = aVBA.Decompress(i);
+#if 0
+/* DR 2005-08-11 #124850# Do not filter special characters from module name.
+ Just put the original module name and let the Basic interpreter deal with
+ it. Needed for roundtrip...
+ */
+ ByteString sByteBasic(aVBA.GetStreamName(i),
+ RTL_TEXTENCODING_ASCII_US,
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_UNDERLINE|
+ RTL_UNICODETOTEXT_FLAGS_INVALID_UNDERLINE |
+ RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 |
+ RTL_UNICODETOTEXT_FLAGS_NOCOMPOSITE)
+ );
+
+ const String sBasicModule(sByteBasic,
+ RTL_TEXTENCODING_ASCII_US);
+#else
+ const String &sBasicModule = aVBA.GetStreamName( i);
+#endif
+ /* #117718# expose information regarding type of Module
+ * Class, Form or plain 'ould VBA module with a REM statment
+ * at the top of the module. Mapping of Module Name
+ * to type is performed in VBA_Impl::Open() method,
+ * ( msvbasic.cxx ) by examining the PROJECT stream.
+ */
+
+ // using name from aVBA.GetStreamName
+ // because the encoding of the same returned
+ // is the same as the encoding for the names
+ // that are keys in the map used by GetModuleType method
+ const String &sOrigVBAModName = aVBA.GetStreamName( i );
+ ModuleType mType = aVBA.GetModuleType( sOrigVBAModName );
+
+ rtl::OUString sClassRem( RTL_CONSTASCII_USTRINGPARAM( "Rem Attribute VBA_ModuleType=" ) );
+
+ rtl::OUString modeTypeComment;
+
+ switch( mType )
+ {
+ case Class:
+ modeTypeComment = sClassRem +
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAClassModule\n" ) );
+ break;
+ case Form:
+ modeTypeComment = sClassRem +
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAFormModule\n" ) );
+ break;
+ case Document:
+ modeTypeComment = sClassRem +
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBADocumentModule\n" ) );
+ break;
+ case Normal:
+ modeTypeComment = sClassRem +
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAModule\n" ) );
+ break;
+ case Unknown:
+ modeTypeComment = sClassRem +
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAUnknown\n" ) );
+ break;
+ default:
+ DBG_ERRORFILE( "SvxImportMSVBasic::ImportCode_Impl - unknown module type" );
+ break;
+ }
+ static ::rtl::OUString sVBAOption( RTL_CONSTASCII_USTRINGPARAM( "Option VBASupport 1\n" ) );
+ static ::rtl::OUString sClassOption( RTL_CONSTASCII_USTRINGPARAM( "Option ClassModule\n" ) );
+ if ( !bAsComment )
+ {
+ modeTypeComment = modeTypeComment + sVBAOption;
+ if ( mType == Class )
+ modeTypeComment = modeTypeComment + sClassOption;
+
+ }
+
+ String sModule(sBasicModule); //#i52606# no need to split Macros in 64KB blocks any more!
+ String sTemp;
+ if (bAsComment)
+ {
+ sTemp+=String(RTL_CONSTASCII_USTRINGPARAM( "Sub " ));
+ String sMunge(sModule);
+ //Streams can have spaces in them, but modulenames
+ //cannot !
+ sMunge.SearchAndReplaceAll(' ','_');
+
+ sTemp += sMunge;
+ sTemp.AppendAscii("\n");
+ };
+ ::rtl::OUString aSource(sTemp);
+
+ for(ULONG j=0;j<aDecompressed.GetSize();j++)
+ {
+ if (bStripped)
+ {
+ String *pStr = aDecompressed.Get(j);
+ bool bMac = true;
+ xub_StrLen nBegin = pStr->Search('\x0D');
+ if ((STRING_NOTFOUND != nBegin) && (pStr->Len() > 1) && (pStr->GetChar(nBegin+1) == '\x0A'))
+ bMac = false;
+
+ const char cLineEnd = bMac ? '\x0D' : '\x0A';
+ const String sAttribute(String::CreateFromAscii(
+ bAsComment ? "Rem Attribute" : "Attribute"));
+ nBegin = 0;
+ while (STRING_NOTFOUND != (nBegin = pStr->Search(sAttribute, nBegin)))
+ {
+ if ((nBegin) && pStr->GetChar(nBegin-1) != cLineEnd)
+ {
+ // npower #i63766# Need to skip instances of Attribute
+ // that are NOT Attribute statements
+ nBegin = nBegin + sAttribute.Len();
+ continue;
+ }
+ xub_StrLen nEnd = pStr->Search(cLineEnd ,nBegin);
+ // DR #i26521# catch STRING_NOTFOUND, will loop endless otherwise
+ if( nEnd == STRING_NOTFOUND )
+ pStr->Erase();
+ else
+ pStr->Erase(nBegin, (nEnd-nBegin)+1);
+ }
+ }
+ if( aDecompressed.Get(j)->Len() )
+ {
+ aSource+=::rtl::OUString( *aDecompressed.Get(j) );
+ }
+
+ }
+ if (bAsComment)
+ {
+ aSource += rtl::OUString::createFromAscii("\nEnd Sub");
+ }
+ ::rtl::OUString aModName( sModule );
+ if ( aSource.getLength() )
+ {
+ aSource = modeTypeComment + aSource;
+
+ Any aSourceAny;
+ aSourceAny <<= aSource;
+ if( xLib->hasByName( aModName ) )
+ xLib->replaceByName( aModName, aSourceAny );
+ else
+ xLib->insertByName( aModName, aSourceAny );
+ }
+
+ bRet = true;
+ }
+ }
+ SFX_APP()->LeaveBasicCall();
+ }
+ return bRet;
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */