diff options
author | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2010-11-04 10:36:00 +0100 |
---|---|---|
committer | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2010-11-04 10:36:00 +0100 |
commit | ea516d858b5f6aa283dac136fe32f3226764c507 (patch) | |
tree | 4be2191875bc5120e29a8a69931dcdb2f1769411 | |
parent | 90286e004d462812d557738278dbd0b484a89f29 (diff) |
undoapi: attempt to fix broken Undo contexts after executing a script
-rw-r--r-- | basctl/source/basicide/basobj2.cxx | 236 | ||||
-rw-r--r-- | basctl/source/basicide/iderdll.cxx | 15 | ||||
-rw-r--r-- | basctl/source/basicide/iderdll2.hxx | 2 | ||||
-rw-r--r-- | basctl/util/makefile.mk | 1 |
4 files changed, 141 insertions, 113 deletions
diff --git a/basctl/source/basicide/basobj2.cxx b/basctl/source/basicide/basobj2.cxx index 8bb3fba16536..6744a7d24930 100644 --- a/basctl/source/basicide/basobj2.cxx +++ b/basctl/source/basicide/basobj2.cxx @@ -30,23 +30,29 @@ #include <ide_pch.hxx> -#include <vector> -#include <algorithm> -#include <basic/sbx.hxx> -#include <unotools/moduleoptions.hxx> +#include "basobj.hxx" +#include "iderdll.hxx" +#include "iderdll2.hxx" +#include "iderid.hxx" +#include "macrodlg.hxx" +#include "moduldlg.hxx" +#include "basidesh.hxx" +#include "basidesh.hrc" +#include "baside2.hxx" +#include "basicmod.hxx" +#include "basdoc.hxx" + #include <com/sun/star/document/XEmbeddedScripts.hpp> #include <com/sun/star/document/XScriptInvocationContext.hpp> -#include <basobj.hxx> -#include <iderdll.hxx> -#include <iderdll2.hxx> -#include <iderid.hxx> -#include <macrodlg.hxx> -#include <moduldlg.hxx> -#include <basidesh.hxx> -#include <basidesh.hrc> -#include <baside2.hxx> -#include <basicmod.hxx> -#include <basdoc.hxx> + +#include <basic/sbx.hxx> +#include <framework/documentundoguard.hxx> +#include <tools/diagnose_ex.h> +#include <unotools/moduleoptions.hxx> + +#include <vector> +#include <algorithm> +#include <memory> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -216,6 +222,50 @@ bool RenameModule( Window* pErrorParent, const ScriptDocument& rDocument, const return true; } + +//---------------------------------------------------------------------------- + +namespace +{ + struct MacroExecutionData + { + ScriptDocument aDocument; + SbMethodRef xMethod; + + MacroExecutionData() + :aDocument( ScriptDocument::NoDocument ) + ,xMethod( NULL ) + { + } + }; + + class MacroExecution + { + public: + DECL_STATIC_LINK( MacroExecution, ExecuteMacroEvent, MacroExecutionData* ); + }; + + + IMPL_STATIC_LINK( MacroExecution, ExecuteMacroEvent, MacroExecutionData*, i_pData ) + { + ENSURE_OR_RETURN( i_pData, "wrong MacroExecutionData", 0L ); + // take ownership of the data + ::std::auto_ptr< MacroExecutionData > pData( i_pData ); + + DBG_ASSERT( pData->xMethod->GetParent()->GetFlags() & SBX_EXTSEARCH, "Kein EXTSEARCH!" ); + + // in case this is a document-local macro, try to protect the document's Undo Manager from + // flawed scripts + ::std::auto_ptr< ::framework::DocumentUndoGuard > pUndoGuard; + if ( pData->aDocument.isDocument() ) + pUndoGuard.reset( new ::framework::DocumentUndoGuard( pData->aDocument.getDocument() ) ); + + BasicIDE::RunMethod( pData->xMethod ); + + return 1L; + } +} + //---------------------------------------------------------------------------- ::rtl::OUString ChooseMacro( const uno::Reference< frame::XModel >& rxLimitToDocument, BOOL bChooseOnly, const ::rtl::OUString& rMacroDesc ) @@ -230,7 +280,7 @@ bool RenameModule( Window* pErrorParent, const ScriptDocument& rDocument, const BOOL bError = FALSE; SbMethod* pMethod = NULL; - MacroChooser* pChooser = new MacroChooser( NULL, TRUE ); + ::std::auto_ptr< MacroChooser > pChooser( new MacroChooser( NULL, TRUE ) ); if ( bChooseOnly || !SvtModuleOptions().IsBasicIDE() ) pChooser->SetMode( MACROCHOOSER_CHOOSEONLY ); @@ -250,101 +300,95 @@ bool RenameModule( Window* pErrorParent, const ScriptDocument& rDocument, const if ( !pMethod && pChooser->GetMode() == MACROCHOOSER_RECORDING ) pMethod = pChooser->CreateMacro(); - if ( pMethod ) + if ( !pMethod ) + break; + + SbModule* pModule = pMethod->GetModule(); + ENSURE_OR_BREAK( pModule, "BasicIDE::ChooseMacro: No Module found!" ); + + StarBASIC* pBasic = (StarBASIC*)pModule->GetParent(); + ENSURE_OR_BREAK( pBasic, "BasicIDE::ChooseMacro: No Basic found!" ); + + BasicManager* pBasMgr = BasicIDE::FindBasicManager( pBasic ); + ENSURE_OR_BREAK( pBasMgr, "BasicIDE::ChooseMacro: No BasicManager found!" ); + + // name + String aName; + aName += pBasic->GetName(); + aName += '.'; + aName += pModule->GetName(); + aName += '.'; + aName += pMethod->GetName(); + + // language + String aLanguage = String::CreateFromAscii("Basic"); + + // location + String aLocation; + ScriptDocument aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr ) ); + if ( aDocument.isDocument() ) { - SbModule* pModule = pMethod->GetModule(); - DBG_ASSERT(pModule, "BasicIDE::ChooseMacro: No Module found!"); - if ( pModule ) - { - StarBASIC* pBasic = (StarBASIC*)pModule->GetParent(); - DBG_ASSERT(pBasic, "BasicIDE::ChooseMacro: No Basic found!"); - if ( pBasic ) - { - BasicManager* pBasMgr = BasicIDE::FindBasicManager( pBasic ); - DBG_ASSERT(pBasMgr, "BasicIDE::ChooseMacro: No BasicManager found!"); - if ( pBasMgr ) - { - // name - String aName; - aName += pBasic->GetName(); - aName += '.'; - aName += pModule->GetName(); - aName += '.'; - aName += pMethod->GetName(); - - // language - String aLanguage = String::CreateFromAscii("Basic"); - - // location - String aLocation; - ScriptDocument aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr ) ); - if ( aDocument.isDocument() ) - { - // document basic - aLocation = String::CreateFromAscii("document"); - - if ( rxLimitToDocument.is() ) - { - uno::Reference< frame::XModel > xLimitToDocument( rxLimitToDocument ); - - uno::Reference< document::XEmbeddedScripts > xScripts( rxLimitToDocument, UNO_QUERY ); - if ( !xScripts.is() ) - { // the document itself does not support embedding scripts - uno::Reference< document::XScriptInvocationContext > xContext( rxLimitToDocument, UNO_QUERY ); - if ( xContext.is() ) - xScripts = xContext->getScriptContainer(); - if ( xScripts.is() ) - { // but it is able to refer to a document which actually does support this - xLimitToDocument.set( xScripts, UNO_QUERY ); - if ( !xLimitToDocument.is() ) - { - OSL_ENSURE( false, "BasicIDE::ChooseMacro: a script container which is no document!?" ); - xLimitToDocument = rxLimitToDocument; - } - } - } - - if ( xLimitToDocument != aDocument.getDocument() ) - { - // error - bError = TRUE; - ErrorBox( NULL, WB_OK | WB_DEF_OK, String( IDEResId( RID_STR_ERRORCHOOSEMACRO ) ) ).Execute(); - } - } - } - else - { - // application basic - aLocation = String::CreateFromAscii("application"); - } + // document basic + aLocation = String::CreateFromAscii("document"); - // script URL - if ( !bError ) + if ( rxLimitToDocument.is() ) + { + uno::Reference< frame::XModel > xLimitToDocument( rxLimitToDocument ); + + uno::Reference< document::XEmbeddedScripts > xScripts( rxLimitToDocument, UNO_QUERY ); + if ( !xScripts.is() ) + { // the document itself does not support embedding scripts + uno::Reference< document::XScriptInvocationContext > xContext( rxLimitToDocument, UNO_QUERY ); + if ( xContext.is() ) + xScripts = xContext->getScriptContainer(); + if ( xScripts.is() ) + { // but it is able to refer to a document which actually does support this + xLimitToDocument.set( xScripts, UNO_QUERY ); + if ( !xLimitToDocument.is() ) { - aScriptURL = String::CreateFromAscii("vnd.sun.star.script:"); - aScriptURL += aName; - aScriptURL += String::CreateFromAscii("?language="); - aScriptURL += aLanguage; - aScriptURL += String::CreateFromAscii("&location="); - aScriptURL += aLocation; + OSL_ENSURE( false, "BasicIDE::ChooseMacro: a script container which is no document!?" ); + xLimitToDocument = rxLimitToDocument; } } } + + if ( xLimitToDocument != aDocument.getDocument() ) + { + // error + bError = TRUE; + ErrorBox( NULL, WB_OK | WB_DEF_OK, String( IDEResId( RID_STR_ERRORCHOOSEMACRO ) ) ).Execute(); + } } } + else + { + // application basic + aLocation = String::CreateFromAscii("application"); + } + + // script URL + if ( !bError ) + { + aScriptURL = String::CreateFromAscii("vnd.sun.star.script:"); + aScriptURL += aName; + aScriptURL += String::CreateFromAscii("?language="); + aScriptURL += aLanguage; + aScriptURL += String::CreateFromAscii("&location="); + aScriptURL += aLocation; + } - if ( pMethod && !rxLimitToDocument.is() ) + if ( !rxLimitToDocument.is() ) { - pMethod->AddRef(); // festhalten, bis Event abgearbeitet. - Application::PostUserEvent( LINK( IDE_DLL()->GetExtraData(), BasicIDEData, ExecuteMacroEvent ), pMethod ); + MacroExecutionData* pExecData = new MacroExecutionData; + pExecData->aDocument = aDocument; + pExecData->xMethod = pMethod; // keep alive until the event has been processed + Application::PostUserEvent( STATIC_LINK( NULL, MacroExecution, ExecuteMacroEvent ), pExecData ); } } break; } - delete pChooser; - - return ::rtl::OUString( aScriptURL ); + return aScriptURL; } //---------------------------------------------------------------------------- diff --git a/basctl/source/basicide/iderdll.cxx b/basctl/source/basicide/iderdll.cxx index fac7ff2407cb..25f00564c703 100644 --- a/basctl/source/basicide/iderdll.cxx +++ b/basctl/source/basicide/iderdll.cxx @@ -211,18 +211,3 @@ IMPL_LINK( BasicIDEData, GlobalBasicBreakHdl, StarBASIC *, pBasic ) return nRet; } - -IMPL_LINK( BasicIDEData, ExecuteMacroEvent, void *, pData ) -{ - if ( pData ) - { - SbMethod* pMethod = (SbMethod*)pData; - - // Ist es eine StarScript-Methode? Am Parent erkennen - DBG_ASSERT( pMethod->GetParent()->GetFlags() & SBX_EXTSEARCH, "Kein EXTSEARCH!" ); - BasicIDE::RunMethod( pMethod ); - pMethod->ReleaseRef(); // muss vorher inkrementiert worden sein! - } - return 0; -} - diff --git a/basctl/source/basicide/iderdll2.hxx b/basctl/source/basicide/iderdll2.hxx index 162d08ddcb5e..fd811de71b08 100644 --- a/basctl/source/basicide/iderdll2.hxx +++ b/basctl/source/basicide/iderdll2.hxx @@ -100,8 +100,6 @@ public: const String& GetAddLibFilter() const { return aAddLibFilter; } void SetAddLibFilter( const String& rFilter ) { aAddLibFilter = rFilter; } - - DECL_LINK( ExecuteMacroEvent, void * ); }; diff --git a/basctl/util/makefile.mk b/basctl/util/makefile.mk index b33fa3f1d721..9401bbfb8d4d 100644 --- a/basctl/util/makefile.mk +++ b/basctl/util/makefile.mk @@ -54,6 +54,7 @@ SHL1STDLIBS= \ $(SVXCORELIB) \ $(SVXLIB) \ $(SFX2LIB) \ + $(FWELIB) \ $(BASICLIB) \ $(SVTOOLLIB) \ $(TKLIB) \ |