diff options
author | Mathias Bauer <mba@openoffice.org> | 2002-04-22 15:59:54 +0000 |
---|---|---|
committer | Mathias Bauer <mba@openoffice.org> | 2002-04-22 15:59:54 +0000 |
commit | 8f826827adc6fbe69f0ab6f2b9d8a5f993e70a45 (patch) | |
tree | 14b56484afc16c8ae94fe4b0e6de1f9a3643ebb0 | |
parent | c8b89777318de1a91c9c80fe45a4120c72283250 (diff) |
#98405#: new macro recording functionality
-rw-r--r-- | sfx2/source/control/dispatch.cxx | 32 | ||||
-rw-r--r-- | sfx2/source/control/msgpool.cxx | 45 | ||||
-rw-r--r-- | sfx2/source/control/objface.cxx | 6 | ||||
-rw-r--r-- | sfx2/source/control/request.cxx | 117 | ||||
-rw-r--r-- | sfx2/source/control/statcach.cxx | 64 | ||||
-rw-r--r-- | sfx2/source/view/viewfrm.cxx | 297 |
6 files changed, 445 insertions, 116 deletions
diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx index 4e13f7627b95..809da2d226fd 100644 --- a/sfx2/source/control/dispatch.cxx +++ b/sfx2/source/control/dispatch.cxx @@ -2,9 +2,9 @@ * * $RCSfile: dispatch.cxx,v $ * - * $Revision: 1.16 $ + * $Revision: 1.17 $ * - * last change: $Author: mba $ $Date: 2002-04-05 11:32:19 $ + * last change: $Author: mba $ $Date: 2002-04-22 16:56:18 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -63,6 +63,14 @@ #include <com/sun/star/frame/XTask.hpp> #endif +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ +#include <com/sun/star/beans/XPropertySet.hpp> +#endif + +#ifndef _COM_SUN_STAR_FRAME_XDISPATCHRECORDERSUPPLIER_HPP_ +#include <com/sun/star/frame/XDispatchRecorderSupplier.hpp> +#endif + #ifndef _SFXITEMPOOL_HXX //autogen #include <svtools/itempool.hxx> #endif @@ -275,9 +283,23 @@ int SfxDispatcher::Call_Impl( SfxShell& rShell, const SfxSlot &rSlot, SfxRequest if ( rSlot.IsMode(SFX_SLOT_FASTCALL) || rShell.CanExecuteSlot_Impl(rSlot) ) { // ggf. Recording anwerfen - SfxMacro *pMacro = GetFrame() ? GetFrame()->GetRecordingMacro_Impl() : NULL; - if ( bRecord && pMacro && !rSlot.IsMode(SFX_SLOT_NORECORD) ) - rReq.Record_Impl( rShell, rSlot, pMacro ); + com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xFrame( + GetFrame()->GetFrame()->GetFrameInterface(), + com::sun::star::uno::UNO_QUERY); + + com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xSet( + xFrame, + com::sun::star::uno::UNO_QUERY); + + com::sun::star::uno::Any aProp = xSet->getPropertyValue(::rtl::OUString::createFromAscii("DispatchRecorderSupplier")); + com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorderSupplier > xSupplier; + com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > xRecorder; + aProp >>= xSupplier; + if(xSupplier.is()) + xRecorder = xSupplier->getDispatchRecorder(); + + if ( bRecord && xRecorder.is() && !rSlot.IsMode(SFX_SLOT_NORECORD) ) + rReq.Record_Impl( rShell, rSlot, xRecorder ); // ggf. die Bindings locken (MI: warum?) SfxBindings *pBindings = GetBindings(); diff --git a/sfx2/source/control/msgpool.cxx b/sfx2/source/control/msgpool.cxx index 6e98f8e9e074..f052a4193ce0 100644 --- a/sfx2/source/control/msgpool.cxx +++ b/sfx2/source/control/msgpool.cxx @@ -2,9 +2,9 @@ * * $RCSfile: msgpool.cxx,v $ * - * $Revision: 1.1.1.1 $ + * $Revision: 1.2 $ * - * last change: $Author: hr $ $Date: 2000-09-18 16:52:29 $ + * last change: $Author: mba $ $Date: 2002-04-22 16:56:18 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -132,7 +132,6 @@ SfxSlotPool::~SfxSlotPool() delete pIF; delete _pInterfaces; delete _pGroups; - delete _pUnoSlots; if ( _pTypes ) { for ( USHORT n =_pTypes->Count(); n--; ) @@ -179,13 +178,6 @@ void SfxSlotPool::RegisterInterface( SfxInterface& rInterface ) for ( USHORT nFunc = 0; nFunc < rInterface.Count(); ++nFunc ) { SfxSlot *pDef = rInterface[nFunc]; - if ( pDef->GetUnoName() ) - { - if ( !_pUnoSlots ) - _pUnoSlots = new SfxSlotArr_Impl; - _pUnoSlots->Insert( pDef, _pUnoSlots->Count() ); - } - if ( pDef->GetGroupId() && /* pDef->GetGroupId() != GID_INTERN && */ !_pGroups->Contains(pDef->GetGroupId()) ) { @@ -579,44 +571,19 @@ void SfxSlotPool::ReleaseSID( const String &rGroup, const String &rName ) { } -const SfxSlot* SfxSlotPool::GetUnoSlot( USHORT nId ) -{ - const SfxSlot *pSlot = NULL; - if ( _pParentPool ) - pSlot = _pParentPool->GetUnoSlot( nId ); - - if ( !pSlot && _pUnoSlots ) - { - USHORT nCount = _pUnoSlots->Count(); - for ( USHORT n=0; n<nCount; n++ ) - { - if ( (*_pUnoSlots)[n]->GetSlotId() == nId ) - { - pSlot = (*_pUnoSlots)[n]; - break; - } - } - } - - return pSlot; -} - const SfxSlot* SfxSlotPool::GetUnoSlot( const String& rName ) { const SfxSlot *pSlot = NULL; if ( _pParentPool ) pSlot = _pParentPool->GetUnoSlot( rName ); - if ( !pSlot && _pUnoSlots ) + if ( !pSlot ) { - USHORT nCount = _pUnoSlots->Count(); - for ( USHORT n=0; n<nCount; n++ ) + for ( USHORT nInterface=0; nInterface<_pInterfaces->Count(); nInterface++ ) { - if ( rName.EqualsAscii((*_pUnoSlots)[n]->GetUnoName()) ) - { - pSlot = (*_pUnoSlots)[n]; + pSlot = (*_pInterfaces)[nInterface]->GetSlot( rName ); + if ( pSlot ) break; - } } } diff --git a/sfx2/source/control/objface.cxx b/sfx2/source/control/objface.cxx index 82e9e7838112..9aa9b9a1be43 100644 --- a/sfx2/source/control/objface.cxx +++ b/sfx2/source/control/objface.cxx @@ -2,9 +2,9 @@ * * $RCSfile: objface.cxx,v $ * - * $Revision: 1.5 $ + * $Revision: 1.6 $ * - * last change: $Author: cd $ $Date: 2002-04-22 07:04:20 $ + * last change: $Author: mba $ $Date: 2002-04-22 16:56:18 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -482,7 +482,7 @@ const SfxSlot* SfxInterface::GetSlot( const String& rCommand ) const SfxSlotPool& rPool = SFX_SLOTPOOL(); for ( USHORT n=0; n<nCount; n++ ) { - if ( aCommand.CompareIgnoreCaseToAscii( (pSlots+n)->GetUnoName() ) == COMPARE_EQUAL ) + if ( (pSlots+n)->pUnoName && aCommand.CompareIgnoreCaseToAscii( (pSlots+n)->GetUnoName() ) == COMPARE_EQUAL ) return pSlots+n; } diff --git a/sfx2/source/control/request.cxx b/sfx2/source/control/request.cxx index 721d7c7023a0..ee5487dcb854 100644 --- a/sfx2/source/control/request.cxx +++ b/sfx2/source/control/request.cxx @@ -2,7 +2,7 @@ // class SfxRequest // // (C) 1996 - 2000 StarDivision GmbH, Hamburg, Germany -// $Author: mba $ $Date: 2002-04-11 08:05:49 $ $Revision: 1.4 $ +// $Author: mba $ $Date: 2002-04-22 16:56:18 $ $Revision: 1.5 $ // $Logfile: T:/sfx2/source/control/request.cxv $ $Workfile: REQUEST.CXX $ //------------------------------------------------------------------*/ @@ -14,6 +14,18 @@ #include <com/sun/star/uno/Sequence.hxx> #endif +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ +#include <com/sun/star/beans/XPropertySet.hpp> +#endif + +#ifndef _COM_SUN_STAR_UTIL_XURLTRANSFORMER_HPP_ +#include <com/sun/star/util/XURLTransformer.hpp> +#endif + +#ifndef _COM_SUN_STAR_FRAME_XDISPATCHRECORDERSUPPLIER_HPP_ +#include <com/sun/star/frame/XDispatchRecorderSupplier.hpp> +#endif + #ifndef _SFXITEMITER_HXX //autogen #include <svtools/itemiter.hxx> #endif @@ -26,6 +38,8 @@ #include <svtools/itemdel.hxx> #endif +#include <comphelper/processfactory.hxx> + #pragma hdrstop #include "request.hxx" @@ -50,7 +64,6 @@ struct SfxRequest_Impl: public SfxListener SfxRequest* pAnti; // Owner wegen sterbendem Pool SfxMacro* pMacro; // falls != 0, soll hierdrin recorded werden String aTarget; // ggf. von App gesetztes Zielobjekt - String aStatement; // Statement bei manuellem Recording SfxItemPool* pPool; // ItemSet mit diesem Pool bauen SfxPoolItem* pRetVal; // R"uckgabewert geh"ort sich selbst const SfxShell* pShell; // ausgef"uhrt an dieser Shell @@ -63,6 +76,8 @@ struct SfxRequest_Impl: public SfxListener USHORT nCallMode; // Synch/Asynch/API/Record SfxAllItemSet* pInternalArgs; + com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > xRecorder; + SfxRequest_Impl( SfxRequest *pOwner ) : pAnti( pOwner), bCancelled(FALSE), nCallMode( SFX_CALLMODE_SYNCHRON ), nModifier(0), @@ -73,7 +88,7 @@ struct SfxRequest_Impl: public SfxListener void SetPool( SfxItemPool *pNewPool ); virtual void Notify( SfxBroadcaster &rBC, const SfxHint &rHint ); - SfxMacroStatement* CreateStatement( uno::Sequence < beans::PropertyValue > rArgs ); + void Record( const uno::Sequence < beans::PropertyValue >& rArgs ); }; @@ -108,8 +123,8 @@ SfxRequest::~SfxRequest() DBG_MEMTEST(); // nicht mit Done() marktierte Requests mit 'rem' rausschreiben - if ( pImp->pMacro && !pImp->bDone && !pImp->bIgnored ) -// pImp->pMacro->Record( pImp->CreateStatement( *pImp->pSlot ) ); + if ( pImp->xRecorder.is() && !pImp->bDone && !pImp->bIgnored ) +// pImp->Record( uno::Sequence < beans::PropertyValue >() ); Done(); // Objekt abr"aumen @@ -183,8 +198,8 @@ SfxRequest::SfxRequest pImp->pSlot = rShell.GetInterface()->GetSlot(nSlotId); DBG_ASSERT( pImp->pSlot, "recording slot unsupported by shell" ); if ( pImp->pSlot ) // Hosentr"ager damit man besser testen kann - Record_Impl( rShell, *pImp->pSlot, GetRecordingMacro() ); - DBG_ASSERTWARNING( GetRecordingMacro(), "recording without recording macro is overfluous" ); + Record_Impl( rShell, *pImp->pSlot, SfxRequest::GetMacroRecorder() ); + DBG_ASSERTWARNING( (SfxRequest::GetMacroRecorder().is()), "recording without recording macro is overfluous" ); } //-------------------------------------------------------------------- @@ -280,9 +295,9 @@ const SfxItemSet* SfxRequest::GetInternalArgs_Impl() const //-------------------------------------------------------------------- -SfxMacroStatement* SfxRequest_Impl::CreateStatement +void SfxRequest_Impl::Record ( - uno::Sequence < beans::PropertyValue > rArgs // aktuelle Parameter + const uno::Sequence < beans::PropertyValue >& rArgs // aktuelle Parameter ) /* [Beschreibung] @@ -295,12 +310,27 @@ SfxMacroStatement* SfxRequest_Impl::CreateStatement */ { - if ( bUseTarget ) - return new SfxMacroStatement( aTarget, *pSlot, bDone, rArgs ); - else - return new SfxMacroStatement( *pShell, aTarget, - SFX_MACRO_RECORDINGABSOLUTE == pMacro->GetMode(), - *pSlot, bDone, rArgs ); + String aCommand = String::CreateFromAscii(".uno:"); + aCommand.AppendAscii( pSlot->GetUnoName() ); + if(xRecorder.is()) + { + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > xFactory( + ::comphelper::getProcessServiceFactory(), + com::sun::star::uno::UNO_QUERY); + + com::sun::star::uno::Reference< com::sun::star::util::XURLTransformer > xTransform( + xFactory->createInstance(rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer")), + com::sun::star::uno::UNO_QUERY); + + com::sun::star::util::URL aURL; + aURL.Complete = ::rtl::OUString(aCommand); + xTransform->parseStrict(aURL); + + if (bDone) + xRecorder->recordDispatch(aURL,rArgs); + else + xRecorder->recordDispatchAsComment(aURL,rArgs); + } } //-------------------------------------------------------------------- @@ -309,7 +339,7 @@ void SfxRequest::Record_Impl ( const SfxShell& rSh, // die <SfxShell>, die den Request ausgef"uhrt hat const SfxSlot& rSlot, // der <SfxSlot>, der den Request ausgef"uhrt hat - SfxMacro* pMacro // das <SfxMakro>, in dem aufgezeichnet wird + com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > xRecorder // der Recorder, mit dem aufgezeichnet wird ) /* [Beschreibung] @@ -325,7 +355,7 @@ void SfxRequest::Record_Impl DBG_MEMTEST(); pImp->pShell = &rSh; pImp->pSlot = &rSlot; - pImp->pMacro = pMacro; + pImp->xRecorder = xRecorder; pImp->aTarget = rSh.GetName(); } @@ -603,7 +633,7 @@ void SfxRequest::Done_Impl pImp->bDone = TRUE; // nicht Recorden - if ( !pImp->pMacro ) + if ( !pImp->xRecorder.is() ) return; // wurde ein anderer Slot ausgef"uhrt als angefordert (Delegation) @@ -634,12 +664,10 @@ void SfxRequest::Done_Impl USHORT nWhich = rPool.GetWhich(pImp->pSlot->GetSlotId()); SfxItemState eState = pSet ? pSet->GetItemState( nWhich, FALSE, &pItem ) : SFX_ITEM_UNKNOWN; DBG_ASSERT( eState == SFX_ITEM_SET, "recording property not available" ); + uno::Sequence < beans::PropertyValue > aSeq; if ( eState == SFX_ITEM_SET ) - { - uno::Sequence < beans::PropertyValue > aSeq; TransformItems( pImp->pSlot->GetSlotId(), *pSet, aSeq, pImp->pSlot ); - pImp->pMacro->Record( pImp->CreateStatement( aSeq ) ); - } + pImp->Record( aSeq ); } // alles in ein einziges Statement aufzeichnen? @@ -648,7 +676,7 @@ void SfxRequest::Done_Impl uno::Sequence < beans::PropertyValue > aSeq; if ( pSet ) TransformItems( pImp->pSlot->GetSlotId(), *pSet, aSeq, pImp->pSlot ); - pImp->pMacro->Record( pImp->CreateStatement( aSeq ) ); + pImp->Record( aSeq ); } // jedes Item als einzelnes Statement recorden @@ -681,13 +709,9 @@ void SfxRequest::Done_Impl else { HACK(hierueber nochmal nachdenken) - pImp->pMacro->Record( pImp->CreateStatement( uno::Sequence < beans::PropertyValue >() ) ); + pImp->Record( uno::Sequence < beans::PropertyValue >() ); } } - - // manual Recording? - else if ( pImp->pSlot->IsMode(SFX_SLOT_RECORDMANUAL) ) - pImp->pMacro->Record( new SfxMacroStatement( pImp->aStatement ) ); } //-------------------------------------------------------------------- @@ -726,7 +750,39 @@ SfxMacro* SfxRequest::GetRecordingMacro() */ { - return SfxViewFrame::Current()->GetRecordingMacro_Impl(); +// return SfxViewFrame::Current()->GetRecordingMacro_Impl(); + return NULL; +} + +//-------------------------------------------------------------------- + +com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > SfxRequest::GetMacroRecorder() + +/* [Beschreibung] + + Hier wird versucht einen Recorder fuer dispatch() Aufrufe vom Frame zu bekommen. + Dieser ist dort per Property an einem Supplier verfuegbar - aber nur dann, wenn + recording angeschaltet wurde. + (Siehe auch SfxViewFrame::MiscExec_Impl() und SID_RECORDING) +*/ + +{ + com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > xRecorder; + + com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xSet( + SfxViewFrame::Current()->GetFrame()->GetFrameInterface(), + com::sun::star::uno::UNO_QUERY); + + if(xSet.is()) + { + com::sun::star::uno::Any aProp = xSet->getPropertyValue(rtl::OUString::createFromAscii("DispatchRecorderSupplier")); + com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorderSupplier > xSupplier; + aProp >>= xSupplier; + if(xSupplier.is()) + xRecorder = xSupplier->getDispatchRecorder(); + } + + return xRecorder; } //-------------------------------------------------------------------- @@ -805,6 +861,9 @@ void SfxRequest::SetTarget( const String &rTarget ) /*------------------------------------------------------------------------ $Log: not supported by cvs2svn $ + Revision 1.4 2002/04/11 08:05:49 mba + #98405#: support macro recorder + Revision 1.3 2002/04/05 11:32:19 mba #98405#: support macro recording diff --git a/sfx2/source/control/statcach.cxx b/sfx2/source/control/statcach.cxx index a8053325b215..93c2ce6c0dcd 100644 --- a/sfx2/source/control/statcach.cxx +++ b/sfx2/source/control/statcach.cxx @@ -2,9 +2,9 @@ * * $RCSfile: statcach.cxx,v $ * - * $Revision: 1.8 $ + * $Revision: 1.9 $ * - * last change: $Author: cd $ $Date: 2002-04-22 07:04:20 $ + * last change: $Author: mba $ $Date: 2002-04-22 16:56:18 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -302,7 +302,11 @@ const SfxSlotServer* SfxStateCache::GetSlotServer( SfxDispatcher &rDispat , cons if ( xProv.is() ) { DBG_ASSERT( !pDispatch, "Altes Dispatch nicht entfernt!" ); - const SfxSlot* pSlot = SFX_APP()->GetSlotPool( rDispat.GetFrame() ).GetUnoSlot( nId ); + + // get the slot - even if it is disabled on the dispatcher + const SfxSlot* pSlot = SFX_APP()->GetSlotPool( rDispat.GetFrame() ).GetSlot( nId ); + + // create the dispatch name from the slot data ::com::sun::star::util::URL aURL; String aName( pSlot ? String::CreateFromAscii(pSlot->GetUnoName()) : String() ); String aCmd; @@ -317,12 +321,14 @@ const SfxSlotServer* SfxStateCache::GetSlotServer( SfxDispatcher &rDispat , cons aCmd += String::CreateFromInt32( nId ); } + // try to get a dispatch object for this command aURL.Complete = aCmd; Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY ); xTrans->parseStrict( aURL ); ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > xDisp = xProv->queryDispatch( aURL, ::rtl::OUString(), 0 ); if ( xDisp.is() ) { + // test the dispatch object if it is just a wrapper for a SfxDispatcher ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xTunnel( xDisp, ::com::sun::star::uno::UNO_QUERY ); SfxOfficeDispatch* pDisp = NULL; if ( xTunnel.is() ) @@ -339,7 +345,7 @@ const SfxSlotServer* SfxStateCache::GetSlotServer( SfxDispatcher &rDispat , cons pDispatcher->_FindServer( nId, aSlotServ, sal_False ); SfxShell* pShell = pDispatcher->GetShell( aSlotServ.GetShellLevel() ); - // Check if this shell is active on the active dispatcher + // Check if this shell is active on the active dispatcher, if not, we treat it like any other UNO component sal_uInt16 nLevel = rDispat.GetShellLevel( *pShell ); if ( nLevel != USHRT_MAX ) { @@ -351,46 +357,36 @@ const SfxSlotServer* SfxStateCache::GetSlotServer( SfxDispatcher &rDispat , cons //MI: wozu das? bItemDirty = sal_True; return aSlotServ.GetSlot()? &aSlotServ: 0; } - else - { - rDispat._FindServer( nId, aSlotServ, sal_False ); - pDispatch = new BindDispatch_Impl( xDisp, aURL, this ); - pDispatch->acquire(); - - // flags must be set before adding StatusListener because the dispatch object will set the state - bSlotDirty = sal_False; - bCtrlDirty = sal_True; - xDisp->addStatusListener( pDispatch, aURL ); - aSlotServ.SetSlot(0); - return NULL; - } - } - else - { - rDispat._FindServer( nId, aSlotServ, sal_False ); - pDispatch = new BindDispatch_Impl( xDisp, aURL, this ); - pDispatch->acquire(); - - // flags must be set before adding StatusListener because the dispatch object will set the state - bSlotDirty = sal_False; - bCtrlDirty = sal_True; - xDisp->addStatusListener( pDispatch, aURL ); - aSlotServ.SetSlot(0); - return NULL; } + + // here we are if the dispatch object isn't a SfxDispatcher wrapper or if the wrapper uses another + // dispatcher, but not rDispat + // first we need the SlotServer temporarily, because the BindDispatch will need it to access the slot + rDispat._FindServer( nId, aSlotServ, sal_False ); + pDispatch = new BindDispatch_Impl( xDisp, aURL, this ); + pDispatch->acquire(); + + // flags must be set before adding StatusListener because the dispatch object will set the state + bSlotDirty = sal_False; + bCtrlDirty = sal_True; + xDisp->addStatusListener( pDispatch, aURL ); + + // now we must forget the SlotServer + aSlotServ.SetSlot(0); + return NULL; } } else { - // Don't find a server for every case. We have a configuration file that - // can disable specified commands. See bug #98419# - // if ( !rDispat._TryIntercept_Impl( nId, aSlotServ, sal_False ) ) + // Without a dispatch provider we are on our own! + // Don't find a server for the case "Dispatch Provider, but no dispatch". + // We have a configuration file that can disable specified commands. See bug #98419# rDispat._FindServer(nId, aSlotServ, sal_False); - //MI: wozu das? bItemDirty = sal_True; } bSlotDirty = sal_False; bCtrlDirty = sal_True; + //MI: wozu das? bItemDirty = sal_True; } return aSlotServ.GetSlot()? &aSlotServ: 0; diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index 227f0bf6eaef..0c0eb86b5c04 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -2,9 +2,9 @@ * * $RCSfile: viewfrm.cxx,v $ * - * $Revision: 1.44 $ + * $Revision: 1.45 $ * - * last change: $Author: mba $ $Date: 2002-04-08 16:45:05 $ + * last change: $Author: mba $ $Date: 2002-04-22 16:56:51 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -59,6 +59,8 @@ * ************************************************************************/ +#include <stdio.h> + #include "viewfrm.hxx" #ifndef _IPENV_HXX //autogen @@ -118,6 +120,12 @@ #ifndef _COM_SUN_STAR_UTIL_XURLTRANSFORMER_HPP_ #include <com/sun/star/util/XURLTransformer.hpp> #endif +#ifndef _COM_SUN_STAR_FRAME_XDISPATCHRECORDERSUPPLIER_HPP_ +#include <com/sun/star/frame/XDispatchRecorderSupplier.hpp> +#endif +#ifndef _RTL_USTRBUF_HXX_ +#include <rtl/ustrbuf.hxx> +#endif #include <unotools/localfilehelper.hxx> #include <comphelper/processfactory.hxx> @@ -125,6 +133,12 @@ #include <com/sun/star/uno/Reference.h> #include <com/sun/star/ucb/XContent.hpp> +#include <basic/basmgr.hxx> +#include <basic/sbmod.hxx> +#include <basic/sbmeth.hxx> +#include <svtools/sbx.hxx> + + using namespace ::com::sun::star::uno; using namespace ::com::sun::star::ucb; using namespace ::com::sun::star::frame; @@ -3153,7 +3167,6 @@ void SfxViewFrame::Resize() DoAdjustPosSizePixel( pShell, Point(), GetWindow().GetOutputSizePixel() ); if ( pShell->UseObjectSize() ) ForceOuterResize_Impl(FALSE); - SfxViewFrame* pActFrame = this; while ( pActFrame->GetActiveChildFrame_Impl() ) pActFrame = pActFrame->GetActiveChildFrame_Impl(); @@ -3170,6 +3183,237 @@ void SfxViewFrame::Resize() } } +#define LINE_SEP 0x0A + +void CutLines( String& rStr, USHORT nStartLine, USHORT nLines, BOOL bEraseTrailingEmptyLines ) +{ + rStr.ConvertLineEnd( LINEEND_LF ); + + USHORT nStartPos = 0; + USHORT nEndPos = 0; + USHORT nLine = 0; + while ( nLine < nStartLine ) + { + nStartPos = rStr.Search( LINE_SEP, nStartPos ); + nStartPos++; // nicht das \n. + nLine++; + } + + DBG_ASSERTWARNING( nStartPos != STRING_NOTFOUND, "CutLines: Startzeile nicht gefunden!" ); + + if ( nStartPos != STRING_NOTFOUND ) + { + nEndPos = nStartPos; + for ( USHORT i = 0; i < nLines; i++ ) + nEndPos = rStr.Search( LINE_SEP, nEndPos+1 ); + + if ( nEndPos != STRING_NOTFOUND ) // kann bei letzter Zeile passieren + nEndPos++; + if ( nEndPos > rStr.Len() ) + nEndPos = rStr.Len(); + + rStr.Erase( nStartPos, nEndPos-nStartPos ); + } + if ( bEraseTrailingEmptyLines ) + { + USHORT n = nStartPos; + while ( ( n < rStr.Len() ) && ( rStr.GetChar( n ) == LINE_SEP ) ) + n++; + + if ( n > nStartPos ) + rStr.Erase( nStartPos, n-nStartPos ); + } +} + +/* + add new recorded dispatch macro script into the application global basic lib container + It generates a new unique id for it and insert the macro by using this number as name for + the modul + */ +void SfxViewFrame::AddDispatchMacroToBasic_Impl( const ::rtl::OUString& sMacro ) +{ + /* + // get lib and modul name from dialog + SfxModule *pMod = GetObjectShell()->GetModule(); + SfxRequest aReq( SID_BASICCHOOSER, SFX_CALLMODE_SYNCHRON, pMod->GetPool() ); + const SfxPoolItem* pRet = pMod->ExecuteSlot( aReq ); + if ( pRet ) + ::rtl::OUString = ((SfxStringItem*)pRet)->GetValue(); + */ + + SfxApplication* pSfxApp = SFX_APP(); + SfxRequest aReq( SID_BASICCHOOSER, SFX_CALLMODE_SYNCHRON, pSfxApp->GetPool() ); + aReq.AppendItem( SfxBoolItem(SID_RECORDMACRO,TRUE) ); + const SfxPoolItem* pRet = SFX_APP()->ExecuteSlot( aReq ); + String aScriptURL; + if ( pRet ) + aScriptURL = ((SfxStringItem*)pRet)->GetValue(); + if ( aScriptURL.Len() ) + { + // parse script URL + BOOL bFound; + String aValue; + INetURLObject aINetScriptURL( aScriptURL ); + + // get language + String aLanguage; + bFound = aINetScriptURL.getParameter( String( RTL_CONSTASCII_USTRINGPARAM("language") ), &aValue ); + if ( bFound ) + aLanguage = aValue; + + // get macro + String aMacro; + String aLibName; + String aModuleName; + String aMacroName; + bFound = aINetScriptURL.getParameter( String( RTL_CONSTASCII_USTRINGPARAM("macro") ), &aValue ); + if ( bFound ) + { + aMacro = aValue; + aLibName = aMacro.GetToken(0, sal_Unicode('.')); + aModuleName = aMacro.GetToken(1, sal_Unicode('.')); + aMacroName = aMacro.GetToken(2, sal_Unicode('.')); + } + + // get location + String aLocation; + bFound = aINetScriptURL.getParameter( String( RTL_CONSTASCII_USTRINGPARAM("location") ), &aValue ); + if ( bFound ) + aLocation = aValue; + + pSfxApp->EnterBasicCall(); + + SfxObjectShell* pShell = 0; + BasicManager* pBasMgr = 0; + if ( aLocation.EqualsIgnoreCaseAscii( "application" ) ) + { + // application basic + pBasMgr = pSfxApp->GetBasicManager(); + } + else if ( aLocation.EqualsIgnoreCaseAscii( "document" ) ) + { + pBasMgr = GetObjectShell()->GetBasicManager(); + } + + String aSource; + if ( pBasMgr) + { + StarBASIC* pBasic = pBasMgr->GetLib( aLibName ); + if ( pBasic ) + { + SbModule* pModule = pBasic->FindModule( aModuleName ); + if ( pModule ) + { + SbMethod* pMethod = (SbMethod*)pModule->GetMethods()->Find( aMacroName, SbxCLASS_METHOD ); + aSource = pModule->GetSource(); + USHORT nStart, nEnd; + pMethod->GetLineRange( nStart, nEnd ); + CutLines( aSource, nStart-1, nEnd-nStart+1, TRUE ); + } + } + } + + // open lib container and break operation if it couldn't be opened + com::sun::star::uno::Reference< com::sun::star::script::XLibraryContainer > xLibCont; + if ( aLocation.EqualsIgnoreCaseAscii( "application" ) ) + { + xLibCont = SFX_APP()->GetBasicContainer(); + } + else if ( aLocation.EqualsIgnoreCaseAscii( "document" ) ) + { + xLibCont = GetObjectShell()->GetBasicContainer(); + } + + if(!xLibCont.is()) + { + DBG_ERRORFILE("couldn't get access to the basic lib container. Adding of macro isn't possible."); + return; + } + + // get LibraryContainer + com::sun::star::uno::Any aTemp; + com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xRoot( + xLibCont, + com::sun::star::uno::UNO_QUERY); + + ::rtl::OUString sLib( aLibName ); + com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xLib; + if(xRoot->hasByName(sLib)) + { + // library must be loaded + aTemp = xRoot->getByName(sLib); + xLibCont->loadLibrary(sLib); + aTemp >>= xLib; + } + else + { + xLib = com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >( + xLibCont->createLibrary(sLib), + com::sun::star::uno::UNO_QUERY); + } + + // pack the macro as direct usable "sub" routine + ::rtl::OUString sCode; + ::rtl::OUStringBuffer sRoutine(10000); + ::rtl::OUString sMacroName( aMacroName ); + BOOL bReplace = FALSE; + + // get module + ::rtl::OUString sModule( aModuleName ); + if(xLib->hasByName(sModule)) + { + if ( aSource.Len() ) + { + sRoutine.append( aSource ); + } + else + { + aTemp = xLib->getByName(sModule); + aTemp >>= sCode; + sRoutine.append( sCode ); + } + + bReplace = TRUE; + } + + // append new method + sRoutine.appendAscii("\nsub " ); + sRoutine.append (sMacroName ); + sRoutine.appendAscii("\n" ); + sRoutine.append (sMacro ); + sRoutine.appendAscii("\nend sub\n"); + + // create the modul inside the library and insert the macro routine + aTemp <<= sRoutine.makeStringAndClear(); + if ( bReplace ) + { + com::sun::star::uno::Reference< com::sun::star::container::XNameContainer > xModulCont( + xLib, + com::sun::star::uno::UNO_QUERY); + xModulCont->replaceByName(sModule,aTemp); + } + else + { + com::sun::star::uno::Reference< com::sun::star::container::XNameContainer > xModulCont( + xLib, + com::sun::star::uno::UNO_QUERY); + xModulCont->insertByName(sModule,aTemp); + } + + pSfxApp->LeaveBasicCall(); + } + else + { + // add code for "session only" macro + } + + /* + FILE* pFile = fopen( "macro.bas", "a" ); + fprintf( pFile, "%s", ::rtl::OUStringToOString(sBuffer.makeStringAndClear(),RTL_TEXTENCODING_UTF8).getStr() ); + fclose ( pFile ); + */ +} + void SfxViewFrame::MiscExec_Impl( SfxRequest& rReq ) { DBG_MEMTEST(); @@ -3178,10 +3422,51 @@ void SfxViewFrame::MiscExec_Impl( SfxRequest& rReq ) { case SID_RECORDMACRO : { - if ( pImp->pMacro ) - DELETEZ( pImp->pMacro ); + ::rtl::OUString sProperty = rtl::OUString::createFromAscii("DispatchRecorderSupplier"); + + // try to find any active recorder on this frame + com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xFrame( + GetFrame()->GetFrameInterface(), + com::sun::star::uno::UNO_QUERY); + + com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xSet(xFrame,com::sun::star::uno::UNO_QUERY); + com::sun::star::uno::Any aProp = xSet->getPropertyValue(sProperty); + com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorderSupplier > xSupplier; + aProp >>= xSupplier; + com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > xRecorder; + if (xSupplier.is()) + xRecorder = xSupplier->getDispatchRecorder(); + + if ( xRecorder.is() ) + { + // disable active recording and insert script into basic library container of application + xRecorder->endRecording(); + aProp <<= com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorderSupplier >(); + xSet->setPropertyValue(sProperty,aProp); + AddDispatchMacroToBasic_Impl(xRecorder->getRecordedMacro()); + xRecorder = NULL; + } else - pImp->pMacro = new SfxMacro( SFX_MACRO_RECORDINGRELATIVE ); + { + // enable recording + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > xFactory( + ::comphelper::getProcessServiceFactory(), + com::sun::star::uno::UNO_QUERY); + + xRecorder = com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder >( + xFactory->createInstance(rtl::OUString::createFromAscii("com.sun.star.frame.DispatchRecorder")), + com::sun::star::uno::UNO_QUERY); + + com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorderSupplier > xSupplier( + xFactory->createInstance(rtl::OUString::createFromAscii("com.sun.star.frame.DispatchRecorderSupplier")), + com::sun::star::uno::UNO_QUERY); + + xSupplier->setDispatchRecorder(xRecorder); + xRecorder->startRecording(xFrame); + aProp <<= xSupplier; + xSet->setPropertyValue(sProperty,aProp); + } + rReq.Done(); break; } |