diff options
author | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2009-12-03 09:29:45 +0100 |
---|---|---|
committer | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2009-12-03 09:29:45 +0100 |
commit | 6732980b94b87b23d7565ac04847ef70bf58d565 (patch) | |
tree | fcf2a2d8dbd05455fd778c00ee4f67a0a7782adc /sfx2 | |
parent | 5b4f0e7f834b27ddb0bdfece3786ced33c3917dd (diff) |
[CWS autorecovery] somewhat separated the 'switch view shell on SFX level' from the 'load new document on UNO level' case
Diffstat (limited to 'sfx2')
-rw-r--r-- | sfx2/inc/sfx2/sfxbasemodel.hxx | 3 | ||||
-rw-r--r-- | sfx2/inc/sfx2/viewfrm.hxx | 19 | ||||
-rw-r--r-- | sfx2/source/doc/sfxbasemodel.cxx | 61 | ||||
-rw-r--r-- | sfx2/source/view/frmload.cxx | 10 | ||||
-rw-r--r-- | sfx2/source/view/impframe.hxx | 7 | ||||
-rw-r--r-- | sfx2/source/view/topfrm.cxx | 11 | ||||
-rw-r--r-- | sfx2/source/view/viewfrm.cxx | 130 |
7 files changed, 166 insertions, 75 deletions
diff --git a/sfx2/inc/sfx2/sfxbasemodel.hxx b/sfx2/inc/sfx2/sfxbasemodel.hxx index 6ef67b6a009a..b3b542715ab6 100644 --- a/sfx2/inc/sfx2/sfxbasemodel.hxx +++ b/sfx2/inc/sfx2/sfxbasemodel.hxx @@ -200,6 +200,7 @@ class SfxPrinter; class SfxViewShell; class SfxObjectShell ; class SfxEventHint; +class SfxViewFrame; struct IMPL_SfxBaseModel_DataContainer ; // impl. struct to hold member of class SfxBaseModel //________________________________________________________________________________________________________ @@ -1521,6 +1522,8 @@ private: SAL_DLLPRIVATE css::uno::Reference< css::frame::XTitle > impl_getTitleHelper (); SAL_DLLPRIVATE css::uno::Reference< css::frame::XUntitledNumbers > impl_getUntitledHelper (); + SAL_DLLPRIVATE SfxViewFrame* FindOrCreateViewFrame_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& i_rFrame ) const; + //________________________________________________________________________________________________________ // private variables and methods //________________________________________________________________________________________________________ diff --git a/sfx2/inc/sfx2/viewfrm.hxx b/sfx2/inc/sfx2/viewfrm.hxx index d120923bea23..2db001023cdc 100644 --- a/sfx2/inc/sfx2/viewfrm.hxx +++ b/sfx2/inc/sfx2/viewfrm.hxx @@ -41,6 +41,7 @@ #include <svtools/poolitem.hxx> #include <com/sun/star/frame/status/Verb.hpp> #include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/frame/XController2.hpp> class SfxMacro; class SvBorder; @@ -164,9 +165,8 @@ public: SFX_DECL_INTERFACE(SFX_INTERFACE_SFXVIEWFRM) static void SetViewFrame( SfxViewFrame* ); - static SfxViewFrame* CreateViewFrame( SfxObjectShell& rDoc, - USHORT nViewId=0, - BOOL bHidden=FALSE ); + static SfxViewFrame* CreateViewFrame( SfxObjectShell& rDoc, USHORT nViewId=0, BOOL bHidden = FALSE ); + static SfxViewFrame* Create( SfxFrame& i_rFrame, SfxObjectShell& i_rDoc, const USHORT i_nViewId ); static SfxViewFrame* Current(); static SfxViewFrame* GetFirst( const SfxObjectShell* pDoc = 0, BOOL bOnlyVisible = TRUE ); @@ -301,11 +301,20 @@ public: SAL_DLLPRIVATE void INetExecute_Impl(SfxRequest &); SAL_DLLPRIVATE void INetState_Impl(SfxItemSet &); - SAL_DLLPRIVATE BOOL SwitchToViewShell_Impl( USHORT nNo, BOOL bIsIndex = FALSE ); + SAL_DLLPRIVATE void SetCurViewId_Impl( const USHORT i_nID ); + //#endif private: - SAL_DLLPRIVATE SfxViewShell* LoadNewView_Impl( const USHORT i_nNewViewNo, SfxViewShell* i_pOldShell ); + SAL_DLLPRIVATE BOOL SwitchToViewShell_Impl( USHORT nNo, BOOL bIsIndex = FALSE ); + SAL_DLLPRIVATE SfxViewShell* LoadNewView_Impl( const USHORT i_nViewId, SfxViewShell* i_pOldShell ); SAL_DLLPRIVATE void PopShellAndSubShells_Impl( SfxViewShell& i_rViewShell ); + SAL_DLLPRIVATE static ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController2 > + LoadDocument_Impl( + const SfxObjectShell& i_rDoc, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& i_rFrame, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& i_rArgs, + const USHORT i_nViewId + ); }; //-------------------------------------------------------------------- diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index df4fa2133480..62c96bf498f7 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -3947,7 +3947,46 @@ css::uno::Reference< css::frame::XController2 > SAL_CALL SfxBaseModel::createDef css::uno::Exception ) { return createViewController( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "view0" ) ), Sequence< PropertyValue >(), i_rFrame ); - // TODO: extende the SfxViewFactory with support for speaking view names + // TODO: extend the SfxViewFactory with support for speaking view names +} + +//============================================================================= +SfxViewFrame* SfxBaseModel::FindOrCreateViewFrame_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& i_rFrame ) const +{ + SfxViewFrame* pViewFrame = NULL; + for ( pViewFrame = SfxViewFrame::GetFirst( GetObjectShell(), FALSE ); + pViewFrame; + pViewFrame= SfxViewFrame::GetNext( *pViewFrame, GetObjectShell(), FALSE ) + ) + { + if ( pViewFrame->GetFrame()->GetFrameInterface() == i_rFrame ) + break; + } + if ( !pViewFrame ) + { + // no view frame, yet, but perhaps a mere frame? + SfxFrame* pFrame = NULL; + for ( pFrame = SfxFrame::GetFirst(); + pFrame; + pFrame = SfxFrame::GetNext( *pFrame ) + ) + { + if ( ( pFrame->GetFrameInterface() == i_rFrame ) + && ( pFrame->GetCurrentViewFrame() == NULL ) + // TODO: this condition is somewhat hacky, as it relies on the fact that this is (usually) + // the SfxFrame which is, up the stack, within its InsertDocument_Impl call. + // Before the refactoring is finally done, this is to be removed. + ) + break; + } + if ( !pFrame ) + { + pFrame = SfxFrame::Create( i_rFrame ); + ENSURE_OR_THROW( pFrame, "no SfxFrame created for the XFrame" ); + } + pViewFrame = new SfxViewFrame( pFrame, GetObjectShell() ); + } + return pViewFrame; } //============================================================================= @@ -3983,22 +4022,7 @@ css::uno::Reference< css::frame::XController2 > SAL_CALL SfxBaseModel::createVie "SfxBaseModel::createViewController: invalid old controller!" ); // determine the ViewFrame belonging to the given XFrame - SfxViewFrame* pViewFrame = NULL; - for ( pViewFrame = SfxViewFrame::GetFirst( GetObjectShell(), FALSE ); - pViewFrame; - pViewFrame= SfxViewFrame::GetNext( *pViewFrame, GetObjectShell(), FALSE ) - ) - { - if ( pViewFrame->GetFrame()->GetFrameInterface() == i_rFrame ) - break; - } - if ( !pViewFrame ) - // TODO: Effectively, this means that only our dedicated SFX-Loader can load documents into an arbitrary - // XFrame, since it will (directly or indirectly) create the Sfx(View)Frame which we need here. - // We should evaluate whether (after the re-factoring) it is possible/feasible to allow for an arbitrary - // XFrame here, by creating the necessary Sfx(View)Frame ourself. Finally, this is what a "view factory" - // is about ... - throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "invalid frame" ) ), *this, 3 ); + SfxViewFrame* pViewFrame = FindOrCreateViewFrame_Impl( i_rFrame ); // delegate to SFX' view factory SfxViewFactory& rViewFactory = rDocumentFactory.GetViewFactory( nViewNo ); @@ -4009,6 +4033,9 @@ css::uno::Reference< css::frame::XController2 > SAL_CALL SfxBaseModel::createVie pViewFrame->GetDispatcher()->SetDisableFlags( 0 ); pViewFrame->SetViewShell_Impl( pViewShell ); + // remember ViewID + pViewFrame->SetCurViewId_Impl( rViewFactory.GetOrdinal() ); + // ensure a default controller, if the view shell did not provide an own implementation if ( !pViewShell->GetController().is() ) pViewShell->SetController( new SfxBaseController( pViewShell ) ); diff --git a/sfx2/source/view/frmload.cxx b/sfx2/source/view/frmload.cxx index cde8265a1842..a8c6e9ae5f03 100644 --- a/sfx2/source/view/frmload.cxx +++ b/sfx2/source/view/frmload.cxx @@ -565,11 +565,6 @@ sal_Bool SAL_CALL SfxFrameLoader_Impl::load( const Sequence< PropertyValue >& rA // the latter. } - // create a frame - SfxFrame* pTargetFrame = SfxFrame::Create( _rTargetFrame ); - ENSURE_OR_THROW( pTargetFrame, "could not create an SfxFrame" ); - wFrame = pTargetFrame; - // get the SfxObjectShell (still needed at the moment) SfxObjectShellLock xDoc = impl_findObjectShell( xModel ); ENSURE_OR_THROW( xDoc.Is(), "no SfxObjectShell for the given model" ); @@ -584,6 +579,11 @@ sal_Bool SAL_CALL SfxFrameLoader_Impl::load( const Sequence< PropertyValue >& rA // code at the very end of this method cares for closing the XModel, which should also close the // ObjectShell. + // create a frame + SfxFrame* pTargetFrame = SfxFrame::Create( _rTargetFrame ); + ENSURE_OR_THROW( pTargetFrame, "could not create an SfxFrame" ); + wFrame = pTargetFrame; + // insert the document into the frame if ( !impl_plugDocIntoFrame( aDescriptor, *pTargetFrame, *xDoc ) ) throw RuntimeException(); diff --git a/sfx2/source/view/impframe.hxx b/sfx2/source/view/impframe.hxx index 4f27f3aedc3b..e710b9f44167 100644 --- a/sfx2/source/view/impframe.hxx +++ b/sfx2/source/view/impframe.hxx @@ -56,14 +56,10 @@ class SfxFrame_Impl : public SfxBroadcaster, public SvCompatWeakBase { public: ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame; - String aFrameIdName; sal_uInt32 nType; - sal_uInt32 nHistoryPos; SfxViewFrame* pCurrentViewFrame; SfxFrameDescriptor* pDescr; - sal_uInt16 nFrameId; sal_uInt16 nLocks; - sal_Bool bCloseOnUnlock : 1; sal_Bool bClosing : 1; sal_Bool bPrepClosing : 1; sal_Bool bInCancelTransfers : 1; @@ -82,12 +78,9 @@ public: SfxFrame_Impl( SfxFrame* pAntiImplP ) :SvCompatWeakBase( pAntiImplP ) ,nType( 0L ) - ,nHistoryPos( 0 ) ,pCurrentViewFrame( NULL ) ,pDescr( NULL ) - ,nFrameId( 0 ) ,nLocks( 0 ) - ,bCloseOnUnlock( sal_False ) ,bClosing(sal_False) ,bPrepClosing(sal_False) ,bInCancelTransfers( sal_False ) diff --git a/sfx2/source/view/topfrm.cxx b/sfx2/source/view/topfrm.cxx index 76b6b12346ad..30c94384b3ca 100644 --- a/sfx2/source/view/topfrm.cxx +++ b/sfx2/source/view/topfrm.cxx @@ -34,6 +34,7 @@ #endif #include <sfx2/viewfrm.hxx> +#include <sfx2/viewfac.hxx> #include <sfx2/signaturestate.hxx> #include <com/sun/star/frame/XModuleManager.hpp> #include <com/sun/star/util/XURLTransformer.hpp> @@ -768,13 +769,11 @@ sal_Bool SfxFrame::InsertDocument_Impl( SfxObjectShell& rDoc, const SfxItemSet& if ( nPluginMode && ( nPluginMode != 2 ) ) SetInPlace_Impl( TRUE ); - SfxViewFrame* pViewFrame = new SfxViewFrame( this, &rDoc ); - if ( !pViewFrame->SwitchToViewShell_Impl( nViewId ) ) - { // TODO: better error handling? Under which conditions can this fail? - OSL_ENSURE( false, "SfxFrame::InsertDocument_Impl: something went wrong while creating the SfxViewFrame!" ); - pViewFrame->DoClose(); + SfxViewFrame* pViewFrame = SfxViewFrame::Create( *this, rDoc, nViewId ? nViewId : rDoc.GetFactory().GetViewFactory( 0 ).GetOrdinal() ); + OSL_ENSURE( pViewFrame, "SfxFrame::InsertDocument_Impl: something went wrong while creating the SfxViewFrame!" ); + if ( !pViewFrame ) + // TODO: better error handling? Under which conditions can this fail? return sal_False; - } if ( nPluginMode == 1 ) { diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index 6867f90b3603..1f14a3a9b0ec 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -102,6 +102,7 @@ using namespace ::com::sun::star::ucb; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::lang; using ::com::sun::star::awt::XWindow; +using ::com::sun::star::beans::PropertyValue; namespace css = ::com::sun::star; #ifndef GCC @@ -2017,44 +2018,93 @@ SfxViewFrame* SfxViewFrame::GetActiveChildFrame_Impl() const } //-------------------------------------------------------------------- -SfxViewShell* SfxViewFrame::LoadNewView_Impl( const USHORT i_nNewViewNo, SfxViewShell* i_pOldShell ) +Reference< XController2 > SfxViewFrame::LoadDocument_Impl( + const SfxObjectShell& i_rDoc, const Reference< XFrame >& i_rFrame, const Sequence< PropertyValue >& i_rArgs, + const USHORT i_nViewId ) { - OSL_PRECOND( GetViewShell() == NULL, "SfxViewFrame::LoadNewView_Impl: not allowed to be called with an exsiting view shell!" ); - OSL_PRECOND( GetObjectShell() != NULL, "SfxViewFrame::LoadNewView_Impl: no document -> no loading!" ); - - const Reference < XFrame > xFrame( GetFrame()->GetFrameInterface() ); - const Reference < XModel2 > xModel( GetObjectShell()->GetModel(), UNO_QUERY_THROW ); + ENSURE_OR_THROW( i_rFrame.is(), "illegal frame" ); + const Reference < XModel2 > xModel( i_rDoc.GetModel(), UNO_QUERY_THROW ); - const USHORT nViewId = GetObjectShell()->GetFactory().GetViewFactory( i_nNewViewNo ).GetOrdinal(); ::rtl::OUStringBuffer sViewName; sViewName.appendAscii( "view" ); - sViewName.append( sal_Int32( nViewId ) ); - // TODO: extende the SfxViewFactory with support for speaking view names + sViewName.append( sal_Int32( i_nViewId ) ); + // TODO: extend the SfxViewFactory with support for speaking view names // let the model create a new controller + const Reference< XController2 > xController( xModel->createViewController( + sViewName.makeStringAndClear(), + i_rArgs, + i_rFrame + ), UNO_SET_THROW ); + + // introduce model/view/controller to each other + xController->attachModel( xModel.get() ); + xModel->connectController( xController.get() ); + i_rFrame->setComponent( xController->getComponentWindow(), xController.get() ); + xController->attachFrame( i_rFrame ); + xModel->setCurrentController( xController.get() ); + + return xController; +} + +//-------------------------------------------------------------------- +SfxViewShell* SfxViewFrame::LoadNewView_Impl( const USHORT i_nViewId, SfxViewShell* i_pOldShell ) +{ + ENSURE_OR_THROW( GetObjectShell() != NULL, "not possible without a document" ); + OSL_PRECOND( GetViewShell() == NULL, "SfxViewFrame::LoadNewView_Impl: not allowed to be called with an exsiting view shell!" ); + ::comphelper::NamedValueCollection aViewCreationArgs; if ( i_pOldShell != NULL ) aViewCreationArgs.put( "PreviousView", i_pOldShell->GetController() ); - const Reference< XController2 > xController( xModel->createViewController( - sViewName.makeStringAndClear(), + const Reference< XController2 > xController = LoadDocument_Impl( + *GetObjectShell(), + GetFrame()->GetFrameInterface(), aViewCreationArgs.getPropertyValues(), - xFrame - ) ); + i_nViewId + ); + SfxViewShell* pViewShell = SfxViewShell::Get( xController.get() ); ENSURE_OR_THROW( pViewShell, "invalid controller returned by view factory" ); + return pViewShell; +} - // remember ViewID - pImp->nCurViewId = nViewId; +//-------------------------------------------------------------------- - // introduce model/view/controller to each other - xController->attachModel( xModel.get() ); - xModel->connectController( xController.get() ); - xFrame->setComponent( xController->getComponentWindow(), xController.get() ); - xController->attachFrame( xFrame ); - xModel->setCurrentController( xController.get() ); +SfxViewFrame* SfxViewFrame::Create( SfxFrame& i_rFrame, SfxObjectShell& i_rDoc, const USHORT i_nViewId ) +{ + bool bSuccess = false; + SfxViewFrame* pViewFrame = NULL; + try + { + Reference< XController2 > xController = LoadDocument_Impl( + i_rDoc, i_rFrame.GetFrameInterface(), Sequence< PropertyValue >(), i_nViewId ); + ENSURE_OR_THROW( xController.is(), "invalid controller returned by LoadDocument_Impl" ); + // this is expected to throw in case of a failure ... - return pViewShell; + if ( xController.is() ) + { + for ( pViewFrame = SfxViewFrame::GetFirst( &i_rDoc, FALSE ); + pViewFrame; + pViewFrame = SfxViewFrame::GetNext( *pViewFrame, &i_rDoc, FALSE ) + ) + { + if ( pViewFrame->GetViewShell()->GetController() == xController ) + break; + } + if ( !pViewFrame ) + { + OSL_ENSURE( false, "SfxViewFrame::Create: wrong controller implementation!" ); + Reference< XComponent > xComponent( xController, UNO_QUERY_THROW ); + xComponent->dispose(); + } + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return pViewFrame; } //-------------------------------------------------------------------- @@ -2099,13 +2149,9 @@ sal_Bool SfxViewFrame::SwitchToViewShell_Impl { try { - ENSURE_OR_THROW( GetObjectShell() != NULL, "not possible without a document" ); - - GetBindings().ENTERREGISTRATIONS(); - LockAdjustPosSizePixel(); - // if we already have a view shell, remove it SfxViewShell* pOldSh = GetViewShell(); + OSL_PRECOND( pOldSh, "SfxViewFrame::SwitchToViewShell_Impl: that's called *switch* (not for *initial-load*) for a reason" ); if ( pOldSh ) { // ask wether it can be closed @@ -2120,10 +2166,13 @@ sal_Bool SfxViewFrame::SwitchToViewShell_Impl SetViewShell_Impl( NULL ); } + GetBindings().ENTERREGISTRATIONS(); + LockAdjustPosSizePixel(); + // create and load new ViewShell SfxObjectFactory& rDocFact = GetObjectShell()->GetFactory(); - const sal_uInt16 nNewNo = ( bIsIndex || !nViewIdOrNo ) ? nViewIdOrNo : rDocFact.GetViewNo_Impl( nViewIdOrNo, 0 ); - SfxViewShell* pNewSh = LoadNewView_Impl( nNewNo, pOldSh ); + const sal_uInt16 nViewId = ( bIsIndex || !nViewIdOrNo ) ? rDocFact.GetViewFactory( nViewIdOrNo ).GetOrdinal() : nViewIdOrNo; + SfxViewShell* pNewSh = LoadNewView_Impl( nViewId, pOldSh ); // allow resize events to be processed UnlockAdjustPosSizePixel(); @@ -2147,6 +2196,12 @@ sal_Bool SfxViewFrame::SwitchToViewShell_Impl } //------------------------------------------------------------------------- +void SfxViewFrame::SetCurViewId_Impl( const USHORT i_nID ) +{ + pImp->nCurViewId = i_nID; +} + +//------------------------------------------------------------------------- sal_uInt16 SfxViewFrame::GetCurViewId() const { return pImp->nCurViewId; @@ -2224,10 +2279,14 @@ void SfxViewFrame::ExecView_Impl case SID_VIEWSHELL: { const SfxPoolItem *pItem = 0; - if ( rReq.GetArgs() && - SFX_ITEM_SET == rReq.GetArgs()->GetItemState( SID_VIEWSHELL, sal_False, &pItem ) ) - rReq.SetReturnValue( SfxBoolItem(0, SwitchToViewShell_Impl( - (sal_uInt16)((const SfxUInt16Item*) pItem)->GetValue()) )); + if ( rReq.GetArgs() + && SFX_ITEM_SET == rReq.GetArgs()->GetItemState( SID_VIEWSHELL, sal_False, &pItem ) + ) + { + const sal_uInt16 nViewId = static_cast< const SfxUInt16Item* >( pItem )->GetValue(); + BOOL bSuccess = SwitchToViewShell_Impl( nViewId ); + rReq.SetReturnValue( SfxBoolItem( 0, bSuccess ) ); + } break; } @@ -2237,8 +2296,9 @@ void SfxViewFrame::ExecView_Impl case SID_VIEWSHELL3: case SID_VIEWSHELL4: { - rReq.SetReturnValue( SfxBoolItem(0, - SwitchToViewShell_Impl( rReq.GetSlot() - SID_VIEWSHELL0, sal_True ) ) ); + const sal_uInt16 nViewNo = rReq.GetSlot() - SID_VIEWSHELL0; + BOOL bSuccess = SwitchToViewShell_Impl( nViewNo, sal_True ); + rReq.SetReturnValue( SfxBoolItem( 0, bSuccess ) ); break; } |