summaryrefslogtreecommitdiff
path: root/sfx2
diff options
context:
space:
mode:
authorFrank Schoenheit [fs] <frank.schoenheit@sun.com>2010-09-01 13:39:49 +0200
committerFrank Schoenheit [fs] <frank.schoenheit@sun.com>2010-09-01 13:39:49 +0200
commit7c006c81f4d7eb4c1dd371585ca09bfc3549a0d7 (patch)
tree2f22cbb93099ba2fffaa5b392dbe7b74e01b765a /sfx2
parent6fc90af7fff8c629587051cc9c31a135da3b6a99 (diff)
dba33i: #i111146# completely put the responsibility for remembering/restoring view data, when switching to the
print preview and back, to SFX In particular, the following changes have been applied - the SfxViewFactory now supports a programmatic API name, as documented in XModel2.getAvailableViewControllerNames - the new SFX_IMPL_NAMED_VIEWFACTORY, complementing the existing SFX_IMPL_VIEWFACTORY, allows to create view factories for such named views - SfxViewFrame::SwitchToViewShell_Impl has been extended to recognize the case where a non-PrintPreview view is exchanged with another view. In this case, it preserves the view's view data at the model - Calc's own mechanism for preserving the standard view's view data, and restoring it when coming back from the print preview, has been removed completely. What probably is left here is to migrate the other applications from SFX_IMPL_VIEWFACTORY to SFX_IMPL_NAMED_VIEWFACTORY. This way, they could also benefit from the new mechanism. Also, the UNO API would then be more precise, as the view names would be speaking then, instead of the current "view<number>" names.
Diffstat (limited to 'sfx2')
-rw-r--r--sfx2/inc/sfx2/docfac.hxx2
-rw-r--r--sfx2/inc/sfx2/viewfrm.hxx1
-rw-r--r--sfx2/inc/sfx2/viewsh.hxx11
-rw-r--r--sfx2/inc/viewfac.hxx14
-rw-r--r--sfx2/source/doc/docfac.cxx4
-rw-r--r--sfx2/source/doc/sfxbasemodel.cxx4
-rw-r--r--sfx2/source/view/frmload.cxx2
-rw-r--r--sfx2/source/view/sfxbasecontroller.cxx51
-rw-r--r--sfx2/source/view/viewfac.cxx29
-rw-r--r--sfx2/source/view/viewfrm.cxx69
10 files changed, 168 insertions, 19 deletions
diff --git a/sfx2/inc/sfx2/docfac.hxx b/sfx2/inc/sfx2/docfac.hxx
index 7468394d2617..89062d7b7263 100644
--- a/sfx2/inc/sfx2/docfac.hxx
+++ b/sfx2/inc/sfx2/docfac.hxx
@@ -94,7 +94,7 @@ public:
USHORT GetViewFactoryCount() const;
SfxViewFactory& GetViewFactory(USHORT i = 0) const;
- /// returns the view factory whose GetViewName delivers the requested logical name
+ /// returns the view factory whose GetAPIViewName or GetLegacyViewName delivers the requested logical name
SfxViewFactory* GetViewFactoryByViewName( const String& i_rViewName ) const;
// Filter
diff --git a/sfx2/inc/sfx2/viewfrm.hxx b/sfx2/inc/sfx2/viewfrm.hxx
index d376236bf830..a0f5eadd5148 100644
--- a/sfx2/inc/sfx2/viewfrm.hxx
+++ b/sfx2/inc/sfx2/viewfrm.hxx
@@ -253,6 +253,7 @@ public:
private:
SAL_DLLPRIVATE BOOL SwitchToViewShell_Impl( USHORT nNo, BOOL bIsIndex = FALSE );
SAL_DLLPRIVATE void PopShellAndSubShells_Impl( SfxViewShell& i_rViewShell );
+ SAL_DLLPRIVATE void SaveCurrentViewData_Impl();
/** loads the given existing document into the given frame
diff --git a/sfx2/inc/sfx2/viewsh.hxx b/sfx2/inc/sfx2/viewsh.hxx
index 8465a238cd5b..34362500b690 100644
--- a/sfx2/inc/sfx2/viewsh.hxx
+++ b/sfx2/inc/sfx2/viewsh.hxx
@@ -134,6 +134,17 @@ public: \
} \
void Class::InitFactory()
+#define SFX_IMPL_NAMED_VIEWFACTORY(Class, AsciiViewName) \
+ SfxViewFactory* Class::pFactory; \
+ SfxViewShell* __EXPORT Class::CreateInstance(SfxViewFrame *pFrame, SfxViewShell *pOldView) \
+ { return new Class(pFrame, pOldView); } \
+ void Class::RegisterFactory( USHORT nPrio ) \
+ { \
+ pFactory = new SfxViewFactory(&CreateInstance,&InitFactory,nPrio,AsciiViewName);\
+ InitFactory(); \
+ } \
+ void Class::InitFactory()
+
#define SFX_VIEW_REGISTRATION(DocClass) \
DocClass::Factory().RegisterViewFactory( Factory() )
diff --git a/sfx2/inc/viewfac.hxx b/sfx2/inc/viewfac.hxx
index 6f9ae1d3cb37..0e6498b1f8a5 100644
--- a/sfx2/inc/viewfac.hxx
+++ b/sfx2/inc/viewfac.hxx
@@ -47,6 +47,8 @@ class SFX2_DLLPUBLIC SfxViewFactory
public:
SfxViewFactory( SfxViewCtor fnC, SfxViewInit fnI,
USHORT nOrdinal, const ResId& aDescrResId );
+ SfxViewFactory( SfxViewCtor fnC, SfxViewInit fnI,
+ USHORT nOrdinal, const sal_Char* asciiViewName );
~SfxViewFactory();
SfxViewShell *CreateInstance(SfxViewFrame *pViewFrame, SfxViewShell *pOldSh);
@@ -56,14 +58,22 @@ public:
{ return String( aDescription ); }
USHORT GetOrdinal() const { return nOrd; }
- /// returns an API-compatible view name. For the moment, this is "view" with an appended ordinal/ID
- String GetViewName() const;
+ /// returns a legacy view name. This is "view" with an appended ordinal/ID.
+ String GetLegacyViewName() const;
+
+ /** returns a API-compatible view name.
+
+ For details on which view names are specified, see the XModel2.getAvailableViewControllerNames
+ documentation.
+ */
+ String GetAPIViewName() const;
private:
SfxViewCtor fnCreate;
SfxViewInit fnInit;
USHORT nOrd;
ResId aDescription;
+ const String m_sViewName;
};
#endif
diff --git a/sfx2/source/doc/docfac.cxx b/sfx2/source/doc/docfac.cxx
index bfd67210ec44..8f8a4a969740 100644
--- a/sfx2/source/doc/docfac.cxx
+++ b/sfx2/source/doc/docfac.cxx
@@ -467,7 +467,9 @@ SfxViewFactory* SfxObjectFactory::GetViewFactoryByViewName( const String& i_rVie
)
{
SfxViewFactory& rViewFac( GetViewFactory( nViewNo ) );
- if ( rViewFac.GetViewName() == i_rViewName )
+ if ( ( rViewFac.GetAPIViewName() == i_rViewName )
+ || ( rViewFac.GetLegacyViewName() == i_rViewName )
+ )
return &rViewFac;
}
return NULL;
diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx
index fe4ffa50f67d..846cc669b9a7 100644
--- a/sfx2/source/doc/sfxbasemodel.cxx
+++ b/sfx2/source/doc/sfxbasemodel.cxx
@@ -3812,7 +3812,7 @@ css::uno::Sequence< ::rtl::OUString > SAL_CALL SfxBaseModel::getAvailableViewCon
Sequence< ::rtl::OUString > aViewNames( nViewFactoryCount );
for ( sal_Int32 nViewNo = 0; nViewNo < nViewFactoryCount; ++nViewNo )
- aViewNames[nViewNo] = rDocumentFactory.GetViewFactory( nViewNo ).GetViewName();
+ aViewNames[nViewNo] = rDocumentFactory.GetViewFactory( nViewNo ).GetAPIViewName();
return aViewNames;
}
@@ -3826,7 +3826,7 @@ css::uno::Reference< css::frame::XController2 > SAL_CALL SfxBaseModel::createDef
SfxModelGuard aGuard( *this );
const SfxObjectFactory& rDocumentFactory = GetObjectShell()->GetFactory();
- const ::rtl::OUString sDefaultViewName = rDocumentFactory.GetViewFactory( 0 ).GetViewName();
+ const ::rtl::OUString sDefaultViewName = rDocumentFactory.GetViewFactory( 0 ).GetAPIViewName();
aGuard.clear();
diff --git a/sfx2/source/view/frmload.cxx b/sfx2/source/view/frmload.cxx
index ed158ce009e3..df252b831803 100644
--- a/sfx2/source/view/frmload.cxx
+++ b/sfx2/source/view/frmload.cxx
@@ -650,7 +650,7 @@ sal_Bool SAL_CALL SfxFrameLoader_Impl::load( const Sequence< PropertyValue >& rA
// ensure the ID of the to-be-created view is in the descriptor, if possible
const sal_Int16 nViewId = impl_determineEffectiveViewId_nothrow( *xDoc, aDescriptor );
const sal_Int16 nViewNo = xDoc->GetFactory().GetViewNo_Impl( nViewId, 0 );
- const ::rtl::OUString sViewName( xDoc->GetFactory().GetViewFactory( nViewNo ).GetViewName() );
+ const ::rtl::OUString sViewName( xDoc->GetFactory().GetViewFactory( nViewNo ).GetAPIViewName() );
// if the document is created hidden, prevent it from being deleted until it is shown or disposed
impl_lockHiddenDocument( *xDoc, aDescriptor );
diff --git a/sfx2/source/view/sfxbasecontroller.cxx b/sfx2/source/view/sfxbasecontroller.cxx
index f5c24b195af7..cda5fd0bdd7d 100644
--- a/sfx2/source/view/sfxbasecontroller.cxx
+++ b/sfx2/source/view/sfxbasecontroller.cxx
@@ -118,6 +118,7 @@ using namespace ::com::sun::star;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::RuntimeException;
using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
using ::com::sun::star::lang::DisposedException;
using ::com::sun::star::awt::XWindow;
using ::com::sun::star::frame::XController;
@@ -579,7 +580,7 @@ Reference< XWindow > SAL_CALL SfxBaseController::getComponentWindow() throw (Run
::rtl::OUString sViewName;
if ( nViewNo < rDocFac.GetViewFactoryCount() )
- sViewName = rDocFac.GetViewFactory( nViewNo ).GetViewName();
+ sViewName = rDocFac.GetViewFactory( nViewNo ).GetAPIViewName();
return sViewName;
}
@@ -1421,20 +1422,52 @@ void SfxBaseController::ConnectSfxFrame_Impl( const ConnectSfxFrame i_eConnect )
// if so, forward it to the view/shell.
if ( !bHasPluginMode && !bHasJumpMark )
{
+ // Note that this might not be the ideal place here. Restoring view data should, IMO, be the
+ // responsibility of the loader, not an implementation detail burried here deep within the controller's
+ // implementation.
+ // What I think should be done to replace the below code:
+ // - change SfxBaseController::restoreViewData to also accept a PropertyValue[] (it currently accepts
+ // a string only), and forward it to its ViewShell's ReadUserDataSequence
+ // - change the frame loader so that when a new document is loaded (as opposed to an existing
+ // document being loaded into a new frame), the model's view data is examine the very same
+ // way as below, and the proper view data is set via XController::restoreViewData
+ // - extend SfxViewFrame::SwitchToViewShell_Impl. Currently, it cares for the case where a non-PrintPreview
+ // view is exchanged, and sets the old view's data at the model. It should also care for the other
+ // way, were the PrintPreview view is left: in this case, the new view should also be initialized
+ // with the model's view data
try
{
- Reference< XViewDataSupplier > xViewDataSupplier( getModel(), UNO_QUERY );
- Reference< XIndexAccess > xViewData;
- if ( xViewDataSupplier.is() )
- xViewData = xViewDataSupplier->getViewData();
- if ( xViewData.is() && xViewData->getCount() > 0 )
+ Reference< XViewDataSupplier > xViewDataSupplier( getModel(), UNO_QUERY_THROW );
+ Reference< XIndexAccess > xViewData( xViewDataSupplier->getViewData(), UNO_SET_THROW );
+
+ // find the view data item whose ViewId matches the ID of the view we're just connecting to
+ const SfxObjectFactory& rDocFactory( rDoc.GetFactory() );
+ const sal_Int32 nCount = xViewData->getCount();
+ sal_Int32 nViewDataIndex = 0;
+ for ( sal_Int32 i=0; i<nCount; ++i )
{
- Sequence< PropertyValue > aViewData;
- if ( ( xViewData->getByIndex( 0 ) >>= aViewData ) && ( aViewData.getLength() ) )
+ const ::comphelper::NamedValueCollection aViewData( xViewData->getByIndex(i) );
+ ::rtl::OUString sViewId( aViewData.getOrDefault( "ViewId", ::rtl::OUString() ) );
+ if ( sViewId.getLength() == 0 )
+ continue;
+
+ const SfxViewFactory* pViewFactory = rDocFactory.GetViewFactoryByViewName( sViewId );
+ if ( pViewFactory == NULL )
+ continue;
+
+ if ( pViewFactory->GetOrdinal() == pViewFrame->GetCurViewId() )
{
- m_pData->m_pViewShell->ReadUserDataSequence( aViewData, TRUE );
+ nViewDataIndex = i;
+ break;
}
}
+ if ( nViewDataIndex < nCount )
+ {
+ Sequence< PropertyValue > aViewData;
+ OSL_VERIFY( xViewData->getByIndex( nViewDataIndex ) >>= aViewData );
+ if ( aViewData.getLength() > 0 )
+ m_pData->m_pViewShell->ReadUserDataSequence( aViewData, TRUE );
+ }
}
catch( const Exception& )
{
diff --git a/sfx2/source/view/viewfac.cxx b/sfx2/source/view/viewfac.cxx
index b58bbc2840da..5ef64a2a8b0d 100644
--- a/sfx2/source/view/viewfac.cxx
+++ b/sfx2/source/view/viewfac.cxx
@@ -30,6 +30,7 @@
// INCLUDE ---------------------------------------------------------------
#include <sfx2/app.hxx>
+#include "sfxresid.hxx"
#include <rtl/ustrbuf.hxx>
#include "viewfac.hxx"
@@ -49,7 +50,7 @@ void SfxViewFactory::InitFactory()
(*fnInit)();
}
-String SfxViewFactory::GetViewName() const
+String SfxViewFactory::GetLegacyViewName() const
{
::rtl::OUStringBuffer aViewName;
aViewName.appendAscii( "view" );
@@ -57,6 +58,17 @@ String SfxViewFactory::GetViewName() const
return aViewName.makeStringAndClear();
}
+String SfxViewFactory::GetAPIViewName() const
+{
+ if ( m_sViewName.Len() > 0 )
+ return m_sViewName;
+
+ if ( GetOrdinal() == 0 )
+ return String::CreateFromAscii( "Default" );
+
+ return GetLegacyViewName();
+}
+
// CTOR / DTOR -----------------------------------------------------------
SfxViewFactory::SfxViewFactory( SfxViewCtor fnC, SfxViewInit fnI,
@@ -64,11 +76,22 @@ SfxViewFactory::SfxViewFactory( SfxViewCtor fnC, SfxViewInit fnI,
fnCreate(fnC),
fnInit(fnI),
nOrd(nOrdinal),
- aDescription(aDescrResId.GetId(), *aDescrResId.GetResMgr())
+ aDescription(aDescrResId.GetId(), *aDescrResId.GetResMgr()),
+ m_sViewName()
{
aDescription.SetRT(aDescrResId.GetRT());
DBG_CTOR(SfxViewFactory, 0);
-// SFX_APP()->RegisterViewFactory_Impl(*this);
+}
+
+SfxViewFactory::SfxViewFactory( SfxViewCtor fnC, SfxViewInit fnI,
+ USHORT nOrdinal, const sal_Char* asciiViewName ):
+ fnCreate(fnC),
+ fnInit(fnI),
+ nOrd(nOrdinal),
+ aDescription( SfxResId( 0 ) ),
+ m_sViewName( String::CreateFromAscii( asciiViewName ) )
+{
+ DBG_CTOR(SfxViewFactory, 0);
}
SfxViewFactory::~SfxViewFactory()
diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx
index ed924623c700..f1e6e45c5217 100644
--- a/sfx2/source/view/viewfrm.cxx
+++ b/sfx2/source/view/viewfrm.cxx
@@ -75,6 +75,8 @@
#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/document/XViewDataSupplier.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
#include <rtl/ustrbuf.hxx>
#include <unotools/localfilehelper.hxx>
@@ -106,6 +108,8 @@ using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::lang;
using ::com::sun::star::awt::XWindow;
using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::document::XViewDataSupplier;
+using ::com::sun::star::container::XIndexContainer;
namespace css = ::com::sun::star;
#ifndef GCC
@@ -2242,6 +2246,68 @@ SfxViewFrame* SfxViewFrame::Get( const Reference< XController>& i_rController, c
//--------------------------------------------------------------------
+void SfxViewFrame::SaveCurrentViewData_Impl()
+{
+ SfxViewShell* pCurrentShell = GetViewShell();
+ ENSURE_OR_RETURN_VOID( pCurrentShell != NULL, "SfxViewFrame::SaveCurrentViewData_Impl: no current view shell -> no current view data!" );
+
+ // determine the logical (API) view name
+ const SfxObjectFactory& rDocFactory( pCurrentShell->GetObjectShell()->GetFactory() );
+ const sal_uInt16 nViewNo = rDocFactory.GetViewNo_Impl( GetCurViewId(), 0 );
+ const String sViewName = rDocFactory.GetViewFactory( nViewNo ).GetAPIViewName();
+ if ( sViewName.Len() == 0 )
+ {
+ // can't say anything about the view, the respective application did not yet migrate its code to
+ // named view factories => bail out
+ return;
+ }
+
+ // do *not* save view data when the view is a print preview
+ if ( sViewName.EqualsAscii( "PrintPreview" ) )
+ return;
+
+ // retrieve the view data from the view
+ Sequence< PropertyValue > aViewData;
+ pCurrentShell->WriteUserDataSequence( aViewData );
+
+ try
+ {
+ // retrieve view data (for *all* views) from the model
+ const Reference< XController > xController( pCurrentShell->GetController(), UNO_SET_THROW );
+ const Reference< XViewDataSupplier > xViewDataSupplier( xController->getModel(), UNO_QUERY_THROW );
+ const Reference< XIndexContainer > xViewData( xViewDataSupplier->getViewData(), UNO_QUERY_THROW );
+
+ // look up the one view data item which corresponds to our current view, and remove it
+ const sal_Int32 nCount = xViewData->getCount();
+ for ( sal_Int32 i=0; i<nCount; ++i )
+ {
+ const ::comphelper::NamedValueCollection aViewData( xViewData->getByIndex(i) );
+ ::rtl::OUString sViewId( aViewData.getOrDefault( "ViewId", ::rtl::OUString() ) );
+ if ( sViewId.getLength() == 0 )
+ continue;
+
+ const SfxViewFactory* pViewFactory = rDocFactory.GetViewFactoryByViewName( sViewId );
+ if ( pViewFactory == NULL )
+ continue;
+
+ if ( pViewFactory->GetOrdinal() == GetCurViewId() )
+ {
+ xViewData->removeByIndex(i);
+ break;
+ }
+ }
+
+ // then replace it with the most recent view data we just obtained
+ xViewData->insertByIndex( 0, makeAny( aViewData ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+//--------------------------------------------------------------------
+
sal_Bool SfxViewFrame::SwitchToViewShell_Impl
(
sal_uInt16 nViewIdOrNo, /* > 0
@@ -2304,6 +2370,9 @@ sal_Bool SfxViewFrame::SwitchToViewShell_Impl
SfxObjectFactory& rDocFact = GetObjectShell()->GetFactory();
const USHORT nViewId = ( bIsIndex || !nViewIdOrNo ) ? rDocFact.GetViewFactory( nViewIdOrNo ).GetOrdinal() : nViewIdOrNo;
+ // save the view data of the old view, so it can be restored later on (when needed)
+ SaveCurrentViewData_Impl();
+
// create and load new ViewShell
SfxViewShell* pNewSh = LoadViewIntoFrame_Impl(
*GetObjectShell(),