summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Schoenheit [fs] <frank.schoenheit@sun.com>2009-11-23 21:43:54 +0100
committerFrank Schoenheit [fs] <frank.schoenheit@sun.com>2009-11-23 21:43:54 +0100
commit05aee339c8c9a3bfe0e6ecb94bb9e58748e5fa1b (patch)
treed1fac01a5722d97073a2a334669450e07c782dd5
parent56a09166696e29083638325b34c6b98167592ce0 (diff)
[CWS autorecovery] #i65597# when reloading an SFX document, do this via UNO, not via internal methods.
In particular, do not re-use existing SfxTopFrames. This implies slightly more flickering, but this should be bearable nowadays. The advantage is more simplified code. Also, on the medium run, when UNO view factories are implemented for SFX documents, the old approach would not have worked, anyway.
-rw-r--r--sfx2/source/doc/objcont.cxx37
-rw-r--r--sfx2/source/view/topfrm.cxx56
-rw-r--r--sfx2/source/view/viewfrm.cxx105
3 files changed, 71 insertions, 127 deletions
diff --git a/sfx2/source/doc/objcont.cxx b/sfx2/source/doc/objcont.cxx
index 99253fbce806..3ea51f6b54e9 100644
--- a/sfx2/source/doc/objcont.cxx
+++ b/sfx2/source/doc/objcont.cxx
@@ -226,39 +226,12 @@ bool SfxObjectShell::LoadView_Impl( SfxTopFrame& rTargetFrame )
pSet->ClearItem( SID_USER_DATA );
pSet->Put( SfxUInt16Item( SID_VIEW_ID, nViewId ) );
- if ( rTargetFrame.GetCurrentViewFrame() )
- {
- // TODO: the only client of this case is the Reload-implementation for SFX-based documents. This should be
- // migrated to use UNO mechanisms, too. In this case, we can simplify the code here.
-
- // use the frame from the arguments, but don't set a window size
- SfxViewFrame* pViewFrame = rTargetFrame.GetCurrentViewFrame();
- if ( pViewFrame->GetViewShell() || !pViewFrame->GetObjectShell() )
- {
- pSet->ClearItem( SID_VIEW_POS_SIZE );
- pSet->ClearItem( SID_WIN_POSSIZE );
- pSet->ClearItem( SID_VIEW_ZOOM_MODE );
-
- // avoid flickering controllers
- SfxBindings &rBind = pViewFrame->GetBindings();
- rBind.ENTERREGISTRATIONS();
+ OSL_ENSURE( rTargetFrame.GetCurrentViewFrame() == NULL,
+ "SfxObjectShell::LoadView_Impl: no support (anymore) for loading into a non-empty frame!" );
+ // Since some refactoring in CWS autorecovery, this shouldn't happen anymore. Frame re-usage is nowadays
+ // done in higher layers, namely in the framework.
- // set document into frame
- rTargetFrame.InsertDocument_Impl( *this );
-
- // restart controller updating
- rBind.LEAVEREGISTRATIONS();
- }
- else
- {
- // create new view
- pViewFrame->CreateView_Impl( nViewId );
- }
- }
- else
- {
- rTargetFrame.InsertDocument_Impl( *this );
- }
+ rTargetFrame.InsertDocument_Impl( *this );
SfxViewFrame* pViewFrame = rTargetFrame.GetCurrentViewFrame();
// only temporary data, don't hold it in the itemset
diff --git a/sfx2/source/view/topfrm.cxx b/sfx2/source/view/topfrm.cxx
index 0f434a115fd8..740698d34e7c 100644
--- a/sfx2/source/view/topfrm.cxx
+++ b/sfx2/source/view/topfrm.cxx
@@ -822,48 +822,30 @@ sal_Bool SfxTopFrame::InsertDocument_Impl( SfxObjectShell& rDoc )
UpdateDescriptor( &rDoc );
- SfxViewFrame* pViewFrame = GetCurrentViewFrame();
- if ( pViewFrame )
- {
- // TODO: the only client of this case is the Reload-implementation for SFX-based documents. This should be
- // migrated to use UNO mechanisms, too. In this case, we can simplify the code here.
- if ( pViewFrame->GetActiveChildFrame_Impl() && pViewFrame->GetActiveChildFrame_Impl() == SfxViewFrame::Current() )
- {
- pViewFrame->SetActiveChildFrame_Impl(0);
- SfxViewFrame::SetViewFrame( pViewFrame );
- }
+ if ( pPluginMode && pPluginMode->GetValue() != 2 )
+ SetInPlace_Impl( TRUE );
- if ( pViewFrame->GetObjectShell() )
- {
- pViewFrame->ReleaseObjectShell_Impl( sal_False );
- }
+ OSL_ENSURE( GetCurrentViewFrame() == NULL,
+ "SfxTopFrame::InsertDocument_Impl: no support (anymore) for loading a document into a non-empty frame!" );
+ // Since some refactoring in CWS autorecovery, this shouldn't happen anymore. Frame re-usage is nowadays
+ // done in higher layers, namely in the framework.
- if ( pViewIdItem )
- pViewFrame->SetViewData_Impl( pViewIdItem->GetValue(), String() );
- pViewFrame->SetObjectShell_Impl( rDoc );
- }
- else
- {
- if ( pPluginMode && pPluginMode->GetValue() != 2 )
- SetInPlace_Impl( TRUE );
-
- pViewFrame = new SfxTopViewFrame( this, &rDoc, nViewId );
- if ( !pViewFrame->GetViewShell() )
- return sal_False;
+ SfxViewFrame* pViewFrame = new SfxTopViewFrame( this, &rDoc, nViewId );
+ if ( !pViewFrame->GetViewShell() )
+ return sal_False;
- if ( pPluginMode && pPluginMode->GetValue() == 1 )
- {
- pViewFrame->ForceOuterResize_Impl( FALSE );
- pViewFrame->GetBindings().HidePopups(TRUE);
+ if ( pPluginMode && pPluginMode->GetValue() == 1 )
+ {
+ pViewFrame->ForceOuterResize_Impl( FALSE );
+ pViewFrame->GetBindings().HidePopups(TRUE);
- // MBA: layoutmanager of inplace frame starts locked and invisible
- GetWorkWindow_Impl()->MakeVisible_Impl( FALSE );
- GetWorkWindow_Impl()->Lock_Impl( TRUE );
+ // MBA: layoutmanager of inplace frame starts locked and invisible
+ GetWorkWindow_Impl()->MakeVisible_Impl( FALSE );
+ GetWorkWindow_Impl()->Lock_Impl( TRUE );
- GetWindow().SetBorderStyle( WINDOW_BORDER_NOBORDER );
- if ( GetCurrentViewFrame() )
- GetCurrentViewFrame()->GetWindow().SetBorderStyle( WINDOW_BORDER_NOBORDER );
- }
+ GetWindow().SetBorderStyle( WINDOW_BORDER_NOBORDER );
+ if ( GetCurrentViewFrame() )
+ GetCurrentViewFrame()->GetWindow().SetBorderStyle( WINDOW_BORDER_NOBORDER );
}
OSL_ENSURE( ( rDoc.Get_Impl()->nLoadedFlags & SFX_LOADED_MAINDOCUMENT ) == SFX_LOADED_MAINDOCUMENT,
diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx
index bbdfa40a78a0..081adde3a42f 100644
--- a/sfx2/source/view/viewfrm.cxx
+++ b/sfx2/source/view/viewfrm.cxx
@@ -37,6 +37,7 @@
#include <com/sun/star/document/MacroExecMode.hpp>
#include <com/sun/star/frame/XLoadable.hpp>
#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/unohlp.hxx>
@@ -56,6 +57,7 @@
#endif
#include <svtools/sfxecode.hxx>
#include <svtools/ehdl.hxx>
+#include <tools/diagnose_ex.h>
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/frame/XFramesSupplier.hpp>
#include <com/sun/star/frame/FrameSearchFlag.hpp>
@@ -66,6 +68,7 @@
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
#include <com/sun/star/document/MacroExecMode.hpp>
#include <com/sun/star/document/UpdateDocMode.hpp>
@@ -79,6 +82,7 @@
#include <unotools/localfilehelper.hxx>
#include <unotools/ucbhelper.hxx>
#include <comphelper/processfactory.hxx>
+#include <comphelper/namedvaluecollection.hxx>
#include <comphelper/configurationhelper.hxx>
#include <com/sun/star/uno/Reference.h>
@@ -245,6 +249,7 @@ SfxObjectShell* SfxViewFrame::GetImportingObjectShell_Impl() const
}
+//--------------------------------------------------------------------
class SfxViewNotificatedFrameList_Impl :
public SfxListener, public SfxViewFrameArr_Impl
{
@@ -632,25 +637,22 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
// bestehende SfxMDIFrames f"ur dieses Doc leeren
// eigenes Format oder R/O jetzt editierbar "offnen?
- SfxViewNotificatedFrameList_Impl aFrames;
SfxObjectShellLock xNewObj;
- sal_Bool bRestoreView = ( pURLItem == NULL );
TypeId aOldType = xOldObj->Type();
- SfxViewFrame *pView = GetFirst(xOldObj);
- while(pView)
+ // collect the views of the document
+ // TODO: when UNO ViewFactories are available for SFX-based documents, the below code should
+ // be UNOized, too
+ typedef ::std::pair< Reference< XFrame >, USHORT > ViewDescriptor;
+ ::std::list< ViewDescriptor > aViewFrames;
+ SfxViewFrame *pView = GetFirst( xOldObj );
+ while ( pView )
{
- if( bHandsOff )
- pView->GetDispatcher()->LockUI_Impl(sal_True);
- aFrames.InsertViewFrame( pView );
- pView->GetBindings().ENTERREGISTRATIONS();
-
- // RestoreView nur wenn keine neue Datei geladen
- // (Client-Pull-Reloading)
- pView = /*bHandsOff ? (SfxTopViewFrame*) GetFirst(
- xOldObj, TYPE(SfxTopViewFrame) ) :*/
- (SfxTopViewFrame*)GetNext( *pView, xOldObj,
- TYPE( SfxTopViewFrame ) );
+ Reference< XFrame > xFrame( pView->GetFrame()->GetFrameInterface() );
+ OSL_ENSURE( xFrame.is(), "SfxViewFrame::ExecReload_Impl: no XFrame?!" );
+ aViewFrames.push_back( ViewDescriptor( xFrame, pView->GetCurViewId() ) );
+
+ pView = (SfxTopViewFrame*)GetNext( *pView, xOldObj, TYPE( SfxTopViewFrame ) );
}
DELETEZ( xOldObj->Get_Impl()->pReloadTimer );
@@ -759,12 +761,12 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
}
xNewObj = SfxObjectShell::CreateObject( pFilter->GetServiceName(), SFX_CREATE_MODE_STANDARD );
+ uno::Sequence < beans::PropertyValue > aLoadArgs;
+ TransformItems( SID_OPENDOC, *pNewSet, aLoadArgs );
try
{
- uno::Sequence < beans::PropertyValue > aProps;
- TransformItems( SID_OPENDOC, *pNewSet, aProps );
uno::Reference < frame::XLoadable > xLoad( xNewObj->GetModel(), uno::UNO_QUERY );
- xLoad->load( aProps );
+ xLoad->load( aLoadArgs );
}
catch ( uno::Exception& )
{
@@ -816,56 +818,48 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
{
if ( xNewObj->IsDocShared() )
{
- // the file is shared but the closing can chang the sharing control file
+ // the file is shared but the closing can change the sharing control file
xOldObj->DoNotCleanShareControlFile();
}
+ // the Reload and Silent items were only temporary, remove them
xNewObj->GetMedium()->GetItemSet()->ClearItem( SID_RELOAD );
xNewObj->GetMedium()->GetItemSet()->ClearItem( SID_SILENT );
+ TransformItems( SID_OPENDOC, *xNewObj->GetMedium()->GetItemSet(), aLoadArgs );
+
UpdateDocument_Impl();
}
- SfxViewFrame* pThis = (SfxViewFrame*)this;
- sal_Bool bDeleted = aFrames.C40_GETPOS( SfxViewFrame, pThis ) == USHRT_MAX;
-
- if( !bDeleted )
+ if ( xNewObj.Is() )
{
- GetBindings().Invalidate( SID_RELOAD );
- pImp->bReloading = sal_False;
- }
-
- // neues Doc in die bestehenden SfxMDIFrames einsetzen; wenn
- // das Reload geklappt hat, mu\s in diesem Frame kein Dokument
- // eingesetzt werden, weil das schon vom LoadEnvironment
- // gemacht wurde
- if ( xNewObj.Is() && xNewObj->Type() != aOldType )
- // RestoreView nur, wenn gleicher Dokumenttyp
- bRestoreView = sal_False;
+ try
+ {
+ ::comphelper::NamedValueCollection aTransformLoadArgs( aLoadArgs );
+ Reference< XModel > xDocument( xNewObj->GetModel(), UNO_SET_THROW );
+ aTransformLoadArgs.put( "Model", xDocument );
- const sal_uInt16 nCount = aFrames.Count();
- for(sal_uInt16 i = 0; i < nCount; ++i)
- {
- SfxViewFrame *pCurrView = aFrames.GetObject( i );
- if ( xNewObj.Is() )
+ while ( !aViewFrames.empty() )
+ {
+ aTransformLoadArgs.put( "ViewId", aViewFrames.front().second );
+ Reference< XComponentLoader > xLoader( aViewFrames.front().first, UNO_QUERY_THROW );
+ xLoader->loadComponentFromURL( xDocument->getURL(), ::rtl::OUString::createFromAscii( "_self" ), 0,
+ aTransformLoadArgs.getPropertyValues() );
+ aViewFrames.pop_front();
+ }
+ }
+ catch( const Exception& )
{
- //if( /*!bHandsOff &&*/ this != pView )
- pCurrView->ReleaseObjectShell_Impl( bRestoreView );
- pCurrView->SetRestoreView_Impl( bRestoreView );
- //if( pView != this || !xNewObj.Is() )
+ // close the remaining frames
+ // Don't catch exceptions herein, if this fails, then we're left in an indetermined state, and
+ // crashing is better than trying to proceed
+ while ( !aViewFrames.empty() )
{
- SfxTopFrame* pFrame = dynamic_cast< SfxTopFrame* >( pCurrView->GetFrame() );
- OSL_ENSURE( pFrame, "An SfxFrame which is no SfxTopFrame?!" );
- if ( pFrame )
- pFrame->InsertDocument_Impl( *xNewObj );
+ Reference< util::XCloseable > xClose( aViewFrames.front().first, UNO_QUERY_THROW );
+ xClose->close( sal_True );
+ aViewFrames.pop_front();
}
}
- pCurrView->GetBindings().LEAVEREGISTRATIONS();
- pCurrView->GetDispatcher()->LockUI_Impl( sal_False );
- }
-
- if ( xNewObj.Is() )
- {
// Propagate document closure.
SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_CLOSEDOC, GlobalEventConfig::GetEventName( STR_EVENT_CLOSEDOC ), xOldObj ) );
}
@@ -873,11 +867,6 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
// als erledigt recorden
rReq.Done( sal_True );
rReq.SetReturnValue(SfxBoolItem(rReq.GetSlot(), sal_True));
- if( !bDeleted )
- {
- Notify( *GetObjectShell(), SfxSimpleHint(
- SFX_HINT_TITLECHANGED ));
- }
return;
}
else