diff options
-rw-r--r-- | sfx2/inc/sfx2/docfac.hxx | 2 | ||||
-rw-r--r-- | sfx2/inc/sfx2/viewfrm.hxx | 1 | ||||
-rw-r--r-- | sfx2/inc/sfx2/viewsh.hxx | 11 | ||||
-rw-r--r-- | sfx2/inc/viewfac.hxx | 14 | ||||
-rw-r--r-- | sfx2/source/doc/docfac.cxx | 4 | ||||
-rw-r--r-- | sfx2/source/doc/sfxbasemodel.cxx | 4 | ||||
-rw-r--r-- | sfx2/source/view/frmload.cxx | 2 | ||||
-rw-r--r-- | sfx2/source/view/sfxbasecontroller.cxx | 51 | ||||
-rw-r--r-- | sfx2/source/view/viewfac.cxx | 29 | ||||
-rw-r--r-- | sfx2/source/view/viewfrm.cxx | 69 |
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(), |