summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Schoenheit [fs] <frank.schoenheit@sun.com>2009-11-27 11:49:21 +0100
committerFrank Schoenheit [fs] <frank.schoenheit@sun.com>2009-11-27 11:49:21 +0100
commit83ee99a9a2119bdd7948f702977c8a017e9aff0c (patch)
tree4a12ed4955b96e15b7599c4a6a5e5ee0a3532b01
parentd96b191fe42ab3396f0386d74da4c92730dbcc65 (diff)
[CWS autorecovery] #i65597# refactored SfxViewFrame::SwitchToViewShell_Impl to move some functionality
to the UNO implementations, instead of doing it here. This is another step towards a fully UNOized view factory for SFX documents.
-rw-r--r--sfx2/inc/frmload.hxx2
-rw-r--r--sfx2/inc/sfx2/docfac.hxx1
-rw-r--r--sfx2/inc/sfx2/sfxbasecontroller.hxx12
-rw-r--r--sfx2/inc/sfx2/viewfrm.hxx4
-rw-r--r--sfx2/inc/sfx2/viewsh.hxx2
-rw-r--r--sfx2/source/control/dispatch.cxx2
-rw-r--r--sfx2/source/doc/docfac.cxx16
-rw-r--r--sfx2/source/view/sfxbasecontroller.cxx87
-rw-r--r--sfx2/source/view/topfrm.cxx10
-rw-r--r--sfx2/source/view/viewfrm.cxx236
-rw-r--r--sfx2/source/view/viewsh.cxx11
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
{
}
}
+