diff options
-rw-r--r-- | sfx2/inc/frmload.hxx | 2 | ||||
-rw-r--r-- | sfx2/inc/sfx2/docfac.hxx | 1 | ||||
-rw-r--r-- | sfx2/inc/sfx2/sfxbasecontroller.hxx | 12 | ||||
-rw-r--r-- | sfx2/inc/sfx2/viewfrm.hxx | 4 | ||||
-rw-r--r-- | sfx2/inc/sfx2/viewsh.hxx | 2 | ||||
-rw-r--r-- | sfx2/source/control/dispatch.cxx | 2 | ||||
-rw-r--r-- | sfx2/source/doc/docfac.cxx | 16 | ||||
-rw-r--r-- | sfx2/source/view/sfxbasecontroller.cxx | 87 | ||||
-rw-r--r-- | sfx2/source/view/topfrm.cxx | 10 | ||||
-rw-r--r-- | sfx2/source/view/viewfrm.cxx | 236 | ||||
-rw-r--r-- | sfx2/source/view/viewsh.cxx | 11 |
11 files changed, 178 insertions, 205 deletions
diff --git a/sfx2/inc/frmload.hxx b/sfx2/inc/frmload.hxx index 1421c3df25e4..dbd8eb1ef9fb 100644 --- a/sfx2/inc/frmload.hxx +++ b/sfx2/inc/frmload.hxx @@ -63,7 +63,7 @@ class SfxTopFrame; class SfxFrameWeak; -class SfxFrameLoader_Impl : public ::cppu::WeakImplHelper2< ::com::sun::star::frame::XSynchronousFrameLoader, ::com::sun::star::lang::XServiceInfo > +class SAL_DLLPRIVATE SfxFrameLoader_Impl : public ::cppu::WeakImplHelper2< ::com::sun::star::frame::XSynchronousFrameLoader, ::com::sun::star::lang::XServiceInfo > { ::comphelper::ComponentContext m_aContext; diff --git a/sfx2/inc/sfx2/docfac.hxx b/sfx2/inc/sfx2/docfac.hxx index d7c7999db8e1..52e6c5e579a7 100644 --- a/sfx2/inc/sfx2/docfac.hxx +++ b/sfx2/inc/sfx2/docfac.hxx @@ -109,6 +109,7 @@ public: //#if 0 // _SOLAR__PRIVATE SAL_DLLPRIVATE void SetModule_Impl( SfxModule* ); SAL_DLLPRIVATE static void UpdateFilterContainers_Impl(); + SAL_DLLPRIVATE sal_uInt16 GetViewNo_Impl( const sal_uInt16 i_nViewId, const sal_uInt16 i_nFallback ); //#endif private: diff --git a/sfx2/inc/sfx2/sfxbasecontroller.hxx b/sfx2/inc/sfx2/sfxbasecontroller.hxx index c952e550996e..125b5af21908 100644 --- a/sfx2/inc/sfx2/sfxbasecontroller.hxx +++ b/sfx2/inc/sfx2/sfxbasecontroller.hxx @@ -499,21 +499,13 @@ public: SAL_DLLPRIVATE BOOL HasMouseClickListeners_Impl(); SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::frame::XTitle > impl_getTitleHelper (); //#endif +private: + SAL_DLLPRIVATE void ConnectSfxFrame_Impl( const bool i_bConnect ); //________________________________________________________________________________________________________ // private variables //________________________________________________________________________________________________________ - /** With this method you can set the flag that controlls whether the - frame is released together with a controller when the later one is - disposed. - @param bFlag - When passing <true/>, the default value of this flag, then - disposing the controller results in releasing the frame. - Passing <false/> leaves the frame unaffected. - */ - void FrameIsReleasedWithController (sal_Bool bFlag); - private: IMPL_SfxBaseController_DataContainer* m_pData ; diff --git a/sfx2/inc/sfx2/viewfrm.hxx b/sfx2/inc/sfx2/viewfrm.hxx index b759195c9b1c..7b73682c636a 100644 --- a/sfx2/inc/sfx2/viewfrm.hxx +++ b/sfx2/inc/sfx2/viewfrm.hxx @@ -301,7 +301,11 @@ public: SAL_DLLPRIVATE void MiscState_Impl(SfxItemSet &); SAL_DLLPRIVATE SfxWorkWindow* GetWorkWindow_Impl( USHORT nId ); SAL_DLLPRIVATE void AddDispatchMacroToBasic_Impl(const ::rtl::OUString& sMacro); + //#endif +private: + SAL_DLLPRIVATE SfxViewShell* LoadNewView_Impl( const USHORT i_nNewViewNo, SfxViewShell* i_pOldShell ); + SAL_DLLPRIVATE void PopShellAndSubShells_Impl( SfxViewShell& i_rViewShell ); }; //-------------------------------------------------------------------- diff --git a/sfx2/inc/sfx2/viewsh.hxx b/sfx2/inc/sfx2/viewsh.hxx index d0ac30a9fcd9..9b4e66ff84c6 100644 --- a/sfx2/inc/sfx2/viewsh.hxx +++ b/sfx2/inc/sfx2/viewsh.hxx @@ -339,11 +339,11 @@ public: SAL_DLLPRIVATE void SetFrameSet_Impl(SfxFrameSetDescriptor*); SAL_DLLPRIVATE void CheckIPClient_Impl( SfxInPlaceClient*, const Rectangle& ); SAL_DLLPRIVATE void PushSubShells_Impl( BOOL bPush=TRUE ); + SAL_DLLPRIVATE void PopSubShells_Impl() { PushSubShells_Impl( FALSE ); } SAL_DLLPRIVATE void TakeOwnerShip_Impl(); SAL_DLLPRIVATE void CheckOwnerShip_Impl(); SAL_DLLPRIVATE void TakeFrameOwnerShip_Impl(); SAL_DLLPRIVATE BOOL ExecKey_Impl(const KeyEvent& aKey); - #endif }; diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx index e4a292857e49..6e834dbd7678 100644 --- a/sfx2/source/control/dispatch.cxx +++ b/sfx2/source/control/dispatch.cxx @@ -522,7 +522,7 @@ void SfxDispatcher::Pop SfxApplication *pSfxApp = SFX_APP(); #ifdef DBG_UTIL - ByteString aMsg( "SfxDispatcher(" ); + ByteString aMsg( "-SfxDispatcher(" ); aMsg += ByteString::CreateFromInt64( (sal_uIntPtr) this ); aMsg += bPush ? ")::Push(" : ")::Pop("; if ( rShell.GetInterface() ) diff --git a/sfx2/source/doc/docfac.cxx b/sfx2/source/doc/docfac.cxx index 3a00bbe3097a..0a4150604d27 100644 --- a/sfx2/source/doc/docfac.cxx +++ b/sfx2/source/doc/docfac.cxx @@ -305,10 +305,22 @@ String SfxObjectFactory::GetModuleName() const ::rtl::OUString sModuleName = aPropSet.getUnpackedValueOrDefault(PROP_MODULEUINAME, ::rtl::OUString()); return String(sModuleName); } - catch(const css::uno::RuntimeException& exRun) - { throw exRun; } + catch(const css::uno::RuntimeException&) + { throw; } catch(const css::uno::Exception&) {} return String(); } + + +sal_uInt16 SfxObjectFactory::GetViewNo_Impl( const sal_uInt16 i_nViewId, const sal_uInt16 i_nFallback ) +{ + for ( sal_uInt16 curViewNo = 0; curViewNo < GetViewFactoryCount(); ++curViewNo ) + { + const sal_uInt16 curViewId = GetViewFactory( curViewNo ).GetOrdinal(); + if ( i_nViewId == curViewId ) + return curViewNo; + } + return i_nFallback; +} diff --git a/sfx2/source/view/sfxbasecontroller.cxx b/sfx2/source/view/sfxbasecontroller.cxx index 54ccd29a7dd7..6a609f15ca3f 100644 --- a/sfx2/source/view/sfxbasecontroller.cxx +++ b/sfx2/source/view/sfxbasecontroller.cxx @@ -65,6 +65,7 @@ #include <basic/sbstar.hxx> #include <uno/mapping.hxx> #include <sfx2/viewsh.hxx> +#include <sfx2/docfac.hxx> #include <sfx2/viewfrm.hxx> #include <sfx2/objsh.hxx> #include <sfx2/app.hxx> @@ -86,6 +87,7 @@ #include <toolkit/helper/convert.hxx> #include <framework/titlehelper.hxx> #include <comphelper/processfactory.hxx> +#include <tools/diagnose_ex.h> #include <hash_map> @@ -440,17 +442,6 @@ struct IMPL_SfxBaseController_DataContainer SfxBaseController* m_pController ; sal_Bool m_bDisposing ; sal_Bool m_bSuspendState; - /** When this flag is <true/> (the default) then in dispose() the frame - and with it the view shell are released together with the - controller. - A derived class can set the flag to <false/> when it wants to - exchange controllers that work on the same view shell. One - application is the Impress Multi Pane GUI that changes shells that - are stacked on one view shell. Controllers are associated with the - stacked shells and thus must not destroy the view shell which is not - affected by the switching. - */ - sal_Bool m_bIsFrameReleasedWithController; css::uno::Reference< css::frame::XTitle > m_xTitleHelper; IMPL_SfxBaseController_DataContainer( MUTEX& aMutex , @@ -465,7 +456,6 @@ struct IMPL_SfxBaseController_DataContainer , m_pController ( pController ) , m_bDisposing ( sal_False ) , m_bSuspendState ( sal_False ) - , m_bIsFrameReleasedWithController( sal_True ) { } @@ -703,9 +693,7 @@ void SAL_CALL SfxBaseController::attachFrame( const REFERENCE< XFRAME >& xFrame if ( m_pData->m_pViewShell ) { - SfxViewFrame* pActFrame = m_pData->m_pViewShell->GetFrame() ; - pActFrame->Enable( TRUE ); - pActFrame->GetDispatcher()->Lock( FALSE ); + ConnectSfxFrame_Impl( true ); } } } @@ -766,9 +754,7 @@ sal_Bool SAL_CALL SfxBaseController::suspend( sal_Bool bSuspend ) throw( ::com:: BOOL bRet = bOther || pDocShell->PrepareClose(); if ( bRet ) { - // disable window and dispatcher until suspend call is withdrawn - pActFrame->Enable( FALSE ); - pActFrame->GetDispatcher()->Lock( TRUE ); + ConnectSfxFrame_Impl( false ); m_pData->m_bSuspendState = sal_True; } @@ -781,9 +767,7 @@ sal_Bool SAL_CALL SfxBaseController::suspend( sal_Bool bSuspend ) throw( ::com:: if ( m_pData->m_pViewShell ) { - SfxViewFrame* pActFrame = m_pData->m_pViewShell->GetFrame() ; - pActFrame->Enable( TRUE ); - pActFrame->GetDispatcher()->Lock( FALSE ); + ConnectSfxFrame_Impl( true ); } m_pData->m_bSuspendState = sal_False; @@ -1102,11 +1086,6 @@ void SfxBaseController::BorderWidthsChanged_Impl() // SfxBaseController -> XComponent //________________________________________________________________________________________________________ -void SfxBaseController::FrameIsReleasedWithController (sal_Bool bFlag) -{ - m_pData->m_bIsFrameReleasedWithController = bFlag; -} - void SAL_CALL SfxBaseController::dispose() throw( ::com::sun::star::uno::RuntimeException ) { ::vos::OGuard aGuard( Application::GetSolarMutex() ); @@ -1123,13 +1102,10 @@ void SAL_CALL SfxBaseController::dispose() throw( ::com::sun::star::uno::Runtime if ( m_pData->m_pViewShell ) { SfxViewFrame* pFrame = m_pData->m_pViewShell->GetViewFrame() ; - if (m_pData->m_bIsFrameReleasedWithController) - { - if ( pFrame && pFrame->GetViewShell() == m_pData->m_pViewShell ) - pFrame->GetFrame()->SetIsClosing_Impl(); - m_pData->m_pViewShell->DiscardClients_Impl(); - m_pData->m_pViewShell->pImp->bControllerSet = sal_False ; - } + if ( pFrame && pFrame->GetViewShell() == m_pData->m_pViewShell ) + pFrame->GetFrame()->SetIsClosing_Impl(); + m_pData->m_pViewShell->DiscardClients_Impl(); + m_pData->m_pViewShell->pImp->bControllerSet = sal_False ; if ( pFrame ) { @@ -1146,12 +1122,9 @@ void SAL_CALL SfxBaseController::dispose() throw( ::com::sun::star::uno::Runtime pView = SfxViewFrame::GetNext( *pView, pDoc ); } - if ( m_pData->m_bIsFrameReleasedWithController ) - { - SFX_APP()->NotifyEvent( SfxEventHint(SFX_EVENT_CLOSEVIEW, GlobalEventConfig::GetEventName( STR_EVENT_CLOSEVIEW ), pDoc ) ); - if ( !pView ) - SFX_APP()->NotifyEvent( SfxEventHint(SFX_EVENT_CLOSEDOC, GlobalEventConfig::GetEventName( STR_EVENT_CLOSEDOC ), pDoc) ); - } + SFX_APP()->NotifyEvent( SfxEventHint(SFX_EVENT_CLOSEVIEW, GlobalEventConfig::GetEventName( STR_EVENT_CLOSEVIEW ), pDoc ) ); + if ( !pView ) + SFX_APP()->NotifyEvent( SfxEventHint(SFX_EVENT_CLOSEDOC, GlobalEventConfig::GetEventName( STR_EVENT_CLOSEDOC ), pDoc) ); REFERENCE< XMODEL > xModel = pDoc->GetModel(); REFERENCE < ::com::sun::star::util::XCloseable > xCloseable( xModel, com::sun::star::uno::UNO_QUERY ); @@ -1168,8 +1141,7 @@ void SAL_CALL SfxBaseController::dispose() throw( ::com::sun::star::uno::Runtime m_pData->m_xListener->disposing( aObject ); SfxViewShell *pShell = m_pData->m_pViewShell; m_pData->m_pViewShell = NULL; - if ( pFrame->GetViewShell() == pShell - && m_pData->m_bIsFrameReleasedWithController) + if ( pFrame->GetViewShell() == pShell ) { // Enter registrations only allowed if we are the owner! if ( pFrame->GetFrame()->OwnsBindings_Impl() ) @@ -1374,6 +1346,39 @@ BOOL SfxBaseController::HasMouseClickListeners_Impl() return m_pData->m_aUserInputInterception.hasMouseClickListeners(); } +void SfxBaseController::ConnectSfxFrame_Impl( const bool i_bConnect ) +{ + ENSURE_OR_THROW( m_pData->m_pViewShell, "not to be called without a view shell" ); + SfxViewFrame* pActFrame = m_pData->m_pViewShell->GetFrame(); + ENSURE_OR_THROW( pActFrame, "a view shell without a view frame is pretty pathological" ); + + // disable window and dispatcher + pActFrame->Enable( i_bConnect ); + pActFrame->GetDispatcher()->Lock( !i_bConnect ); + + if ( i_bConnect ) + { + pActFrame->GetDispatcher()->Push( *m_pData->m_pViewShell ); + if ( m_pData->m_pViewShell->GetSubShell() ) + pActFrame->GetDispatcher()->Push( *m_pData->m_pViewShell->GetSubShell() ); + m_pData->m_pViewShell->PushSubShells_Impl(); + pActFrame->GetDispatcher()->Flush(); + + Window* pEditWin = m_pData->m_pViewShell->GetWindow(); + if ( pEditWin && m_pData->m_pViewShell->IsShowView_Impl() ) + pEditWin->Show(); + + if ( SfxViewFrame::Current() == pActFrame ) + pActFrame->GetDispatcher()->Update_Impl( sal_True ); + } + + // invalidate slot corresponding to the view shell + const sal_uInt16 nViewNo = m_pData->m_pViewShell->GetObjectShell()->GetFactory().GetViewNo_Impl( pActFrame->GetCurViewId(), USHRT_MAX ); + DBG_ASSERT( nViewNo != USHRT_MAX, "view shell id not found" ); + if ( nViewNo != USHRT_MAX ) + pActFrame->GetBindings().Invalidate( nViewNo + SID_VIEWSHELL0 ); +} + //============================================================================= css::uno::Reference< css::frame::XTitle > SfxBaseController::impl_getTitleHelper () { diff --git a/sfx2/source/view/topfrm.cxx b/sfx2/source/view/topfrm.cxx index 6f6c2939cc7c..d3f094dbc947 100644 --- a/sfx2/source/view/topfrm.cxx +++ b/sfx2/source/view/topfrm.cxx @@ -1180,15 +1180,9 @@ SfxTopViewFrame::SfxTopViewFrame LockAdjustPosSizePixel(); } - try - { - if ( pObjShell ) - SwitchToViewShell_Impl( nViewId ); - } - catch (com::sun::star::uno::Exception& ) + if ( pObjShell && !SwitchToViewShell_Impl( nViewId ) ) { - // make sure that the ctor is left regularly - ReleaseObjectShell_Impl(); + // TODO: better error handling? Under which conditions can this fail? return; } diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index 8835886b857b..042e48edeb70 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -101,6 +101,7 @@ using namespace ::com::sun::star::uno; using namespace ::com::sun::star::ucb; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::lang; +using ::com::sun::star::awt::XWindow; namespace css = ::com::sun::star; #ifndef GCC @@ -1032,6 +1033,29 @@ void SfxViewFrame::StateHistory_Impl( SfxItemSet &rSet ) } //-------------------------------------------------------------------- +void SfxViewFrame::PopShellAndSubShells_Impl( SfxViewShell& i_rViewShell ) +{ + i_rViewShell.PopSubShells_Impl(); + sal_uInt16 nLevel = pDispatcher->GetShellLevel( i_rViewShell ); + if ( nLevel != USHRT_MAX ) + { + if ( nLevel ) + { + // more sub shells on the stack, which were not affected by PopSubShells_Impl + SfxShell *pSubShell = pDispatcher->GetShell( nLevel-1 ); + if ( pSubShell == i_rViewShell.GetSubShell() ) + // "real" sub shells will be deleted elsewhere + pDispatcher->Pop( *pSubShell, SFX_SHELL_POP_UNTIL ); + else + pDispatcher->Pop( *pSubShell, SFX_SHELL_POP_UNTIL | SFX_SHELL_POP_DELETE ); + } + pDispatcher->Pop( i_rViewShell ); + pDispatcher->Flush(); + } + +} + +//-------------------------------------------------------------------- void SfxViewFrame::ReleaseObjectShell_Impl() /* [Beschreibung] @@ -1044,7 +1068,7 @@ void SfxViewFrame::ReleaseObjectShell_Impl() die SfxObjectShell ausgetauscht werden. Zwischen RealeaseObjectShell() und SetObjectShell() darf die Kontrolle - nicht an das ::com::sun::star::chaos::System abgegeben werden. + nicht an das System abgegeben werden. [Querverweise] @@ -1065,21 +1089,7 @@ void SfxViewFrame::ReleaseObjectShell_Impl() SfxViewShell *pDyingViewSh = GetViewShell(); if ( pDyingViewSh ) { - // Jetzt alle SubShells wechhauen - pDyingViewSh->PushSubShells_Impl( sal_False ); - sal_uInt16 nLevel = pDispatcher->GetShellLevel( *pDyingViewSh ); - if ( nLevel && nLevel != USHRT_MAX ) - { - // Es gibt immer nocht SubShells - SfxShell *pSubShell = pDispatcher->GetShell( nLevel-1 ); - if ( pSubShell == pDyingViewSh->GetSubShell() ) - //"Echte" Subshells nicht deleten - pDispatcher->Pop( *pSubShell, SFX_SHELL_POP_UNTIL ); - else - pDispatcher->Pop( *pSubShell, SFX_SHELL_POP_UNTIL | SFX_SHELL_POP_DELETE ); - } - pDispatcher->Pop( *pDyingViewSh ); - pDispatcher->Flush(); + PopShellAndSubShells_Impl( *pDyingViewSh ); pDyingViewSh->DisconnectAllClients(); SetViewShell_Impl(0); delete pDyingViewSh; @@ -2127,10 +2137,57 @@ SfxViewFrame* SfxViewFrame::GetActiveChildFrame_Impl() const } //-------------------------------------------------------------------- +SfxViewShell* SfxViewFrame::LoadNewView_Impl( const USHORT i_nNewViewNo, SfxViewShell* i_pOldShell ) +{ + 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!" ); + + // our UNO doc + const Reference < XModel > xModel( GetObjectShell()->GetModel(), UNO_QUERY_THROW ); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // >>> to be moved into a UNO view factory implementation + SfxObjectFactory& rDocumentFactory = GetObjectShell()->GetFactory(); + + // remember ViewID + pImp->nCurViewId = rDocumentFactory.GetViewFactory( i_nNewViewNo ).GetOrdinal(); + // TODO: shouldn't this be done in success case only? + + SfxViewFactory& rViewFactory = rDocumentFactory.GetViewFactory( i_nNewViewNo ); + + SfxViewShell* pViewShell = rViewFactory.CreateInstance( this, i_pOldShell ); + ENSURE_OR_THROW( pViewShell, "invalid view shell provided by factory" ); + + // by setting the ViewShell it is prevented that disposing the Controller will destroy this ViewFrame also + GetDispatcher()->SetDisableFlags( 0 ); + SetViewShell_Impl( pViewShell ); + + // ensure a default controller, if the view shell did not provide an own implementation + if ( !pViewShell->GetController().is() ) + pViewShell->SetController( new SfxBaseController( pViewShell ) ); + + // <<< to be moved into a UNO view factory implementation + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + // introduce model/view/controller to each other + Reference < XWindow > xWindow( GetFrame()->GetWindow().GetComponentInterface(), UNO_QUERY ); + Reference < XFrame > xFrame( GetFrame()->GetFrameInterface() ); + Reference < XController > xController( pViewShell->GetController() ); + + xController->attachModel( xModel ); + xModel->connectController( xController ); + xFrame->setComponent( xWindow, xController ); + xController->attachFrame( xFrame ); + xModel->setCurrentController( xController ); + + return pViewShell; +} + +//-------------------------------------------------------------------- sal_Bool SfxViewFrame::SwitchToViewShell_Impl ( - sal_uInt16 nViewId, /* > 0 + sal_uInt16 nViewIdOrNo, /* > 0 Registrierungs-Id der View, auf die umge- schaltet werden soll, bzw. die erstmalig erzeugt werden soll. @@ -2139,7 +2196,7 @@ sal_Bool SfxViewFrame::SwitchToViewShell_Impl Es soll die Default-View verwendet werden. */ sal_Bool bIsIndex /* sal_True - 'nViewId' ist keine Registrations-Id sondern + 'nViewIdOrNo' ist keine Registrations-Id sondern ein Index in die f"ur die in diesem <SfxViewFrame> dargestellte <SfxObjectShell>. */ @@ -2166,133 +2223,44 @@ sal_Bool SfxViewFrame::SwitchToViewShell_Impl */ { - try{ - DBG_ASSERT( GetObjectShell(), "Kein Dokument!" ); - - SfxObjectFactory &rDocFact = GetObjectShell()->GetFactory(); - - // find index of old and new ViewShell - sal_uInt16 nOldNo = USHRT_MAX, nNewNo = USHRT_MAX; - bIsIndex |= 0 == nViewId; - for ( sal_uInt16 nNo = 0; nNo < rDocFact.GetViewFactoryCount(); ++nNo ) - { - sal_uInt16 nFoundId = rDocFact.GetViewFactory(nNo).GetOrdinal(); - if ( nNewNo == USHRT_MAX ) - { - if ( bIsIndex && nViewId == nNo ) - { - nNewNo = nNo; - nViewId = nFoundId; // for nViewId == 0 - } - else if ( !bIsIndex && nViewId == nFoundId ) - nNewNo = nNo; - } - if ( pImp->nCurViewId == nFoundId ) - nOldNo = nNo; - } - - if ( nNewNo == USHRT_MAX ) + try { - // unknown ID -> fall back to default - sal_uInt16 nFoundId = rDocFact.GetViewFactory(0).GetOrdinal(); - nNewNo = 0; - nViewId = nFoundId; - if ( pImp->nCurViewId == nFoundId ) - nOldNo = 0; - } - - SfxViewShell *pSh = GetViewShell(); + ENSURE_OR_THROW( GetObjectShell() != NULL, "not possible without a document" ); - DBG_ASSERT( !pSh || nOldNo != USHRT_MAX, "old shell id not found" ); - - // does a ViewShell exist already? - SfxViewShell *pOldSh = pSh; - if ( pOldSh ) - { - // ask wether it can be closed - if ( !pOldSh->PrepareClose() ) - return sal_False; + GetBindings().ENTERREGISTRATIONS(); + LockAdjustPosSizePixel(); - // remove SubShells from Dispatcher before switching to new ViewShell - pOldSh->PushSubShells_Impl( sal_False ); - sal_uInt16 nLevel = pDispatcher->GetShellLevel( *pOldSh ); - if ( nLevel ) + // if we already have a view shell, remove it + SfxViewShell* pOldSh = GetViewShell(); + if ( pOldSh ) { - SfxShell *pSubShell = pDispatcher->GetShell( nLevel-1 ); - if ( pSubShell == pOldSh->GetSubShell() ) - //"real" SubShells are not deleted - pDispatcher->Pop( *pSubShell, SFX_SHELL_POP_UNTIL ); - else - // SubShells only known to Dispatcher must be deleted - pDispatcher->Pop( *pSubShell, SFX_SHELL_POP_UNTIL | SFX_SHELL_POP_DELETE ); - } - - pDispatcher->Pop( *pOldSh ); - GetBindings().Invalidate( nOldNo + SID_VIEWSHELL0 ); - } - - // remember ViewID - pImp->nCurViewId = nViewId; - GetBindings().Invalidate( nNewNo + SID_VIEWSHELL0 ); + // ask wether it can be closed + Reference< XController > xController( pOldSh->GetController(), UNO_SET_THROW ); + if ( !xController->suspend( sal_True ) ) + return sal_False; - // create new ViewShell - SfxViewFactory &rViewFactory = rDocFact.GetViewFactory( nNewNo ); - LockAdjustPosSizePixel(); - - GetBindings().ENTERREGISTRATIONS(); - pSh = rViewFactory.CreateInstance(this, pOldSh); - - Window *pEditWin = pSh->GetWindow(); - DBG_ASSERT( !pEditWin || !pEditWin->IsReallyVisible(), "don`t show your ViewShell`s Window by yourself!" ); - - // by setting the ViewShell it is prevented that disposing the Controller will destroy this ViewFrame also - GetDispatcher()->SetDisableFlags( 0 ); - SetViewShell_Impl(pSh); + // remove sub shells from Dispatcher before switching to new ViewShell + PopShellAndSubShells_Impl( *pOldSh ); - Reference < ::com::sun::star::awt::XWindow > xWindow( - GetFrame()->GetWindow().GetComponentInterface(), UNO_QUERY ); - Reference < XFrame > xFrame( GetFrame()->GetFrameInterface() ); - if ( !pSh->GetController().is() ) - pSh->SetController( new SfxBaseController( pSh ) ); - Reference < XController > xController( pSh->GetController() ); - xFrame->setComponent( xWindow, xController ); - - xController->attachFrame( xFrame ); - Reference < XModel > xModel( GetObjectShell()->GetModel() ); - if ( xModel.is() ) - { - xController->attachModel( xModel ); - xModel->connectController( xController ); - xModel->setCurrentController( xController ); - } - - GetDispatcher()->Push( *pSh ); - if ( pSh->GetSubShell() ) - GetDispatcher()->Push( *pSh->GetSubShell() ); - pSh->PushSubShells_Impl(); - GetDispatcher()->Flush(); - - // create UI elements before size is set - if ( SfxViewFrame::Current() == this ) - GetDispatcher()->Update_Impl( sal_True ); - - // allow resize events to be processed - UnlockAdjustPosSizePixel(); + // reset view shell, that's a precondition for the LoadNewView_Impl below + SetViewShell_Impl( NULL ); + } - Window* pFrameWin = &GetWindow(); - if ( pFrameWin != &GetFrame()->GetWindow() ) - pFrameWin->Show(); + // 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 ); - if ( GetWindow().IsReallyVisible() ) - DoAdjustPosSizePixel( pSh, Point(), GetWindow().GetOutputSizePixel() ); + // allow resize events to be processed + UnlockAdjustPosSizePixel(); - if ( pEditWin && pSh->IsShowView_Impl() ) - pEditWin->Show(); + if ( GetWindow().IsReallyVisible() ) + DoAdjustPosSizePixel( pNewSh, Point(), GetWindow().GetOutputSizePixel() ); - GetBindings().LEAVEREGISTRATIONS(); - delete pOldSh; + GetBindings().LEAVEREGISTRATIONS(); + delete pOldSh; } - catch ( com::sun::star::uno::Exception& ) + catch ( const com::sun::star::uno::Exception& ) { // the SfxCode is not able to cope with exceptions thrown while creating views // the code will crash in the stack unwinding procedure, so we shouldn't let exceptions go through here diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx index f6053a467ed4..755859dcdcd7 100644 --- a/sfx2/source/view/viewsh.cxx +++ b/sfx2/source/view/viewsh.cxx @@ -1517,16 +1517,12 @@ void SfxViewShell::PushSubShells_Impl( BOOL bPush ) { for ( USHORT n=0; n<nCount; n++ ) pDisp->Push( *pImp->aArr[n] ); - -// HACK(evtl. PushSubShells fuer SW virtuell machen oder im SW umbauen) -// Notify( *this, SfxSimpleHint( SFX_HINT_RESERVED4 ) ); } else if ( nCount ) { - pDisp->Pop( *pImp->aArr[0], SFX_SHELL_POP_UNTIL ); - -// HACK(evtl. PushSubShells fuer SW virtuell machen oder im SW umbauen) -// Notify( *this, SfxSimpleHint( SFX_HINT_RESERVED3 ) ); + SfxShell& rPopUntil = *pImp->aArr[0]; + if ( pDisp->GetShellLevel( rPopUntil ) != USHRT_MAX ) + pDisp->Pop( rPopUntil, SFX_SHELL_POP_UNTIL ); } pDisp->Flush(); @@ -2243,3 +2239,4 @@ void SfxViewShell::AddRemoveClipboardListener( const uno::Reference < datatransf { } } + |