1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
26 #include <config_features.h>
28 #include <sfx2/sfxbasemodel.hxx>
30 #include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
31 #include <com/sun/star/task/XInteractionHandler.hpp>
32 #include <com/sun/star/task/ErrorCodeIOException.hpp>
33 #include <com/sun/star/task/ErrorCodeRequest2.hpp>
34 #include <com/sun/star/view/XSelectionSupplier.hpp>
35 #include <com/sun/star/view/XPrintJobListener.hpp>
36 #include <com/sun/star/lang/DisposedException.hpp>
37 #include <com/sun/star/lang/IllegalArgumentException.hpp>
38 #include <com/sun/star/lang/NoSupportException.hpp>
39 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
40 #include <com/sun/star/lang/NotInitializedException.hpp>
41 #include <com/sun/star/frame/Desktop.hpp>
42 #include <com/sun/star/frame/IllegalArgumentIOException.hpp>
43 #include <com/sun/star/frame/XUntitledNumbers.hpp>
44 #include <com/sun/star/frame/DoubleInitializationException.hpp>
45 #include <com/sun/star/embed/XStorage.hpp>
46 #include <com/sun/star/document/XStorageChangeListener.hpp>
47 #include <com/sun/star/beans/XPropertySet.hpp>
48 #include <com/sun/star/beans/XPropertySetInfo.hpp>
49 #include <com/sun/star/container/XIndexContainer.hpp>
50 #include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp>
51 #include <com/sun/star/script/provider/XScriptProvider.hpp>
52 #include <com/sun/star/ui/UIConfigurationManager.hpp>
53 #include <com/sun/star/embed/ElementModes.hpp>
54 #include <com/sun/star/embed/Aspects.hpp>
55 #include <com/sun/star/document/DocumentProperties.hpp>
56 #include <com/sun/star/frame/XTransientDocumentsDocumentContentFactory.hpp>
57 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
58 #include <com/sun/star/ucb/ContentCreationException.hpp>
59 #include <com/sun/star/ucb/CommandAbortedException.hpp>
60 #include <com/sun/star/util/XCloneable.hpp>
61 #include <com/sun/star/util/InvalidStateException.hpp>
62 #include <com/sun/star/util/CloseVetoException.hpp>
63 #include <comphelper/enumhelper.hxx>
64 #include <comphelper/indexedpropertyvalues.hxx>
65 #include <comphelper/interfacecontainer3.hxx>
66 #include <comphelper/string.hxx>
68 #include <cppuhelper/implbase.hxx>
69 #include <comphelper/lok.hxx>
70 #include <comphelper/multicontainer2.hxx>
71 #include <cppuhelper/exc_hlp.hxx>
72 #include <comphelper/processfactory.hxx>
73 #include <comphelper/propertyvalue.hxx>
74 #include <comphelper/sequenceashashmap.hxx>
75 #include <comphelper/namedvaluecollection.hxx>
76 #include <o3tl/safeint.hxx>
77 #include <o3tl/string_view.hxx>
78 #include <svl/itemset.hxx>
79 #include <svl/stritem.hxx>
80 #include <svl/eitem.hxx>
81 #include <svl/grabbagitem.hxx>
82 #include <tools/urlobj.hxx>
83 #include <tools/debug.hxx>
84 #include <comphelper/diagnose_ex.hxx>
85 #include <tools/svborder.hxx>
86 #include <unotools/tempfile.hxx>
87 #include <osl/mutex.hxx>
88 #include <comphelper/errcode.hxx>
89 #include <vcl/filter/SvmWriter.hxx>
90 #include <vcl/salctype.hxx>
91 #include <vcl/gdimtf.hxx>
92 #include <comphelper/fileformat.h>
93 #include <comphelper/servicehelper.hxx>
94 #include <comphelper/storagehelper.hxx>
95 #include <toolkit/helper/vclunohelper.hxx>
96 #include <vcl/transfer.hxx>
97 #include <svtools/ehdl.hxx>
98 #include <svtools/sfxecode.hxx>
99 #include <sal/log.hxx>
100 #include <framework/configimporter.hxx>
101 #include <framework/titlehelper.hxx>
102 #include <comphelper/numberedcollection.hxx>
103 #include <unotools/ucbhelper.hxx>
104 #include <ucbhelper/content.hxx>
106 #include <sfx2/sfxbasecontroller.hxx>
107 #include <sfx2/viewfac.hxx>
108 #include <workwin.hxx>
109 #include <sfx2/signaturestate.hxx>
110 #include <sfx2/sfxuno.hxx>
111 #include <objshimp.hxx>
112 #include <sfx2/viewfrm.hxx>
113 #include <sfx2/viewsh.hxx>
114 #include <sfx2/docfile.hxx>
115 #include <sfx2/docfilt.hxx>
116 #include <sfx2/dispatch.hxx>
117 #include <sfx2/module.hxx>
118 #include <basic/basmgr.hxx>
119 #include <sfx2/event.hxx>
120 #include <eventsupplier.hxx>
121 #include <sfx2/sfxsids.hrc>
122 #include <sfx2/strings.hrc>
123 #include <sfx2/app.hxx>
124 #include <sfx2/docfac.hxx>
125 #include <sfx2/fcontnr.hxx>
126 #include <sfx2/docstoragemodifylistener.hxx>
127 #include <sfx2/brokenpackageint.hxx>
128 #include "graphhelp.hxx"
129 #include <docundomanager.hxx>
130 #include <openurlhint.hxx>
131 #include <sfx2/msgpool.hxx>
132 #include <sfx2/DocumentMetadataAccess.hxx>
133 #include "printhelper.hxx"
134 #include <sfx2/sfxresid.hxx>
135 #include <sfx2/filedlghelper.hxx>
136 #include <comphelper/profilezone.hxx>
137 #include <vcl/threadex.hxx>
138 #include <unotools/mediadescriptor.hxx>
140 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
145 using namespace ::com::sun::star
;
146 using namespace ::com::sun::star::uno
;
147 using ::com::sun::star::beans::PropertyValue
;
148 using ::com::sun::star::document::CmisProperty
;
149 using ::com::sun::star::frame::XFrame
;
150 using ::com::sun::star::frame::XController
;
151 using ::com::sun::star::frame::XController2
;
152 using ::com::sun::star::lang::IllegalArgumentException
;
153 using ::com::sun::star::io::IOException
;
154 using ::com::sun::star::uno::Sequence
;
155 using ::com::sun::star::document::XDocumentRecovery
;
156 using ::com::sun::star::document::XUndoManager
;
157 using ::com::sun::star::document::XUndoAction
;
158 using ::com::sun::star::frame::XModel
;
162 /** This Listener is used to get notified when the XDocumentProperties of the
165 class SfxDocInfoListener_Impl
: public ::cppu::WeakImplHelper
<
166 util::XModifyListener
>
170 SfxObjectShell
& m_rShell
;
172 explicit SfxDocInfoListener_Impl( SfxObjectShell
& i_rDoc
)
176 virtual void SAL_CALL
disposing( const lang::EventObject
& ) override
;
177 virtual void SAL_CALL
modified( const lang::EventObject
& ) override
;
182 void SAL_CALL
SfxDocInfoListener_Impl::modified( const lang::EventObject
& )
184 SolarMutexGuard aSolarGuard
;
186 // notify changes to the SfxObjectShell
187 m_rShell
.FlushDocInfo();
190 void SAL_CALL
SfxDocInfoListener_Impl::disposing( const lang::EventObject
& )
195 // impl. declarations
198 struct IMPL_SfxBaseModel_DataContainer
: public ::sfx2::IModifiableDocument
200 // counter for SfxBaseModel instances created.
201 inline static std::atomic
<sal_Int64
> g_nInstanceCounter
= 0 ;
202 SfxObjectShellRef m_pObjectShell
;
204 OUString m_sRuntimeUID
;
205 OUString m_aPreusedFilterName
;
206 comphelper::OInterfaceContainerHelper3
<view::XPrintJobListener
> m_aPrintJobListeners
;
207 comphelper::OInterfaceContainerHelper3
<lang::XEventListener
> m_aEventListeners
;
208 comphelper::OInterfaceContainerHelper3
<util::XModifyListener
> m_aModifyListeners
;
209 comphelper::OInterfaceContainerHelper3
<document::XEventListener
> m_aDocumentEventListeners1
;
210 comphelper::OInterfaceContainerHelper3
<document::XDocumentEventListener
> m_aDocumentEventListeners2
;
211 comphelper::OInterfaceContainerHelper3
<document::XStorageChangeListener
> m_aStorageChangeListeners
;
212 comphelper::OInterfaceContainerHelper3
<util::XCloseListener
> m_aCloseListeners
;
213 std::unordered_map
<css::uno::Reference
< css::drawing::XShape
>,
214 std::vector
<css::uno::Reference
< css::document::XShapeEventListener
>>> maShapeListeners
;
215 Reference
< XInterface
> m_xParent
;
216 Reference
< frame::XController
> m_xCurrent
;
217 Reference
< document::XDocumentProperties
> m_xDocumentProperties
;
218 Reference
< script::XStarBasicAccess
> m_xStarBasicAccess
;
219 rtl::Reference
< SfxEvents_Impl
> m_xEvents
;
220 Sequence
< beans::PropertyValue
> m_seqArguments
;
221 std::vector
< Reference
< frame::XController
> > m_seqControllers
;
222 Reference
< container::XIndexAccess
> m_contViewData
;
223 sal_uInt16 m_nControllerLockCount
;
228 bool m_bExternalTitle
;
230 rtl::Reference
< SfxPrintHelper
> m_xPrintable
;
231 Reference
< ui::XUIConfigurationManager2
> m_xUIConfigurationManager
;
232 ::rtl::Reference
< ::sfx2::DocumentStorageModifyListener
> m_pStorageModifyListen
;
233 OUString m_sModuleIdentifier
;
234 rtl::Reference
< ::framework::TitleHelper
> m_xTitleHelper
;
235 rtl::Reference
< ::comphelper::NumberedCollection
> m_xNumberedControllers
;
236 rtl::Reference
<::sfx2::DocumentMetadataAccess
> m_xDocumentMetadata
;
237 ::rtl::Reference
< ::sfx2::DocumentUndoManager
> m_pDocumentUndoManager
;
238 Sequence
< document::CmisProperty
> m_cmisProperties
;
239 std::shared_ptr
<SfxGrabBagItem
> m_xGrabBagItem
;
240 std::optional
<std::chrono::steady_clock::time_point
> m_oDirtyTimestamp
;
242 IMPL_SfxBaseModel_DataContainer( ::osl::Mutex
& rMutex
, SfxObjectShell
* pObjectShell
)
243 : m_pObjectShell ( pObjectShell
)
244 , m_aPrintJobListeners ( rMutex
)
245 , m_aEventListeners ( rMutex
)
246 , m_aModifyListeners ( rMutex
)
247 , m_aDocumentEventListeners1( rMutex
)
248 , m_aDocumentEventListeners2( rMutex
)
249 , m_aStorageChangeListeners ( rMutex
)
250 , m_aCloseListeners ( rMutex
)
251 , m_nControllerLockCount ( 0 )
252 , m_bClosed ( false )
253 , m_bClosing ( false )
254 , m_bSaving ( false )
255 , m_bSuicide ( false )
256 , m_bExternalTitle ( false )
257 , m_bDisposing ( false )
259 // increase global instance counter, and set own Runtime UID
260 m_sRuntimeUID
= OUString::number(++g_nInstanceCounter
);
263 virtual ~IMPL_SfxBaseModel_DataContainer()
267 // ::sfx2::IModifiableDocument
268 virtual void storageIsModified() override
270 if ( m_pObjectShell
.is() && !m_pObjectShell
->IsModified() )
271 m_pObjectShell
->SetModified();
274 void impl_setDocumentProperties(
275 const Reference
< document::XDocumentProperties
>& );
277 Reference
<rdf::XDocumentMetadataAccess
> GetDMA()
279 if (!m_xDocumentMetadata
.is())
281 OSL_ENSURE(m_pObjectShell
.is(), "GetDMA: no object shell?");
282 if (!m_pObjectShell
.is())
287 const Reference
<XComponentContext
>& xContext(
288 ::comphelper::getProcessComponentContext());
289 const Reference
<frame::XModel
> xModel(
290 m_pObjectShell
->GetModel());
291 const Reference
<lang::XMultiComponentFactory
> xMsf(
292 xContext
->getServiceManager());
293 const Reference
<frame::
294 XTransientDocumentsDocumentContentFactory
> xTDDCF(
295 xMsf
->createInstanceWithContext(
296 u
"com.sun.star.frame.TransientDocumentsDocumentContentFactory"_ustr
,
299 const Reference
<ucb::XContent
> xContent(
300 xTDDCF
->createDocumentContent(xModel
) );
301 OSL_ENSURE(xContent
.is(), "GetDMA: cannot create DocumentContent");
306 OUString uri
= xContent
->getIdentifier()->getContentIdentifier();
307 OSL_ENSURE(!uri
.isEmpty(), "GetDMA: empty uri?");
308 if (!uri
.isEmpty() && !uri
.endsWith("/"))
313 m_xDocumentMetadata
= new ::sfx2::DocumentMetadataAccess(
314 xContext
, *m_pObjectShell
, uri
);
316 return m_xDocumentMetadata
;
319 rtl::Reference
<::sfx2::DocumentMetadataAccess
> CreateDMAUninitialized()
321 return (m_pObjectShell
.is())
322 ? new ::sfx2::DocumentMetadataAccess(
323 ::comphelper::getProcessComponentContext(), *m_pObjectShell
)
327 void setModifiedForAutoSave(bool val
)
331 if (!m_oDirtyTimestamp
)
332 m_oDirtyTimestamp
.emplace(std::chrono::steady_clock::now());
336 m_oDirtyTimestamp
.reset();
343 // Listener that forwards notifications from the PrintHelper to the "real" listeners
344 class SfxPrintHelperListener_Impl
: public ::cppu::WeakImplHelper
< view::XPrintJobListener
>
347 IMPL_SfxBaseModel_DataContainer
* m_pData
;
348 explicit SfxPrintHelperListener_Impl( IMPL_SfxBaseModel_DataContainer
* pData
)
352 virtual void SAL_CALL
disposing( const lang::EventObject
& aEvent
) override
;
353 virtual void SAL_CALL
printJobEvent( const view::PrintJobEvent
& rEvent
) override
;
358 void SAL_CALL
SfxPrintHelperListener_Impl::disposing( const lang::EventObject
& )
360 m_pData
->m_xPrintable
= nullptr;
363 void SAL_CALL
SfxPrintHelperListener_Impl::printJobEvent( const view::PrintJobEvent
& rEvent
)
365 if ( m_pData
->m_aPrintJobListeners
.getLength() )
367 m_pData
->m_aPrintJobListeners
.notifyEach(&view::XPrintJobListener::printJobEvent
, rEvent
);
373 // SfxOwnFramesLocker ====================================================================================
374 // allows to lock all the frames related to the provided SfxObjectShell
375 class SfxOwnFramesLocker
377 Sequence
< Reference
< frame::XFrame
> > m_aLockedFrames
;
379 static vcl::Window
* GetVCLWindow( const Reference
< frame::XFrame
>& xFrame
);
381 explicit SfxOwnFramesLocker( SfxObjectShell
const * ObjechShell
);
382 ~SfxOwnFramesLocker();
387 SfxOwnFramesLocker::SfxOwnFramesLocker( SfxObjectShell
const * pObjectShell
)
392 if ( comphelper::LibreOfficeKit::isForkedChild() )
393 return; // no need to tweak UI when in the background
395 for ( SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( pObjectShell
);
397 pFrame
= SfxViewFrame::GetNext( *pFrame
, pObjectShell
)
400 SfxFrame
& rSfxFrame
= pFrame
->GetFrame();
403 // get vcl window related to the frame and lock it if it is still not locked
404 const Reference
< frame::XFrame
>& xFrame
= rSfxFrame
.GetFrameInterface();
405 vcl::Window
* pWindow
= GetVCLWindow( xFrame
);
407 throw RuntimeException();
409 if ( pWindow
->IsEnabled() )
415 sal_Int32 nLen
= m_aLockedFrames
.getLength();
416 m_aLockedFrames
.realloc( nLen
+ 1 );
417 m_aLockedFrames
.getArray()[nLen
] = xFrame
;
428 OSL_FAIL( "Not possible to lock the frame window!" );
433 SfxOwnFramesLocker::~SfxOwnFramesLocker()
435 for ( auto& rFrame
: asNonConstRange(m_aLockedFrames
) )
441 // get vcl window related to the frame and unlock it
442 vcl::Window
* pWindow
= GetVCLWindow( rFrame
);
444 throw RuntimeException();
453 OSL_FAIL( "Can't unlock the frame window!" );
458 vcl::Window
* SfxOwnFramesLocker::GetVCLWindow( const Reference
< frame::XFrame
>& xFrame
)
460 VclPtr
<vcl::Window
> pWindow
;
464 Reference
< awt::XWindow
> xWindow
= xFrame
->getContainerWindow();
466 pWindow
= VCLUnoHelper::GetWindow( xWindow
);
474 // SfxSaveGuard ====================================================================================
478 Reference
< frame::XModel
> m_xModel
;
479 IMPL_SfxBaseModel_DataContainer
* m_pData
;
480 std::unique_ptr
<SfxOwnFramesLocker
> m_pFramesLock
;
482 SfxSaveGuard(SfxSaveGuard
const &) = delete;
483 void operator =(const SfxSaveGuard
&) = delete;
486 SfxSaveGuard(const Reference
< frame::XModel
>& xModel
,
487 IMPL_SfxBaseModel_DataContainer
* pData
);
493 SfxSaveGuard::SfxSaveGuard(const Reference
< frame::XModel
>& xModel
,
494 IMPL_SfxBaseModel_DataContainer
* pData
)
495 : m_xModel ( xModel
)
498 if ( m_pData
->m_bClosed
)
499 throw lang::DisposedException(u
"Object already disposed."_ustr
);
501 m_pData
->m_bSaving
= true;
502 m_pFramesLock
.reset(new SfxOwnFramesLocker( m_pData
->m_pObjectShell
.get() ));
505 SfxSaveGuard::~SfxSaveGuard()
507 m_pFramesLock
.reset();
509 m_pData
->m_bSaving
= false;
511 // m_bSuicide was set e.g. in case someone tried to close a document, while it was used for
512 // storing at the same time. Further m_bSuicide was set to sal_True only if close(sal_True) was called.
513 // So the ownership was delegated to the place where a veto exception was thrown.
514 // Now we have to call close() again and delegate the ownership to the next one, which
515 // can't accept that. Close(sal_False) can't work in this case. Because then the document will may be never closed...
517 if ( !m_pData
->m_bSuicide
)
520 // Reset this state. In case the new close() request is not accepted by someone else...
521 // it's not a good idea to have two "owners" for close.-)
522 m_pData
->m_bSuicide
= false;
525 Reference
< util::XCloseable
> xClose(m_xModel
, UNO_QUERY
);
529 catch(const util::CloseVetoException
&)
533 SfxBaseModel::SfxBaseModel( SfxObjectShell
*pObjectShell
)
535 , m_pData( std::make_shared
<IMPL_SfxBaseModel_DataContainer
>( m_aMutex
, pObjectShell
) )
536 , m_bSupportEmbeddedScripts( pObjectShell
&& pObjectShell
->Get_Impl() && !pObjectShell
->Get_Impl()->m_bNoBasicCapabilities
)
537 , m_bSupportDocRecovery( pObjectShell
&& pObjectShell
->Get_Impl() && pObjectShell
->Get_Impl()->m_bDocRecoverySupport
)
539 if ( pObjectShell
!= nullptr )
541 StartListening( *pObjectShell
) ;
546 SfxBaseModel::~SfxBaseModel()
551 Any SAL_CALL
SfxBaseModel::queryInterface( const uno::Type
& rType
)
553 if ( ( !m_bSupportEmbeddedScripts
&& rType
.equals( cppu::UnoType
<document::XEmbeddedScripts
>::get() ) )
554 || ( !m_bSupportDocRecovery
&& (rType
.equals( cppu::UnoType
<XDocumentRecovery
>::get() ) || rType
.equals( cppu::UnoType
<XDocumentRecovery2
>::get() )) )
558 return SfxBaseModel_Base::queryInterface( rType
);
567 void lcl_stripType( Sequence
< uno::Type
>& io_rTypes
, const uno::Type
& i_rTypeToStrip
)
569 Sequence
< uno::Type
> aStrippedTypes( io_rTypes
.getLength() - 1 );
570 ::std::remove_copy_if(
571 std::cbegin(io_rTypes
),
572 std::cend(io_rTypes
),
573 aStrippedTypes
.getArray(),
574 [&i_rTypeToStrip
](const uno::Type
& aType
) { return aType
== i_rTypeToStrip
; }
576 io_rTypes
= std::move(aStrippedTypes
);
580 Sequence
< uno::Type
> SAL_CALL
SfxBaseModel::getTypes()
582 Sequence
< uno::Type
> aTypes( SfxBaseModel_Base::getTypes() );
584 if ( !m_bSupportEmbeddedScripts
)
585 lcl_stripType( aTypes
, cppu::UnoType
<document::XEmbeddedScripts
>::get() );
587 if ( !m_bSupportDocRecovery
)
588 lcl_stripType( aTypes
, cppu::UnoType
<XDocumentRecovery2
>::get() );
597 Sequence
< sal_Int8
> SAL_CALL
SfxBaseModel::getImplementationId()
599 return css::uno::Sequence
<sal_Int8
>();
605 #if HAVE_FEATURE_SCRIPTING
607 static Reference
< script::XStarBasicAccess
> implGetStarBasicAccess( SfxObjectShell
const * pObjectShell
)
609 Reference
< script::XStarBasicAccess
> xRet
;
611 #if !HAVE_FEATURE_SCRIPTING
616 BasicManager
* pMgr
= pObjectShell
->GetBasicManager();
617 xRet
= getStarBasicAccess( pMgr
);
625 Reference
< container::XNameContainer
> SAL_CALL
SfxBaseModel::getLibraryContainer()
627 #if !HAVE_FEATURE_SCRIPTING
628 Reference
< container::XNameContainer
> dummy
;
632 SfxModelGuard
aGuard( *this );
634 Reference
< script::XStarBasicAccess
>& rxAccess
= m_pData
->m_xStarBasicAccess
;
635 if( !rxAccess
.is() && m_pData
->m_pObjectShell
.is() )
636 rxAccess
= implGetStarBasicAccess( m_pData
->m_pObjectShell
.get() );
638 Reference
< container::XNameContainer
> xRet
;
640 xRet
= rxAccess
->getLibraryContainer();
645 /**___________________________________________________________________________________________________
646 @seealso XStarBasicAccess
648 void SAL_CALL
SfxBaseModel::createLibrary( const OUString
& LibName
, const OUString
& Password
,
649 const OUString
& ExternalSourceURL
, const OUString
& LinkTargetURL
)
651 #if !HAVE_FEATURE_SCRIPTING
654 (void) ExternalSourceURL
;
655 (void) LinkTargetURL
;
657 SfxModelGuard
aGuard( *this );
659 Reference
< script::XStarBasicAccess
>& rxAccess
= m_pData
->m_xStarBasicAccess
;
660 if( !rxAccess
.is() && m_pData
->m_pObjectShell
.is() )
661 rxAccess
= implGetStarBasicAccess( m_pData
->m_pObjectShell
.get() );
664 rxAccess
->createLibrary( LibName
, Password
, ExternalSourceURL
, LinkTargetURL
);
668 /**___________________________________________________________________________________________________
669 @seealso XStarBasicAccess
671 void SAL_CALL
SfxBaseModel::addModule( const OUString
& LibraryName
, const OUString
& ModuleName
,
672 const OUString
& Language
, const OUString
& Source
)
674 #if !HAVE_FEATURE_SCRIPTING
680 SfxModelGuard
aGuard( *this );
682 Reference
< script::XStarBasicAccess
>& rxAccess
= m_pData
->m_xStarBasicAccess
;
683 if( !rxAccess
.is() && m_pData
->m_pObjectShell
.is() )
684 rxAccess
= implGetStarBasicAccess( m_pData
->m_pObjectShell
.get() );
687 rxAccess
->addModule( LibraryName
, ModuleName
, Language
, Source
);
691 /**___________________________________________________________________________________________________
692 @seealso XStarBasicAccess
694 void SAL_CALL
SfxBaseModel::addDialog( const OUString
& LibraryName
, const OUString
& DialogName
,
695 const Sequence
< sal_Int8
>& Data
)
697 #if !HAVE_FEATURE_SCRIPTING
702 SfxModelGuard
aGuard( *this );
704 Reference
< script::XStarBasicAccess
>& rxAccess
= m_pData
->m_xStarBasicAccess
;
705 if( !rxAccess
.is() && m_pData
->m_pObjectShell
.is() )
706 rxAccess
= implGetStarBasicAccess( m_pData
->m_pObjectShell
.get() );
709 rxAccess
->addDialog( LibraryName
, DialogName
, Data
);
717 Reference
< XInterface
> SAL_CALL
SfxBaseModel::getParent()
719 SfxModelGuard
aGuard( *this );
721 return m_pData
->m_xParent
;
728 void SAL_CALL
SfxBaseModel::setParent(const Reference
< XInterface
>& Parent
)
730 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
731 m_pData
->m_xParent
= Parent
;
738 void SAL_CALL
SfxBaseModel::dispose()
740 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
742 if ( !m_pData
->m_bClosed
)
744 // gracefully accept wrong dispose calls instead of close call
745 // and try to make it work (may be really disposed later!)
750 catch ( util::CloseVetoException
& )
757 if ( m_pData
->m_bDisposing
)
759 m_pData
->m_bDisposing
= true;
761 if ( m_pData
->m_pStorageModifyListen
.is() )
763 m_pData
->m_pStorageModifyListen
->dispose();
764 m_pData
->m_pStorageModifyListen
= nullptr;
767 if ( m_pData
->m_pDocumentUndoManager
.is() )
769 m_pData
->m_pDocumentUndoManager
->disposing();
770 m_pData
->m_pDocumentUndoManager
= nullptr;
773 lang::EventObject
aEvent( static_cast<frame::XModel
*>(this) );
774 m_pData
->m_aPrintJobListeners
.disposeAndClear( aEvent
);
775 m_pData
->m_aEventListeners
.disposeAndClear( aEvent
);
776 m_pData
->m_aModifyListeners
.disposeAndClear( aEvent
);
777 m_pData
->m_aDocumentEventListeners1
.disposeAndClear( aEvent
);
778 m_pData
->m_aDocumentEventListeners2
.disposeAndClear( aEvent
);
779 m_pData
->m_aStorageChangeListeners
.disposeAndClear( aEvent
);
780 m_pData
->m_aCloseListeners
.disposeAndClear( aEvent
);
782 m_pData
->m_xDocumentProperties
.clear();
784 m_pData
->m_xDocumentMetadata
.clear();
786 if ( m_pData
->m_pObjectShell
.is() )
788 EndListening( *m_pData
->m_pObjectShell
);
791 m_pData
->m_xCurrent
.clear();
792 m_pData
->m_seqControllers
.clear();
794 // m_pData member must be set to zero before delete is called to
795 // force disposed exception whenever someone tries to access our
796 // instance while in the dtor.
804 void SAL_CALL
SfxBaseModel::addEventListener( const Reference
< lang::XEventListener
>& aListener
)
806 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
807 m_pData
->m_aEventListeners
.addInterface( aListener
);
814 void SAL_CALL
SfxBaseModel::removeEventListener( const Reference
< lang::XEventListener
>& aListener
)
816 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
817 m_pData
->m_aEventListeners
.removeInterface( aListener
);
821 IMPL_SfxBaseModel_DataContainer::impl_setDocumentProperties(
822 const Reference
< document::XDocumentProperties
>& rxNewDocProps
)
824 m_xDocumentProperties
.set(rxNewDocProps
, UNO_SET_THROW
);
825 if (m_pObjectShell
.is())
827 Reference
<util::XModifyBroadcaster
> const xMB(
828 m_xDocumentProperties
, UNO_QUERY_THROW
);
829 xMB
->addModifyListener(new SfxDocInfoListener_Impl(*m_pObjectShell
));
833 // document::XDocumentPropertiesSupplier:
834 Reference
< document::XDocumentProperties
> SAL_CALL
835 SfxBaseModel::getDocumentProperties()
837 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
838 if ( !m_pData
->m_xDocumentProperties
.is() )
840 Reference
< document::XDocumentProperties
> xDocProps(
841 document::DocumentProperties::create( ::comphelper::getProcessComponentContext() ) );
842 m_pData
->impl_setDocumentProperties(xDocProps
);
845 return m_pData
->m_xDocumentProperties
;
849 // lang::XEventListener
852 void SAL_CALL
SfxBaseModel::disposing( const lang::EventObject
& aObject
)
854 SolarMutexGuard aGuard
;
855 if ( impl_isDisposed() )
858 Reference
< util::XModifyListener
> xMod( aObject
.Source
, UNO_QUERY
);
859 Reference
< lang::XEventListener
> xListener( aObject
.Source
, UNO_QUERY
);
860 Reference
< document::XEventListener
> xDocListener( aObject
.Source
, UNO_QUERY
);
863 m_pData
->m_aModifyListeners
.removeInterface( xMod
);
864 else if ( xListener
.is() )
865 m_pData
->m_aEventListeners
.removeInterface( xListener
);
866 else if ( xDocListener
.is() )
867 m_pData
->m_aDocumentEventListeners1
.removeInterface( xDocListener
);
874 sal_Bool SAL_CALL
SfxBaseModel::attachResource( const OUString
& rURL
,
875 const Sequence
< beans::PropertyValue
>& rArgs
)
877 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
878 if ( rURL
.isEmpty() && rArgs
.getLength() == 1 && rArgs
[0].Name
== "SetEmbedded" )
880 // allows to set a windowless document to EMBEDDED state
881 // but _only_ before load() or initNew() methods
882 if ( m_pData
->m_pObjectShell
.is() && !m_pData
->m_pObjectShell
->GetMedium() )
885 if ( ( rArgs
[0].Value
>>= bEmb
) && bEmb
)
886 m_pData
->m_pObjectShell
->SetCreateMode_Impl( SfxObjectCreateMode::EMBEDDED
);
892 if ( m_pData
->m_pObjectShell
.is() )
894 m_pData
->m_sURL
= rURL
;
896 SfxObjectShell
* pObjectShell
= m_pData
->m_pObjectShell
.get();
898 Sequence
< sal_Int32
> aWinExtent
;
899 for (const beans::PropertyValue
& rProp
: rArgs
)
901 if (rProp
.Name
== "WinExtent" && (rProp
.Value
>>= aWinExtent
) && ( aWinExtent
.getLength() == 4 ) )
903 tools::Rectangle
aVisArea( aWinExtent
[0], aWinExtent
[1], aWinExtent
[2], aWinExtent
[3] );
904 aVisArea
= OutputDevice::LogicToLogic(aVisArea
, MapMode(MapUnit::Map100thMM
), MapMode(pObjectShell
->GetMapUnit()));
905 pObjectShell
->SetVisArea( aVisArea
);
907 bool bBreakMacroSign
= false;
908 if ( rProp
.Name
== "BreakMacroSignature" && (rProp
.Value
>>= bBreakMacroSign
) )
910 pObjectShell
->BreakMacroSign_Impl( bBreakMacroSign
);
912 bool bMacroEventRead
= false;
913 if ( rProp
.Name
== "MacroEventRead" && (rProp
.Value
>>= bMacroEventRead
) && bMacroEventRead
)
915 pObjectShell
->SetMacroCallsSeenWhileLoading();
918 Sequence
<beans::PropertyValue
> aStrippedArgs(rArgs
.getLength());
919 beans::PropertyValue
* pStripped
= aStrippedArgs
.getArray();
920 for (const beans::PropertyValue
& rProp
: rArgs
)
922 if (rProp
.Name
== "WinExtent"
923 || rProp
.Name
== "BreakMacroSignature"
924 || rProp
.Name
== "MacroEventRead"
925 || rProp
.Name
== "Stream"
926 || rProp
.Name
== "InputStream"
927 || rProp
.Name
== "URL"
928 || rProp
.Name
== "Frame"
929 || rProp
.Name
== "Password"
930 || rProp
.Name
== "EncryptionData")
932 *pStripped
++ = rProp
;
934 aStrippedArgs
.realloc(pStripped
- aStrippedArgs
.getArray());
936 // TODO/LATER: all the parameters that are accepted by ItemSet of the DocShell must be removed here
938 m_pData
->m_seqArguments
= std::move(aStrippedArgs
);
940 SfxMedium
* pMedium
= pObjectShell
->GetMedium();
943 SfxAllItemSet
aSet( pObjectShell
->GetPool() );
944 TransformParameters( SID_OPENDOC
, rArgs
, aSet
);
946 // the arguments are not allowed to reach the medium
947 aSet
.ClearItem( SID_FILE_NAME
);
948 aSet
.ClearItem( SID_FILLFRAME
);
950 pMedium
->GetItemSet().Put( aSet
);
951 const SfxStringItem
* pItem
= aSet
.GetItem
<SfxStringItem
>(SID_FILTER_NAME
, false);
954 pObjectShell
->GetFactory().GetFilterContainer()->GetFilter4FilterName( pItem
->GetValue() ) );
956 const SfxStringItem
* pTitleItem
= aSet
.GetItem
<SfxStringItem
>(SID_DOCINFO_TITLE
, false);
959 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( pObjectShell
);
961 pFrame
->UpdateTitle();
973 OUString SAL_CALL
SfxBaseModel::getURL()
975 SfxModelGuard
aGuard( *this );
976 return m_pData
->m_sURL
;
982 Sequence
< beans::PropertyValue
> SAL_CALL
SfxBaseModel::getArgs()
989 Sequence
< beans::PropertyValue
> SAL_CALL
SfxBaseModel::getArgs2(const Sequence
<OUString
> & requestedArgsSeq
)
991 SfxModelGuard
aGuard( *this );
993 if (!SfxApplication::Get()) // tdf#113755
995 SAL_WARN("sfx.appl", "Unexpected operations on model");
996 return m_pData
->m_seqArguments
;
999 std::set
<std::u16string_view
> requestedArgs
;
1000 for (OUString
const & s
: requestedArgsSeq
)
1001 requestedArgs
.insert(s
);
1003 if ( m_pData
->m_pObjectShell
.is() )
1005 Sequence
< beans::PropertyValue
> seqArgsNew
;
1006 Sequence
< beans::PropertyValue
> seqArgsOld
;
1007 SfxAllItemSet
aSet( m_pData
->m_pObjectShell
->GetPool() );
1009 // we need to know which properties are supported by the transformer
1010 // hopefully it is a temporary solution, I guess nonconvertable properties
1011 // should not be supported so then there will be only ItemSet from medium
1013 TransformItems( SID_OPENDOC
, m_pData
->m_pObjectShell
->GetMedium()->GetItemSet(), seqArgsNew
);
1014 TransformParameters( SID_OPENDOC
, m_pData
->m_seqArguments
, aSet
);
1015 TransformItems( SID_OPENDOC
, aSet
, seqArgsOld
);
1017 sal_Int32 nNewLength
= seqArgsNew
.getLength();
1019 if (requestedArgs
.empty() || requestedArgs
.count(u
"WinExtent"))
1021 // "WinExtent" property should be updated always.
1022 // We can store it now to overwrite an old value
1023 // since it is not from ItemSet
1024 tools::Rectangle aTmpRect
= m_pData
->m_pObjectShell
->GetVisArea( ASPECT_CONTENT
);
1025 aTmpRect
= OutputDevice::LogicToLogic(aTmpRect
, MapMode(m_pData
->m_pObjectShell
->GetMapUnit()), MapMode(MapUnit::Map100thMM
));
1027 Sequence
< sal_Int32
> aRectSeq
1029 o3tl::narrowing
<int>(aTmpRect
.Left()),
1030 o3tl::narrowing
<int>(aTmpRect
.Top()),
1031 o3tl::narrowing
<int>(aTmpRect
.IsWidthEmpty() ? aTmpRect
.Left() : aTmpRect
.Right()),
1032 o3tl::narrowing
<int>(aTmpRect
.IsHeightEmpty() ? aTmpRect
.Top() : aTmpRect
.Bottom())
1035 seqArgsNew
.realloc( ++nNewLength
);
1036 auto pseqArgsNew
= seqArgsNew
.getArray();
1037 pseqArgsNew
[ nNewLength
- 1 ].Name
= "WinExtent";
1038 pseqArgsNew
[ nNewLength
- 1 ].Value
<<= aRectSeq
;
1041 if (requestedArgs
.empty() || requestedArgs
.count(u
"PreusedFilterName"))
1043 if ( !m_pData
->m_aPreusedFilterName
.isEmpty() )
1045 seqArgsNew
.realloc( ++nNewLength
);
1046 auto pseqArgsNew
= seqArgsNew
.getArray();
1047 pseqArgsNew
[ nNewLength
- 1 ].Name
= "PreusedFilterName";
1048 pseqArgsNew
[ nNewLength
- 1 ].Value
<<= m_pData
->m_aPreusedFilterName
;
1052 if (requestedArgs
.empty() || requestedArgs
.count(u
"DocumentBorder"))
1054 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get() );
1057 SvBorder aBorder
= pFrame
->GetBorderPixelImpl();
1059 Sequence
< sal_Int32
> aBorderSeq
1061 o3tl::narrowing
<int>(aBorder
.Left()),
1062 o3tl::narrowing
<int>(aBorder
.Top()),
1063 o3tl::narrowing
<int>(aBorder
.Right()),
1064 o3tl::narrowing
<int>(aBorder
.Bottom())
1067 seqArgsNew
.realloc( ++nNewLength
);
1068 auto pseqArgsNew
= seqArgsNew
.getArray();
1069 pseqArgsNew
[ nNewLength
- 1 ].Name
= "DocumentBorder";
1070 pseqArgsNew
[ nNewLength
- 1 ].Value
<<= aBorderSeq
;
1074 if (requestedArgs
.empty())
1076 // only the values that are not supported by the ItemSet must be cached here
1077 Sequence
< beans::PropertyValue
> aFinalCache
;
1078 sal_Int32 nFinalLength
= 0;
1080 for (const auto& rOrg
: m_pData
->m_seqArguments
)
1082 auto bNew
= std::none_of(std::cbegin(seqArgsOld
), std::cend(seqArgsOld
),
1083 [&rOrg
](const beans::PropertyValue
& rOld
){ return rOld
.Name
== rOrg
.Name
; });
1086 // the entity with this name should be new for seqArgsNew
1087 // since it is not supported by transformer
1089 seqArgsNew
.realloc( ++nNewLength
);
1090 seqArgsNew
.getArray()[ nNewLength
- 1 ] = rOrg
;
1092 aFinalCache
.realloc( ++nFinalLength
);
1093 aFinalCache
.getArray()[ nFinalLength
- 1 ] = rOrg
;
1097 m_pData
->m_seqArguments
= std::move(aFinalCache
);
1103 return m_pData
->m_seqArguments
;
1106 void SAL_CALL
SfxBaseModel::setArgs(const Sequence
<beans::PropertyValue
>& aArgs
)
1108 SfxModelGuard
aGuard( *this );
1110 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
1113 throw util::InvalidStateException(
1114 u
"Medium could not be retrieved, unable to execute setArgs"_ustr
);
1117 for (const auto& rArg
: aArgs
)
1122 if (rArg
.Name
== "SuggestedSaveAsName")
1124 if (rArg
.Value
>>= sValue
)
1126 pMedium
->GetItemSet().Put(SfxStringItem(SID_SUGGESTEDSAVEASNAME
, sValue
));
1130 else if (rArg
.Name
== "SuggestedSaveAsDir")
1132 if (rArg
.Value
>>= sValue
)
1134 pMedium
->GetItemSet().Put(SfxStringItem(SID_SUGGESTEDSAVEASDIR
, sValue
));
1138 else if (rArg
.Name
== "LockContentExtraction")
1140 if (rArg
.Value
>>= bValue
)
1142 pMedium
->GetItemSet().Put(SfxBoolItem(SID_LOCK_CONTENT_EXTRACTION
, bValue
));
1146 else if (rArg
.Name
== "LockExport")
1148 if (rArg
.Value
>>= bValue
)
1150 pMedium
->GetItemSet().Put(SfxBoolItem(SID_LOCK_EXPORT
, bValue
));
1154 else if (rArg
.Name
== "LockPrint")
1156 if (rArg
.Value
>>= bValue
)
1158 pMedium
->GetItemSet().Put(SfxBoolItem(SID_LOCK_PRINT
, bValue
));
1162 else if (rArg
.Name
== "LockSave")
1164 if (rArg
.Value
>>= bValue
)
1166 pMedium
->GetItemSet().Put(SfxBoolItem(SID_LOCK_SAVE
, bValue
));
1170 else if (rArg
.Name
== "LockEditDoc")
1172 if (rArg
.Value
>>= bValue
)
1174 pMedium
->GetItemSet().Put(SfxBoolItem(SID_LOCK_EDITDOC
, bValue
));
1178 else if (rArg
.Name
== "Replaceable")
1180 if (rArg
.Value
>>= bValue
)
1182 pMedium
->GetItemSet().Put(SfxBoolItem(SID_REPLACEABLE
, bValue
));
1186 else if (rArg
.Name
== "EncryptionData")
1188 pMedium
->GetItemSet().Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA
, rArg
.Value
));
1191 else if (rArg
.Name
== "FilterName")
1193 // HACK: Needed a way to tweak the filter after loading has started,
1194 // but changing this must be avoided unless clearly intentional.
1195 if (aArgs
.size() == 1)
1197 if (rArg
.Value
>>= sValue
)
1199 pMedium
->GetItemSet().Put(SfxStringItem(SID_FILTER_NAME
, sValue
));
1206 throw lang::IllegalArgumentException("Setting property not supported: " + rArg
.Name
,
1207 comphelper::getProcessComponentContext(), 0);
1215 void SAL_CALL
SfxBaseModel::connectController( const Reference
< frame::XController
>& xController
)
1217 SfxModelGuard
aGuard( *this );
1218 OSL_PRECOND( xController
.is(), "SfxBaseModel::connectController: invalid controller!" );
1219 if ( !xController
.is() )
1222 m_pData
->m_seqControllers
.push_back(xController
);
1224 if ( m_pData
->m_seqControllers
.size() == 1 )
1226 SfxViewFrame
* pViewFrame
= SfxViewFrame::Get( xController
, GetObjectShell() );
1227 ENSURE_OR_THROW( pViewFrame
, "SFX document without SFX view!?" );
1228 pViewFrame
->UpdateDocument_Impl();
1229 const OUString sDocumentURL
= GetObjectShell()->GetMedium()->GetName();
1230 if ( !sDocumentURL
.isEmpty() )
1231 SfxGetpApp()->Broadcast( SfxOpenUrlHint( sDocumentURL
) );
1239 void SAL_CALL
SfxBaseModel::disconnectController( const Reference
< frame::XController
>& xController
)
1241 SfxModelGuard
aGuard( *this );
1243 if ( m_pData
->m_seqControllers
.empty() )
1246 auto& vec
= m_pData
->m_seqControllers
;
1247 std::erase(vec
, xController
);
1249 if ( xController
== m_pData
->m_xCurrent
)
1250 m_pData
->m_xCurrent
.clear();
1255 class ControllerLockUndoAction
: public ::cppu::WeakImplHelper
< XUndoAction
>
1258 ControllerLockUndoAction( const Reference
< XModel
>& i_model
, const bool i_undoIsUnlock
)
1259 :m_xModel( i_model
)
1260 ,m_bUndoIsUnlock( i_undoIsUnlock
)
1265 virtual OUString SAL_CALL
getTitle() override
;
1266 virtual void SAL_CALL
undo( ) override
;
1267 virtual void SAL_CALL
redo( ) override
;
1270 const Reference
< XModel
> m_xModel
;
1271 const bool m_bUndoIsUnlock
;
1274 OUString SAL_CALL
ControllerLockUndoAction::getTitle()
1276 // this action is intended to be used within an UndoContext only, so nobody will ever see this title ...
1280 void SAL_CALL
ControllerLockUndoAction::undo( )
1282 if ( m_bUndoIsUnlock
)
1283 m_xModel
->unlockControllers();
1285 m_xModel
->lockControllers();
1288 void SAL_CALL
ControllerLockUndoAction::redo( )
1290 if ( m_bUndoIsUnlock
)
1291 m_xModel
->lockControllers();
1293 m_xModel
->unlockControllers();
1301 void SAL_CALL
SfxBaseModel::lockControllers()
1303 SfxModelGuard
aGuard( *this );
1305 ++m_pData
->m_nControllerLockCount
;
1307 if ( m_pData
->m_pDocumentUndoManager
.is()
1308 && m_pData
->m_pDocumentUndoManager
->isInContext()
1309 && !m_pData
->m_pDocumentUndoManager
->isLocked()
1312 m_pData
->m_pDocumentUndoManager
->addUndoAction( new ControllerLockUndoAction( this, true ) );
1320 void SAL_CALL
SfxBaseModel::unlockControllers()
1322 SfxModelGuard
aGuard( *this );
1324 --m_pData
->m_nControllerLockCount
;
1326 if ( m_pData
->m_pDocumentUndoManager
.is()
1327 && m_pData
->m_pDocumentUndoManager
->isInContext()
1328 && !m_pData
->m_pDocumentUndoManager
->isLocked()
1331 m_pData
->m_pDocumentUndoManager
->addUndoAction( new ControllerLockUndoAction( this, false ) );
1339 sal_Bool SAL_CALL
SfxBaseModel::hasControllersLocked()
1341 SfxModelGuard
aGuard( *this );
1342 return ( m_pData
->m_nControllerLockCount
!= 0 ) ;
1349 Reference
< frame::XController
> SAL_CALL
SfxBaseModel::getCurrentController()
1351 SfxModelGuard
aGuard( *this );
1353 // get the last active controller of this model
1354 if ( m_pData
->m_xCurrent
.is() )
1355 return m_pData
->m_xCurrent
;
1357 // get the first controller of this model
1358 return !m_pData
->m_seqControllers
.empty() ? m_pData
->m_seqControllers
.front() : m_pData
->m_xCurrent
;
1365 void SAL_CALL
SfxBaseModel::setCurrentController( const Reference
< frame::XController
>& xCurrentController
)
1367 SfxModelGuard
aGuard( *this );
1369 m_pData
->m_xCurrent
= xCurrentController
;
1376 Reference
< XInterface
> SAL_CALL
SfxBaseModel::getCurrentSelection()
1378 SfxModelGuard
aGuard( *this );
1380 Reference
< XInterface
> xReturn
;
1381 Reference
< frame::XController
> xController
= getCurrentController() ;
1383 if ( xController
.is() )
1385 Reference
< view::XSelectionSupplier
> xDocView( xController
, UNO_QUERY
);
1386 if ( xDocView
.is() )
1388 Any aSel
= xDocView
->getSelection();
1400 sal_Bool SAL_CALL
SfxBaseModel::disableSetModified()
1402 SfxModelGuard
aGuard( *this );
1404 if ( !m_pData
->m_pObjectShell
.is() )
1405 throw RuntimeException();
1407 bool bResult
= m_pData
->m_pObjectShell
->IsEnableSetModified();
1408 m_pData
->m_pObjectShell
->EnableSetModified( false );
1413 sal_Bool SAL_CALL
SfxBaseModel::enableSetModified()
1415 SfxModelGuard
aGuard( *this );
1417 if ( !m_pData
->m_pObjectShell
.is() )
1418 throw RuntimeException();
1420 bool bResult
= m_pData
->m_pObjectShell
->IsEnableSetModified();
1421 m_pData
->m_pObjectShell
->EnableSetModified();
1426 sal_Bool SAL_CALL
SfxBaseModel::isSetModifiedEnabled()
1428 SfxModelGuard
aGuard( *this );
1430 if ( !m_pData
->m_pObjectShell
.is() )
1431 throw RuntimeException();
1433 return m_pData
->m_pObjectShell
->IsEnableSetModified();
1440 sal_Bool SAL_CALL
SfxBaseModel::isModified()
1442 SfxModelGuard
aGuard( *this );
1444 return m_pData
->m_pObjectShell
.is() && m_pData
->m_pObjectShell
->IsModified();
1451 void SAL_CALL
SfxBaseModel::setModified( sal_Bool bModified
)
1453 SfxModelGuard
aGuard( *this );
1455 if ( m_pData
->m_pObjectShell
.is() )
1456 m_pData
->m_pObjectShell
->SetModified(bModified
);
1463 void SAL_CALL
SfxBaseModel::addModifyListener(const Reference
< util::XModifyListener
>& xListener
)
1465 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
1467 m_pData
->m_aModifyListeners
.addInterface( xListener
);
1474 void SAL_CALL
SfxBaseModel::removeModifyListener(const Reference
< util::XModifyListener
>& xListener
)
1476 SfxModelGuard
aGuard( *this );
1478 m_pData
->m_aModifyListeners
.removeInterface( xListener
);
1485 void SAL_CALL
SfxBaseModel::close( sal_Bool bDeliverOwnership
)
1487 SolarMutexGuard aGuard
;
1488 if ( impl_isDisposed() || m_pData
->m_bClosed
|| m_pData
->m_bClosing
)
1491 Reference
< XInterface
> xSelfHold( getXWeak() );
1492 lang::EventObject
aSource ( getXWeak() );
1493 if (m_pData
->m_aCloseListeners
.getLength())
1495 comphelper::OInterfaceIteratorHelper3
pIterator(m_pData
->m_aCloseListeners
);
1496 while (pIterator
.hasMoreElements())
1500 pIterator
.next()->queryClosing( aSource
, bDeliverOwnership
);
1502 catch( RuntimeException
& )
1509 if ( m_pData
->m_bSaving
)
1511 if (bDeliverOwnership
)
1512 m_pData
->m_bSuicide
= true;
1513 throw util::CloseVetoException(
1514 u
"Can not close while saving."_ustr
,
1515 static_cast< util::XCloseable
* >(this));
1518 // no own objections against closing!
1519 m_pData
->m_bClosing
= true;
1520 if (m_pData
->m_aCloseListeners
.getLength())
1522 comphelper::OInterfaceIteratorHelper3
pCloseIterator(m_pData
->m_aCloseListeners
);
1523 while (pCloseIterator
.hasMoreElements())
1527 pCloseIterator
.next()->notifyClosing( aSource
);
1529 catch( RuntimeException
& )
1531 pCloseIterator
.remove();
1536 m_pData
->m_bClosed
= true;
1537 m_pData
->m_bClosing
= false;
1543 // XCloseBroadcaster
1546 void SAL_CALL
SfxBaseModel::addCloseListener( const Reference
< util::XCloseListener
>& xListener
)
1548 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
1550 m_pData
->m_aCloseListeners
.addInterface( xListener
);
1554 // XCloseBroadcaster
1557 void SAL_CALL
SfxBaseModel::removeCloseListener( const Reference
< util::XCloseListener
>& xListener
)
1559 SfxModelGuard
aGuard( *this );
1561 m_pData
->m_aCloseListeners
.removeInterface( xListener
);
1568 Sequence
< beans::PropertyValue
> SAL_CALL
SfxBaseModel::getPrinter()
1570 SfxModelGuard
aGuard( *this );
1572 impl_getPrintHelper();
1573 return m_pData
->m_xPrintable
->getPrinter();
1576 void SAL_CALL
SfxBaseModel::setPrinter(const Sequence
< beans::PropertyValue
>& rPrinter
)
1578 SfxModelGuard
aGuard( *this );
1580 impl_getPrintHelper();
1581 m_pData
->m_xPrintable
->setPrinter( rPrinter
);
1584 void SAL_CALL
SfxBaseModel::print(const Sequence
< beans::PropertyValue
>& rOptions
)
1586 SfxModelGuard
aGuard( *this );
1588 impl_getPrintHelper();
1590 // tdf#123728 Always print on main thread to avoid deadlocks
1591 vcl::solarthread::syncExecute([this, &rOptions
]() { m_pData
->m_xPrintable
->print(rOptions
); });
1597 sal_Bool SAL_CALL
SfxBaseModel::hasLocation()
1599 SfxModelGuard
aGuard( *this );
1601 return m_pData
->m_pObjectShell
.is() && m_pData
->m_pObjectShell
->HasName();
1608 OUString SAL_CALL
SfxBaseModel::getLocation()
1610 SfxModelGuard
aGuard( *this );
1612 if ( m_pData
->m_pObjectShell
.is() )
1614 // TODO/LATER: is it correct that the shared document returns shared file location?
1615 if ( m_pData
->m_pObjectShell
->IsDocShared() )
1616 return m_pData
->m_pObjectShell
->GetSharedFileURL();
1618 return m_pData
->m_pObjectShell
->GetMedium()->GetName();
1621 return m_pData
->m_sURL
;
1628 sal_Bool SAL_CALL
SfxBaseModel::isReadonly()
1630 SfxModelGuard
aGuard( *this );
1632 return !m_pData
->m_pObjectShell
.is() || m_pData
->m_pObjectShell
->IsReadOnly();
1638 void SAL_CALL
SfxBaseModel::storeSelf( const Sequence
< beans::PropertyValue
>& aSeqArgs
)
1640 SfxModelGuard
aGuard( *this );
1642 if ( !m_pData
->m_pObjectShell
.is() )
1645 SfxSaveGuard
aSaveGuard(this, m_pData
.get());
1647 bool bCheckIn
= false;
1648 bool bOnMainThread
= false;
1649 for ( const auto& rArg
: aSeqArgs
)
1651 // check that only acceptable parameters are provided here
1652 if ( rArg
.Name
!= "VersionComment" && rArg
.Name
!= "Author"
1653 && rArg
.Name
!= "DontTerminateEdit"
1654 && rArg
.Name
!= "InteractionHandler" && rArg
.Name
!= "StatusIndicator"
1655 && rArg
.Name
!= "VersionMajor"
1656 && rArg
.Name
!= "FailOnWarning"
1657 && rArg
.Name
!= "CheckIn"
1658 && rArg
.Name
!= "NoFileSync"
1659 && rArg
.Name
!= "OnMainThread" )
1661 const OUString
aMessage( "Unexpected MediaDescriptor parameter: " + rArg
.Name
);
1662 throw lang::IllegalArgumentException( aMessage
, Reference
< XInterface
>(), 1 );
1664 else if ( rArg
.Name
== "CheckIn" )
1666 rArg
.Value
>>= bCheckIn
;
1668 else if (rArg
.Name
== "OnMainThread")
1670 rArg
.Value
>>= bOnMainThread
;
1674 // Remove CheckIn property if needed
1675 sal_uInt16 nSlotId
= SID_SAVEDOC
;
1676 Sequence
< beans::PropertyValue
> aArgs
= aSeqArgs
;
1679 nSlotId
= SID_CHECKIN
;
1680 sal_Int32 nLength
= aSeqArgs
.getLength( );
1681 aArgs
= Sequence
< beans::PropertyValue
>( nLength
- 1 );
1682 std::copy_if(aSeqArgs
.begin(), aSeqArgs
.end(), aArgs
.getArray(),
1683 [](const beans::PropertyValue
& rProp
) { return rProp
.Name
!= "CheckIn"; });
1686 std::optional
<SfxAllItemSet
> pParams(SfxGetpApp()->GetPool() );
1687 TransformParameters( nSlotId
, aArgs
, *pParams
);
1689 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveDoc
, GlobalEventConfig::GetEventName(GlobalEventId::SAVEDOC
), m_pData
->m_pObjectShell
.get() ) );
1693 // TODO/LATER: let the embedded case of saving be handled more careful
1694 if ( m_pData
->m_pObjectShell
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
1696 // If this is an embedded object that has no URL based location it should be stored to own storage.
1697 // An embedded object can have a location based on URL in case it is a link, then it should be
1698 // stored in normal way.
1699 if ( !hasLocation() || getLocation().startsWith("private:") )
1701 // actually in this very rare case only UI parameters have sense
1702 // TODO/LATER: should be done later, after integration of sb19
1703 bRet
= m_pData
->m_pObjectShell
->DoSave()
1704 && m_pData
->m_pObjectShell
->DoSaveCompleted();
1708 bRet
= m_pData
->m_pObjectShell
->Save_Impl( &*pParams
);
1713 // Tell the SfxMedium if we are in checkin instead of normal save
1714 m_pData
->m_pObjectShell
->GetMedium( )->SetInCheckIn( nSlotId
== SID_CHECKIN
);
1716 bRet
= vcl::solarthread::syncExecute(
1717 [this, &pParams
] { return m_pData
->m_pObjectShell
->Save_Impl(&*pParams
); });
1719 bRet
= m_pData
->m_pObjectShell
->Save_Impl(&*pParams
);
1720 m_pData
->m_pObjectShell
->GetMedium( )->SetInCheckIn( nSlotId
!= SID_CHECKIN
);
1725 ErrCodeMsg nErrCode
= m_pData
->m_pObjectShell
->GetErrorIgnoreWarning();
1726 m_pData
->m_pObjectShell
->ResetError();
1730 m_pData
->m_aPreusedFilterName
= GetMediumFilterName_Impl();
1732 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveDocDone
, GlobalEventConfig::GetEventName(GlobalEventId::SAVEDOCDONE
), m_pData
->m_pObjectShell
.get() ) );
1737 nErrCode
= ERRCODE_IO_CANTWRITE
;
1738 // write the contents of the logger to the file
1739 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveDocFailed
, GlobalEventConfig::GetEventName(GlobalEventId::SAVEDOCFAILED
), m_pData
->m_pObjectShell
.get() ) );
1741 throw task::ErrorCodeIOException(
1742 "SfxBaseModel::storeSelf: " + nErrCode
.toString(),
1743 Reference
< XInterface
>(), sal_uInt32(nErrCode
.GetCode()));
1751 void SAL_CALL
SfxBaseModel::store()
1753 comphelper::ProfileZone
aZone("store");
1754 storeSelf( Sequence
< beans::PropertyValue
>() );
1761 void SAL_CALL
SfxBaseModel::storeAsURL( const OUString
& rURL
,
1762 const Sequence
< beans::PropertyValue
>& rArgs
)
1764 SfxModelGuard
aGuard( *this );
1765 comphelper::ProfileZone
aZone("storeAs");
1767 if ( !m_pData
->m_pObjectShell
.is() )
1770 SfxSaveGuard
aSaveGuard(this, m_pData
.get());
1772 utl::MediaDescriptor
aDescriptor(rArgs
);
1773 bool bOnMainThread
= aDescriptor
.getUnpackedValueOrDefault(u
"OnMainThread"_ustr
, false);
1776 vcl::solarthread::syncExecute([this, rURL
, rArgs
]() { impl_store(rURL
, rArgs
, false); });
1780 impl_store(rURL
, rArgs
, false);
1783 Sequence
< beans::PropertyValue
> aSequence
;
1784 TransformItems( SID_OPENDOC
, m_pData
->m_pObjectShell
->GetMedium()->GetItemSet(), aSequence
);
1785 attachResource( rURL
, aSequence
);
1787 loadCmisProperties( );
1789 #if OSL_DEBUG_LEVEL > 0
1790 const SfxStringItem
* pPasswdItem
= m_pData
->m_pObjectShell
->GetMedium()->GetItemSet().GetItem(SID_PASSWORD
, false);
1791 OSL_ENSURE( !pPasswdItem
, "There should be no Password property in the document MediaDescriptor!" );
1796 // XUndoManagerSupplier
1798 Reference
< XUndoManager
> SAL_CALL
SfxBaseModel::getUndoManager( )
1800 SfxModelGuard
aGuard( *this );
1801 if ( !m_pData
->m_pDocumentUndoManager
.is() )
1802 m_pData
->m_pDocumentUndoManager
.set( new ::sfx2::DocumentUndoManager( *this ) );
1803 return m_pData
->m_pDocumentUndoManager
;
1810 void SAL_CALL
SfxBaseModel::storeToURL( const OUString
& rURL
,
1811 const Sequence
< beans::PropertyValue
>& rArgs
)
1813 SfxModelGuard
aGuard( *this );
1814 comphelper::ProfileZone
aZone("storeToURL");
1816 if ( !m_pData
->m_pObjectShell
.is() )
1819 SfxSaveGuard
aSaveGuard(this, m_pData
.get());
1821 utl::MediaDescriptor
aDescriptor(rArgs
);
1822 bool bOnMainThread
= aDescriptor
.getUnpackedValueOrDefault(u
"OnMainThread"_ustr
, false);
1824 vcl::solarthread::syncExecute([this, rURL
, rArgs
]() { impl_store(rURL
, rArgs
, true); });
1826 impl_store(rURL
, rArgs
, true);
1828 catch (const uno::Exception
&e
)
1830 // convert to the exception we announce in the throw
1831 // (eg. neon likes to throw InteractiveAugmentedIOException which
1832 // is not an io::IOException)
1833 throw io::IOException(e
.Message
, e
.Context
);
1837 sal_Bool SAL_CALL
SfxBaseModel::wasModifiedSinceLastSave()
1839 SfxModelGuard
aGuard( *this );
1840 return m_pData
->m_oDirtyTimestamp
.has_value();
1843 void SAL_CALL
SfxBaseModel::storeToRecoveryFile( const OUString
& i_TargetLocation
, const Sequence
< PropertyValue
>& i_MediaDescriptor
)
1845 SfxModelGuard
aGuard( *this );
1848 SfxSaveGuard
aSaveGuard( this, m_pData
.get() );
1849 impl_store( i_TargetLocation
, i_MediaDescriptor
, true );
1851 // no need for subsequent calls to storeToRecoveryFile, unless we're modified, again
1852 m_pData
->setModifiedForAutoSave(false);
1855 sal_Int64 SAL_CALL
SfxBaseModel::getModifiedStateDuration()
1857 SfxModelGuard
aGuard(*this);
1858 if (!m_pData
->m_oDirtyTimestamp
)
1860 auto ms
= std::chrono::ceil
<std::chrono::milliseconds
>(std::chrono::steady_clock::now()
1861 - *m_pData
->m_oDirtyTimestamp
);
1865 void SAL_CALL
SfxBaseModel::recoverFromFile( const OUString
& i_SourceLocation
, const OUString
& i_SalvagedFile
, const Sequence
< PropertyValue
>& i_MediaDescriptor
)
1867 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
1869 // delegate to our "load" method
1870 ::comphelper::NamedValueCollection
aMediaDescriptor( i_MediaDescriptor
);
1872 // our load implementation expects the SalvagedFile to be in the media descriptor
1873 OSL_ENSURE( !aMediaDescriptor
.has( u
"SalvagedFile"_ustr
) || ( aMediaDescriptor
.getOrDefault( u
"SalvagedFile"_ustr
, OUString() ) == i_SalvagedFile
),
1874 "SfxBaseModel::recoverFromFile: inconsistent information!" );
1875 aMediaDescriptor
.put( u
"SalvagedFile"_ustr
, i_SalvagedFile
);
1877 // similar for the to-be-loaded file
1878 OSL_ENSURE( !aMediaDescriptor
.has( u
"URL"_ustr
) || ( aMediaDescriptor
.getOrDefault( u
"URL"_ustr
, OUString() ) == i_SourceLocation
),
1879 "SfxBaseModel::recoverFromFile: inconsistent information!" );
1880 aMediaDescriptor
.put( u
"URL"_ustr
, i_SourceLocation
);
1882 load( aMediaDescriptor
.getPropertyValues() );
1884 // Note: The XDocumentRecovery interface specification requires us to do an attachResource after loading.
1885 // However, we will not do this here, as we know that our load implementation (respectively some method
1886 // called from there) already did so.
1887 // In particular, the load process might already have modified some elements of the media
1888 // descriptor, for instance the MacroExecMode (in case the user was involved to decide about it), and we do
1889 // not want to overwrite it with the "old" elements passed to this method here.
1896 void SAL_CALL
SfxBaseModel::initNew()
1898 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
1899 if ( IsInitialized() )
1900 throw frame::DoubleInitializationException( OUString(), *this );
1902 // the object shell should exist always
1903 DBG_ASSERT( m_pData
->m_pObjectShell
.is(), "Model is useless without an ObjectShell" );
1904 if ( !m_pData
->m_pObjectShell
.is() )
1907 if( m_pData
->m_pObjectShell
->GetMedium() )
1908 throw frame::DoubleInitializationException();
1910 bool bRes
= m_pData
->m_pObjectShell
->DoInitNew();
1911 ErrCodeMsg nErrCode
= m_pData
->m_pObjectShell
->GetErrorIgnoreWarning() ?
1912 m_pData
->m_pObjectShell
->GetErrorIgnoreWarning() : ERRCODE_IO_CANTCREATE
;
1913 m_pData
->m_pObjectShell
->ResetError();
1916 throw task::ErrorCodeIOException(
1917 "SfxBaseModel::initNew: " + nErrCode
.toString(),
1918 Reference
< XInterface
>(), sal_uInt32(nErrCode
.GetCode()));
1923 OUString
getFilterProvider( SfxMedium
const & rMedium
)
1925 const std::shared_ptr
<const SfxFilter
>& pFilter
= rMedium
.GetFilter();
1929 return pFilter
->GetProviderName();
1932 void setUpdatePickList( SfxMedium
* pMedium
)
1937 bool bHidden
= false;
1938 const SfxBoolItem
* pHidItem
= pMedium
->GetItemSet().GetItem(SID_HIDDEN
, false);
1940 bHidden
= pHidItem
->GetValue();
1942 pMedium
->SetUpdatePickList(!bHidden
);
1947 void SAL_CALL
SfxBaseModel::load( const Sequence
< beans::PropertyValue
>& seqArguments
)
1949 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
1950 if ( IsInitialized() )
1951 throw frame::DoubleInitializationException( OUString(), *this );
1953 // the object shell should exist always
1954 DBG_ASSERT( m_pData
->m_pObjectShell
.is(), "Model is useless without an ObjectShell" );
1956 if (!m_pData
->m_pObjectShell
.is())
1959 if( m_pData
->m_pObjectShell
->GetMedium() )
1960 // if a Medium is present, the document is already initialized
1961 throw frame::DoubleInitializationException();
1963 SfxMedium
* pMedium
= new SfxMedium( seqArguments
);
1965 ErrCodeMsg nError
= ERRCODE_NONE
;
1966 if (!getFilterProvider(*pMedium
).isEmpty())
1968 if (!m_pData
->m_pObjectShell
->DoLoadExternal(pMedium
))
1969 nError
= ERRCODE_IO_GENERAL
;
1971 pMedium
= handleLoadError(nError
, pMedium
);
1972 setUpdatePickList(pMedium
);
1976 OUString aFilterName
;
1977 const SfxStringItem
* pFilterNameItem
= pMedium
->GetItemSet().GetItem(SID_FILTER_NAME
, false);
1978 if( pFilterNameItem
)
1979 aFilterName
= pFilterNameItem
->GetValue();
1980 if( !m_pData
->m_pObjectShell
->GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName
) )
1982 // filtername is not valid
1984 throw frame::IllegalArgumentIOException();
1987 const SfxStringItem
* pSalvageItem
= pMedium
->GetItemSet().GetItem(SID_DOC_SALVAGE
, false);
1988 bool bSalvage
= pSalvageItem
!= nullptr;
1991 if ( !m_pData
->m_pObjectShell
->DoLoad(pMedium
) )
1992 nError
=ERRCODE_IO_GENERAL
;
1994 // QUESTION: if the following happens outside of DoLoad, something important is missing there!
1995 Reference
< task::XInteractionHandler
> xHandler
= pMedium
->GetInteractionHandler();
1996 if( m_pData
->m_pObjectShell
->GetErrorCode() )
1998 nError
= m_pData
->m_pObjectShell
->GetErrorCode();
1999 if ( nError
== ERRCODE_IO_BROKENPACKAGE
&& xHandler
.is() )
2001 const OUString
aDocName( pMedium
->GetURLObject().getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::WithCharset
) );
2002 if (!pMedium
->IsRepairPackage())
2004 RequestPackageReparation
aRequest( aDocName
);
2005 xHandler
->handle( aRequest
.GetRequest() );
2006 if( aRequest
.isApproved() )
2008 // lok: we want to overwrite file in jail, so don't use template flag
2009 bool bIsLOK
= comphelper::LibreOfficeKit::isActive();
2010 // broken package: try second loading and allow repair
2011 pMedium
->GetItemSet().Put( SfxBoolItem( SID_REPAIRPACKAGE
, true ) );
2012 pMedium
->GetItemSet().Put( SfxBoolItem( SID_TEMPLATE
, !bIsLOK
) );
2013 pMedium
->GetItemSet().Put( SfxStringItem( SID_DOCINFO_TITLE
, aDocName
) );
2015 // the error must be reset and the storage must be reopened in new mode
2016 pMedium
->ResetError();
2017 pMedium
->CloseStorage();
2018 m_pData
->m_pObjectShell
->PrepareSecondTryLoad_Impl();
2019 nError
= ERRCODE_NONE
;
2020 if ( !m_pData
->m_pObjectShell
->DoLoad(pMedium
) )
2021 nError
=ERRCODE_IO_GENERAL
;
2022 if (m_pData
->m_pObjectShell
->GetErrorCode())
2023 nError
= m_pData
->m_pObjectShell
->GetErrorCode();
2027 if ( nError
== ERRCODE_IO_BROKENPACKAGE
)
2029 // repair either not allowed or not successful
2030 NotifyBrokenPackage
aRequest( aDocName
);
2031 xHandler
->handle( aRequest
.GetRequest() );
2036 if( m_pData
->m_pObjectShell
->IsAbortingImport() )
2037 nError
= ERRCODE_ABORT
;
2039 if (bSalvage
&& nError
== ERRCODE_NONE
)
2041 // file recovery: restore original filter
2042 const SfxStringItem
* pFilterItem
= pMedium
->GetItemSet().GetItem(SID_FILTER_NAME
, false);
2043 SfxFilterMatcher
& rMatcher
= SfxGetpApp()->GetFilterMatcher();
2044 std::shared_ptr
<const SfxFilter
> pSetFilter
= rMatcher
.GetFilter4FilterName( pFilterItem
->GetValue() );
2045 pMedium
->SetFilter( pSetFilter
);
2046 m_pData
->m_pObjectShell
->SetModified();
2049 // TODO/LATER: maybe the mode should be retrieved from outside and the preused filter should not be set
2050 if ( m_pData
->m_pObjectShell
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
2052 const SfxStringItem
* pFilterItem
= pMedium
->GetItemSet().GetItem(SID_FILTER_NAME
, false);
2054 m_pData
->m_aPreusedFilterName
= pFilterItem
->GetValue();
2058 nError
= pMedium
->GetErrorIgnoreWarning();
2060 m_pData
->m_pObjectShell
->ResetError();
2062 pMedium
= handleLoadError(nError
, pMedium
);
2063 loadCmisProperties();
2064 setUpdatePickList(pMedium
);
2066 #if OSL_DEBUG_LEVEL > 0
2067 const SfxStringItem
* pPasswdItem
= pMedium
->GetItemSet().GetItem(SID_PASSWORD
, false);
2068 OSL_ENSURE( !pPasswdItem
, "There should be no Password property in the document MediaDescriptor!" );
2076 Any SAL_CALL
SfxBaseModel::getTransferData( const datatransfer::DataFlavor
& aFlavor
)
2078 SfxModelGuard
aGuard( *this );
2082 if ( m_pData
->m_pObjectShell
.is() )
2084 if ( aFlavor
.MimeType
== "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" )
2086 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2087 throw datatransfer::UnsupportedFlavorException();
2089 TransferableObjectDescriptor aDesc
;
2091 aDesc
.maClassName
= m_pData
->m_pObjectShell
->GetClassName();
2092 aDesc
.maTypeName
= aFlavor
.HumanPresentableName
;
2094 // TODO/LATER: ViewAspect needs to be sal_Int64
2095 aDesc
.mnViewAspect
= sal::static_int_cast
< sal_uInt16
>( embed::Aspects::MSOLE_CONTENT
);
2097 Size aSize
= m_pData
->m_pObjectShell
->GetVisArea().GetSize();
2099 MapUnit aMapUnit
= m_pData
->m_pObjectShell
->GetMapUnit();
2100 aDesc
.maSize
= OutputDevice::LogicToLogic(aSize
, MapMode(aMapUnit
), MapMode(MapUnit::Map100thMM
));
2101 aDesc
.maDragStartPos
= Point();
2102 aDesc
.maDisplayName
.clear();
2104 SvMemoryStream
aMemStm( 1024, 1024 );
2105 WriteTransferableObjectDescriptor( aMemStm
, aDesc
);
2106 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( aMemStm
.GetData() ), aMemStm
.Tell() );
2108 else if ( aFlavor
.MimeType
== "application/x-openoffice-embed-source;windows_formatname=\"Star EMBS\"" )
2110 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2111 throw datatransfer::UnsupportedFlavorException();
2115 utl::TempFileNamed aTmp
;
2116 aTmp
.EnableKillingFile();
2117 storeToURL( aTmp
.GetURL(), Sequence
< beans::PropertyValue
>() );
2118 std::unique_ptr
<SvStream
> pStream(aTmp
.GetStream( StreamMode::READ
));
2119 const sal_uInt32 nLen
= pStream
->TellEnd();
2120 Sequence
< sal_Int8
> aSeq( nLen
);
2121 pStream
->ReadBytes(aSeq
.getArray(), nLen
);
2122 if( aSeq
.hasElements() )
2125 catch ( Exception
& )
2129 else if ( aFlavor
.MimeType
== "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2131 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2132 throw datatransfer::UnsupportedFlavorException();
2135 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2136 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2140 SvMemoryStream
aMemStm( 65535, 65535 );
2141 aMemStm
.SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2143 SvmWriter
aWriter( aMemStm
);
2144 aWriter
.Write( *xMetaFile
);
2145 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( aMemStm
.GetData() ),
2146 aMemStm
.TellEnd() );
2149 else if ( aFlavor
.MimeType
== "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2151 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2152 throw datatransfer::UnsupportedFlavorException();
2154 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2155 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2159 SvMemoryStream
aMemStm( 65535, 65535 );
2160 aMemStm
.SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2162 SvmWriter
aWriter( aMemStm
);
2163 aWriter
.Write( *xMetaFile
);
2164 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( aMemStm
.GetData() ),
2165 aMemStm
.TellEnd() );
2168 else if ( aFlavor
.MimeType
== "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" )
2170 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2172 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2173 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2177 std::unique_ptr
<SvMemoryStream
> xStream(
2178 GraphicHelper::getFormatStrFromGDI_Impl(
2179 xMetaFile
.get(), ConvertDataFormat::EMF
) );
2182 xStream
->SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2183 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( xStream
->GetData() ),
2184 xStream
->TellEnd() );
2188 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2189 && aFlavor
.DataType
== cppu::UnoType
<sal_uInt64
>::get())
2191 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2192 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2196 aAny
<<= reinterpret_cast< sal_uInt64
>(
2197 GraphicHelper::getEnhMetaFileFromGDI_Impl( xMetaFile
.get() ) );
2201 throw datatransfer::UnsupportedFlavorException();
2203 else if ( aFlavor
.MimeType
== "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" )
2205 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2207 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2208 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2212 std::unique_ptr
<SvMemoryStream
> xStream(
2213 GraphicHelper::getFormatStrFromGDI_Impl(
2214 xMetaFile
.get(), ConvertDataFormat::WMF
) );
2218 xStream
->SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2219 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( xStream
->GetData() ),
2220 xStream
->TellEnd() );
2224 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2225 && aFlavor
.DataType
== cppu::UnoType
<sal_uInt64
>::get())
2227 // means HGLOBAL handler to memory storage containing METAFILEPICT structure
2229 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2230 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2234 Size aMetaSize
= xMetaFile
->GetPrefSize();
2235 aAny
<<= reinterpret_cast< sal_uInt64
>(
2236 GraphicHelper::getWinMetaFileFromGDI_Impl(
2237 xMetaFile
.get(), aMetaSize
) );
2241 throw datatransfer::UnsupportedFlavorException();
2243 else if ( aFlavor
.MimeType
== "image/svg+xml" )
2245 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2246 throw datatransfer::UnsupportedFlavorException();
2248 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2249 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2253 std::unique_ptr
<SvMemoryStream
> xStream(
2254 GraphicHelper::getFormatStrFromGDI_Impl(
2255 xMetaFile
.get(), ConvertDataFormat::SVG
) );
2259 xStream
->SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2260 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( xStream
->GetData() ),
2261 xStream
->TellEnd() );
2265 else if ( aFlavor
.MimeType
== "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" )
2267 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2268 throw datatransfer::UnsupportedFlavorException();
2270 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2271 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2275 std::unique_ptr
<SvMemoryStream
> xStream(
2276 GraphicHelper::getFormatStrFromGDI_Impl(
2277 xMetaFile
.get(), ConvertDataFormat::BMP
) );
2281 xStream
->SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2282 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( xStream
->GetData() ),
2283 xStream
->TellEnd() );
2287 else if ( aFlavor
.MimeType
== "image/png" )
2289 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2290 throw datatransfer::UnsupportedFlavorException();
2292 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2293 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2297 std::unique_ptr
<SvMemoryStream
> xStream(
2298 GraphicHelper::getFormatStrFromGDI_Impl(
2299 xMetaFile
.get(), ConvertDataFormat::PNG
) );
2303 xStream
->SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2304 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( xStream
->GetData() ),
2305 xStream
->TellEnd() );
2310 throw datatransfer::UnsupportedFlavorException();
2320 Sequence
< datatransfer::DataFlavor
> SAL_CALL
SfxBaseModel::getTransferDataFlavors()
2322 SfxModelGuard
aGuard( *this );
2324 const sal_Int32 nSuppFlavors
= GraphicHelper::supportsMetaFileHandle_Impl() ? 11 : 9;
2325 Sequence
< datatransfer::DataFlavor
> aFlavorSeq( nSuppFlavors
);
2326 auto pFlavorSeq
= aFlavorSeq
.getArray();
2328 pFlavorSeq
[0].MimeType
=
2329 "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"";
2330 pFlavorSeq
[0].HumanPresentableName
= "GDIMetaFile";
2331 pFlavorSeq
[0].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2333 pFlavorSeq
[1].MimeType
=
2334 "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"";
2335 pFlavorSeq
[1].HumanPresentableName
= "GDIMetaFile";
2336 pFlavorSeq
[1].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2338 pFlavorSeq
[2].MimeType
=
2339 "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ;
2340 pFlavorSeq
[2].HumanPresentableName
= "Enhanced Windows MetaFile";
2341 pFlavorSeq
[2].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2343 pFlavorSeq
[3].MimeType
=
2344 "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"";
2345 pFlavorSeq
[3].HumanPresentableName
= "Windows MetaFile";
2346 pFlavorSeq
[3].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2348 pFlavorSeq
[4].MimeType
=
2349 "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"";
2350 pFlavorSeq
[4].HumanPresentableName
= "Star Object Descriptor (XML)";
2351 pFlavorSeq
[4].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2353 pFlavorSeq
[5].MimeType
=
2354 "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
2355 pFlavorSeq
[5].HumanPresentableName
= "Star Embed Source (XML)";
2356 pFlavorSeq
[5].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2358 pFlavorSeq
[6].MimeType
=
2359 "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"";
2360 pFlavorSeq
[6].HumanPresentableName
= "Bitmap";
2361 pFlavorSeq
[6].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2363 pFlavorSeq
[7].MimeType
= "image/png";
2364 pFlavorSeq
[7].HumanPresentableName
= "PNG";
2365 pFlavorSeq
[7].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2367 pFlavorSeq
[8].MimeType
= "image/svg+xml";
2368 pFlavorSeq
[8].HumanPresentableName
= "SVG";
2369 pFlavorSeq
[8].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2371 if ( nSuppFlavors
== 11 )
2373 pFlavorSeq
[9].MimeType
=
2374 "application/x-openoffice-emf;windows_formatname=\"Image EMF\"";
2375 pFlavorSeq
[9].HumanPresentableName
= "Enhanced Windows MetaFile";
2376 pFlavorSeq
[9].DataType
= cppu::UnoType
<sal_uInt64
>::get();
2378 pFlavorSeq
[10].MimeType
=
2379 "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"";
2380 pFlavorSeq
[10].HumanPresentableName
= "Windows MetaFile";
2381 pFlavorSeq
[10].DataType
= cppu::UnoType
<sal_uInt64
>::get();
2391 sal_Bool SAL_CALL
SfxBaseModel::isDataFlavorSupported( const datatransfer::DataFlavor
& aFlavor
)
2393 SfxModelGuard
aGuard( *this );
2395 if ( aFlavor
.MimeType
== "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2397 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2400 else if ( aFlavor
.MimeType
== "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2402 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2405 else if ( aFlavor
.MimeType
== "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" )
2407 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2409 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2410 && aFlavor
.DataType
== cppu::UnoType
<sal_uInt64
>::get())
2413 else if ( aFlavor
.MimeType
== "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" )
2415 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2417 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2418 && aFlavor
.DataType
== cppu::UnoType
<sal_uInt64
>::get())
2421 else if ( aFlavor
.MimeType
== "image/svg+xml" )
2423 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2426 else if ( aFlavor
.MimeType
== "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" )
2428 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2431 else if ( aFlavor
.MimeType
== "application/x-openoffice-embed-source;windows_formatname=\"Star EMBS\"" )
2433 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2436 else if ( aFlavor
.MimeType
== "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" )
2438 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2441 else if ( aFlavor
.MimeType
== "image/png" )
2443 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2454 Reference
< container::XNameReplace
> SAL_CALL
SfxBaseModel::getEvents()
2456 SfxModelGuard
aGuard( *this );
2458 if ( ! m_pData
->m_xEvents
.is() )
2460 m_pData
->m_xEvents
= new SfxEvents_Impl( m_pData
->m_pObjectShell
.get(), this );
2463 return m_pData
->m_xEvents
;
2470 Reference
< script::XStorageBasedLibraryContainer
> SAL_CALL
SfxBaseModel::getBasicLibraries()
2472 SfxModelGuard
aGuard( *this );
2474 Reference
< script::XStorageBasedLibraryContainer
> xBasicLibraries
;
2475 if ( m_pData
->m_pObjectShell
.is() )
2476 xBasicLibraries
.set(m_pData
->m_pObjectShell
->GetBasicContainer(), UNO_QUERY
);
2477 return xBasicLibraries
;
2480 Reference
< script::XStorageBasedLibraryContainer
> SAL_CALL
SfxBaseModel::getDialogLibraries()
2482 SfxModelGuard
aGuard( *this );
2484 Reference
< script::XStorageBasedLibraryContainer
> xDialogLibraries
;
2485 if ( m_pData
->m_pObjectShell
.is() )
2486 xDialogLibraries
.set(m_pData
->m_pObjectShell
->GetDialogContainer(), UNO_QUERY
);
2487 return xDialogLibraries
;
2490 sal_Bool SAL_CALL
SfxBaseModel::getAllowMacroExecution()
2492 SfxModelGuard
aGuard( *this );
2494 if ( m_pData
->m_pObjectShell
.is() )
2495 return m_pData
->m_pObjectShell
->AdjustMacroMode();
2500 // XScriptInvocationContext
2503 Reference
< document::XEmbeddedScripts
> SAL_CALL
SfxBaseModel::getScriptContainer()
2505 SfxModelGuard
aGuard( *this );
2507 Reference
< document::XEmbeddedScripts
> xDocumentScripts
;
2511 Reference
< frame::XModel
> xDocument( this );
2512 xDocumentScripts
.set( xDocument
, UNO_QUERY
);
2513 while ( !xDocumentScripts
.is() && xDocument
.is() )
2515 Reference
< container::XChild
> xDocAsChild( xDocument
, UNO_QUERY
);
2516 if ( !xDocAsChild
.is() )
2518 xDocument
= nullptr;
2522 xDocument
.set( xDocAsChild
->getParent(), UNO_QUERY
);
2523 xDocumentScripts
.set( xDocument
, UNO_QUERY
);
2526 catch( const Exception
& )
2528 DBG_UNHANDLED_EXCEPTION("sfx.doc");
2529 xDocumentScripts
= nullptr;
2532 return xDocumentScripts
;
2536 // XEventBroadcaster
2539 void SAL_CALL
SfxBaseModel::addEventListener( const Reference
< document::XEventListener
>& aListener
)
2541 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
2543 m_pData
->m_aDocumentEventListeners1
.addInterface( aListener
);
2547 // XEventBroadcaster
2550 void SAL_CALL
SfxBaseModel::removeEventListener( const Reference
< document::XEventListener
>& aListener
)
2552 SfxModelGuard
aGuard( *this );
2554 m_pData
->m_aDocumentEventListeners1
.removeInterface( aListener
);
2557 // XShapeEventBroadcaster
2559 void SAL_CALL
SfxBaseModel::addShapeEventListener( const css::uno::Reference
< css::drawing::XShape
>& xShape
, const Reference
< document::XShapeEventListener
>& xListener
)
2561 assert(xShape
.is() && "no shape?");
2562 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
2564 m_pData
->maShapeListeners
[xShape
].push_back(xListener
);
2568 // XShapeEventBroadcaster
2571 void SAL_CALL
SfxBaseModel::removeShapeEventListener( const css::uno::Reference
< css::drawing::XShape
>& xShape
, const Reference
< document::XShapeEventListener
>& xListener
)
2573 SfxModelGuard
aGuard( *this );
2575 auto it
= m_pData
->maShapeListeners
.find(xShape
);
2576 if (it
!= m_pData
->maShapeListeners
.end())
2578 auto rVec
= it
->second
;
2579 auto it2
= std::find(rVec
.begin(), rVec
.end(), xListener
);
2580 if (it2
!= rVec
.end())
2584 m_pData
->maShapeListeners
.erase(it
);
2589 // XDocumentEventBroadcaster
2592 void SAL_CALL
SfxBaseModel::addDocumentEventListener( const Reference
< document::XDocumentEventListener
>& aListener
)
2594 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
2595 m_pData
->m_aDocumentEventListeners2
.addInterface( aListener
);
2599 void SAL_CALL
SfxBaseModel::removeDocumentEventListener( const Reference
< document::XDocumentEventListener
>& aListener
)
2601 SfxModelGuard
aGuard( *this );
2602 m_pData
->m_aDocumentEventListeners2
.removeInterface( aListener
);
2606 void SAL_CALL
SfxBaseModel::notifyDocumentEvent( const OUString
&, const Reference
< frame::XController2
>&, const Any
& )
2608 throw lang::NoSupportException(u
"SfxBaseModel controls all the sent notifications itself!"_ustr
);
2611 Sequence
<document::CmisProperty
> SAL_CALL
SfxBaseModel::getCmisProperties()
2613 if (impl_isDisposed())
2614 return Sequence
<document::CmisProperty
>();
2615 return m_pData
->m_cmisProperties
;
2618 void SAL_CALL
SfxBaseModel::setCmisProperties( const Sequence
< document::CmisProperty
>& _cmisproperties
)
2620 m_pData
->m_cmisProperties
= _cmisproperties
;
2623 void SAL_CALL
SfxBaseModel::updateCmisProperties( const Sequence
< document::CmisProperty
>& aProperties
)
2625 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2631 ::ucbhelper::Content
aContent( pMedium
->GetName( ),
2632 Reference
<ucb::XCommandEnvironment
>(),
2633 comphelper::getProcessComponentContext() );
2635 aContent
.executeCommand( u
"updateProperties"_ustr
, uno::Any( aProperties
) );
2636 loadCmisProperties( );
2638 catch (const Exception
& e
)
2640 css::uno::Any anyEx
= cppu::getCaughtException();
2641 throw lang::WrappedTargetRuntimeException( e
.Message
,
2647 void SAL_CALL
SfxBaseModel::checkOut( )
2649 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2655 ::ucbhelper::Content
aContent( pMedium
->GetName(),
2656 Reference
<ucb::XCommandEnvironment
>(),
2657 comphelper::getProcessComponentContext() );
2659 Any aResult
= aContent
.executeCommand( u
"checkout"_ustr
, Any( ) );
2663 m_pData
->m_pObjectShell
->GetMedium( )->SetName( sURL
);
2664 m_pData
->m_pObjectShell
->GetMedium( )->GetMedium_Impl( );
2665 m_pData
->m_xDocumentProperties
->setTitle( getTitle( ) );
2666 Sequence
< beans::PropertyValue
> aSequence
;
2667 TransformItems( SID_OPENDOC
, pMedium
->GetItemSet(), aSequence
);
2668 attachResource( sURL
, aSequence
);
2670 // Reload the CMIS properties
2671 loadCmisProperties( );
2673 catch ( const Exception
& e
)
2675 css::uno::Any anyEx
= cppu::getCaughtException();
2676 throw lang::WrappedTargetRuntimeException( e
.Message
,
2681 void SAL_CALL
SfxBaseModel::cancelCheckOut( )
2683 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2689 ::ucbhelper::Content
aContent( pMedium
->GetName(),
2690 Reference
<ucb::XCommandEnvironment
>(),
2691 comphelper::getProcessComponentContext() );
2693 Any aResult
= aContent
.executeCommand( u
"cancelCheckout"_ustr
, Any( ) );
2697 m_pData
->m_pObjectShell
->GetMedium( )->SetName( sURL
);
2699 catch ( const Exception
& e
)
2701 css::uno::Any anyEx
= cppu::getCaughtException();
2702 throw lang::WrappedTargetRuntimeException( e
.Message
,
2707 void SAL_CALL
SfxBaseModel::checkIn( sal_Bool bIsMajor
, const OUString
& rMessage
)
2709 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2715 Sequence
< beans::PropertyValue
> aProps
{
2716 comphelper::makePropertyValue(u
"VersionMajor"_ustr
, bIsMajor
),
2717 comphelper::makePropertyValue(u
"VersionComment"_ustr
, rMessage
),
2718 comphelper::makePropertyValue(u
"CheckIn"_ustr
, true)
2721 const OUString
sName( pMedium
->GetName( ) );
2722 storeSelf( aProps
);
2724 // Refresh pMedium as it has probably changed during the storeSelf call
2725 pMedium
= m_pData
->m_pObjectShell
->GetMedium( );
2726 const OUString
sNewName( pMedium
->GetName( ) );
2728 // URL has changed, update the document
2729 if ( sName
!= sNewName
)
2731 m_pData
->m_xDocumentProperties
->setTitle( getTitle( ) );
2732 Sequence
< beans::PropertyValue
> aSequence
;
2733 TransformItems( SID_OPENDOC
, pMedium
->GetItemSet(), aSequence
);
2734 attachResource( sNewName
, aSequence
);
2736 // Reload the CMIS properties
2737 loadCmisProperties( );
2740 catch ( const Exception
& e
)
2742 css::uno::Any anyEx
= cppu::getCaughtException();
2743 throw lang::WrappedTargetRuntimeException( e
.Message
,
2748 uno::Sequence
< document::CmisVersion
> SAL_CALL
SfxBaseModel::getAllVersions( )
2750 uno::Sequence
<document::CmisVersion
> aVersions
;
2751 if (impl_isDisposed())
2753 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2758 ::ucbhelper::Content
aContent( pMedium
->GetName(),
2759 Reference
<ucb::XCommandEnvironment
>(),
2760 comphelper::getProcessComponentContext() );
2762 Any aResult
= aContent
.executeCommand( u
"getAllVersions"_ustr
, Any( ) );
2763 aResult
>>= aVersions
;
2765 catch ( const Exception
& e
)
2767 css::uno::Any anyEx
= cppu::getCaughtException();
2768 throw lang::WrappedTargetRuntimeException( e
.Message
,
2775 bool SfxBaseModel::getBoolPropertyValue( const OUString
& rName
)
2777 bool bValue
= false;
2778 if ( m_pData
->m_pObjectShell
.is() )
2780 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2785 ::ucbhelper::Content
aContent( pMedium
->GetName( ),
2786 utl::UCBContentHelper::getDefaultCommandEnvironment(),
2787 comphelper::getProcessComponentContext() );
2788 Reference
< beans::XPropertySetInfo
> xProps
= aContent
.getProperties();
2789 if ( xProps
->hasPropertyByName( rName
) )
2791 aContent
.getPropertyValue( rName
) >>= bValue
;
2794 catch ( const Exception
& )
2796 // Simply ignore it: it's likely the document isn't versionable in that case
2804 sal_Bool SAL_CALL
SfxBaseModel::isVersionable( )
2806 return getBoolPropertyValue( u
"IsVersionable"_ustr
);
2809 sal_Bool SAL_CALL
SfxBaseModel::canCheckOut( )
2811 return getBoolPropertyValue( u
"CanCheckOut"_ustr
);
2814 sal_Bool SAL_CALL
SfxBaseModel::canCancelCheckOut( )
2816 return getBoolPropertyValue( u
"CanCancelCheckOut"_ustr
);
2819 sal_Bool SAL_CALL
SfxBaseModel::canCheckIn( )
2821 return getBoolPropertyValue( u
"CanCheckIn"_ustr
);
2824 void SfxBaseModel::loadCmisProperties( )
2826 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2832 ::ucbhelper::Content
aContent( pMedium
->GetName( ),
2833 utl::UCBContentHelper::getDefaultCommandEnvironment(),
2834 comphelper::getProcessComponentContext() );
2835 Reference
< beans::XPropertySetInfo
> xProps
= aContent
.getProperties();
2836 static constexpr OUString
aCmisProps( u
"CmisProperties"_ustr
);
2837 if ( xProps
->hasPropertyByName( aCmisProps
) )
2839 Sequence
< document::CmisProperty
> aCmisProperties
;
2840 aContent
.getPropertyValue( aCmisProps
) >>= aCmisProperties
;
2841 setCmisProperties( aCmisProperties
);
2844 catch (const ucb::ContentCreationException
&)
2847 catch (const ucb::CommandAbortedException
&)
2852 SfxMedium
* SfxBaseModel::handleLoadError( const ErrCodeMsg
& rError
, SfxMedium
* pMedium
)
2856 // No error condition.
2860 ErrCodeMsg nError
= rError
;
2861 bool bSilent
= false;
2862 const SfxBoolItem
* pSilentItem
= pMedium
->GetItemSet().GetItem(SID_SILENT
, false);
2864 bSilent
= pSilentItem
->GetValue();
2866 bool bWarning
= nError
.IsWarning();
2867 if ( nError
!= ERRCODE_IO_BROKENPACKAGE
&& !bSilent
)
2869 // broken package was handled already
2870 if ( SfxObjectShell::UseInteractionToHandleError(pMedium
->GetInteractionHandler(), nError
) && !bWarning
)
2872 // abort loading (except for warnings)
2873 nError
= ERRCODE_IO_ABORT
;
2877 if ( m_pData
->m_pObjectShell
->GetMedium() != pMedium
)
2879 // for whatever reason document now has another medium
2880 OSL_FAIL("Document has rejected the medium?!");
2885 if ( !bWarning
) // #i30711# don't abort loading if it's only a warning
2887 nError
= nError
? nError
: ERRCODE_IO_CANTREAD
;
2888 throw task::ErrorCodeIOException(
2889 "SfxBaseModel::handleLoadError: 0x" + nError
.toString(),
2890 Reference
< XInterface
>(), sal_uInt32(nError
.GetCode()));
2893 pMedium
->SetWarningError(nError
);
2902 static void addTitle_Impl( Sequence
< beans::PropertyValue
>& rSeq
, const OUString
& rTitle
)
2904 auto [begin
, end
] = asNonConstRange(rSeq
);
2905 auto pProp
= std::find_if(begin
, end
,
2906 [](const beans::PropertyValue
& rProp
) { return rProp
.Name
== "Title"; });
2909 pProp
->Value
<<= rTitle
;
2913 sal_Int32 nCount
= rSeq
.getLength();
2914 rSeq
.realloc( nCount
+1 );
2915 auto& el
= rSeq
.getArray()[nCount
];
2917 el
.Value
<<= rTitle
;
2921 void SfxBaseModel::Notify( SfxBroadcaster
& rBC
,
2922 const SfxHint
& rHint
)
2927 if ( &rBC
!= m_pData
->m_pObjectShell
.get() )
2930 if ( rHint
.GetId() == SfxHintId::DocChanged
)
2932 else if (rHint
.GetId() == SfxHintId::ThisIsAnSfxEventHint
)
2934 const SfxEventHint
& rNamedHint
= static_cast<const SfxEventHint
&>(rHint
);
2935 switch (rNamedHint
.GetEventId())
2937 case SfxEventHintId::StorageChanged
:
2939 if ( m_pData
->m_xUIConfigurationManager
.is()
2940 && m_pData
->m_pObjectShell
->GetCreateMode() != SfxObjectCreateMode::EMBEDDED
)
2942 Reference
< embed::XStorage
> xConfigStorage
;
2943 static constexpr OUString
aUIConfigFolderName( u
"Configurations2"_ustr
);
2945 xConfigStorage
= getDocumentSubStorage( aUIConfigFolderName
, embed::ElementModes::READWRITE
);
2946 if ( !xConfigStorage
.is() )
2947 xConfigStorage
= getDocumentSubStorage( aUIConfigFolderName
, embed::ElementModes::READ
);
2949 if ( xConfigStorage
.is() || !m_pData
->m_pObjectShell
->GetStorage()->hasByName( aUIConfigFolderName
) )
2951 // the storage is different, since otherwise it could not be opened, so it must be exchanged
2952 m_pData
->m_xUIConfigurationManager
->setStorage( xConfigStorage
);
2956 OSL_FAIL( "Unexpected scenario!" );
2960 ListenForStorage_Impl( m_pData
->m_pObjectShell
->GetStorage() );
2964 case SfxEventHintId::LoadFinished
:
2966 impl_getPrintHelper();
2967 ListenForStorage_Impl( m_pData
->m_pObjectShell
->GetStorage() );
2968 m_pData
->setModifiedForAutoSave(false);
2972 case SfxEventHintId::SaveAsDocDone
:
2974 m_pData
->m_sURL
= m_pData
->m_pObjectShell
->GetMedium()->GetName();
2976 Sequence
< beans::PropertyValue
> aArgs
;
2977 TransformItems( SID_SAVEASDOC
, m_pData
->m_pObjectShell
->GetMedium()->GetItemSet(), aArgs
);
2978 addTitle_Impl( aArgs
, m_pData
->m_pObjectShell
->GetTitle() );
2979 attachResource( m_pData
->m_pObjectShell
->GetMedium()->GetName(), aArgs
);
2983 case SfxEventHintId::DocCreated
:
2985 impl_getPrintHelper();
2986 m_pData
->setModifiedForAutoSave(false);
2990 case SfxEventHintId::ModifyChanged
:
2992 m_pData
->setModifiedForAutoSave(isModified());
2999 if (rNamedHint
.GetEventId() == SfxEventHintId::PrintDoc
)
3000 aSupplement
<<= static_cast<const SfxPrintingHint
*>(&rHint
)->GetWhich();
3001 const SfxViewEventHint
* pViewHint
= dynamic_cast<const SfxViewEventHint
*>(&rHint
);
3002 postEvent_Impl( rNamedHint
.GetEventName(), pViewHint
? pViewHint
->GetController() : Reference
< frame::XController2
>(), aSupplement
);
3004 else if ( rHint
.GetId() == SfxHintId::TitleChanged
)
3006 addTitle_Impl( m_pData
->m_seqArguments
, m_pData
->m_pObjectShell
->GetTitle() );
3007 postEvent_Impl( GlobalEventConfig::GetEventName( GlobalEventId::TITLECHANGED
) );
3009 else if ( rHint
.GetId() == SfxHintId::ModeChanged
)
3011 postEvent_Impl( GlobalEventConfig::GetEventName( GlobalEventId::MODECHANGED
) );
3019 void SfxBaseModel::NotifyModifyListeners_Impl() const
3021 if ( m_pData
->m_aModifyListeners
.getLength() )
3023 lang::EventObject
aEvent( static_cast<frame::XModel
*>(const_cast<SfxBaseModel
*>(this)) );
3024 m_pData
->m_aModifyListeners
.notifyEach( &util::XModifyListener::modified
, aEvent
);
3027 // this notification here is done too generously, we cannot simply assume that we're really modified
3028 // now, but we need to check it ...
3029 m_pData
->setModifiedForAutoSave(const_cast<SfxBaseModel
*>(this)->isModified());
3032 void SfxBaseModel::changing()
3034 SfxModelGuard
aGuard( *this );
3036 // the notification should not be sent if the document can not be modified
3037 if ( !m_pData
->m_pObjectShell
.is() || !m_pData
->m_pObjectShell
->IsEnableSetModified() )
3040 NotifyModifyListeners_Impl();
3047 SfxObjectShell
* SfxBaseModel::GetObjectShell() const
3049 return m_pData
? m_pData
->m_pObjectShell
.get() : nullptr;
3056 bool SfxBaseModel::IsInitialized() const
3058 if ( !m_pData
|| !m_pData
->m_pObjectShell
.is() )
3060 OSL_FAIL( "SfxBaseModel::IsInitialized: this should have been caught earlier!" );
3064 return m_pData
->m_pObjectShell
->GetMedium() != nullptr;
3067 void SfxBaseModel::MethodEntryCheck( const bool i_mustBeInitialized
) const
3069 if ( impl_isDisposed() )
3070 throw lang::DisposedException( OUString(), *const_cast< SfxBaseModel
* >( this ) );
3071 if ( i_mustBeInitialized
&& !IsInitialized() )
3072 throw lang::NotInitializedException( OUString(), *const_cast< SfxBaseModel
* >( this ) );
3075 bool SfxBaseModel::impl_isDisposed() const
3077 return ( m_pData
== nullptr ) ;
3084 OUString
SfxBaseModel::GetMediumFilterName_Impl() const
3086 std::shared_ptr
<const SfxFilter
> pFilter
;
3087 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
3089 pFilter
= pMedium
->GetFilter();
3092 return pFilter
->GetName();
3097 void SfxBaseModel::impl_store( const OUString
& sURL
,
3098 const Sequence
< beans::PropertyValue
>& seqArguments
,
3101 if( sURL
.isEmpty() )
3102 throw frame::IllegalArgumentIOException();
3104 if (!m_pData
->m_pObjectShell
)
3107 ::comphelper::SequenceAsHashMap
aArgHash(seqArguments
);
3108 if ( !bSaveTo
&& !sURL
.isEmpty()
3109 && !sURL
.startsWith( "private:stream" )
3110 && ::utl::UCBContentHelper::EqualURLs( getLocation(), sURL
) )
3112 // this is the same file URL as the current document location, try to use storeOwn if possible
3114 static constexpr OUString
aFilterString( u
"FilterName"_ustr
);
3115 const OUString
aFilterName( aArgHash
.getUnpackedValueOrDefault( aFilterString
, OUString() ) );
3116 if ( !aFilterName
.isEmpty() )
3118 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
3121 const std::shared_ptr
<const SfxFilter
>& pFilter
= pMedium
->GetFilter();
3122 if ( pFilter
&& aFilterName
== pFilter
->GetFilterName() )
3124 // #i119366# - If the former file saving with password, do not trying in StoreSelf anyway...
3125 bool bFormerPassword
= false;
3127 uno::Sequence
< beans::NamedValue
> aOldEncryptionData
;
3128 if (GetEncryptionData_Impl( &pMedium
->GetItemSet(), aOldEncryptionData
))
3130 bFormerPassword
= true;
3133 if ( !bFormerPassword
)
3135 aArgHash
.erase( aFilterString
);
3136 aArgHash
.erase( u
"URL"_ustr
);
3140 storeSelf( aArgHash
.getAsConstPropertyValueList() );
3143 catch( const lang::IllegalArgumentException
& )
3145 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
3146 // some additional arguments do not allow to use saving, SaveAs should be done
3147 // but only for normal documents, the shared documents would be overwritten in this case
3148 // that would mean an information loss
3149 // TODO/LATER: need a new interaction for this case
3150 if ( m_pData
->m_pObjectShell
->IsDocShared() )
3152 uno::Sequence
< beans::NamedValue
> aNewEncryptionData
= aArgHash
.getUnpackedValueOrDefault(u
"EncryptionData"_ustr
, uno::Sequence
< beans::NamedValue
>() );
3153 if ( !aNewEncryptionData
.hasElements() )
3155 aNewEncryptionData
= ::comphelper::OStorageHelper::CreatePackageEncryptionData( aArgHash
.getUnpackedValueOrDefault(u
"Password"_ustr
, OUString()) );
3158 uno::Sequence
< beans::NamedValue
> aOldEncryptionData
;
3159 (void)GetEncryptionData_Impl( &pMedium
->GetItemSet(), aOldEncryptionData
);
3161 if ( !aOldEncryptionData
.hasElements() && !aNewEncryptionData
.hasElements() )
3165 // if the password is changed a special error should be used in case of shared document
3166 throw task::ErrorCodeIOException(u
"Can not change password for shared document."_ustr
, uno::Reference
< uno::XInterface
>(), sal_uInt32(ERRCODE_SFX_SHARED_NOPASSWORDCHANGE
) );
3177 SfxGetpApp()->NotifyEvent( SfxEventHint( bSaveTo
? SfxEventHintId::SaveToDoc
: SfxEventHintId::SaveAsDoc
, GlobalEventConfig::GetEventName( bSaveTo
? GlobalEventId::SAVETODOC
: GlobalEventId::SAVEASDOC
),
3178 m_pData
->m_pObjectShell
.get() ) );
3180 const OUString
aFilterName(aArgHash
.getUnpackedValueOrDefault(u
"FilterName"_ustr
, OUString()));
3181 OUString aPassword
, aPasswordToModify
;
3182 if (!aArgHash
.getUnpackedValueOrDefault(u
"EncryptionData"_ustr
, Sequence
<beans::NamedValue
>())
3184 aPassword
= aArgHash
.getUnpackedValueOrDefault(u
"Password"_ustr
, OUString());
3185 if (!aArgHash
.getUnpackedValueOrDefault(u
"ModifyPasswordInfo"_ustr
, Sequence
<beans::PropertyValue
>())
3187 && aArgHash
.getUnpackedValueOrDefault(u
"ModifyPasswordInfo"_ustr
, static_cast<sal_Int32
>(0)) == 0)
3188 aPasswordToModify
= aArgHash
.getUnpackedValueOrDefault(u
"PasswordToModify"_ustr
, OUString());
3189 aArgHash
.erase(u
"PasswordToModify"_ustr
);
3191 std::optional
<SfxAllItemSet
> pItemSet(SfxGetpApp()->GetPool());
3192 pItemSet
->Put(SfxStringItem(SID_FILE_NAME
, sURL
));
3194 pItemSet
->Put(SfxBoolItem(SID_SAVETO
, true));
3196 if (!aFilterName
.isEmpty() && (!aPassword
.isEmpty() || !aPasswordToModify
.isEmpty()))
3197 sfx2::SetPassword(SfxGetpApp()->GetFilterMatcher().GetFilter4FilterName(aFilterName
),
3198 &*pItemSet
, aPassword
, aPasswordToModify
, false);
3200 TransformParameters(SID_SAVEASDOC
, seqArguments
, *pItemSet
);
3202 const SfxBoolItem
* pCopyStreamItem
= pItemSet
->GetItem
<SfxBoolItem
>(SID_COPY_STREAM_IF_POSSIBLE
, false);
3204 if ( pCopyStreamItem
&& pCopyStreamItem
->GetValue() && !bSaveTo
)
3206 throw frame::IllegalArgumentIOException(
3207 u
"CopyStreamIfPossible parameter is not acceptable for storeAsURL() call!"_ustr
);
3210 sal_uInt32 nModifyPasswordHash
= 0;
3211 Sequence
< beans::PropertyValue
> aModifyPasswordInfo
;
3212 const SfxUnoAnyItem
* pModifyPasswordInfoItem
= pItemSet
->GetItem
<SfxUnoAnyItem
>(SID_MODIFYPASSWORDINFO
, false);
3213 if ( pModifyPasswordInfoItem
)
3215 // it contains either a simple hash or a set of PropertyValues
3216 // TODO/LATER: the sequence of PropertyValue should replace the hash completely in future
3217 sal_Int32 nMPHTmp
= 0;
3218 pModifyPasswordInfoItem
->GetValue() >>= nMPHTmp
;
3219 nModifyPasswordHash
= static_cast<sal_uInt32
>(nMPHTmp
);
3220 pModifyPasswordInfoItem
->GetValue() >>= aModifyPasswordInfo
;
3222 pItemSet
->ClearItem(SID_MODIFYPASSWORDINFO
);
3223 sal_uInt32 nOldModifyPasswordHash
= m_pData
->m_pObjectShell
->GetModifyPasswordHash();
3224 m_pData
->m_pObjectShell
->SetModifyPasswordHash( nModifyPasswordHash
);
3225 Sequence
< beans::PropertyValue
> aOldModifyPasswordInfo
= m_pData
->m_pObjectShell
->GetModifyPasswordInfo();
3226 m_pData
->m_pObjectShell
->SetModifyPasswordInfo( aModifyPasswordInfo
);
3228 // since saving a document modifies its DocumentProperties, the current
3229 // DocumentProperties must be saved on "SaveTo", so it can be restored
3231 bool bCopyTo
= bSaveTo
||
3232 m_pData
->m_pObjectShell
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
;
3233 Reference
<document::XDocumentProperties
> xOldDocProps
;
3236 xOldDocProps
= getDocumentProperties();
3237 const Reference
<util::XCloneable
> xCloneable(xOldDocProps
,
3239 const Reference
<document::XDocumentProperties
> xNewDocProps(
3240 xCloneable
->createClone(), UNO_QUERY_THROW
);
3241 m_pData
->m_xDocumentProperties
= xNewDocProps
;
3244 bool bRet
= m_pData
->m_pObjectShell
->APISaveAs_Impl(sURL
, *pItemSet
, seqArguments
);
3248 // restore DocumentProperties if a copy was created
3249 m_pData
->m_xDocumentProperties
= std::move(xOldDocProps
);
3252 Reference
< task::XInteractionHandler
> xHandler
;
3253 const SfxUnoAnyItem
* pItem
= pItemSet
->GetItem
<SfxUnoAnyItem
>(SID_INTERACTIONHANDLER
, false);
3255 pItem
->GetValue() >>= xHandler
;
3259 ErrCodeMsg nErrCode
= m_pData
->m_pObjectShell
->GetErrorCode();
3260 if ( !bRet
&& !nErrCode
)
3262 SAL_WARN("sfx.doc", "Storing has failed, no error is set!");
3263 nErrCode
= ERRCODE_IO_CANTWRITE
;
3265 m_pData
->m_pObjectShell
->ResetError();
3271 // must be a warning - use Interactionhandler if possible or abandon
3272 if ( xHandler
.is() )
3274 // TODO/LATER: a general way to set the error context should be available
3275 SfxErrorContext
aEc( ERRCTX_SFX_SAVEASDOC
, m_pData
->m_pObjectShell
->GetTitle() );
3277 task::ErrorCodeRequest2
aErrorCode(OUString(), uno::Reference
<XInterface
>(),
3278 sal_Int32(sal_uInt32(nErrCode
.GetCode())), nErrCode
.GetArg1(), nErrCode
.GetArg2(),
3279 static_cast<sal_Int16
>(nErrCode
.GetDialogMask()));
3280 SfxMedium::CallApproveHandler( xHandler
, Any( aErrorCode
), false );
3286 m_pData
->m_aPreusedFilterName
= GetMediumFilterName_Impl();
3287 m_pData
->m_pObjectShell
->SetModifyPasswordEntered();
3289 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveAsDocDone
, GlobalEventConfig::GetEventName(GlobalEventId::SAVEASDOCDONE
), m_pData
->m_pObjectShell
.get() ) );
3293 m_pData
->m_pObjectShell
->SetModifyPasswordHash( nOldModifyPasswordHash
);
3294 m_pData
->m_pObjectShell
->SetModifyPasswordInfo( aOldModifyPasswordInfo
);
3296 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveToDocDone
, GlobalEventConfig::GetEventName(GlobalEventId::SAVETODOCDONE
), m_pData
->m_pObjectShell
.get() ) );
3301 m_pData
->m_pObjectShell
->SetModifyPasswordHash( nOldModifyPasswordHash
);
3302 m_pData
->m_pObjectShell
->SetModifyPasswordInfo( aOldModifyPasswordInfo
);
3305 SfxGetpApp()->NotifyEvent( SfxEventHint( bSaveTo
? SfxEventHintId::SaveToDocFailed
: SfxEventHintId::SaveAsDocFailed
, GlobalEventConfig::GetEventName( bSaveTo
? GlobalEventId::SAVETODOCFAILED
: GlobalEventId::SAVEASDOCFAILED
),
3306 m_pData
->m_pObjectShell
.get() ) );
3308 if (SfxViewShell
* pNotifyView
= comphelper::LibreOfficeKit::isActive() ? SfxViewShell::Current() : nullptr)
3309 pNotifyView
->libreOfficeKitViewCallback(LOK_CALLBACK_EXPORT_FILE
, "ERROR"_ostr
);
3311 std::stringstream aErrCode
;
3312 aErrCode
<< nErrCode
;
3313 throw task::ErrorCodeIOException(
3314 "SfxBaseModel::impl_store <" + sURL
+ "> failed: " + OUString::fromUtf8(aErrCode
.str()),
3315 Reference
< XInterface
>(), sal_uInt32(nErrCode
.GetCode()));
3321 template< typename ListenerT
, typename EventT
>
3322 class NotifySingleListenerIgnoreRE
3325 typedef void ( SAL_CALL
ListenerT::*NotificationMethod
)( const EventT
& );
3326 NotificationMethod m_pMethod
;
3327 const EventT
& m_rEvent
;
3329 NotifySingleListenerIgnoreRE( NotificationMethod method
, const EventT
& event
) : m_pMethod( method
), m_rEvent( event
) { }
3331 void operator()( const Reference
<ListenerT
>& listener
) const
3335 (listener
.get()->*m_pMethod
)( m_rEvent
);
3337 catch( RuntimeException
& )
3339 // this exception is ignored to avoid problems with invalid listeners, the listener should be probably thrown away in future
3340 TOOLS_WARN_EXCEPTION("sfx.appl", "ignoring");
3344 } // anonymous namespace
3346 void SfxBaseModel::postEvent_Impl( const OUString
& aName
, const Reference
< frame::XController2
>& xController
, const Any
& supplement
)
3348 if (aName
.isEmpty())
3350 SAL_WARN("sfx.doc", "postEvent_Impl: Empty event name!");
3354 // also make sure this object doesn't self-destruct while notifying
3355 rtl::Reference
<SfxBaseModel
> xHoldAlive(this);
3356 // keep m_pData alive, if notified target would dispose the document
3357 std::shared_ptr
<IMPL_SfxBaseModel_DataContainer
> xKeepAlive(m_pData
);
3359 // object already disposed?
3360 if ( impl_isDisposed() )
3363 if ( xKeepAlive
->m_aDocumentEventListeners2
.getLength() )
3365 SAL_INFO("sfx.doc", "SfxDocumentEvent: " + aName
);
3367 document::DocumentEvent
aDocumentEvent( static_cast<frame::XModel
*>(this), aName
, xController
, supplement
);
3369 xKeepAlive
->m_aDocumentEventListeners2
.forEach(
3370 NotifySingleListenerIgnoreRE
< document::XDocumentEventListener
, document::DocumentEvent
>(
3371 &document::XDocumentEventListener::documentEventOccured
,
3375 if ( xKeepAlive
->m_aDocumentEventListeners1
.getLength() )
3377 SAL_INFO("sfx.doc", "SfxEvent: " + aName
);
3379 document::EventObject
aEvent( static_cast<frame::XModel
*>(this), aName
);
3381 xKeepAlive
->m_aDocumentEventListeners1
.forEach(
3382 NotifySingleListenerIgnoreRE
< document::XEventListener
, document::EventObject
>(
3383 &document::XEventListener::notifyEvent
,
3388 Reference
< container::XIndexAccess
> SAL_CALL
SfxBaseModel::getViewData()
3390 SfxModelGuard
aGuard( *this );
3392 if ( m_pData
->m_pObjectShell
.is() && !m_pData
->m_contViewData
.is() )
3394 SfxViewFrame
*pActFrame
= SfxViewFrame::Current();
3395 if ( !pActFrame
|| pActFrame
->GetObjectShell() != m_pData
->m_pObjectShell
.get() )
3396 pActFrame
= SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get() );
3398 if ( !pActFrame
|| !pActFrame
->GetViewShell() )
3399 // currently no frame for this document at all or View is under construction
3400 return Reference
< container::XIndexAccess
>();
3402 m_pData
->m_contViewData
= new comphelper::IndexedPropertyValuesContainer();
3404 if ( !m_pData
->m_contViewData
.is() )
3406 // error: no container class available!
3407 return Reference
< container::XIndexAccess
>();
3410 Reference
< container::XIndexContainer
> xCont( m_pData
->m_contViewData
, UNO_QUERY
);
3411 sal_Int32 nCount
= 0;
3412 Sequence
< beans::PropertyValue
> aSeq
;
3413 for ( SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get() ); pFrame
;
3414 pFrame
= SfxViewFrame::GetNext( *pFrame
, m_pData
->m_pObjectShell
.get() ) )
3416 bool bIsActive
= ( pFrame
== pActFrame
);
3417 pFrame
->GetViewShell()->WriteUserDataSequence( aSeq
);
3418 xCont
->insertByIndex( bIsActive
? 0 : nCount
, Any(aSeq
) );
3423 return m_pData
->m_contViewData
;
3426 void SAL_CALL
SfxBaseModel::setViewData( const Reference
< container::XIndexAccess
>& aData
)
3428 SfxModelGuard
aGuard( *this );
3430 m_pData
->m_contViewData
= aData
;
3433 /** calls all XEventListeners */
3434 void SfxBaseModel::notifyEvent( const document::EventObject
& aEvent
) const
3436 // object already disposed?
3437 if ( impl_isDisposed() )
3440 if( !m_pData
->m_aDocumentEventListeners1
.getLength() )
3444 comphelper::OInterfaceIteratorHelper3
aIt( m_pData
->m_aDocumentEventListeners1
);
3445 while( aIt
.hasMoreElements() )
3449 aIt
.next()->notifyEvent( aEvent
);
3451 catch( RuntimeException
& )
3456 // for right now, we're only doing the event that this particular performance problem needed
3457 if (aEvent
.EventName
== "ShapeModified")
3459 uno::Reference
<drawing::XShape
> xShape(aEvent
.Source
, uno::UNO_QUERY
);
3462 auto it
= m_pData
->maShapeListeners
.find(xShape
);
3463 if (it
!= m_pData
->maShapeListeners
.end())
3464 for (auto const & rListenerUnoRef
: it
->second
)
3465 rListenerUnoRef
->notifyShapeEvent(aEvent
);
3470 /** returns true if someone added a XEventListener to this XEventBroadcaster */
3471 bool SfxBaseModel::hasEventListeners() const
3473 return !impl_isDisposed()
3474 && ( m_pData
->m_aDocumentEventListeners1
.getLength() != 0
3475 || !m_pData
->maShapeListeners
.empty());
3478 void SAL_CALL
SfxBaseModel::addPrintJobListener( const Reference
< view::XPrintJobListener
>& xListener
)
3480 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
3482 impl_getPrintHelper();
3483 if ( m_pData
->m_xPrintable
.is() )
3484 m_pData
->m_xPrintable
->addPrintJobListener( xListener
);
3487 void SAL_CALL
SfxBaseModel::removePrintJobListener( const Reference
< view::XPrintJobListener
>& xListener
)
3489 SfxModelGuard
aGuard( *this );
3491 impl_getPrintHelper();
3492 if ( m_pData
->m_xPrintable
.is() )
3493 m_pData
->m_xPrintable
->removePrintJobListener( xListener
);
3496 sal_Int64 SAL_CALL
SfxBaseModel::getSomething( const Sequence
< sal_Int8
>& aIdentifier
)
3498 SvGlobalName
aName( aIdentifier
);
3499 if (aName
== SvGlobalName( SFX_GLOBAL_CLASSID
))
3501 SolarMutexGuard aGuard
;
3502 SfxObjectShell
*const pObjectShell(GetObjectShell());
3505 return comphelper::getSomething_cast(pObjectShell
);
3513 // XDocumentSubStorageSupplier
3516 void SfxBaseModel::ListenForStorage_Impl( const Reference
< embed::XStorage
>& xStorage
)
3518 Reference
< util::XModifiable
> xModifiable( xStorage
, UNO_QUERY
);
3519 if ( xModifiable
.is() )
3521 if ( !m_pData
->m_pStorageModifyListen
.is() )
3523 m_pData
->m_pStorageModifyListen
= new ::sfx2::DocumentStorageModifyListener( *m_pData
, Application::GetSolarMutex() );
3526 // no need to deregister the listening for old storage since it should be disposed automatically
3527 xModifiable
->addModifyListener( m_pData
->m_pStorageModifyListen
);
3531 Reference
< embed::XStorage
> SAL_CALL
SfxBaseModel::getDocumentSubStorage( const OUString
& aStorageName
, sal_Int32 nMode
)
3533 SfxModelGuard
aGuard( *this );
3535 Reference
< embed::XStorage
> xResult
;
3536 if ( m_pData
->m_pObjectShell
.is() )
3538 Reference
< embed::XStorage
> xStorage
= m_pData
->m_pObjectShell
->GetStorage();
3539 if ( xStorage
.is() )
3543 xResult
= xStorage
->openStorageElement( aStorageName
, nMode
);
3545 catch ( Exception
& )
3554 Sequence
< OUString
> SAL_CALL
SfxBaseModel::getDocumentSubStoragesNames()
3556 SfxModelGuard
aGuard( *this );
3558 Sequence
< OUString
> aResult
;
3559 bool bSuccess
= false;
3560 if ( m_pData
->m_pObjectShell
.is() )
3562 Reference
< embed::XStorage
> xStorage
= m_pData
->m_pObjectShell
->GetStorage();
3563 if ( xStorage
.is() )
3565 const Sequence
< OUString
> aTemp
= xStorage
->getElementNames();
3566 sal_Int32 nResultSize
= 0;
3567 for ( const auto& rName
: aTemp
)
3569 if ( xStorage
->isStorageElement( rName
) )
3571 aResult
.realloc( ++nResultSize
);
3572 aResult
.getArray()[ nResultSize
- 1 ] = rName
;
3581 throw io::IOException();
3587 // XScriptProviderSupplier
3590 Reference
< script::provider::XScriptProvider
> SAL_CALL
SfxBaseModel::getScriptProvider()
3592 SfxModelGuard
aGuard( *this );
3594 Reference
< script::provider::XScriptProviderFactory
> xScriptProviderFactory
=
3595 script::provider::theMasterScriptProviderFactory::get( ::comphelper::getProcessComponentContext() );
3597 Reference
< XScriptInvocationContext
> xScriptContext( this );
3599 Reference
< script::provider::XScriptProvider
> xScriptProvider(
3600 xScriptProviderFactory
->createScriptProvider( Any( xScriptContext
) ),
3603 return xScriptProvider
;
3607 // XUIConfigurationManagerSupplier
3610 OUString
const & SfxBaseModel::getRuntimeUID() const
3612 OSL_ENSURE( !m_pData
->m_sRuntimeUID
.isEmpty(),
3613 "SfxBaseModel::getRuntimeUID - ID is empty!" );
3614 return m_pData
->m_sRuntimeUID
;
3617 bool SfxBaseModel::hasValidSignatures() const
3619 SolarMutexGuard aGuard
;
3620 if ( m_pData
->m_pObjectShell
.is() )
3621 return ( m_pData
->m_pObjectShell
->ImplGetSignatureState() == SignatureState::OK
);
3625 void SfxBaseModel::getGrabBagItem(css::uno::Any
& rVal
) const
3627 if (m_pData
->m_xGrabBagItem
)
3628 m_pData
->m_xGrabBagItem
->QueryValue(rVal
);
3630 rVal
<<= uno::Sequence
<beans::PropertyValue
>();
3633 void SfxBaseModel::setGrabBagItem(const css::uno::Any
& rVal
)
3635 if (!m_pData
->m_xGrabBagItem
)
3636 m_pData
->m_xGrabBagItem
= std::make_shared
<SfxGrabBagItem
>();
3638 m_pData
->m_xGrabBagItem
->PutValue(rVal
, 0);
3641 static void GetCommandFromSequence( OUString
& rCommand
, sal_Int32
& nIndex
, const Sequence
< beans::PropertyValue
>& rSeqPropValue
)
3645 auto pPropValue
= std::find_if(rSeqPropValue
.begin(), rSeqPropValue
.end(),
3646 [](const beans::PropertyValue
& rPropValue
) { return rPropValue
.Name
== "Command"; });
3647 if (pPropValue
!= rSeqPropValue
.end())
3649 pPropValue
->Value
>>= rCommand
;
3650 nIndex
= static_cast<sal_Int32
>(std::distance(rSeqPropValue
.begin(), pPropValue
));
3654 static void ConvertSlotsToCommands( SfxObjectShell
const * pDoc
, Reference
< container::XIndexContainer
> const & rToolbarDefinition
)
3659 SfxModule
* pModule( pDoc
->GetFactory().GetModule() );
3660 Sequence
< beans::PropertyValue
> aSeqPropValue
;
3662 for ( sal_Int32 i
= 0; i
< rToolbarDefinition
->getCount(); i
++ )
3664 if ( rToolbarDefinition
->getByIndex( i
) >>= aSeqPropValue
)
3667 sal_Int32
nIndex( -1 );
3668 GetCommandFromSequence( aCommand
, nIndex
, aSeqPropValue
);
3669 if ( nIndex
>= 0 && aCommand
.startsWith( "slot:" ) )
3671 const sal_uInt16 nSlot
= o3tl::toInt32(aCommand
.subView( 5 ));
3673 // We have to replace the old "slot-Command" with our new ".uno:-Command"
3674 const SfxSlot
* pSlot
= pModule
->GetSlotPool()->GetSlot( nSlot
);
3677 aCommand
= pSlot
->GetCommand();
3678 aSeqPropValue
.getArray()[nIndex
].Value
<<= aCommand
;
3679 rToolbarDefinition
->replaceByIndex( i
, Any( aSeqPropValue
));
3686 Reference
< ui::XUIConfigurationManager
> SAL_CALL
SfxBaseModel::getUIConfigurationManager()
3688 return Reference
< ui::XUIConfigurationManager
>( getUIConfigurationManager2(), UNO_QUERY_THROW
);
3691 Reference
< ui::XUIConfigurationManager2
> SfxBaseModel::getUIConfigurationManager2()
3693 SfxModelGuard
aGuard( *this );
3695 if ( !m_pData
->m_xUIConfigurationManager
.is() )
3697 Reference
< ui::XUIConfigurationManager2
> xNewUIConfMan
=
3698 ui::UIConfigurationManager::create( comphelper::getProcessComponentContext() );
3700 Reference
< embed::XStorage
> xConfigStorage
;
3702 OUString
aUIConfigFolderName( u
"Configurations2"_ustr
);
3703 // First try to open with READWRITE and then READ
3704 xConfigStorage
= getDocumentSubStorage( aUIConfigFolderName
, embed::ElementModes::READWRITE
);
3705 if ( xConfigStorage
.is() )
3707 static constexpr OUString
aMediaTypeProp( u
"MediaType"_ustr
);
3708 OUString aMediaType
;
3709 Reference
< beans::XPropertySet
> xPropSet( xConfigStorage
, UNO_QUERY
);
3710 Any a
= xPropSet
->getPropertyValue( aMediaTypeProp
);
3711 if ( !( a
>>= aMediaType
) || aMediaType
.isEmpty())
3713 xPropSet
->setPropertyValue( aMediaTypeProp
, Any(u
"application/vnd.sun.xml.ui.configuration"_ustr
) );
3717 xConfigStorage
= getDocumentSubStorage( aUIConfigFolderName
, embed::ElementModes::READ
);
3719 // initialize ui configuration manager with document substorage
3720 xNewUIConfMan
->setStorage( xConfigStorage
);
3722 // embedded objects did not support local configuration data until OOo 3.0, so there's nothing to
3724 if ( m_pData
->m_pObjectShell
->GetCreateMode() != SfxObjectCreateMode::EMBEDDED
)
3726 // Import old UI configuration from OOo 1.x
3728 // Try to open with READ
3729 Reference
< embed::XStorage
> xOOo1ConfigStorage
= getDocumentSubStorage( u
"Configurations"_ustr
, embed::ElementModes::READ
);
3730 if ( xOOo1ConfigStorage
.is() )
3732 const Reference
< XComponentContext
>& xContext( ::comphelper::getProcessComponentContext() );
3733 std::vector
< Reference
< container::XIndexContainer
> > rToolbars
;
3735 bool bImported
= framework::UIConfigurationImporterOOo1x::ImportCustomToolbars(
3736 xNewUIConfMan
, rToolbars
, xContext
, xOOo1ConfigStorage
);
3739 SfxObjectShell
* pObjShell
= SfxBaseModel::GetObjectShell();
3741 for ( size_t i
= 0; i
< rToolbars
.size(); i
++ )
3743 const OUString
sId(OUString::number( i
+ 1 ));
3744 const OUString aCustomTbxName
= "private:resource/toolbar/custom_OOo1x_" + sId
;
3746 const Reference
< container::XIndexContainer
>& xToolbar
= rToolbars
[i
];
3747 ConvertSlotsToCommands( pObjShell
, xToolbar
);
3748 if ( !xNewUIConfMan
->hasSettings( aCustomTbxName
))
3750 // Set UIName for the toolbar with container property
3751 Reference
< beans::XPropertySet
> xPropSet( xToolbar
, UNO_QUERY
);
3752 if ( xPropSet
.is() )
3756 xPropSet
->setPropertyValue( u
"UIName"_ustr
, Any( "Toolbar " + sId
) );
3758 catch ( beans::UnknownPropertyException
& )
3763 xNewUIConfMan
->insertSettings( aCustomTbxName
, xToolbar
);
3764 xNewUIConfMan
->store();
3771 m_pData
->m_xUIConfigurationManager
= std::move(xNewUIConfMan
);
3774 return m_pData
->m_xUIConfigurationManager
;
3781 void SAL_CALL
SfxBaseModel::setVisualAreaSize( sal_Int64 nAspect
, const awt::Size
& aSize
)
3783 SfxModelGuard
aGuard( *this );
3785 if ( !m_pData
->m_pObjectShell
.is() )
3786 throw Exception(u
"no object shell"_ustr
, nullptr); // TODO: error handling
3788 SfxViewFrame
* pViewFrm
= SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get(), false );
3789 if ( pViewFrm
&& m_pData
->m_pObjectShell
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
&& !pViewFrm
->GetFrame().IsInPlace() )
3791 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow( pViewFrm
->GetFrame().GetFrameInterface()->getContainerWindow() );
3792 Size aWinSize
= pWindow
->GetSizePixel();
3793 awt::Size aCurrent
= getVisualAreaSize( nAspect
);
3794 Size
aDiff( aSize
.Width
-aCurrent
.Width
, aSize
.Height
-aCurrent
.Height
);
3795 aDiff
= pViewFrm
->GetViewShell()->GetWindow()->LogicToPixel( aDiff
);
3796 aWinSize
.AdjustWidth(aDiff
.Width() );
3797 aWinSize
.AdjustHeight(aDiff
.Height() );
3798 pWindow
->SetSizePixel( aWinSize
);
3802 tools::Rectangle aTmpRect
= m_pData
->m_pObjectShell
->GetVisArea( ASPECT_CONTENT
);
3803 aTmpRect
.SetSize( Size( aSize
.Width
, aSize
.Height
) );
3804 m_pData
->m_pObjectShell
->SetVisArea( aTmpRect
);
3808 awt::Size SAL_CALL
SfxBaseModel::getVisualAreaSize( sal_Int64
/*nAspect*/ )
3810 SfxModelGuard
aGuard( *this );
3812 if ( !m_pData
->m_pObjectShell
.is() )
3813 throw Exception(u
"no object shell"_ustr
, nullptr); // TODO: error handling
3815 tools::Rectangle aTmpRect
= m_pData
->m_pObjectShell
->GetVisArea( ASPECT_CONTENT
);
3817 return awt::Size( aTmpRect
.GetWidth(), aTmpRect
.GetHeight() );
3821 sal_Int32 SAL_CALL
SfxBaseModel::getMapUnit( sal_Int64
/*nAspect*/ )
3823 SfxModelGuard
aGuard( *this );
3825 if ( !m_pData
->m_pObjectShell
.is() )
3826 throw Exception(u
"no object shell"_ustr
, nullptr); // TODO: error handling
3828 return VCLUnoHelper::VCL2UnoEmbedMapUnit( m_pData
->m_pObjectShell
->GetMapUnit() );
3831 embed::VisualRepresentation SAL_CALL
SfxBaseModel::getPreferredVisualRepresentation( ::sal_Int64
/*nAspect*/ )
3833 SfxModelGuard
aGuard( *this );
3835 datatransfer::DataFlavor
aDataFlavor(
3836 u
"application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\""_ustr
,
3837 u
"GDIMetaFile"_ustr
,
3838 cppu::UnoType
<Sequence
< sal_Int8
>>::get() );
3840 embed::VisualRepresentation aVisualRepresentation
;
3841 aVisualRepresentation
.Data
= getTransferData( aDataFlavor
);
3842 aVisualRepresentation
.Flavor
= std::move(aDataFlavor
);
3844 return aVisualRepresentation
;
3848 // XStorageBasedDocument
3851 void SAL_CALL
SfxBaseModel::loadFromStorage( const Reference
< embed::XStorage
>& xStorage
,
3852 const Sequence
< beans::PropertyValue
>& aMediaDescriptor
)
3854 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
3855 if ( IsInitialized() )
3856 throw frame::DoubleInitializationException( OUString(), *this );
3858 // after i36090 is fixed the pool from object shell can be used
3859 // SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() );
3860 SfxAllItemSet
aSet( SfxGetpApp()->GetPool() );
3862 // the BaseURL is part of the ItemSet
3863 SfxMedium
* pMedium
= new SfxMedium( xStorage
, OUString() );
3864 TransformParameters( SID_OPENDOC
, aMediaDescriptor
, aSet
);
3865 pMedium
->GetItemSet().Put( aSet
);
3867 // allow to use an interactionhandler (if there is one)
3868 pMedium
->UseInteractionHandler( true );
3870 const SfxBoolItem
* pTemplateItem
= aSet
.GetItem
<SfxBoolItem
>(SID_TEMPLATE
, false);
3871 bool bTemplate
= pTemplateItem
&& pTemplateItem
->GetValue();
3872 m_pData
->m_pObjectShell
->SetActivateEvent_Impl( bTemplate
? SfxEventHintId::CreateDoc
: SfxEventHintId::OpenDoc
);
3873 m_pData
->m_pObjectShell
->Get_Impl()->bOwnsStorage
= false;
3876 if ( !m_pData
->m_pObjectShell
->DoLoad(pMedium
) )
3878 ErrCodeMsg nError
= m_pData
->m_pObjectShell
->GetErrorCode();
3879 nError
= nError
? nError
: ERRCODE_IO_CANTREAD
;
3880 throw task::ErrorCodeIOException(
3881 "SfxBaseModel::loadFromStorage: " + nError
.toString(),
3882 Reference
< XInterface
>(), sal_uInt32(nError
.GetCode()));
3884 loadCmisProperties( );
3887 void SAL_CALL
SfxBaseModel::storeToStorage( const Reference
< embed::XStorage
>& xStorage
,
3888 const Sequence
< beans::PropertyValue
>& aMediaDescriptor
)
3890 SfxModelGuard
aGuard( *this );
3892 if ( !m_pData
->m_pObjectShell
.is() )
3893 throw io::IOException(); // TODO:
3895 auto xSet
= std::make_shared
<SfxAllItemSet
>(m_pData
->m_pObjectShell
->GetPool());
3896 TransformParameters( SID_SAVEASDOC
, aMediaDescriptor
, *xSet
);
3898 // TODO/LATER: maybe a special URL "private:storage" should be used
3899 const SfxStringItem
* pItem
= xSet
->GetItem
<SfxStringItem
>(SID_FILTER_NAME
, false);
3900 sal_Int32 nVersion
= SOFFICE_FILEFORMAT_CURRENT
;
3903 std::shared_ptr
<const SfxFilter
> pFilter
= SfxGetpApp()->GetFilterMatcher().GetFilter4FilterName( pItem
->GetValue() );
3904 if ( pFilter
&& pFilter
->UsesStorage() )
3905 nVersion
= pFilter
->GetVersion();
3908 bool bSuccess
= false;
3909 if ( xStorage
== m_pData
->m_pObjectShell
->GetStorage() )
3911 // storing to the own storage
3912 bSuccess
= m_pData
->m_pObjectShell
->DoSave();
3916 // TODO/LATER: if the provided storage has some data inside the storing might fail, probably the storage must be truncated
3917 // TODO/LATER: is it possible to have a template here?
3918 m_pData
->m_pObjectShell
->SetupStorage( xStorage
, nVersion
, false );
3920 // BaseURL is part of the ItemSet
3921 SfxMedium
aMedium( xStorage
, OUString(), xSet
);
3922 aMedium
.CanDisposeStorage_Impl( false );
3923 if ( aMedium
.GetFilter() )
3925 // storing without a valid filter will often crash
3926 bSuccess
= m_pData
->m_pObjectShell
->DoSaveObjectAs( aMedium
, true );
3927 m_pData
->m_pObjectShell
->DoSaveCompleted();
3931 ErrCodeMsg nError
= m_pData
->m_pObjectShell
->GetErrorCode();
3932 m_pData
->m_pObjectShell
->ResetError();
3934 // the warnings are currently not transported
3937 nError
= nError
? nError
: ERRCODE_IO_GENERAL
;
3938 throw task::ErrorCodeIOException(
3939 "SfxBaseModel::storeToStorage: " + nError
.toString(),
3940 Reference
< XInterface
>(), sal_uInt32(nError
.GetCode()));
3944 void SAL_CALL
SfxBaseModel::switchToStorage( const Reference
< embed::XStorage
>& xStorage
)
3946 SfxModelGuard
aGuard( *this );
3948 if ( !m_pData
->m_pObjectShell
.is() )
3949 throw io::IOException(); // TODO:
3951 // the persistence should be switched only if the storage is different
3952 if ( xStorage
!= m_pData
->m_pObjectShell
->GetStorage() )
3954 if ( !m_pData
->m_pObjectShell
->SwitchPersistence( xStorage
) )
3956 ErrCodeMsg nError
= m_pData
->m_pObjectShell
->GetErrorCode();
3957 nError
= nError
? nError
: ERRCODE_IO_GENERAL
;
3958 throw task::ErrorCodeIOException(
3959 "SfxBaseModel::switchToStorage: " + nError
.toString(),
3960 Reference
< XInterface
>(), sal_uInt32(nError
.GetCode()));
3964 // UICfgMgr has a reference to the old storage, update it
3965 getUIConfigurationManager2()->setStorage( xStorage
);
3968 m_pData
->m_pObjectShell
->Get_Impl()->bOwnsStorage
= false;
3971 Reference
< embed::XStorage
> SAL_CALL
SfxBaseModel::getDocumentStorage()
3973 SfxModelGuard
aGuard( *this );
3975 if ( !m_pData
->m_pObjectShell
.is() )
3976 throw io::IOException(); // TODO
3978 return m_pData
->m_pObjectShell
->GetStorage();
3981 void SAL_CALL
SfxBaseModel::addStorageChangeListener(
3982 const Reference
< document::XStorageChangeListener
>& xListener
)
3984 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
3986 m_pData
->m_aStorageChangeListeners
.addInterface( xListener
);
3989 void SAL_CALL
SfxBaseModel::removeStorageChangeListener(
3990 const Reference
< document::XStorageChangeListener
>& xListener
)
3992 SfxModelGuard
aGuard( *this );
3994 m_pData
->m_aStorageChangeListeners
.removeInterface( xListener
);
3997 void SfxBaseModel::impl_getPrintHelper()
3999 if ( m_pData
->m_xPrintable
.is() )
4001 m_pData
->m_xPrintable
= new SfxPrintHelper();
4002 m_pData
->m_xPrintable
->initialize( { Any(Reference
< frame::XModel
> (this)) } );
4003 m_pData
->m_xPrintable
->addPrintJobListener( new SfxPrintHelperListener_Impl( m_pData
.get() ) );
4007 // css.frame.XModule
4008 void SAL_CALL
SfxBaseModel::setIdentifier(const OUString
& Identifier
)
4010 SfxModelGuard
aGuard( *this );
4011 m_pData
->m_sModuleIdentifier
= Identifier
;
4015 // css.frame.XModule
4016 OUString SAL_CALL
SfxBaseModel::getIdentifier()
4018 SfxModelGuard
aGuard( *this );
4019 if (!m_pData
->m_sModuleIdentifier
.isEmpty())
4020 return m_pData
->m_sModuleIdentifier
;
4021 if (m_pData
->m_pObjectShell
.is())
4022 return m_pData
->m_pObjectShell
->GetFactory().GetDocumentServiceName();
4027 Reference
< frame::XTitle
> SfxBaseModel::impl_getTitleHelper ()
4029 SfxModelGuard
aGuard( *this );
4031 if ( ! m_pData
->m_xTitleHelper
.is ())
4033 const Reference
< XComponentContext
>& xContext
= ::comphelper::getProcessComponentContext();
4034 Reference
< frame::XUntitledNumbers
> xDesktop( frame::Desktop::create(xContext
), UNO_QUERY_THROW
);
4036 m_pData
->m_xTitleHelper
= new ::framework::TitleHelper(xContext
, Reference
< frame::XModel
>(this), xDesktop
);
4039 return m_pData
->m_xTitleHelper
;
4043 Reference
< frame::XUntitledNumbers
> SfxBaseModel::impl_getUntitledHelper ()
4045 SfxModelGuard
aGuard( *this );
4047 if ( ! m_pData
->m_xNumberedControllers
.is ())
4049 m_pData
->m_xNumberedControllers
= new ::comphelper::NumberedCollection();
4050 m_pData
->m_xNumberedControllers
->setOwner (Reference
< frame::XModel
>(this));
4051 m_pData
->m_xNumberedControllers
->setUntitledPrefix (u
" : "_ustr
);
4054 return m_pData
->m_xNumberedControllers
;
4059 OUString SAL_CALL
SfxBaseModel::getTitle()
4062 SfxModelGuard
aGuard( *this );
4064 OUString aResult
= impl_getTitleHelper()->getTitle ();
4065 if ( !m_pData
->m_bExternalTitle
&& m_pData
->m_pObjectShell
)
4067 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
4071 ::ucbhelper::Content
aContent( pMedium
->GetName(),
4072 utl::UCBContentHelper::getDefaultCommandEnvironment(),
4073 comphelper::getProcessComponentContext() );
4074 const Reference
< beans::XPropertySetInfo
> xProps
4075 = aContent
.getProperties();
4078 static constexpr OUString
aServerTitle( u
"TitleOnServer"_ustr
);
4079 if ( xProps
->hasPropertyByName( aServerTitle
) )
4081 Any aAny
= aContent
.getPropertyValue( aServerTitle
);
4086 catch (const ucb::ContentCreationException
&)
4089 catch (const ucb::CommandAbortedException
&)
4092 if (pMedium
->IsRepairPackage())
4093 aResult
+= SfxResId(STR_REPAIREDDOCUMENT
);
4096 if ( m_pData
->m_pObjectShell
->IsReadOnlyUI() || (pMedium
&& pMedium
->IsReadOnly()) )
4097 aResult
+= SfxResId(STR_READONLY
);
4098 else if ( m_pData
->m_pObjectShell
->IsDocShared() )
4099 aResult
+= SfxResId(STR_SHARED
);
4101 if ( m_pData
->m_pObjectShell
->GetDocumentSignatureState() == SignatureState::OK
)
4102 aResult
+= SfxResId(RID_XMLSEC_DOCUMENTSIGNED
);
4110 void SAL_CALL
SfxBaseModel::setTitle( const OUString
& sTitle
)
4113 SfxModelGuard
aGuard( *this );
4115 impl_getTitleHelper()->setTitle (sTitle
);
4116 m_pData
->m_bExternalTitle
= true;
4120 // css.frame.XTitleChangeBroadcaster
4121 void SAL_CALL
SfxBaseModel::addTitleChangeListener( const Reference
< frame::XTitleChangeListener
>& xListener
)
4124 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
4126 Reference
< frame::XTitleChangeBroadcaster
> xBroadcaster(impl_getTitleHelper(), UNO_QUERY
);
4127 if (xBroadcaster
.is ())
4128 xBroadcaster
->addTitleChangeListener (xListener
);
4132 // css.frame.XTitleChangeBroadcaster
4133 void SAL_CALL
SfxBaseModel::removeTitleChangeListener( const Reference
< frame::XTitleChangeListener
>& xListener
)
4136 SfxModelGuard
aGuard( *this );
4138 Reference
< frame::XTitleChangeBroadcaster
> xBroadcaster(impl_getTitleHelper(), UNO_QUERY
);
4139 if (xBroadcaster
.is ())
4140 xBroadcaster
->removeTitleChangeListener (xListener
);
4144 // css.frame.XUntitledNumbers
4145 ::sal_Int32 SAL_CALL
SfxBaseModel::leaseNumber( const Reference
< XInterface
>& xComponent
)
4147 SfxModelGuard
aGuard( *this );
4149 return impl_getUntitledHelper ()->leaseNumber (xComponent
);
4153 // css.frame.XUntitledNumbers
4154 void SAL_CALL
SfxBaseModel::releaseNumber( ::sal_Int32 nNumber
)
4156 SfxModelGuard
aGuard( *this );
4157 impl_getUntitledHelper ()->releaseNumber (nNumber
);
4161 // css.frame.XUntitledNumbers
4162 void SAL_CALL
SfxBaseModel::releaseNumberForComponent( const Reference
< XInterface
>& xComponent
)
4164 SfxModelGuard
aGuard( *this );
4165 impl_getUntitledHelper ()->releaseNumberForComponent (xComponent
);
4169 // css.frame.XUntitledNumbers
4170 OUString SAL_CALL
SfxBaseModel::getUntitledPrefix()
4172 SfxModelGuard
aGuard( *this );
4173 return impl_getUntitledHelper ()->getUntitledPrefix ();
4178 Reference
< container::XEnumeration
> SAL_CALL
SfxBaseModel::getControllers()
4180 SfxModelGuard
aGuard( *this );
4182 sal_Int32 c
= m_pData
->m_seqControllers
.size();
4183 Sequence
< Any
> lEnum(c
);
4184 std::transform(m_pData
->m_seqControllers
.begin(), m_pData
->m_seqControllers
.end(),
4185 lEnum
.getArray(), [](const auto& x
) { return css::uno::Any(x
); });
4187 return new ::comphelper::OAnyEnumeration(lEnum
);
4192 Sequence
< OUString
> SAL_CALL
SfxBaseModel::getAvailableViewControllerNames()
4194 SfxModelGuard
aGuard( *this );
4196 const SfxObjectFactory
& rDocumentFactory
= GetObjectShell()->GetFactory();
4197 const sal_Int16 nViewFactoryCount
= rDocumentFactory
.GetViewFactoryCount();
4199 Sequence
< OUString
> aViewNames( nViewFactoryCount
);
4200 auto aViewNamesRange
= asNonConstRange(aViewNames
);
4201 for ( sal_Int16 nViewNo
= 0; nViewNo
< nViewFactoryCount
; ++nViewNo
)
4202 aViewNamesRange
[nViewNo
] = rDocumentFactory
.GetViewFactory( nViewNo
).GetAPIViewName();
4208 Reference
< frame::XController2
> SAL_CALL
SfxBaseModel::createDefaultViewController( const Reference
< frame::XFrame
>& i_rFrame
)
4210 SfxModelGuard
aGuard( *this );
4212 const SfxObjectFactory
& rDocumentFactory
= GetObjectShell()->GetFactory();
4213 const OUString sDefaultViewName
= rDocumentFactory
.GetViewFactory().GetAPIViewName();
4217 return createViewController( sDefaultViewName
, Sequence
< PropertyValue
>(), i_rFrame
);
4221 namespace sfx::intern
{
4223 /** a class which, in its dtor, cleans up various objects (well, at the moment only the frame) collected during
4224 the creation of a document view, unless the creation was successful.
4226 class ViewCreationGuard
4230 :m_bSuccess( false )
4234 ~ViewCreationGuard()
4236 if ( !m_bSuccess
&& m_aWeakFrame
&& !m_aWeakFrame
->GetCurrentDocument() )
4238 m_aWeakFrame
->SetFrameInterface_Impl( nullptr );
4239 m_aWeakFrame
->DoClose();
4243 void takeFrameOwnership( SfxFrame
* i_pFrame
)
4245 OSL_PRECOND( !m_aWeakFrame
, "ViewCreationGuard::takeFrameOwnership: already have a frame!" );
4246 OSL_PRECOND( i_pFrame
!= nullptr, "ViewCreationGuard::takeFrameOwnership: invalid frame!" );
4247 m_aWeakFrame
= i_pFrame
;
4257 SfxFrameWeakRef m_aWeakFrame
;
4262 SfxViewFrame
* SfxBaseModel::FindOrCreateViewFrame_Impl( const Reference
< XFrame
>& i_rFrame
, ::sfx::intern::ViewCreationGuard
& i_rGuard
) const
4264 SfxViewFrame
* pViewFrame
= nullptr;
4265 for ( pViewFrame
= SfxViewFrame::GetFirst( GetObjectShell(), false );
4267 pViewFrame
= SfxViewFrame::GetNext( *pViewFrame
, GetObjectShell(), false )
4270 if ( pViewFrame
->GetFrame().GetFrameInterface() == i_rFrame
)
4275 #if OSL_DEBUG_LEVEL > 0
4276 for ( SfxFrame
* pCheckFrame
= SfxFrame::GetFirst();
4278 pCheckFrame
= SfxFrame::GetNext( *pCheckFrame
)
4281 if ( pCheckFrame
->GetFrameInterface() == i_rFrame
)
4283 if ( ( pCheckFrame
->GetCurrentViewFrame() != nullptr )
4284 || ( pCheckFrame
->GetCurrentDocument() != nullptr )
4286 // Note that it is perfectly legitimate that during loading into an XFrame which already contains
4287 // a document, there exist two SfxFrame instances bound to this XFrame - the old one, which will be
4288 // destroyed later, and the new one, which we're going to create
4291 OSL_FAIL( "SfxBaseModel::FindOrCreateViewFrame_Impl: there already is an SfxFrame for the given XFrame, but no view in it!" );
4292 // nowadays, we're the only instance allowed to create an SfxFrame for an XFrame, so this case here should not happen
4298 SfxFrame
* pTargetFrame
= SfxFrame::Create( i_rFrame
);
4299 ENSURE_OR_THROW( pTargetFrame
, "could not create an SfxFrame" );
4300 i_rGuard
.takeFrameOwnership( pTargetFrame
);
4303 pTargetFrame
->PrepareForDoc_Impl( *GetObjectShell() );
4305 // create view frame
4306 pViewFrame
= new SfxViewFrame( *pTargetFrame
, GetObjectShell() );
4313 Reference
< frame::XController2
> SAL_CALL
SfxBaseModel::createViewController(
4314 const OUString
& i_rViewName
, const Sequence
< PropertyValue
>& i_rArguments
, const Reference
< XFrame
>& i_rFrame
)
4316 SfxModelGuard
aGuard( *this );
4318 if ( !i_rFrame
.is() )
4319 throw lang::IllegalArgumentException( OUString(), *this, 3 );
4321 // find the proper SFX view factory
4322 SfxViewFactory
* pViewFactory
= GetObjectShell()->GetFactory().GetViewFactoryByViewName( i_rViewName
);
4323 if ( !pViewFactory
)
4324 throw IllegalArgumentException( OUString(), *this, 1 );
4326 // determine previous shell (used in some special cases)
4327 Reference
< XController
> xPreviousController( i_rFrame
->getController() );
4328 const Reference
< XModel
> xMe( this );
4329 if ( ( xPreviousController
.is() )
4330 && ( xMe
!= xPreviousController
->getModel() )
4333 xPreviousController
.clear();
4335 SfxViewShell
* pOldViewShell
= SfxViewShell::Get( xPreviousController
);
4336 OSL_ENSURE( !xPreviousController
.is() || ( pOldViewShell
!= nullptr ),
4337 "SfxBaseModel::createViewController: invalid old controller!" );
4339 // a guard which will clean up in case of failure
4340 ::sfx::intern::ViewCreationGuard aViewCreationGuard
;
4342 // determine the ViewFrame belonging to the given XFrame
4343 SfxViewFrame
* pViewFrame
= FindOrCreateViewFrame_Impl( i_rFrame
, aViewCreationGuard
);
4344 assert(pViewFrame
&& "SfxBaseModel::createViewController: no frame");
4346 // delegate to SFX' view factory
4347 pViewFrame
->GetBindings().ENTERREGISTRATIONS();
4348 SfxViewShell
* pViewShell
= pViewFactory
->CreateInstance(*pViewFrame
, pOldViewShell
);
4349 pViewFrame
->GetBindings().LEAVEREGISTRATIONS();
4350 ENSURE_OR_THROW( pViewShell
, "invalid view shell provided by factory" );
4352 // by setting the ViewShell it is prevented that disposing the Controller will destroy this ViewFrame also
4353 pViewFrame
->GetDispatcher()->SetDisableFlags( SfxDisableFlags::NONE
);
4354 pViewFrame
->SetViewShell_Impl( pViewShell
);
4357 pViewFrame
->SetCurViewId_Impl( pViewFactory
->GetOrdinal() );
4359 // ensure a default controller, if the view shell did not provide an own implementation
4360 if ( !pViewShell
->GetController().is() )
4361 pViewShell
->SetController( new SfxBaseController( pViewShell
) );
4363 // pass the creation arguments to the controller
4364 SfxBaseController
* pBaseController
= pViewShell
->GetBaseController_Impl();
4365 ENSURE_OR_THROW( pBaseController
, "invalid controller implementation!" );
4366 pBaseController
->SetCreationArguments_Impl( i_rArguments
);
4368 // some initial view settings, coming from our most recent attachResource call
4369 ::comphelper::NamedValueCollection
aDocumentLoadArgs( getArgs2( { u
"ViewOnly"_ustr
, u
"PluginMode"_ustr
} ) );
4370 if ( aDocumentLoadArgs
.getOrDefault( u
"ViewOnly"_ustr
, false ) )
4371 pViewFrame
->GetFrame().SetMenuBarOn_Impl( false );
4373 const sal_Int16 nPluginMode
= aDocumentLoadArgs
.getOrDefault( u
"PluginMode"_ustr
, sal_Int16( 0 ) );
4374 if ( nPluginMode
== 1 )
4376 pViewFrame
->ForceOuterResize_Impl();
4377 pViewFrame
->GetBindings().HidePopups();
4379 SfxFrame
& rFrame
= pViewFrame
->GetFrame();
4380 // MBA: layoutmanager of inplace frame starts locked and invisible
4381 rFrame
.GetWorkWindow_Impl()->MakeVisible_Impl( false );
4382 rFrame
.GetWorkWindow_Impl()->Lock_Impl( true );
4384 rFrame
.GetWindow().SetBorderStyle( WindowBorderStyle::NOBORDER
);
4385 pViewFrame
->GetWindow().SetBorderStyle( WindowBorderStyle::NOBORDER
);
4388 // tell the guard we were successful
4389 aViewCreationGuard
.releaseAll();
4392 return pBaseController
;
4396 // RDF DocumentMetadataAccess
4398 // rdf::XRepositorySupplier:
4399 Reference
< rdf::XRepository
> SAL_CALL
4400 SfxBaseModel::getRDFRepository()
4402 SfxModelGuard
aGuard( *this );
4404 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4406 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4409 return xDMA
->getRDFRepository();
4414 SfxBaseModel::getStringValue()
4416 SfxModelGuard
aGuard( *this );
4418 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4420 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4423 return xDMA
->getStringValue();
4428 SfxBaseModel::getNamespace()
4430 SfxModelGuard
aGuard( *this );
4432 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4434 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4437 return xDMA
->getNamespace();
4441 SfxBaseModel::getLocalName()
4443 SfxModelGuard
aGuard( *this );
4445 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4447 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4450 return xDMA
->getLocalName();
4453 // rdf::XDocumentMetadataAccess:
4454 Reference
< rdf::XMetadatable
> SAL_CALL
4455 SfxBaseModel::getElementByMetadataReference(
4456 const beans::StringPair
& i_rReference
)
4458 SfxModelGuard
aGuard( *this );
4460 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4462 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4465 return xDMA
->getElementByMetadataReference(i_rReference
);
4468 Reference
< rdf::XMetadatable
> SAL_CALL
4469 SfxBaseModel::getElementByURI(const Reference
< rdf::XURI
> & i_xURI
)
4471 SfxModelGuard
aGuard( *this );
4473 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4475 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4478 return xDMA
->getElementByURI(i_xURI
);
4481 Sequence
< Reference
< rdf::XURI
> > SAL_CALL
4482 SfxBaseModel::getMetadataGraphsWithType(
4483 const Reference
<rdf::XURI
> & i_xType
)
4485 SfxModelGuard
aGuard( *this );
4487 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4489 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4492 return xDMA
->getMetadataGraphsWithType(i_xType
);
4495 Reference
<rdf::XURI
> SAL_CALL
4496 SfxBaseModel::addMetadataFile(const OUString
& i_rFileName
,
4497 const Sequence
< Reference
< rdf::XURI
> > & i_rTypes
)
4499 SfxModelGuard
aGuard( *this );
4501 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4503 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4506 return xDMA
->addMetadataFile(i_rFileName
, i_rTypes
);
4509 Reference
<rdf::XURI
> SAL_CALL
4510 SfxBaseModel::importMetadataFile(::sal_Int16 i_Format
,
4511 const Reference
< io::XInputStream
> & i_xInStream
,
4512 const OUString
& i_rFileName
,
4513 const Reference
< rdf::XURI
> & i_xBaseURI
,
4514 const Sequence
< Reference
< rdf::XURI
> > & i_rTypes
)
4516 SfxModelGuard
aGuard( *this );
4518 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4520 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4523 return xDMA
->importMetadataFile(i_Format
,
4524 i_xInStream
, i_rFileName
, i_xBaseURI
, i_rTypes
);
4528 SfxBaseModel::removeMetadataFile(
4529 const Reference
< rdf::XURI
> & i_xGraphName
)
4531 SfxModelGuard
aGuard( *this );
4533 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4535 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4538 return xDMA
->removeMetadataFile(i_xGraphName
);
4542 SfxBaseModel::addContentOrStylesFile(const OUString
& i_rFileName
)
4544 SfxModelGuard
aGuard( *this );
4546 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4548 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4551 return xDMA
->addContentOrStylesFile(i_rFileName
);
4555 SfxBaseModel::removeContentOrStylesFile(const OUString
& i_rFileName
)
4557 SfxModelGuard
aGuard( *this );
4559 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4561 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4564 return xDMA
->removeContentOrStylesFile(i_rFileName
);
4568 SfxBaseModel::loadMetadataFromStorage(
4569 Reference
< embed::XStorage
> const & i_xStorage
,
4570 Reference
<rdf::XURI
> const & i_xBaseURI
,
4571 Reference
<task::XInteractionHandler
> const & i_xHandler
)
4573 SfxModelGuard
aGuard( *this );
4575 rtl::Reference
<::sfx2::DocumentMetadataAccess
> xDMA(
4576 m_pData
->CreateDMAUninitialized());
4578 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4582 xDMA
->loadMetadataFromStorage(i_xStorage
, i_xBaseURI
, i_xHandler
);
4583 } catch (lang::IllegalArgumentException
&) {
4584 throw; // not initialized
4585 } catch (Exception
&) {
4586 // UGLY: if it's a RuntimeException, we can't be sure DMA is initialized
4587 m_pData
->m_xDocumentMetadata
= xDMA
;
4590 m_pData
->m_xDocumentMetadata
= std::move(xDMA
);
4594 SfxBaseModel::storeMetadataToStorage(
4595 Reference
< embed::XStorage
> const & i_xStorage
)
4597 SfxModelGuard
aGuard( *this );
4599 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4601 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4604 return xDMA
->storeMetadataToStorage(i_xStorage
);
4608 SfxBaseModel::loadMetadataFromMedium(
4609 const Sequence
< beans::PropertyValue
> & i_rMedium
)
4611 SfxModelGuard
aGuard( *this );
4613 rtl::Reference
<::sfx2::DocumentMetadataAccess
> xDMA(
4614 m_pData
->CreateDMAUninitialized());
4616 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4620 xDMA
->loadMetadataFromMedium(i_rMedium
);
4621 } catch (lang::IllegalArgumentException
&) {
4622 throw; // not initialized
4623 } catch (Exception
&) {
4624 // UGLY: if it's a RuntimeException, we can't be sure DMA is initialized
4625 m_pData
->m_xDocumentMetadata
= xDMA
;
4628 m_pData
->m_xDocumentMetadata
= std::move(xDMA
);
4632 SfxBaseModel::storeMetadataToMedium(
4633 const Sequence
< beans::PropertyValue
> & i_rMedium
)
4635 SfxModelGuard
aGuard( *this );
4637 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4639 throw RuntimeException( u
"model has no document metadata"_ustr
, *this );
4642 return xDMA
->storeMetadataToMedium(i_rMedium
);
4646 // = SfxModelSubComponent
4649 SfxModelSubComponent::~SfxModelSubComponent()
4653 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */