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>
24 #include <config_features.h>
26 #include <sfx2/sfxbasemodel.hxx>
28 #include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
29 #include <com/sun/star/task/XInteractionHandler.hpp>
30 #include <com/sun/star/task/ErrorCodeIOException.hpp>
31 #include <com/sun/star/task/ErrorCodeRequest.hpp>
32 #include <com/sun/star/view/XSelectionSupplier.hpp>
33 #include <com/sun/star/view/XPrintJobListener.hpp>
34 #include <com/sun/star/lang/DisposedException.hpp>
35 #include <com/sun/star/lang/IllegalArgumentException.hpp>
36 #include <com/sun/star/lang/NoSupportException.hpp>
37 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
38 #include <com/sun/star/lang/NotInitializedException.hpp>
39 #include <com/sun/star/frame/Desktop.hpp>
40 #include <com/sun/star/frame/IllegalArgumentIOException.hpp>
41 #include <com/sun/star/frame/XUntitledNumbers.hpp>
42 #include <com/sun/star/frame/DoubleInitializationException.hpp>
43 #include <com/sun/star/embed/XStorage.hpp>
44 #include <com/sun/star/document/XStorageChangeListener.hpp>
45 #include <com/sun/star/document/IndexedPropertyValues.hpp>
46 #include <com/sun/star/beans/XPropertySet.hpp>
47 #include <com/sun/star/beans/XPropertySetInfo.hpp>
48 #include <com/sun/star/container/XIndexContainer.hpp>
49 #include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp>
50 #include <com/sun/star/script/provider/XScriptProvider.hpp>
51 #include <com/sun/star/ui/UIConfigurationManager.hpp>
52 #include <com/sun/star/embed/ElementModes.hpp>
53 #include <com/sun/star/embed/Aspects.hpp>
54 #include <com/sun/star/document/DocumentProperties.hpp>
55 #include <com/sun/star/frame/XTransientDocumentsDocumentContentFactory.hpp>
56 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
57 #include <com/sun/star/ucb/ContentCreationException.hpp>
58 #include <com/sun/star/ucb/CommandAbortedException.hpp>
59 #include <com/sun/star/util/XCloneable.hpp>
60 #include <com/sun/star/util/InvalidStateException.hpp>
61 #include <com/sun/star/util/CloseVetoException.hpp>
62 #include <comphelper/enumhelper.hxx>
64 #include <cppuhelper/implbase.hxx>
65 #include <comphelper/multicontainer2.hxx>
66 #include <cppuhelper/exc_hlp.hxx>
67 #include <comphelper/processfactory.hxx>
68 #include <comphelper/propertyvalue.hxx>
69 #include <comphelper/sequenceashashmap.hxx>
70 #include <comphelper/namedvaluecollection.hxx>
71 #include <o3tl/safeint.hxx>
72 #include <svl/itemset.hxx>
73 #include <svl/stritem.hxx>
74 #include <svl/eitem.hxx>
75 #include <svl/grabbagitem.hxx>
76 #include <tools/urlobj.hxx>
77 #include <tools/debug.hxx>
78 #include <tools/diagnose_ex.h>
79 #include <tools/svborder.hxx>
80 #include <unotools/tempfile.hxx>
81 #include <osl/mutex.hxx>
82 #include <vcl/errcode.hxx>
83 #include <vcl/filter/SvmWriter.hxx>
84 #include <vcl/salctype.hxx>
85 #include <vcl/gdimtf.hxx>
86 #include <comphelper/fileformat.h>
87 #include <comphelper/servicehelper.hxx>
88 #include <comphelper/storagehelper.hxx>
89 #include <toolkit/helper/vclunohelper.hxx>
90 #include <vcl/transfer.hxx>
91 #include <svtools/ehdl.hxx>
92 #include <svtools/sfxecode.hxx>
93 #include <sal/log.hxx>
94 #include <framework/configimporter.hxx>
95 #include <framework/titlehelper.hxx>
96 #include <comphelper/numberedcollection.hxx>
97 #include <unotools/ucbhelper.hxx>
98 #include <ucbhelper/content.hxx>
100 #include <sfx2/sfxbasecontroller.hxx>
101 #include <sfx2/viewfac.hxx>
102 #include <workwin.hxx>
103 #include <sfx2/signaturestate.hxx>
104 #include <sfx2/sfxuno.hxx>
105 #include <objshimp.hxx>
106 #include <sfx2/viewfrm.hxx>
107 #include <sfx2/viewsh.hxx>
108 #include <sfx2/docfile.hxx>
109 #include <sfx2/docfilt.hxx>
110 #include <sfx2/dispatch.hxx>
111 #include <sfx2/module.hxx>
112 #include <basic/basmgr.hxx>
113 #include <sfx2/event.hxx>
114 #include <eventsupplier.hxx>
115 #include <sfx2/sfxsids.hrc>
116 #include <sfx2/strings.hrc>
117 #include <sfx2/app.hxx>
118 #include <sfx2/docfac.hxx>
119 #include <sfx2/fcontnr.hxx>
120 #include <sfx2/docstoragemodifylistener.hxx>
121 #include <sfx2/brokenpackageint.hxx>
122 #include "graphhelp.hxx"
123 #include <docundomanager.hxx>
124 #include <openurlhint.hxx>
125 #include <sfx2/msgpool.hxx>
126 #include <sfx2/DocumentMetadataAccess.hxx>
127 #include "printhelper.hxx"
128 #include <sfx2/sfxresid.hxx>
129 #include <comphelper/profilezone.hxx>
130 #include <vcl/threadex.hxx>
131 #include <unotools/mediadescriptor.hxx>
136 using namespace ::com::sun::star
;
137 using namespace ::com::sun::star::uno
;
138 using ::com::sun::star::beans::PropertyValue
;
139 using ::com::sun::star::document::CmisProperty
;
140 using ::com::sun::star::frame::XFrame
;
141 using ::com::sun::star::frame::XController
;
142 using ::com::sun::star::frame::XController2
;
143 using ::com::sun::star::lang::IllegalArgumentException
;
144 using ::com::sun::star::io::IOException
;
145 using ::com::sun::star::uno::Sequence
;
146 using ::com::sun::star::document::XDocumentRecovery
;
147 using ::com::sun::star::document::XUndoManager
;
148 using ::com::sun::star::document::XUndoAction
;
149 using ::com::sun::star::frame::XModel
;
153 /** This Listener is used to get notified when the XDocumentProperties of the
156 class SfxDocInfoListener_Impl
: public ::cppu::WeakImplHelper
<
157 util::XModifyListener
>
161 SfxObjectShell
& m_rShell
;
163 explicit SfxDocInfoListener_Impl( SfxObjectShell
& i_rDoc
)
167 virtual void SAL_CALL
disposing( const lang::EventObject
& ) override
;
168 virtual void SAL_CALL
modified( const lang::EventObject
& ) override
;
173 void SAL_CALL
SfxDocInfoListener_Impl::modified( const lang::EventObject
& )
175 SolarMutexGuard aSolarGuard
;
177 // notify changes to the SfxObjectShell
178 m_rShell
.FlushDocInfo();
181 void SAL_CALL
SfxDocInfoListener_Impl::disposing( const lang::EventObject
& )
186 // impl. declarations
189 struct IMPL_SfxBaseModel_DataContainer
: public ::sfx2::IModifiableDocument
191 // counter for SfxBaseModel instances created.
192 static sal_Int64 g_nInstanceCounter
;
193 SfxObjectShellRef m_pObjectShell
;
195 OUString m_sRuntimeUID
;
196 OUString m_aPreusedFilterName
;
197 comphelper::OMultiTypeInterfaceContainerHelper2 m_aInterfaceContainer
;
198 std::unordered_map
<css::uno::Reference
< css::drawing::XShape
>,
199 std::vector
<css::uno::Reference
< css::document::XShapeEventListener
>>> maShapeListeners
;
200 Reference
< XInterface
> m_xParent
;
201 Reference
< frame::XController
> m_xCurrent
;
202 Reference
< document::XDocumentProperties
> m_xDocumentProperties
;
203 Reference
< script::XStarBasicAccess
> m_xStarBasicAccess
;
204 Reference
< container::XNameReplace
> m_xEvents
;
205 Sequence
< beans::PropertyValue
> m_seqArguments
;
206 std::vector
< Reference
< frame::XController
> > m_seqControllers
;
207 Reference
< container::XIndexAccess
> m_contViewData
;
208 sal_uInt16 m_nControllerLockCount
;
213 bool m_bExternalTitle
;
214 bool m_bModifiedSinceLastSave
;
215 Reference
< view::XPrintable
> m_xPrintable
;
216 Reference
< ui::XUIConfigurationManager2
> m_xUIConfigurationManager
;
217 ::rtl::Reference
< ::sfx2::DocumentStorageModifyListener
> m_pStorageModifyListen
;
218 OUString m_sModuleIdentifier
;
219 Reference
< frame::XTitle
> m_xTitleHelper
;
220 Reference
< frame::XUntitledNumbers
> m_xNumberedControllers
;
221 Reference
< rdf::XDocumentMetadataAccess
> m_xDocumentMetadata
;
222 ::rtl::Reference
< ::sfx2::DocumentUndoManager
> m_pDocumentUndoManager
;
223 Sequence
< document::CmisProperty
> m_cmisProperties
;
224 std::shared_ptr
<SfxGrabBagItem
> m_xGrabBagItem
;
226 IMPL_SfxBaseModel_DataContainer( ::osl::Mutex
& rMutex
, SfxObjectShell
* pObjectShell
)
227 : m_pObjectShell ( pObjectShell
)
228 , m_aInterfaceContainer ( rMutex
)
229 , m_nControllerLockCount ( 0 )
230 , m_bClosed ( false )
231 , m_bClosing ( false )
232 , m_bSaving ( false )
233 , m_bSuicide ( false )
234 , m_bExternalTitle ( false )
235 , m_bModifiedSinceLastSave( false )
237 // increase global instance counter.
238 ++g_nInstanceCounter
;
239 // set own Runtime UID
240 m_sRuntimeUID
= OUString::number( g_nInstanceCounter
);
243 virtual ~IMPL_SfxBaseModel_DataContainer()
247 // ::sfx2::IModifiableDocument
248 virtual void storageIsModified() override
250 if ( m_pObjectShell
.is() && !m_pObjectShell
->IsModified() )
251 m_pObjectShell
->SetModified();
254 void impl_setDocumentProperties(
255 const Reference
< document::XDocumentProperties
>& );
257 Reference
<rdf::XDocumentMetadataAccess
> GetDMA()
259 if (!m_xDocumentMetadata
.is())
261 OSL_ENSURE(m_pObjectShell
.is(), "GetDMA: no object shell?");
262 if (!m_pObjectShell
.is())
267 const Reference
<XComponentContext
> xContext(
268 ::comphelper::getProcessComponentContext());
269 const Reference
<frame::XModel
> xModel(
270 m_pObjectShell
->GetModel());
271 const Reference
<lang::XMultiComponentFactory
> xMsf(
272 xContext
->getServiceManager());
273 const Reference
<frame::
274 XTransientDocumentsDocumentContentFactory
> xTDDCF(
275 xMsf
->createInstanceWithContext(
276 "com.sun.star.frame.TransientDocumentsDocumentContentFactory",
279 const Reference
<ucb::XContent
> xContent(
280 xTDDCF
->createDocumentContent(xModel
) );
281 OSL_ENSURE(xContent
.is(), "GetDMA: cannot create DocumentContent");
286 OUString uri
= xContent
->getIdentifier()->getContentIdentifier();
287 OSL_ENSURE(!uri
.isEmpty(), "GetDMA: empty uri?");
288 if (!uri
.isEmpty() && !uri
.endsWith("/"))
293 m_xDocumentMetadata
= new ::sfx2::DocumentMetadataAccess(
294 xContext
, *m_pObjectShell
, uri
);
296 return m_xDocumentMetadata
;
299 Reference
<rdf::XDocumentMetadataAccess
> CreateDMAUninitialized()
301 return (m_pObjectShell
.is())
302 ? new ::sfx2::DocumentMetadataAccess(
303 ::comphelper::getProcessComponentContext(), *m_pObjectShell
)
308 // static member initialization.
309 sal_Int64
IMPL_SfxBaseModel_DataContainer::g_nInstanceCounter
= 0;
313 // Listener that forwards notifications from the PrintHelper to the "real" listeners
314 class SfxPrintHelperListener_Impl
: public ::cppu::WeakImplHelper
< view::XPrintJobListener
>
317 IMPL_SfxBaseModel_DataContainer
* m_pData
;
318 explicit SfxPrintHelperListener_Impl( IMPL_SfxBaseModel_DataContainer
* pData
)
322 virtual void SAL_CALL
disposing( const lang::EventObject
& aEvent
) override
;
323 virtual void SAL_CALL
printJobEvent( const view::PrintJobEvent
& rEvent
) override
;
328 void SAL_CALL
SfxPrintHelperListener_Impl::disposing( const lang::EventObject
& )
330 m_pData
->m_xPrintable
= nullptr;
333 void SAL_CALL
SfxPrintHelperListener_Impl::printJobEvent( const view::PrintJobEvent
& rEvent
)
335 ::comphelper::OInterfaceContainerHelper2
* pContainer
= m_pData
->m_aInterfaceContainer
.getContainer( cppu::UnoType
<view::XPrintJobListener
>::get());
336 if ( pContainer
!=nullptr )
338 ::comphelper::OInterfaceIteratorHelper2
pIterator(*pContainer
);
339 while (pIterator
.hasMoreElements())
340 static_cast<view::XPrintJobListener
*>(pIterator
.next())->printJobEvent( rEvent
);
346 // SfxOwnFramesLocker ====================================================================================
347 // allows to lock all the frames related to the provided SfxObjectShell
348 class SfxOwnFramesLocker
350 Sequence
< Reference
< frame::XFrame
> > m_aLockedFrames
;
352 static vcl::Window
* GetVCLWindow( const Reference
< frame::XFrame
>& xFrame
);
354 explicit SfxOwnFramesLocker( SfxObjectShell
const * ObjechShell
);
355 ~SfxOwnFramesLocker();
360 SfxOwnFramesLocker::SfxOwnFramesLocker( SfxObjectShell
const * pObjectShell
)
365 for ( SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( pObjectShell
);
367 pFrame
= SfxViewFrame::GetNext( *pFrame
, pObjectShell
)
370 SfxFrame
& rSfxFrame
= pFrame
->GetFrame();
373 // get vcl window related to the frame and lock it if it is still not locked
374 const Reference
< frame::XFrame
>& xFrame
= rSfxFrame
.GetFrameInterface();
375 vcl::Window
* pWindow
= GetVCLWindow( xFrame
);
377 throw RuntimeException();
379 if ( pWindow
->IsEnabled() )
385 sal_Int32 nLen
= m_aLockedFrames
.getLength();
386 m_aLockedFrames
.realloc( nLen
+ 1 );
387 m_aLockedFrames
.getArray()[nLen
] = xFrame
;
398 OSL_FAIL( "Not possible to lock the frame window!" );
403 SfxOwnFramesLocker::~SfxOwnFramesLocker()
405 for ( auto& rFrame
: asNonConstRange(m_aLockedFrames
) )
411 // get vcl window related to the frame and unlock it
412 vcl::Window
* pWindow
= GetVCLWindow( rFrame
);
414 throw RuntimeException();
423 OSL_FAIL( "Can't unlock the frame window!" );
428 vcl::Window
* SfxOwnFramesLocker::GetVCLWindow( const Reference
< frame::XFrame
>& xFrame
)
430 VclPtr
<vcl::Window
> pWindow
;
434 Reference
< awt::XWindow
> xWindow
= xFrame
->getContainerWindow();
436 pWindow
= VCLUnoHelper::GetWindow( xWindow
);
444 // SfxSaveGuard ====================================================================================
448 Reference
< frame::XModel
> m_xModel
;
449 IMPL_SfxBaseModel_DataContainer
* m_pData
;
450 std::unique_ptr
<SfxOwnFramesLocker
> m_pFramesLock
;
452 SfxSaveGuard(SfxSaveGuard
const &) = delete;
453 void operator =(const SfxSaveGuard
&) = delete;
456 SfxSaveGuard(const Reference
< frame::XModel
>& xModel
,
457 IMPL_SfxBaseModel_DataContainer
* pData
);
463 SfxSaveGuard::SfxSaveGuard(const Reference
< frame::XModel
>& xModel
,
464 IMPL_SfxBaseModel_DataContainer
* pData
)
465 : m_xModel ( xModel
)
468 if ( m_pData
->m_bClosed
)
469 throw lang::DisposedException("Object already disposed.");
471 m_pData
->m_bSaving
= true;
472 m_pFramesLock
.reset(new SfxOwnFramesLocker( m_pData
->m_pObjectShell
.get() ));
475 SfxSaveGuard::~SfxSaveGuard()
477 m_pFramesLock
.reset();
479 m_pData
->m_bSaving
= false;
481 // m_bSuicide was set e.g. in case someone tried to close a document, while it was used for
482 // storing at the same time. Further m_bSuicide was set to sal_True only if close(sal_True) was called.
483 // So the ownership was delegated to the place where a veto exception was thrown.
484 // Now we have to call close() again and delegate the ownership to the next one, which
485 // can't accept that. Close(sal_False) can't work in this case. Because then the document will may be never closed...
487 if ( !m_pData
->m_bSuicide
)
490 // Reset this state. In case the new close() request is not accepted by someone else...
491 // it's not a good idea to have two "owners" for close.-)
492 m_pData
->m_bSuicide
= false;
495 Reference
< util::XCloseable
> xClose(m_xModel
, UNO_QUERY
);
499 catch(const util::CloseVetoException
&)
503 SfxBaseModel::SfxBaseModel( SfxObjectShell
*pObjectShell
)
505 , m_pData( std::make_shared
<IMPL_SfxBaseModel_DataContainer
>( m_aMutex
, pObjectShell
) )
506 , m_bSupportEmbeddedScripts( pObjectShell
&& pObjectShell
->Get_Impl() && !pObjectShell
->Get_Impl()->m_bNoBasicCapabilities
)
507 , m_bSupportDocRecovery( pObjectShell
&& pObjectShell
->Get_Impl() && pObjectShell
->Get_Impl()->m_bDocRecoverySupport
)
509 if ( pObjectShell
!= nullptr )
511 StartListening( *pObjectShell
) ;
516 SfxBaseModel::~SfxBaseModel()
521 Any SAL_CALL
SfxBaseModel::queryInterface( const uno::Type
& rType
)
523 if ( ( !m_bSupportEmbeddedScripts
&& rType
.equals( cppu::UnoType
<document::XEmbeddedScripts
>::get() ) )
524 || ( !m_bSupportDocRecovery
&& rType
.equals( cppu::UnoType
<XDocumentRecovery
>::get() ) )
528 return SfxBaseModel_Base::queryInterface( rType
);
537 void lcl_stripType( Sequence
< uno::Type
>& io_rTypes
, const uno::Type
& i_rTypeToStrip
)
539 Sequence
< uno::Type
> aStrippedTypes( io_rTypes
.getLength() - 1 );
540 ::std::remove_copy_if(
541 std::cbegin(io_rTypes
),
542 std::cend(io_rTypes
),
543 aStrippedTypes
.getArray(),
544 [&i_rTypeToStrip
](const uno::Type
& aType
) { return aType
== i_rTypeToStrip
; }
546 io_rTypes
= aStrippedTypes
;
550 Sequence
< uno::Type
> SAL_CALL
SfxBaseModel::getTypes()
552 Sequence
< uno::Type
> aTypes( SfxBaseModel_Base::getTypes() );
554 if ( !m_bSupportEmbeddedScripts
)
555 lcl_stripType( aTypes
, cppu::UnoType
<document::XEmbeddedScripts
>::get() );
557 if ( !m_bSupportDocRecovery
)
558 lcl_stripType( aTypes
, cppu::UnoType
<XDocumentRecovery
>::get() );
567 Sequence
< sal_Int8
> SAL_CALL
SfxBaseModel::getImplementationId()
569 return css::uno::Sequence
<sal_Int8
>();
575 #if HAVE_FEATURE_SCRIPTING
577 static Reference
< script::XStarBasicAccess
> implGetStarBasicAccess( SfxObjectShell
const * pObjectShell
)
579 Reference
< script::XStarBasicAccess
> xRet
;
581 #if !HAVE_FEATURE_SCRIPTING
586 BasicManager
* pMgr
= pObjectShell
->GetBasicManager();
587 xRet
= getStarBasicAccess( pMgr
);
595 Reference
< container::XNameContainer
> SAL_CALL
SfxBaseModel::getLibraryContainer()
597 #if !HAVE_FEATURE_SCRIPTING
598 Reference
< container::XNameContainer
> dummy
;
602 SfxModelGuard
aGuard( *this );
604 Reference
< script::XStarBasicAccess
>& rxAccess
= m_pData
->m_xStarBasicAccess
;
605 if( !rxAccess
.is() && m_pData
->m_pObjectShell
.is() )
606 rxAccess
= implGetStarBasicAccess( m_pData
->m_pObjectShell
.get() );
608 Reference
< container::XNameContainer
> xRet
;
610 xRet
= rxAccess
->getLibraryContainer();
615 /**___________________________________________________________________________________________________
616 @seealso XStarBasicAccess
618 void SAL_CALL
SfxBaseModel::createLibrary( const OUString
& LibName
, const OUString
& Password
,
619 const OUString
& ExternalSourceURL
, const OUString
& LinkTargetURL
)
621 #if !HAVE_FEATURE_SCRIPTING
624 (void) ExternalSourceURL
;
625 (void) LinkTargetURL
;
627 SfxModelGuard
aGuard( *this );
629 Reference
< script::XStarBasicAccess
>& rxAccess
= m_pData
->m_xStarBasicAccess
;
630 if( !rxAccess
.is() && m_pData
->m_pObjectShell
.is() )
631 rxAccess
= implGetStarBasicAccess( m_pData
->m_pObjectShell
.get() );
634 rxAccess
->createLibrary( LibName
, Password
, ExternalSourceURL
, LinkTargetURL
);
638 /**___________________________________________________________________________________________________
639 @seealso XStarBasicAccess
641 void SAL_CALL
SfxBaseModel::addModule( const OUString
& LibraryName
, const OUString
& ModuleName
,
642 const OUString
& Language
, const OUString
& Source
)
644 #if !HAVE_FEATURE_SCRIPTING
650 SfxModelGuard
aGuard( *this );
652 Reference
< script::XStarBasicAccess
>& rxAccess
= m_pData
->m_xStarBasicAccess
;
653 if( !rxAccess
.is() && m_pData
->m_pObjectShell
.is() )
654 rxAccess
= implGetStarBasicAccess( m_pData
->m_pObjectShell
.get() );
657 rxAccess
->addModule( LibraryName
, ModuleName
, Language
, Source
);
661 /**___________________________________________________________________________________________________
662 @seealso XStarBasicAccess
664 void SAL_CALL
SfxBaseModel::addDialog( const OUString
& LibraryName
, const OUString
& DialogName
,
665 const Sequence
< sal_Int8
>& Data
)
667 #if !HAVE_FEATURE_SCRIPTING
672 SfxModelGuard
aGuard( *this );
674 Reference
< script::XStarBasicAccess
>& rxAccess
= m_pData
->m_xStarBasicAccess
;
675 if( !rxAccess
.is() && m_pData
->m_pObjectShell
.is() )
676 rxAccess
= implGetStarBasicAccess( m_pData
->m_pObjectShell
.get() );
679 rxAccess
->addDialog( LibraryName
, DialogName
, Data
);
687 Reference
< XInterface
> SAL_CALL
SfxBaseModel::getParent()
689 SfxModelGuard
aGuard( *this );
691 return m_pData
->m_xParent
;
698 void SAL_CALL
SfxBaseModel::setParent(const Reference
< XInterface
>& Parent
)
700 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
701 m_pData
->m_xParent
= Parent
;
708 void SAL_CALL
SfxBaseModel::dispose()
710 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
712 if ( !m_pData
->m_bClosed
)
714 // gracefully accept wrong dispose calls instead of close call
715 // and try to make it work (may be really disposed later!)
720 catch ( util::CloseVetoException
& )
727 if ( m_pData
->m_pStorageModifyListen
.is() )
729 m_pData
->m_pStorageModifyListen
->dispose();
730 m_pData
->m_pStorageModifyListen
= nullptr;
733 if ( m_pData
->m_pDocumentUndoManager
.is() )
735 m_pData
->m_pDocumentUndoManager
->disposing();
736 m_pData
->m_pDocumentUndoManager
= nullptr;
739 lang::EventObject
aEvent( static_cast<frame::XModel
*>(this) );
740 m_pData
->m_aInterfaceContainer
.disposeAndClear( aEvent
);
742 m_pData
->m_xDocumentProperties
.clear();
744 m_pData
->m_xDocumentMetadata
.clear();
746 if ( m_pData
->m_pObjectShell
.is() )
748 EndListening( *m_pData
->m_pObjectShell
);
751 m_pData
->m_xCurrent
.clear();
752 m_pData
->m_seqControllers
.clear();
754 // m_pData member must be set to zero before delete is called to
755 // force disposed exception whenever someone tries to access our
756 // instance while in the dtor.
764 void SAL_CALL
SfxBaseModel::addEventListener( const Reference
< lang::XEventListener
>& aListener
)
766 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
767 m_pData
->m_aInterfaceContainer
.addInterface( cppu::UnoType
<lang::XEventListener
>::get(), aListener
);
774 void SAL_CALL
SfxBaseModel::removeEventListener( const Reference
< lang::XEventListener
>& aListener
)
776 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
777 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<lang::XEventListener
>::get(), aListener
);
781 IMPL_SfxBaseModel_DataContainer::impl_setDocumentProperties(
782 const Reference
< document::XDocumentProperties
>& rxNewDocProps
)
784 m_xDocumentProperties
.set(rxNewDocProps
, UNO_SET_THROW
);
785 if (m_pObjectShell
.is())
787 Reference
<util::XModifyBroadcaster
> const xMB(
788 m_xDocumentProperties
, UNO_QUERY_THROW
);
789 xMB
->addModifyListener(new SfxDocInfoListener_Impl(*m_pObjectShell
));
793 // document::XDocumentPropertiesSupplier:
794 Reference
< document::XDocumentProperties
> SAL_CALL
795 SfxBaseModel::getDocumentProperties()
797 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
798 if ( !m_pData
->m_xDocumentProperties
.is() )
800 Reference
< document::XDocumentProperties
> xDocProps(
801 document::DocumentProperties::create( ::comphelper::getProcessComponentContext() ) );
802 m_pData
->impl_setDocumentProperties(xDocProps
);
805 return m_pData
->m_xDocumentProperties
;
809 // lang::XEventListener
812 void SAL_CALL
SfxBaseModel::disposing( const lang::EventObject
& aObject
)
814 SolarMutexGuard aGuard
;
815 if ( impl_isDisposed() )
818 Reference
< util::XModifyListener
> xMod( aObject
.Source
, UNO_QUERY
);
819 Reference
< lang::XEventListener
> xListener( aObject
.Source
, UNO_QUERY
);
820 Reference
< document::XEventListener
> xDocListener( aObject
.Source
, UNO_QUERY
);
823 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<util::XModifyListener
>::get(), xMod
);
824 else if ( xListener
.is() )
825 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<lang::XEventListener
>::get(), xListener
);
826 else if ( xDocListener
.is() )
827 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<document::XEventListener
>::get(), xListener
);
834 sal_Bool SAL_CALL
SfxBaseModel::attachResource( const OUString
& rURL
,
835 const Sequence
< beans::PropertyValue
>& rArgs
)
837 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
838 if ( rURL
.isEmpty() && rArgs
.getLength() == 1 && rArgs
[0].Name
== "SetEmbedded" )
840 // allows to set a windowless document to EMBEDDED state
841 // but _only_ before load() or initNew() methods
842 if ( m_pData
->m_pObjectShell
.is() && !m_pData
->m_pObjectShell
->GetMedium() )
845 if ( ( rArgs
[0].Value
>>= bEmb
) && bEmb
)
846 m_pData
->m_pObjectShell
->SetCreateMode_Impl( SfxObjectCreateMode::EMBEDDED
);
852 if ( m_pData
->m_pObjectShell
.is() )
854 m_pData
->m_sURL
= rURL
;
856 SfxObjectShell
* pObjectShell
= m_pData
->m_pObjectShell
.get();
858 ::comphelper::NamedValueCollection
aArgs( rArgs
);
860 Sequence
< sal_Int32
> aWinExtent
;
861 if ( ( aArgs
.get( "WinExtent" ) >>= aWinExtent
)&& ( aWinExtent
.getLength() == 4 ) )
863 tools::Rectangle
aVisArea( aWinExtent
[0], aWinExtent
[1], aWinExtent
[2], aWinExtent
[3] );
864 aVisArea
= OutputDevice::LogicToLogic(aVisArea
, MapMode(MapUnit::Map100thMM
), MapMode(pObjectShell
->GetMapUnit()));
865 pObjectShell
->SetVisArea( aVisArea
);
868 bool bBreakMacroSign
= false;
869 if ( aArgs
.get( "BreakMacroSignature" ) >>= bBreakMacroSign
)
871 pObjectShell
->BreakMacroSign_Impl( bBreakMacroSign
);
874 bool bMacroEventRead
= false;
875 if ((aArgs
.get("MacroEventRead") >>= bMacroEventRead
) && bMacroEventRead
)
877 pObjectShell
->SetMacroCallsSeenWhileLoading();
880 aArgs
.remove( "WinExtent" );
881 aArgs
.remove( "BreakMacroSignature" );
882 aArgs
.remove( "MacroEventRead" );
883 aArgs
.remove( "Stream" );
884 aArgs
.remove( "InputStream" );
885 aArgs
.remove( "URL" );
886 aArgs
.remove( "Frame" );
887 aArgs
.remove( "Password" );
888 aArgs
.remove( "EncryptionData" );
890 // TODO/LATER: all the parameters that are accepted by ItemSet of the DocShell must be removed here
892 m_pData
->m_seqArguments
= aArgs
.getPropertyValues();
894 SfxMedium
* pMedium
= pObjectShell
->GetMedium();
897 SfxAllItemSet
aSet( pObjectShell
->GetPool() );
898 TransformParameters( SID_OPENDOC
, rArgs
, aSet
);
900 // the arguments are not allowed to reach the medium
901 aSet
.ClearItem( SID_FILE_NAME
);
902 aSet
.ClearItem( SID_FILLFRAME
);
904 pMedium
->GetItemSet()->Put( aSet
);
905 const SfxStringItem
* pItem
= aSet
.GetItem
<SfxStringItem
>(SID_FILTER_NAME
, false);
908 pObjectShell
->GetFactory().GetFilterContainer()->GetFilter4FilterName( pItem
->GetValue() ) );
910 const SfxStringItem
* pTitleItem
= aSet
.GetItem
<SfxStringItem
>(SID_DOCINFO_TITLE
, false);
913 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( pObjectShell
);
915 pFrame
->UpdateTitle();
927 OUString SAL_CALL
SfxBaseModel::getURL()
929 SfxModelGuard
aGuard( *this );
930 return m_pData
->m_sURL
;
936 Sequence
< beans::PropertyValue
> SAL_CALL
SfxBaseModel::getArgs()
943 Sequence
< beans::PropertyValue
> SAL_CALL
SfxBaseModel::getArgs2(const Sequence
<OUString
> & requestedArgsSeq
)
945 SfxModelGuard
aGuard( *this );
947 if (!SfxApplication::Get()) // tdf#113755
949 SAL_WARN("sfx.appl", "Unexpected operations on model");
950 return m_pData
->m_seqArguments
;
953 std::set
<std::u16string_view
> requestedArgs
;
954 for (OUString
const & s
: requestedArgsSeq
)
955 requestedArgs
.insert(s
);
957 if ( m_pData
->m_pObjectShell
.is() )
959 Sequence
< beans::PropertyValue
> seqArgsNew
;
960 Sequence
< beans::PropertyValue
> seqArgsOld
;
961 SfxAllItemSet
aSet( m_pData
->m_pObjectShell
->GetPool() );
963 // we need to know which properties are supported by the transformer
964 // hopefully it is a temporary solution, I guess nonconvertable properties
965 // should not be supported so then there will be only ItemSet from medium
967 TransformItems( SID_OPENDOC
, *(m_pData
->m_pObjectShell
->GetMedium()->GetItemSet()), seqArgsNew
);
968 TransformParameters( SID_OPENDOC
, m_pData
->m_seqArguments
, aSet
);
969 TransformItems( SID_OPENDOC
, aSet
, seqArgsOld
);
971 sal_Int32 nNewLength
= seqArgsNew
.getLength();
973 if (requestedArgs
.empty() || requestedArgs
.count(u
"WinExtent"))
975 // "WinExtent" property should be updated always.
976 // We can store it now to overwrite an old value
977 // since it is not from ItemSet
978 tools::Rectangle aTmpRect
= m_pData
->m_pObjectShell
->GetVisArea( ASPECT_CONTENT
);
979 aTmpRect
= OutputDevice::LogicToLogic(aTmpRect
, MapMode(m_pData
->m_pObjectShell
->GetMapUnit()), MapMode(MapUnit::Map100thMM
));
981 Sequence
< sal_Int32
> aRectSeq
983 o3tl::narrowing
<int>(aTmpRect
.Left()),
984 o3tl::narrowing
<int>(aTmpRect
.Top()),
985 o3tl::narrowing
<int>(aTmpRect
.IsWidthEmpty() ? aTmpRect
.Left() : aTmpRect
.Right()),
986 o3tl::narrowing
<int>(aTmpRect
.IsHeightEmpty() ? aTmpRect
.Top() : aTmpRect
.Bottom())
989 seqArgsNew
.realloc( ++nNewLength
);
990 auto pseqArgsNew
= seqArgsNew
.getArray();
991 pseqArgsNew
[ nNewLength
- 1 ].Name
= "WinExtent";
992 pseqArgsNew
[ nNewLength
- 1 ].Value
<<= aRectSeq
;
995 if (requestedArgs
.empty() || requestedArgs
.count(u
"PreusedFilterName"))
997 if ( !m_pData
->m_aPreusedFilterName
.isEmpty() )
999 seqArgsNew
.realloc( ++nNewLength
);
1000 auto pseqArgsNew
= seqArgsNew
.getArray();
1001 pseqArgsNew
[ nNewLength
- 1 ].Name
= "PreusedFilterName";
1002 pseqArgsNew
[ nNewLength
- 1 ].Value
<<= m_pData
->m_aPreusedFilterName
;
1006 if (requestedArgs
.empty() || requestedArgs
.count(u
"DocumentBorder"))
1008 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get() );
1011 SvBorder aBorder
= pFrame
->GetBorderPixelImpl();
1013 Sequence
< sal_Int32
> aBorderSeq
1015 o3tl::narrowing
<int>(aBorder
.Left()),
1016 o3tl::narrowing
<int>(aBorder
.Top()),
1017 o3tl::narrowing
<int>(aBorder
.Right()),
1018 o3tl::narrowing
<int>(aBorder
.Bottom())
1021 seqArgsNew
.realloc( ++nNewLength
);
1022 auto pseqArgsNew
= seqArgsNew
.getArray();
1023 pseqArgsNew
[ nNewLength
- 1 ].Name
= "DocumentBorder";
1024 pseqArgsNew
[ nNewLength
- 1 ].Value
<<= aBorderSeq
;
1028 if (requestedArgs
.empty())
1030 // only the values that are not supported by the ItemSet must be cached here
1031 Sequence
< beans::PropertyValue
> aFinalCache
;
1032 sal_Int32 nFinalLength
= 0;
1034 for ( const auto& rOrg
: std::as_const(m_pData
->m_seqArguments
) )
1036 auto bNew
= std::none_of(std::cbegin(seqArgsOld
), std::cend(seqArgsOld
),
1037 [&rOrg
](const beans::PropertyValue
& rOld
){ return rOld
.Name
== rOrg
.Name
; });
1040 // the entity with this name should be new for seqArgsNew
1041 // since it is not supported by transformer
1043 seqArgsNew
.realloc( ++nNewLength
);
1044 seqArgsNew
.getArray()[ nNewLength
- 1 ] = rOrg
;
1046 aFinalCache
.realloc( ++nFinalLength
);
1047 aFinalCache
.getArray()[ nFinalLength
- 1 ] = rOrg
;
1051 m_pData
->m_seqArguments
= aFinalCache
;
1057 return m_pData
->m_seqArguments
;
1060 void SAL_CALL
SfxBaseModel::setArgs(const Sequence
<beans::PropertyValue
>& aArgs
)
1062 SfxModelGuard
aGuard( *this );
1064 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
1067 throw util::InvalidStateException(
1068 "Medium could not be retrieved, unable to execute setArgs");
1071 for (const auto& rArg
: aArgs
)
1076 if (rArg
.Name
== "SuggestedSaveAsName")
1078 if (rArg
.Value
>>= sValue
)
1080 pMedium
->GetItemSet()->Put(SfxStringItem(SID_SUGGESTEDSAVEASNAME
, sValue
));
1084 else if (rArg
.Name
== "SuggestedSaveAsDir")
1086 if (rArg
.Value
>>= sValue
)
1088 pMedium
->GetItemSet()->Put(SfxStringItem(SID_SUGGESTEDSAVEASDIR
, sValue
));
1092 else if (rArg
.Name
== "LockContentExtraction")
1094 if (rArg
.Value
>>= bValue
)
1096 pMedium
->GetItemSet()->Put(SfxBoolItem(SID_LOCK_CONTENT_EXTRACTION
, bValue
));
1100 else if (rArg
.Name
== "LockExport")
1102 if (rArg
.Value
>>= bValue
)
1104 pMedium
->GetItemSet()->Put(SfxBoolItem(SID_LOCK_EXPORT
, bValue
));
1108 else if (rArg
.Name
== "LockPrint")
1110 if (rArg
.Value
>>= bValue
)
1112 pMedium
->GetItemSet()->Put(SfxBoolItem(SID_LOCK_PRINT
, bValue
));
1116 else if (rArg
.Name
== "LockSave")
1118 if (rArg
.Value
>>= bValue
)
1120 pMedium
->GetItemSet()->Put(SfxBoolItem(SID_LOCK_SAVE
, bValue
));
1124 else if (rArg
.Name
== "LockEditDoc")
1126 if (rArg
.Value
>>= bValue
)
1128 pMedium
->GetItemSet()->Put(SfxBoolItem(SID_LOCK_EDITDOC
, bValue
));
1132 else if (rArg
.Name
== "Replaceable")
1134 if (rArg
.Value
>>= bValue
)
1136 pMedium
->GetItemSet()->Put(SfxBoolItem(SID_REPLACEABLE
, bValue
));
1140 else if (rArg
.Name
== "EncryptionData")
1142 pMedium
->GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA
, rArg
.Value
));
1147 throw lang::IllegalArgumentException("Setting property not supported: " + rArg
.Name
,
1148 comphelper::getProcessComponentContext(), 0);
1156 void SAL_CALL
SfxBaseModel::connectController( const Reference
< frame::XController
>& xController
)
1158 SfxModelGuard
aGuard( *this );
1159 OSL_PRECOND( xController
.is(), "SfxBaseModel::connectController: invalid controller!" );
1160 if ( !xController
.is() )
1163 m_pData
->m_seqControllers
.push_back(xController
);
1165 if ( m_pData
->m_seqControllers
.size() == 1 )
1167 SfxViewFrame
* pViewFrame
= SfxViewFrame::Get( xController
, GetObjectShell() );
1168 ENSURE_OR_THROW( pViewFrame
, "SFX document without SFX view!?" );
1169 pViewFrame
->UpdateDocument_Impl();
1170 const OUString sDocumentURL
= GetObjectShell()->GetMedium()->GetName();
1171 if ( !sDocumentURL
.isEmpty() )
1172 SfxGetpApp()->Broadcast( SfxOpenUrlHint( sDocumentURL
) );
1180 void SAL_CALL
SfxBaseModel::disconnectController( const Reference
< frame::XController
>& xController
)
1182 SfxModelGuard
aGuard( *this );
1184 if ( m_pData
->m_seqControllers
.empty() )
1187 auto& vec
= m_pData
->m_seqControllers
;
1188 vec
.erase(std::remove(vec
.begin(), vec
.end(), xController
), vec
.end());
1190 if ( xController
== m_pData
->m_xCurrent
)
1191 m_pData
->m_xCurrent
.clear();
1196 class ControllerLockUndoAction
: public ::cppu::WeakImplHelper
< XUndoAction
>
1199 ControllerLockUndoAction( const Reference
< XModel
>& i_model
, const bool i_undoIsUnlock
)
1200 :m_xModel( i_model
)
1201 ,m_bUndoIsUnlock( i_undoIsUnlock
)
1206 virtual OUString SAL_CALL
getTitle() override
;
1207 virtual void SAL_CALL
undo( ) override
;
1208 virtual void SAL_CALL
redo( ) override
;
1211 const Reference
< XModel
> m_xModel
;
1212 const bool m_bUndoIsUnlock
;
1215 OUString SAL_CALL
ControllerLockUndoAction::getTitle()
1217 // this action is intended to be used within an UndoContext only, so nobody will ever see this title ...
1221 void SAL_CALL
ControllerLockUndoAction::undo( )
1223 if ( m_bUndoIsUnlock
)
1224 m_xModel
->unlockControllers();
1226 m_xModel
->lockControllers();
1229 void SAL_CALL
ControllerLockUndoAction::redo( )
1231 if ( m_bUndoIsUnlock
)
1232 m_xModel
->lockControllers();
1234 m_xModel
->unlockControllers();
1242 void SAL_CALL
SfxBaseModel::lockControllers()
1244 SfxModelGuard
aGuard( *this );
1246 ++m_pData
->m_nControllerLockCount
;
1248 if ( m_pData
->m_pDocumentUndoManager
.is()
1249 && m_pData
->m_pDocumentUndoManager
->isInContext()
1250 && !m_pData
->m_pDocumentUndoManager
->isLocked()
1253 m_pData
->m_pDocumentUndoManager
->addUndoAction( new ControllerLockUndoAction( this, true ) );
1261 void SAL_CALL
SfxBaseModel::unlockControllers()
1263 SfxModelGuard
aGuard( *this );
1265 --m_pData
->m_nControllerLockCount
;
1267 if ( m_pData
->m_pDocumentUndoManager
.is()
1268 && m_pData
->m_pDocumentUndoManager
->isInContext()
1269 && !m_pData
->m_pDocumentUndoManager
->isLocked()
1272 m_pData
->m_pDocumentUndoManager
->addUndoAction( new ControllerLockUndoAction( this, false ) );
1280 sal_Bool SAL_CALL
SfxBaseModel::hasControllersLocked()
1282 SfxModelGuard
aGuard( *this );
1283 return ( m_pData
->m_nControllerLockCount
!= 0 ) ;
1290 Reference
< frame::XController
> SAL_CALL
SfxBaseModel::getCurrentController()
1292 SfxModelGuard
aGuard( *this );
1294 // get the last active controller of this model
1295 if ( m_pData
->m_xCurrent
.is() )
1296 return m_pData
->m_xCurrent
;
1298 // get the first controller of this model
1299 return !m_pData
->m_seqControllers
.empty() ? m_pData
->m_seqControllers
.front() : m_pData
->m_xCurrent
;
1306 void SAL_CALL
SfxBaseModel::setCurrentController( const Reference
< frame::XController
>& xCurrentController
)
1308 SfxModelGuard
aGuard( *this );
1310 m_pData
->m_xCurrent
= xCurrentController
;
1317 Reference
< XInterface
> SAL_CALL
SfxBaseModel::getCurrentSelection()
1319 SfxModelGuard
aGuard( *this );
1321 Reference
< XInterface
> xReturn
;
1322 Reference
< frame::XController
> xController
= getCurrentController() ;
1324 if ( xController
.is() )
1326 Reference
< view::XSelectionSupplier
> xDocView( xController
, UNO_QUERY
);
1327 if ( xDocView
.is() )
1329 Any aSel
= xDocView
->getSelection();
1341 sal_Bool SAL_CALL
SfxBaseModel::disableSetModified()
1343 SfxModelGuard
aGuard( *this );
1345 if ( !m_pData
->m_pObjectShell
.is() )
1346 throw RuntimeException();
1348 bool bResult
= m_pData
->m_pObjectShell
->IsEnableSetModified();
1349 m_pData
->m_pObjectShell
->EnableSetModified( false );
1354 sal_Bool SAL_CALL
SfxBaseModel::enableSetModified()
1356 SfxModelGuard
aGuard( *this );
1358 if ( !m_pData
->m_pObjectShell
.is() )
1359 throw RuntimeException();
1361 bool bResult
= m_pData
->m_pObjectShell
->IsEnableSetModified();
1362 m_pData
->m_pObjectShell
->EnableSetModified();
1367 sal_Bool SAL_CALL
SfxBaseModel::isSetModifiedEnabled()
1369 SfxModelGuard
aGuard( *this );
1371 if ( !m_pData
->m_pObjectShell
.is() )
1372 throw RuntimeException();
1374 return m_pData
->m_pObjectShell
->IsEnableSetModified();
1381 sal_Bool SAL_CALL
SfxBaseModel::isModified()
1383 SfxModelGuard
aGuard( *this );
1385 return m_pData
->m_pObjectShell
.is() && m_pData
->m_pObjectShell
->IsModified();
1392 void SAL_CALL
SfxBaseModel::setModified( sal_Bool bModified
)
1394 SfxModelGuard
aGuard( *this );
1396 if ( m_pData
->m_pObjectShell
.is() )
1397 m_pData
->m_pObjectShell
->SetModified(bModified
);
1404 void SAL_CALL
SfxBaseModel::addModifyListener(const Reference
< util::XModifyListener
>& xListener
)
1406 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
1408 m_pData
->m_aInterfaceContainer
.addInterface( cppu::UnoType
<util::XModifyListener
>::get(),xListener
);
1415 void SAL_CALL
SfxBaseModel::removeModifyListener(const Reference
< util::XModifyListener
>& xListener
)
1417 SfxModelGuard
aGuard( *this );
1419 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<util::XModifyListener
>::get(), xListener
);
1426 void SAL_CALL
SfxBaseModel::close( sal_Bool bDeliverOwnership
)
1428 SolarMutexGuard aGuard
;
1429 if ( impl_isDisposed() || m_pData
->m_bClosed
|| m_pData
->m_bClosing
)
1432 Reference
< XInterface
> xSelfHold( static_cast< ::cppu::OWeakObject
* >(this) );
1433 lang::EventObject
aSource ( static_cast< ::cppu::OWeakObject
* >(this) );
1434 comphelper::OInterfaceContainerHelper2
* pContainer
= m_pData
->m_aInterfaceContainer
.getContainer( cppu::UnoType
<util::XCloseListener
>::get());
1435 if (pContainer
!=nullptr)
1437 comphelper::OInterfaceIteratorHelper2
pIterator(*pContainer
);
1438 while (pIterator
.hasMoreElements())
1442 static_cast<util::XCloseListener
*>(pIterator
.next())->queryClosing( aSource
, bDeliverOwnership
);
1444 catch( RuntimeException
& )
1451 if ( m_pData
->m_bSaving
)
1453 if (bDeliverOwnership
)
1454 m_pData
->m_bSuicide
= true;
1455 throw util::CloseVetoException(
1456 "Can not close while saving.",
1457 static_cast< util::XCloseable
* >(this));
1460 // no own objections against closing!
1461 m_pData
->m_bClosing
= true;
1462 pContainer
= m_pData
->m_aInterfaceContainer
.getContainer( cppu::UnoType
<util::XCloseListener
>::get());
1463 if (pContainer
!=nullptr)
1465 comphelper::OInterfaceIteratorHelper2
pCloseIterator(*pContainer
);
1466 while (pCloseIterator
.hasMoreElements())
1470 static_cast<util::XCloseListener
*>(pCloseIterator
.next())->notifyClosing( aSource
);
1472 catch( RuntimeException
& )
1474 pCloseIterator
.remove();
1479 m_pData
->m_bClosed
= true;
1480 m_pData
->m_bClosing
= false;
1486 // XCloseBroadcaster
1489 void SAL_CALL
SfxBaseModel::addCloseListener( const Reference
< util::XCloseListener
>& xListener
)
1491 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
1493 m_pData
->m_aInterfaceContainer
.addInterface( cppu::UnoType
<util::XCloseListener
>::get(), xListener
);
1497 // XCloseBroadcaster
1500 void SAL_CALL
SfxBaseModel::removeCloseListener( const Reference
< util::XCloseListener
>& xListener
)
1502 SfxModelGuard
aGuard( *this );
1504 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<util::XCloseListener
>::get(), xListener
);
1511 Sequence
< beans::PropertyValue
> SAL_CALL
SfxBaseModel::getPrinter()
1513 SfxModelGuard
aGuard( *this );
1515 impl_getPrintHelper();
1516 return m_pData
->m_xPrintable
->getPrinter();
1519 void SAL_CALL
SfxBaseModel::setPrinter(const Sequence
< beans::PropertyValue
>& rPrinter
)
1521 SfxModelGuard
aGuard( *this );
1523 impl_getPrintHelper();
1524 m_pData
->m_xPrintable
->setPrinter( rPrinter
);
1527 void SAL_CALL
SfxBaseModel::print(const Sequence
< beans::PropertyValue
>& rOptions
)
1529 SfxModelGuard
aGuard( *this );
1531 impl_getPrintHelper();
1533 // tdf#123728 Always print on main thread to avoid deadlocks
1534 vcl::solarthread::syncExecute([this, &rOptions
]() { m_pData
->m_xPrintable
->print(rOptions
); });
1540 sal_Bool SAL_CALL
SfxBaseModel::hasLocation()
1542 SfxModelGuard
aGuard( *this );
1544 return m_pData
->m_pObjectShell
.is() && m_pData
->m_pObjectShell
->HasName();
1551 OUString SAL_CALL
SfxBaseModel::getLocation()
1553 SfxModelGuard
aGuard( *this );
1555 if ( m_pData
->m_pObjectShell
.is() )
1557 // TODO/LATER: is it correct that the shared document returns shared file location?
1558 if ( m_pData
->m_pObjectShell
->IsDocShared() )
1559 return m_pData
->m_pObjectShell
->GetSharedFileURL();
1561 return m_pData
->m_pObjectShell
->GetMedium()->GetName();
1564 return m_pData
->m_sURL
;
1571 sal_Bool SAL_CALL
SfxBaseModel::isReadonly()
1573 SfxModelGuard
aGuard( *this );
1575 return !m_pData
->m_pObjectShell
.is() || m_pData
->m_pObjectShell
->IsReadOnly();
1581 void SAL_CALL
SfxBaseModel::storeSelf( const Sequence
< beans::PropertyValue
>& aSeqArgs
)
1583 SfxModelGuard
aGuard( *this );
1585 if ( !m_pData
->m_pObjectShell
.is() )
1588 SfxSaveGuard
aSaveGuard(this, m_pData
.get());
1590 bool bCheckIn
= false;
1591 bool bOnMainThread
= false;
1592 for ( const auto& rArg
: aSeqArgs
)
1594 // check that only acceptable parameters are provided here
1595 if ( rArg
.Name
!= "VersionComment" && rArg
.Name
!= "Author"
1596 && rArg
.Name
!= "DontTerminateEdit"
1597 && rArg
.Name
!= "InteractionHandler" && rArg
.Name
!= "StatusIndicator"
1598 && rArg
.Name
!= "VersionMajor"
1599 && rArg
.Name
!= "FailOnWarning"
1600 && rArg
.Name
!= "CheckIn"
1601 && rArg
.Name
!= "NoFileSync"
1602 && rArg
.Name
!= "OnMainThread" )
1604 const OUString
aMessage( "Unexpected MediaDescriptor parameter: " + rArg
.Name
);
1605 throw lang::IllegalArgumentException( aMessage
, Reference
< XInterface
>(), 1 );
1607 else if ( rArg
.Name
== "CheckIn" )
1609 rArg
.Value
>>= bCheckIn
;
1611 else if (rArg
.Name
== "OnMainThread")
1613 rArg
.Value
>>= bOnMainThread
;
1617 // Remove CheckIn property if needed
1618 sal_uInt16 nSlotId
= SID_SAVEDOC
;
1619 Sequence
< beans::PropertyValue
> aArgs
= aSeqArgs
;
1622 nSlotId
= SID_CHECKIN
;
1623 sal_Int32 nLength
= aSeqArgs
.getLength( );
1624 aArgs
= Sequence
< beans::PropertyValue
>( nLength
- 1 );
1625 std::copy_if(aSeqArgs
.begin(), aSeqArgs
.end(), aArgs
.getArray(),
1626 [](const beans::PropertyValue
& rProp
) { return rProp
.Name
!= "CheckIn"; });
1629 std::optional
<SfxAllItemSet
> pParams(SfxGetpApp()->GetPool() );
1630 TransformParameters( nSlotId
, aArgs
, *pParams
);
1632 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveDoc
, GlobalEventConfig::GetEventName(GlobalEventId::SAVEDOC
), m_pData
->m_pObjectShell
.get() ) );
1636 // TODO/LATER: let the embedded case of saving be handled more careful
1637 if ( m_pData
->m_pObjectShell
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
1639 // If this is an embedded object that has no URL based location it should be stored to own storage.
1640 // An embedded object can have a location based on URL in case it is a link, then it should be
1641 // stored in normal way.
1642 if ( !hasLocation() || getLocation().startsWith("private:") )
1644 // actually in this very rare case only UI parameters have sense
1645 // TODO/LATER: should be done later, after integration of sb19
1646 bRet
= m_pData
->m_pObjectShell
->DoSave()
1647 && m_pData
->m_pObjectShell
->DoSaveCompleted();
1651 bRet
= m_pData
->m_pObjectShell
->Save_Impl( &*pParams
);
1656 // Tell the SfxMedium if we are in checkin instead of normal save
1657 m_pData
->m_pObjectShell
->GetMedium( )->SetInCheckIn( nSlotId
== SID_CHECKIN
);
1659 bRet
= vcl::solarthread::syncExecute(
1660 [this, &pParams
] { return m_pData
->m_pObjectShell
->Save_Impl(&*pParams
); });
1662 bRet
= m_pData
->m_pObjectShell
->Save_Impl(&*pParams
);
1663 m_pData
->m_pObjectShell
->GetMedium( )->SetInCheckIn( nSlotId
!= SID_CHECKIN
);
1668 ErrCode nErrCode
= m_pData
->m_pObjectShell
->GetError() ? m_pData
->m_pObjectShell
->GetError()
1669 : ERRCODE_IO_CANTWRITE
;
1670 m_pData
->m_pObjectShell
->ResetError();
1674 m_pData
->m_aPreusedFilterName
= GetMediumFilterName_Impl();
1676 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveDocDone
, GlobalEventConfig::GetEventName(GlobalEventId::SAVEDOCDONE
), m_pData
->m_pObjectShell
.get() ) );
1680 // write the contents of the logger to the file
1681 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveDocFailed
, GlobalEventConfig::GetEventName(GlobalEventId::SAVEDOCFAILED
), m_pData
->m_pObjectShell
.get() ) );
1683 throw task::ErrorCodeIOException(
1684 "SfxBaseModel::storeSelf: " + nErrCode
.toHexString(),
1685 Reference
< XInterface
>(), sal_uInt32(nErrCode
));
1693 void SAL_CALL
SfxBaseModel::store()
1695 comphelper::ProfileZone
aZone("store");
1696 storeSelf( Sequence
< beans::PropertyValue
>() );
1703 void SAL_CALL
SfxBaseModel::storeAsURL( const OUString
& rURL
,
1704 const Sequence
< beans::PropertyValue
>& rArgs
)
1706 SfxModelGuard
aGuard( *this );
1707 comphelper::ProfileZone
aZone("storeAs");
1709 if ( !m_pData
->m_pObjectShell
.is() )
1712 SfxSaveGuard
aSaveGuard(this, m_pData
.get());
1714 utl::MediaDescriptor
aDescriptor(rArgs
);
1715 bool bOnMainThread
= aDescriptor
.getUnpackedValueOrDefault("OnMainThread", false);
1718 vcl::solarthread::syncExecute([this, rURL
, rArgs
]() { impl_store(rURL
, rArgs
, false); });
1722 impl_store(rURL
, rArgs
, false);
1725 Sequence
< beans::PropertyValue
> aSequence
;
1726 TransformItems( SID_OPENDOC
, *m_pData
->m_pObjectShell
->GetMedium()->GetItemSet(), aSequence
);
1727 attachResource( rURL
, aSequence
);
1729 loadCmisProperties( );
1731 #if OSL_DEBUG_LEVEL > 0
1732 const SfxStringItem
* pPasswdItem
= SfxItemSet::GetItem
<SfxStringItem
>(m_pData
->m_pObjectShell
->GetMedium()->GetItemSet(), SID_PASSWORD
, false);
1733 OSL_ENSURE( !pPasswdItem
, "There should be no Password property in the document MediaDescriptor!" );
1738 // XUndoManagerSupplier
1740 Reference
< XUndoManager
> SAL_CALL
SfxBaseModel::getUndoManager( )
1742 SfxModelGuard
aGuard( *this );
1743 if ( !m_pData
->m_pDocumentUndoManager
.is() )
1744 m_pData
->m_pDocumentUndoManager
.set( new ::sfx2::DocumentUndoManager( *this ) );
1745 return m_pData
->m_pDocumentUndoManager
;
1752 void SAL_CALL
SfxBaseModel::storeToURL( const OUString
& rURL
,
1753 const Sequence
< beans::PropertyValue
>& rArgs
)
1755 SfxModelGuard
aGuard( *this );
1756 comphelper::ProfileZone
aZone("storeToURL");
1758 if ( !m_pData
->m_pObjectShell
.is() )
1761 SfxSaveGuard
aSaveGuard(this, m_pData
.get());
1763 utl::MediaDescriptor
aDescriptor(rArgs
);
1764 bool bOnMainThread
= aDescriptor
.getUnpackedValueOrDefault("OnMainThread", false);
1766 vcl::solarthread::syncExecute([this, rURL
, rArgs
]() { impl_store(rURL
, rArgs
, true); });
1768 impl_store(rURL
, rArgs
, true);
1770 catch (const uno::Exception
&e
)
1772 // convert to the exception we announce in the throw
1773 // (eg. neon likes to throw InteractiveAugmentedIOException which
1774 // is not an io::IOException)
1775 throw io::IOException(e
.Message
, e
.Context
);
1779 sal_Bool SAL_CALL
SfxBaseModel::wasModifiedSinceLastSave()
1781 SfxModelGuard
aGuard( *this );
1782 return m_pData
->m_bModifiedSinceLastSave
;
1785 void SAL_CALL
SfxBaseModel::storeToRecoveryFile( const OUString
& i_TargetLocation
, const Sequence
< PropertyValue
>& i_MediaDescriptor
)
1787 SfxModelGuard
aGuard( *this );
1790 SfxSaveGuard
aSaveGuard( this, m_pData
.get() );
1791 impl_store( i_TargetLocation
, i_MediaDescriptor
, true );
1793 // no need for subsequent calls to storeToRecoveryFile, unless we're modified, again
1794 m_pData
->m_bModifiedSinceLastSave
= false;
1797 void SAL_CALL
SfxBaseModel::recoverFromFile( const OUString
& i_SourceLocation
, const OUString
& i_SalvagedFile
, const Sequence
< PropertyValue
>& i_MediaDescriptor
)
1799 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
1801 // delegate to our "load" method
1802 ::comphelper::NamedValueCollection
aMediaDescriptor( i_MediaDescriptor
);
1804 // our load implementation expects the SalvagedFile to be in the media descriptor
1805 OSL_ENSURE( !aMediaDescriptor
.has( "SalvagedFile" ) || ( aMediaDescriptor
.getOrDefault( "SalvagedFile", OUString() ) == i_SalvagedFile
),
1806 "SfxBaseModel::recoverFromFile: inconsistent information!" );
1807 aMediaDescriptor
.put( "SalvagedFile", i_SalvagedFile
);
1809 // similar for the to-be-loaded file
1810 OSL_ENSURE( !aMediaDescriptor
.has( "URL" ) || ( aMediaDescriptor
.getOrDefault( "URL", OUString() ) == i_SourceLocation
),
1811 "SfxBaseModel::recoverFromFile: inconsistent information!" );
1812 aMediaDescriptor
.put( "URL", i_SourceLocation
);
1814 load( aMediaDescriptor
.getPropertyValues() );
1816 // Note: The XDocumentRecovery interface specification requires us to do an attachResource after loading.
1817 // However, we will not do this here, as we know that our load implementation (respectively some method
1818 // called from there) already did so.
1819 // In particular, the load process might already have modified some elements of the media
1820 // descriptor, for instance the MacroExecMode (in case the user was involved to decide about it), and we do
1821 // not want to overwrite it with the "old" elements passed to this method here.
1828 void SAL_CALL
SfxBaseModel::initNew()
1830 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
1831 if ( IsInitialized() )
1832 throw frame::DoubleInitializationException( OUString(), *this );
1834 // the object shell should exist always
1835 DBG_ASSERT( m_pData
->m_pObjectShell
.is(), "Model is useless without an ObjectShell" );
1836 if ( !m_pData
->m_pObjectShell
.is() )
1839 if( m_pData
->m_pObjectShell
->GetMedium() )
1840 throw frame::DoubleInitializationException();
1842 bool bRes
= m_pData
->m_pObjectShell
->DoInitNew();
1843 ErrCode nErrCode
= m_pData
->m_pObjectShell
->GetError() ?
1844 m_pData
->m_pObjectShell
->GetError() : ERRCODE_IO_CANTCREATE
;
1845 m_pData
->m_pObjectShell
->ResetError();
1848 throw task::ErrorCodeIOException(
1849 "SfxBaseModel::initNew: " + nErrCode
.toHexString(),
1850 Reference
< XInterface
>(), sal_uInt32(nErrCode
));
1855 OUString
getFilterProvider( SfxMedium
const & rMedium
)
1857 const std::shared_ptr
<const SfxFilter
>& pFilter
= rMedium
.GetFilter();
1861 return pFilter
->GetProviderName();
1864 void setUpdatePickList( SfxMedium
* pMedium
)
1869 bool bHidden
= false;
1870 const SfxBoolItem
* pHidItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_HIDDEN
, false);
1872 bHidden
= pHidItem
->GetValue();
1874 pMedium
->SetUpdatePickList(!bHidden
);
1879 void SAL_CALL
SfxBaseModel::load( const Sequence
< beans::PropertyValue
>& seqArguments
)
1881 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
1882 if ( IsInitialized() )
1883 throw frame::DoubleInitializationException( OUString(), *this );
1885 // the object shell should exist always
1886 DBG_ASSERT( m_pData
->m_pObjectShell
.is(), "Model is useless without an ObjectShell" );
1888 if (!m_pData
->m_pObjectShell
.is())
1891 if( m_pData
->m_pObjectShell
->GetMedium() )
1892 // if a Medium is present, the document is already initialized
1893 throw frame::DoubleInitializationException();
1895 SfxMedium
* pMedium
= new SfxMedium( seqArguments
);
1897 ErrCode nError
= ERRCODE_NONE
;
1898 if (!getFilterProvider(*pMedium
).isEmpty())
1900 if (!m_pData
->m_pObjectShell
->DoLoadExternal(pMedium
))
1901 nError
= ERRCODE_IO_GENERAL
;
1903 pMedium
= handleLoadError(nError
, pMedium
);
1904 setUpdatePickList(pMedium
);
1908 OUString aFilterName
;
1909 const SfxStringItem
* pFilterNameItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_FILTER_NAME
, false);
1910 if( pFilterNameItem
)
1911 aFilterName
= pFilterNameItem
->GetValue();
1912 if( !m_pData
->m_pObjectShell
->GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName
) )
1914 // filtername is not valid
1916 throw frame::IllegalArgumentIOException();
1919 const SfxStringItem
* pSalvageItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_DOC_SALVAGE
, false);
1920 bool bSalvage
= pSalvageItem
!= nullptr;
1923 if ( !m_pData
->m_pObjectShell
->DoLoad(pMedium
) )
1924 nError
=ERRCODE_IO_GENERAL
;
1926 // QUESTION: if the following happens outside of DoLoad, something important is missing there!
1927 Reference
< task::XInteractionHandler
> xHandler
= pMedium
->GetInteractionHandler();
1928 if( m_pData
->m_pObjectShell
->GetErrorCode() )
1930 nError
= m_pData
->m_pObjectShell
->GetErrorCode();
1931 if ( nError
== ERRCODE_IO_BROKENPACKAGE
&& xHandler
.is() )
1933 const OUString
aDocName( pMedium
->GetURLObject().getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::WithCharset
) );
1934 const SfxBoolItem
* pRepairItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_REPAIRPACKAGE
, false);
1935 if ( !pRepairItem
|| !pRepairItem
->GetValue() )
1937 RequestPackageReparation
aRequest( aDocName
);
1938 xHandler
->handle( aRequest
.GetRequest() );
1939 if( aRequest
.isApproved() )
1941 // broken package: try second loading and allow repair
1942 pMedium
->GetItemSet()->Put( SfxBoolItem( SID_REPAIRPACKAGE
, true ) );
1943 pMedium
->GetItemSet()->Put( SfxBoolItem( SID_TEMPLATE
, true ) );
1944 pMedium
->GetItemSet()->Put( SfxStringItem( SID_DOCINFO_TITLE
, aDocName
) );
1946 // the error must be reset and the storage must be reopened in new mode
1947 pMedium
->ResetError();
1948 pMedium
->CloseStorage();
1949 m_pData
->m_pObjectShell
->PrepareSecondTryLoad_Impl();
1950 nError
= ERRCODE_NONE
;
1951 if ( !m_pData
->m_pObjectShell
->DoLoad(pMedium
) )
1952 nError
=ERRCODE_IO_GENERAL
;
1953 if (m_pData
->m_pObjectShell
->GetErrorCode())
1954 nError
= m_pData
->m_pObjectShell
->GetErrorCode();
1958 if ( nError
== ERRCODE_IO_BROKENPACKAGE
)
1960 // repair either not allowed or not successful
1961 NotifyBrokenPackage
aRequest( aDocName
);
1962 xHandler
->handle( aRequest
.GetRequest() );
1967 if( m_pData
->m_pObjectShell
->IsAbortingImport() )
1968 nError
= ERRCODE_ABORT
;
1972 // file recovery: restore original filter
1973 const SfxStringItem
* pFilterItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_FILTER_NAME
, false);
1974 SfxFilterMatcher
& rMatcher
= SfxGetpApp()->GetFilterMatcher();
1975 std::shared_ptr
<const SfxFilter
> pSetFilter
= rMatcher
.GetFilter4FilterName( pFilterItem
->GetValue() );
1976 pMedium
->SetFilter( pSetFilter
);
1977 m_pData
->m_pObjectShell
->SetModified();
1980 // TODO/LATER: maybe the mode should be retrieved from outside and the preused filter should not be set
1981 if ( m_pData
->m_pObjectShell
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
1983 const SfxStringItem
* pFilterItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_FILTER_NAME
, false);
1985 m_pData
->m_aPreusedFilterName
= pFilterItem
->GetValue();
1989 nError
= pMedium
->GetError();
1991 m_pData
->m_pObjectShell
->ResetError();
1993 pMedium
= handleLoadError(nError
, pMedium
);
1994 loadCmisProperties();
1995 setUpdatePickList(pMedium
);
1997 #if OSL_DEBUG_LEVEL > 0
1998 const SfxStringItem
* pPasswdItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_PASSWORD
, false);
1999 OSL_ENSURE( !pPasswdItem
, "There should be no Password property in the document MediaDescriptor!" );
2007 Any SAL_CALL
SfxBaseModel::getTransferData( const datatransfer::DataFlavor
& aFlavor
)
2009 SfxModelGuard
aGuard( *this );
2013 if ( m_pData
->m_pObjectShell
.is() )
2015 if ( aFlavor
.MimeType
== "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" )
2017 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2018 throw datatransfer::UnsupportedFlavorException();
2020 TransferableObjectDescriptor aDesc
;
2022 aDesc
.maClassName
= m_pData
->m_pObjectShell
->GetClassName();
2023 aDesc
.maTypeName
= aFlavor
.HumanPresentableName
;
2025 // TODO/LATER: ViewAspect needs to be sal_Int64
2026 aDesc
.mnViewAspect
= sal::static_int_cast
< sal_uInt16
>( embed::Aspects::MSOLE_CONTENT
);
2028 Size aSize
= m_pData
->m_pObjectShell
->GetVisArea().GetSize();
2030 MapUnit aMapUnit
= m_pData
->m_pObjectShell
->GetMapUnit();
2031 aDesc
.maSize
= OutputDevice::LogicToLogic(aSize
, MapMode(aMapUnit
), MapMode(MapUnit::Map100thMM
));
2032 aDesc
.maDragStartPos
= Point();
2033 aDesc
.maDisplayName
.clear();
2035 SvMemoryStream
aMemStm( 1024, 1024 );
2036 WriteTransferableObjectDescriptor( aMemStm
, aDesc
);
2037 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( aMemStm
.GetData() ), aMemStm
.Tell() );
2039 else if ( aFlavor
.MimeType
== "application/x-openoffice-embed-source;windows_formatname=\"Star EMBS\"" )
2041 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2042 throw datatransfer::UnsupportedFlavorException();
2047 aTmp
.EnableKillingFile();
2048 storeToURL( aTmp
.GetURL(), Sequence
< beans::PropertyValue
>() );
2049 std::unique_ptr
<SvStream
> pStream(aTmp
.GetStream( StreamMode::READ
));
2050 const sal_uInt32 nLen
= pStream
->TellEnd();
2051 Sequence
< sal_Int8
> aSeq( nLen
);
2052 pStream
->ReadBytes(aSeq
.getArray(), nLen
);
2053 if( aSeq
.hasElements() )
2056 catch ( Exception
& )
2060 else if ( aFlavor
.MimeType
== "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2062 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2063 throw datatransfer::UnsupportedFlavorException();
2066 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2067 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2071 SvMemoryStream
aMemStm( 65535, 65535 );
2072 aMemStm
.SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2074 SvmWriter
aWriter( aMemStm
);
2075 aWriter
.Write( *xMetaFile
);
2076 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( aMemStm
.GetData() ),
2077 aMemStm
.TellEnd() );
2080 else if ( aFlavor
.MimeType
== "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2082 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2083 throw datatransfer::UnsupportedFlavorException();
2085 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2086 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2090 SvMemoryStream
aMemStm( 65535, 65535 );
2091 aMemStm
.SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2093 SvmWriter
aWriter( aMemStm
);
2094 aWriter
.Write( *xMetaFile
);
2095 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( aMemStm
.GetData() ),
2096 aMemStm
.TellEnd() );
2099 else if ( aFlavor
.MimeType
== "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" )
2101 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2103 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2104 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2108 std::unique_ptr
<SvMemoryStream
> xStream(
2109 GraphicHelper::getFormatStrFromGDI_Impl(
2110 xMetaFile
.get(), ConvertDataFormat::EMF
) );
2113 xStream
->SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2114 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( xStream
->GetData() ),
2115 xStream
->TellEnd() );
2119 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2120 && aFlavor
.DataType
== cppu::UnoType
<sal_uInt64
>::get())
2122 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2123 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2127 aAny
<<= reinterpret_cast< sal_uInt64
>(
2128 GraphicHelper::getEnhMetaFileFromGDI_Impl( xMetaFile
.get() ) );
2132 throw datatransfer::UnsupportedFlavorException();
2134 else if ( aFlavor
.MimeType
== "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" )
2136 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2138 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2139 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2143 std::unique_ptr
<SvMemoryStream
> xStream(
2144 GraphicHelper::getFormatStrFromGDI_Impl(
2145 xMetaFile
.get(), ConvertDataFormat::WMF
) );
2149 xStream
->SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2150 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( xStream
->GetData() ),
2151 xStream
->TellEnd() );
2155 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2156 && aFlavor
.DataType
== cppu::UnoType
<sal_uInt64
>::get())
2158 // means HGLOBAL handler to memory storage containing METAFILEPICT structure
2160 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2161 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2165 Size aMetaSize
= xMetaFile
->GetPrefSize();
2166 aAny
<<= reinterpret_cast< sal_uInt64
>(
2167 GraphicHelper::getWinMetaFileFromGDI_Impl(
2168 xMetaFile
.get(), aMetaSize
) );
2172 throw datatransfer::UnsupportedFlavorException();
2174 else if ( aFlavor
.MimeType
== "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" )
2176 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2177 throw datatransfer::UnsupportedFlavorException();
2179 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2180 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2184 std::unique_ptr
<SvMemoryStream
> xStream(
2185 GraphicHelper::getFormatStrFromGDI_Impl(
2186 xMetaFile
.get(), ConvertDataFormat::BMP
) );
2190 xStream
->SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2191 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( xStream
->GetData() ),
2192 xStream
->TellEnd() );
2196 else if ( aFlavor
.MimeType
== "image/png" )
2198 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2199 throw datatransfer::UnsupportedFlavorException();
2201 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2202 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2206 std::unique_ptr
<SvMemoryStream
> xStream(
2207 GraphicHelper::getFormatStrFromGDI_Impl(
2208 xMetaFile
.get(), ConvertDataFormat::PNG
) );
2212 xStream
->SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2213 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( xStream
->GetData() ),
2214 xStream
->TellEnd() );
2219 throw datatransfer::UnsupportedFlavorException();
2229 Sequence
< datatransfer::DataFlavor
> SAL_CALL
SfxBaseModel::getTransferDataFlavors()
2231 SfxModelGuard
aGuard( *this );
2233 const sal_Int32 nSuppFlavors
= GraphicHelper::supportsMetaFileHandle_Impl() ? 10 : 8;
2234 Sequence
< datatransfer::DataFlavor
> aFlavorSeq( nSuppFlavors
);
2235 auto pFlavorSeq
= aFlavorSeq
.getArray();
2237 pFlavorSeq
[0].MimeType
=
2238 "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"";
2239 pFlavorSeq
[0].HumanPresentableName
= "GDIMetaFile";
2240 pFlavorSeq
[0].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2242 pFlavorSeq
[1].MimeType
=
2243 "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"";
2244 pFlavorSeq
[1].HumanPresentableName
= "GDIMetaFile";
2245 pFlavorSeq
[1].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2247 pFlavorSeq
[2].MimeType
=
2248 "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ;
2249 pFlavorSeq
[2].HumanPresentableName
= "Enhanced Windows MetaFile";
2250 pFlavorSeq
[2].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2252 pFlavorSeq
[3].MimeType
=
2253 "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"";
2254 pFlavorSeq
[3].HumanPresentableName
= "Windows MetaFile";
2255 pFlavorSeq
[3].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2257 pFlavorSeq
[4].MimeType
=
2258 "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"";
2259 pFlavorSeq
[4].HumanPresentableName
= "Star Object Descriptor (XML)";
2260 pFlavorSeq
[4].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2262 pFlavorSeq
[5].MimeType
=
2263 "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
2264 pFlavorSeq
[5].HumanPresentableName
= "Star Embed Source (XML)";
2265 pFlavorSeq
[5].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2267 pFlavorSeq
[6].MimeType
=
2268 "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"";
2269 pFlavorSeq
[6].HumanPresentableName
= "Bitmap";
2270 pFlavorSeq
[6].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2272 pFlavorSeq
[7].MimeType
= "image/png";
2273 pFlavorSeq
[7].HumanPresentableName
= "PNG";
2274 pFlavorSeq
[7].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2276 if ( nSuppFlavors
== 10 )
2278 pFlavorSeq
[8].MimeType
=
2279 "application/x-openoffice-emf;windows_formatname=\"Image EMF\"";
2280 pFlavorSeq
[8].HumanPresentableName
= "Enhanced Windows MetaFile";
2281 pFlavorSeq
[8].DataType
= cppu::UnoType
<sal_uInt64
>::get();
2283 pFlavorSeq
[9].MimeType
=
2284 "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"";
2285 pFlavorSeq
[9].HumanPresentableName
= "Windows MetaFile";
2286 pFlavorSeq
[9].DataType
= cppu::UnoType
<sal_uInt64
>::get();
2296 sal_Bool SAL_CALL
SfxBaseModel::isDataFlavorSupported( const datatransfer::DataFlavor
& aFlavor
)
2298 SfxModelGuard
aGuard( *this );
2300 if ( aFlavor
.MimeType
== "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2302 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2305 else if ( aFlavor
.MimeType
== "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2307 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2310 else if ( aFlavor
.MimeType
== "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" )
2312 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2314 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2315 && aFlavor
.DataType
== cppu::UnoType
<sal_uInt64
>::get())
2318 else if ( aFlavor
.MimeType
== "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" )
2320 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2322 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2323 && aFlavor
.DataType
== cppu::UnoType
<sal_uInt64
>::get())
2326 else if ( aFlavor
.MimeType
== "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" )
2328 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2331 else if ( aFlavor
.MimeType
== "application/x-openoffice-embed-source;windows_formatname=\"Star EMBS\"" )
2333 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2336 else if ( aFlavor
.MimeType
== "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" )
2338 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2341 else if ( aFlavor
.MimeType
== "image/png" )
2343 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2354 Reference
< container::XNameReplace
> SAL_CALL
SfxBaseModel::getEvents()
2356 SfxModelGuard
aGuard( *this );
2358 if ( ! m_pData
->m_xEvents
.is() )
2360 m_pData
->m_xEvents
= new SfxEvents_Impl( m_pData
->m_pObjectShell
.get(), this );
2363 return m_pData
->m_xEvents
;
2370 Reference
< script::XStorageBasedLibraryContainer
> SAL_CALL
SfxBaseModel::getBasicLibraries()
2372 SfxModelGuard
aGuard( *this );
2374 Reference
< script::XStorageBasedLibraryContainer
> xBasicLibraries
;
2375 if ( m_pData
->m_pObjectShell
.is() )
2376 xBasicLibraries
.set(m_pData
->m_pObjectShell
->GetBasicContainer(), UNO_QUERY
);
2377 return xBasicLibraries
;
2380 Reference
< script::XStorageBasedLibraryContainer
> SAL_CALL
SfxBaseModel::getDialogLibraries()
2382 SfxModelGuard
aGuard( *this );
2384 Reference
< script::XStorageBasedLibraryContainer
> xDialogLibraries
;
2385 if ( m_pData
->m_pObjectShell
.is() )
2386 xDialogLibraries
.set(m_pData
->m_pObjectShell
->GetDialogContainer(), UNO_QUERY
);
2387 return xDialogLibraries
;
2390 sal_Bool SAL_CALL
SfxBaseModel::getAllowMacroExecution()
2392 SfxModelGuard
aGuard( *this );
2394 if ( m_pData
->m_pObjectShell
.is() )
2395 return m_pData
->m_pObjectShell
->AdjustMacroMode();
2400 // XScriptInvocationContext
2403 Reference
< document::XEmbeddedScripts
> SAL_CALL
SfxBaseModel::getScriptContainer()
2405 SfxModelGuard
aGuard( *this );
2407 Reference
< document::XEmbeddedScripts
> xDocumentScripts
;
2411 Reference
< frame::XModel
> xDocument( this );
2412 xDocumentScripts
.set( xDocument
, UNO_QUERY
);
2413 while ( !xDocumentScripts
.is() && xDocument
.is() )
2415 Reference
< container::XChild
> xDocAsChild( xDocument
, UNO_QUERY
);
2416 if ( !xDocAsChild
.is() )
2418 xDocument
= nullptr;
2422 xDocument
.set( xDocAsChild
->getParent(), UNO_QUERY
);
2423 xDocumentScripts
.set( xDocument
, UNO_QUERY
);
2426 catch( const Exception
& )
2428 DBG_UNHANDLED_EXCEPTION("sfx.doc");
2429 xDocumentScripts
= nullptr;
2432 return xDocumentScripts
;
2436 // XEventBroadcaster
2439 void SAL_CALL
SfxBaseModel::addEventListener( const Reference
< document::XEventListener
>& aListener
)
2441 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
2443 m_pData
->m_aInterfaceContainer
.addInterface( cppu::UnoType
<document::XEventListener
>::get(), aListener
);
2447 // XEventBroadcaster
2450 void SAL_CALL
SfxBaseModel::removeEventListener( const Reference
< document::XEventListener
>& aListener
)
2452 SfxModelGuard
aGuard( *this );
2454 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<document::XEventListener
>::get(), aListener
);
2457 // XShapeEventBroadcaster
2459 void SAL_CALL
SfxBaseModel::addShapeEventListener( const css::uno::Reference
< css::drawing::XShape
>& xShape
, const Reference
< document::XShapeEventListener
>& xListener
)
2461 assert(xShape
.is() && "no shape?");
2462 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
2464 m_pData
->maShapeListeners
[xShape
].push_back(xListener
);
2468 // XShapeEventBroadcaster
2471 void SAL_CALL
SfxBaseModel::removeShapeEventListener( const css::uno::Reference
< css::drawing::XShape
>& xShape
, const Reference
< document::XShapeEventListener
>& xListener
)
2473 SfxModelGuard
aGuard( *this );
2475 auto it
= m_pData
->maShapeListeners
.find(xShape
);
2476 if (it
!= m_pData
->maShapeListeners
.end())
2478 auto rVec
= it
->second
;
2479 auto it2
= std::find(rVec
.begin(), rVec
.end(), xListener
);
2480 if (it2
!= rVec
.end())
2484 m_pData
->maShapeListeners
.erase(it
);
2489 // XDocumentEventBroadcaster
2492 void SAL_CALL
SfxBaseModel::addDocumentEventListener( const Reference
< document::XDocumentEventListener
>& aListener
)
2494 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
2495 m_pData
->m_aInterfaceContainer
.addInterface( cppu::UnoType
<document::XDocumentEventListener
>::get(), aListener
);
2499 void SAL_CALL
SfxBaseModel::removeDocumentEventListener( const Reference
< document::XDocumentEventListener
>& aListener
)
2501 SfxModelGuard
aGuard( *this );
2502 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<document::XDocumentEventListener
>::get(), aListener
);
2506 void SAL_CALL
SfxBaseModel::notifyDocumentEvent( const OUString
&, const Reference
< frame::XController2
>&, const Any
& )
2508 throw lang::NoSupportException("SfxBaseModel controls all the sent notifications itself!" );
2511 Sequence
<document::CmisProperty
> SAL_CALL
SfxBaseModel::getCmisProperties()
2513 if (impl_isDisposed())
2514 return Sequence
<document::CmisProperty
>();
2515 return m_pData
->m_cmisProperties
;
2518 void SAL_CALL
SfxBaseModel::setCmisProperties( const Sequence
< document::CmisProperty
>& _cmisproperties
)
2520 m_pData
->m_cmisProperties
= _cmisproperties
;
2523 void SAL_CALL
SfxBaseModel::updateCmisProperties( const Sequence
< document::CmisProperty
>& aProperties
)
2525 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2531 ::ucbhelper::Content
aContent( pMedium
->GetName( ),
2532 Reference
<ucb::XCommandEnvironment
>(),
2533 comphelper::getProcessComponentContext() );
2535 aContent
.executeCommand( "updateProperties", uno::makeAny( aProperties
) );
2536 loadCmisProperties( );
2538 catch (const Exception
& e
)
2540 css::uno::Any anyEx
= cppu::getCaughtException();
2541 throw lang::WrappedTargetRuntimeException( e
.Message
,
2547 void SAL_CALL
SfxBaseModel::checkOut( )
2549 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2555 ::ucbhelper::Content
aContent( pMedium
->GetName(),
2556 Reference
<ucb::XCommandEnvironment
>(),
2557 comphelper::getProcessComponentContext() );
2559 Any aResult
= aContent
.executeCommand( "checkout", Any( ) );
2563 m_pData
->m_pObjectShell
->GetMedium( )->SetName( sURL
);
2564 m_pData
->m_pObjectShell
->GetMedium( )->GetMedium_Impl( );
2565 m_pData
->m_xDocumentProperties
->setTitle( getTitle( ) );
2566 Sequence
< beans::PropertyValue
> aSequence
;
2567 TransformItems( SID_OPENDOC
, *pMedium
->GetItemSet(), aSequence
);
2568 attachResource( sURL
, aSequence
);
2570 // Reload the CMIS properties
2571 loadCmisProperties( );
2573 catch ( const Exception
& e
)
2575 css::uno::Any anyEx
= cppu::getCaughtException();
2576 throw lang::WrappedTargetRuntimeException( e
.Message
,
2581 void SAL_CALL
SfxBaseModel::cancelCheckOut( )
2583 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2589 ::ucbhelper::Content
aContent( pMedium
->GetName(),
2590 Reference
<ucb::XCommandEnvironment
>(),
2591 comphelper::getProcessComponentContext() );
2593 Any aResult
= aContent
.executeCommand( "cancelCheckout", Any( ) );
2597 m_pData
->m_pObjectShell
->GetMedium( )->SetName( sURL
);
2599 catch ( const Exception
& e
)
2601 css::uno::Any anyEx
= cppu::getCaughtException();
2602 throw lang::WrappedTargetRuntimeException( e
.Message
,
2607 void SAL_CALL
SfxBaseModel::checkIn( sal_Bool bIsMajor
, const OUString
& rMessage
)
2609 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2615 Sequence
< beans::PropertyValue
> aProps
{
2616 comphelper::makePropertyValue("VersionMajor", bIsMajor
),
2617 comphelper::makePropertyValue("VersionComment", rMessage
),
2618 comphelper::makePropertyValue("CheckIn", true)
2621 const OUString
sName( pMedium
->GetName( ) );
2622 storeSelf( aProps
);
2624 // Refresh pMedium as it has probably changed during the storeSelf call
2625 pMedium
= m_pData
->m_pObjectShell
->GetMedium( );
2626 const OUString
sNewName( pMedium
->GetName( ) );
2628 // URL has changed, update the document
2629 if ( sName
!= sNewName
)
2631 m_pData
->m_xDocumentProperties
->setTitle( getTitle( ) );
2632 Sequence
< beans::PropertyValue
> aSequence
;
2633 TransformItems( SID_OPENDOC
, *pMedium
->GetItemSet(), aSequence
);
2634 attachResource( sNewName
, aSequence
);
2636 // Reload the CMIS properties
2637 loadCmisProperties( );
2640 catch ( const Exception
& e
)
2642 css::uno::Any anyEx
= cppu::getCaughtException();
2643 throw lang::WrappedTargetRuntimeException( e
.Message
,
2648 uno::Sequence
< document::CmisVersion
> SAL_CALL
SfxBaseModel::getAllVersions( )
2650 uno::Sequence
<document::CmisVersion
> aVersions
;
2651 if (impl_isDisposed())
2653 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2658 ::ucbhelper::Content
aContent( pMedium
->GetName(),
2659 Reference
<ucb::XCommandEnvironment
>(),
2660 comphelper::getProcessComponentContext() );
2662 Any aResult
= aContent
.executeCommand( "getAllVersions", Any( ) );
2663 aResult
>>= aVersions
;
2665 catch ( const Exception
& e
)
2667 css::uno::Any anyEx
= cppu::getCaughtException();
2668 throw lang::WrappedTargetRuntimeException( e
.Message
,
2675 bool SfxBaseModel::getBoolPropertyValue( const OUString
& rName
)
2677 bool bValue
= false;
2678 if ( m_pData
->m_pObjectShell
.is() )
2680 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2685 ::ucbhelper::Content
aContent( pMedium
->GetName( ),
2686 utl::UCBContentHelper::getDefaultCommandEnvironment(),
2687 comphelper::getProcessComponentContext() );
2688 Reference
< beans::XPropertySetInfo
> xProps
= aContent
.getProperties();
2689 if ( xProps
->hasPropertyByName( rName
) )
2691 aContent
.getPropertyValue( rName
) >>= bValue
;
2694 catch ( const Exception
& )
2696 // Simply ignore it: it's likely the document isn't versionable in that case
2704 sal_Bool SAL_CALL
SfxBaseModel::isVersionable( )
2706 return getBoolPropertyValue( "IsVersionable" );
2709 sal_Bool SAL_CALL
SfxBaseModel::canCheckOut( )
2711 return getBoolPropertyValue( "CanCheckOut" );
2714 sal_Bool SAL_CALL
SfxBaseModel::canCancelCheckOut( )
2716 return getBoolPropertyValue( "CanCancelCheckOut" );
2719 sal_Bool SAL_CALL
SfxBaseModel::canCheckIn( )
2721 return getBoolPropertyValue( "CanCheckIn" );
2724 void SfxBaseModel::loadCmisProperties( )
2726 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2732 ::ucbhelper::Content
aContent( pMedium
->GetName( ),
2733 utl::UCBContentHelper::getDefaultCommandEnvironment(),
2734 comphelper::getProcessComponentContext() );
2735 Reference
< beans::XPropertySetInfo
> xProps
= aContent
.getProperties();
2736 static const OUStringLiteral
aCmisProps( u
"CmisProperties" );
2737 if ( xProps
->hasPropertyByName( aCmisProps
) )
2739 Sequence
< document::CmisProperty
> aCmisProperties
;
2740 aContent
.getPropertyValue( aCmisProps
) >>= aCmisProperties
;
2741 setCmisProperties( aCmisProperties
);
2744 catch (const ucb::ContentCreationException
&)
2747 catch (const ucb::CommandAbortedException
&)
2752 SfxMedium
* SfxBaseModel::handleLoadError( ErrCode nError
, SfxMedium
* pMedium
)
2756 // No error condition.
2760 bool bSilent
= false;
2761 const SfxBoolItem
* pSilentItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_SILENT
, false);
2763 bSilent
= pSilentItem
->GetValue();
2765 bool bWarning
= nError
.IsWarning();
2766 if ( nError
!= ERRCODE_IO_BROKENPACKAGE
&& !bSilent
)
2768 // broken package was handled already
2769 if ( SfxObjectShell::UseInteractionToHandleError(pMedium
->GetInteractionHandler(), nError
) && !bWarning
)
2771 // abort loading (except for warnings)
2772 nError
= ERRCODE_IO_ABORT
;
2776 if ( m_pData
->m_pObjectShell
->GetMedium() != pMedium
)
2778 // for whatever reason document now has another medium
2779 OSL_FAIL("Document has rejected the medium?!");
2784 if ( !bWarning
) // #i30711# don't abort loading if it's only a warning
2786 nError
= nError
? nError
: ERRCODE_IO_CANTREAD
;
2787 throw task::ErrorCodeIOException(
2788 "SfxBaseModel::handleLoadError: 0x" + nError
.toHexString(),
2789 Reference
< XInterface
>(), sal_uInt32(nError
));
2799 static void addTitle_Impl( Sequence
< beans::PropertyValue
>& rSeq
, const OUString
& rTitle
)
2801 auto [begin
, end
] = asNonConstRange(rSeq
);
2802 auto pProp
= std::find_if(begin
, end
,
2803 [](const beans::PropertyValue
& rProp
) { return rProp
.Name
== "Title"; });
2806 pProp
->Value
<<= rTitle
;
2810 sal_Int32 nCount
= rSeq
.getLength();
2811 rSeq
.realloc( nCount
+1 );
2812 auto& el
= rSeq
.getArray()[nCount
];
2814 el
.Value
<<= rTitle
;
2818 void SfxBaseModel::Notify( SfxBroadcaster
& rBC
,
2819 const SfxHint
& rHint
)
2824 if ( &rBC
!= m_pData
->m_pObjectShell
.get() )
2827 if ( rHint
.GetId() == SfxHintId::DocChanged
)
2830 const SfxEventHint
* pNamedHint
= dynamic_cast<const SfxEventHint
*>(&rHint
);
2834 switch ( pNamedHint
->GetEventId() )
2836 case SfxEventHintId::StorageChanged
:
2838 if ( m_pData
->m_xUIConfigurationManager
.is()
2839 && m_pData
->m_pObjectShell
->GetCreateMode() != SfxObjectCreateMode::EMBEDDED
)
2841 Reference
< embed::XStorage
> xConfigStorage
;
2842 static const OUStringLiteral
aUIConfigFolderName( u
"Configurations2" );
2844 xConfigStorage
= getDocumentSubStorage( aUIConfigFolderName
, embed::ElementModes::READWRITE
);
2845 if ( !xConfigStorage
.is() )
2846 xConfigStorage
= getDocumentSubStorage( aUIConfigFolderName
, embed::ElementModes::READ
);
2848 if ( xConfigStorage
.is() || !m_pData
->m_pObjectShell
->GetStorage()->hasByName( aUIConfigFolderName
) )
2850 // the storage is different, since otherwise it could not be opened, so it must be exchanged
2851 m_pData
->m_xUIConfigurationManager
->setStorage( xConfigStorage
);
2855 OSL_FAIL( "Unexpected scenario!" );
2859 ListenForStorage_Impl( m_pData
->m_pObjectShell
->GetStorage() );
2863 case SfxEventHintId::LoadFinished
:
2865 impl_getPrintHelper();
2866 ListenForStorage_Impl( m_pData
->m_pObjectShell
->GetStorage() );
2867 m_pData
->m_bModifiedSinceLastSave
= false;
2871 case SfxEventHintId::SaveAsDocDone
:
2873 m_pData
->m_sURL
= m_pData
->m_pObjectShell
->GetMedium()->GetName();
2875 SfxItemSet
*pSet
= m_pData
->m_pObjectShell
->GetMedium()->GetItemSet();
2876 Sequence
< beans::PropertyValue
> aArgs
;
2877 TransformItems( SID_SAVEASDOC
, *pSet
, aArgs
);
2878 addTitle_Impl( aArgs
, m_pData
->m_pObjectShell
->GetTitle() );
2879 attachResource( m_pData
->m_pObjectShell
->GetMedium()->GetName(), aArgs
);
2883 case SfxEventHintId::DocCreated
:
2885 impl_getPrintHelper();
2886 m_pData
->m_bModifiedSinceLastSave
= false;
2890 case SfxEventHintId::ModifyChanged
:
2892 m_pData
->m_bModifiedSinceLastSave
= isModified();
2898 const SfxViewEventHint
* pViewHint
= dynamic_cast<const SfxViewEventHint
*>(&rHint
);
2901 const SfxPrintingHint
* pPrintingHint
= dynamic_cast<const SfxPrintingHint
*>(&rHint
);
2902 postEvent_Impl( pNamedHint
->GetEventName(), pViewHint
->GetController(), pPrintingHint
? Any(pPrintingHint
->GetWhich()) : Any() );
2905 postEvent_Impl( pNamedHint
->GetEventName(), Reference
< frame::XController2
>() );
2908 if ( rHint
.GetId() == SfxHintId::TitleChanged
)
2910 addTitle_Impl( m_pData
->m_seqArguments
, m_pData
->m_pObjectShell
->GetTitle() );
2911 postEvent_Impl( GlobalEventConfig::GetEventName( GlobalEventId::TITLECHANGED
) );
2913 else if ( rHint
.GetId() == SfxHintId::ModeChanged
)
2915 postEvent_Impl( GlobalEventConfig::GetEventName( GlobalEventId::MODECHANGED
) );
2923 void SfxBaseModel::NotifyModifyListeners_Impl() const
2925 comphelper::OInterfaceContainerHelper2
* pIC
= m_pData
->m_aInterfaceContainer
.getContainer( cppu::UnoType
<util::XModifyListener
>::get());
2928 lang::EventObject
aEvent( static_cast<frame::XModel
*>(const_cast<SfxBaseModel
*>(this)) );
2929 pIC
->notifyEach( &util::XModifyListener::modified
, aEvent
);
2932 // this notification here is done too generously, we cannot simply assume that we're really modified
2933 // now, but we need to check it ...
2934 m_pData
->m_bModifiedSinceLastSave
= const_cast< SfxBaseModel
* >( this )->isModified();
2937 void SfxBaseModel::changing()
2939 SfxModelGuard
aGuard( *this );
2941 // the notification should not be sent if the document can not be modified
2942 if ( !m_pData
->m_pObjectShell
.is() || !m_pData
->m_pObjectShell
->IsEnableSetModified() )
2945 NotifyModifyListeners_Impl();
2952 SfxObjectShell
* SfxBaseModel::GetObjectShell() const
2954 return m_pData
? m_pData
->m_pObjectShell
.get() : nullptr;
2961 bool SfxBaseModel::IsInitialized() const
2963 if ( !m_pData
|| !m_pData
->m_pObjectShell
.is() )
2965 OSL_FAIL( "SfxBaseModel::IsInitialized: this should have been caught earlier!" );
2969 return m_pData
->m_pObjectShell
->GetMedium() != nullptr;
2972 void SfxBaseModel::MethodEntryCheck( const bool i_mustBeInitialized
) const
2974 if ( impl_isDisposed() )
2975 throw lang::DisposedException( OUString(), *const_cast< SfxBaseModel
* >( this ) );
2976 if ( i_mustBeInitialized
&& !IsInitialized() )
2977 throw lang::NotInitializedException( OUString(), *const_cast< SfxBaseModel
* >( this ) );
2980 bool SfxBaseModel::impl_isDisposed() const
2982 return ( m_pData
== nullptr ) ;
2989 OUString
SfxBaseModel::GetMediumFilterName_Impl() const
2991 std::shared_ptr
<const SfxFilter
> pFilter
;
2992 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2994 pFilter
= pMedium
->GetFilter();
2997 return pFilter
->GetName();
3002 void SfxBaseModel::impl_store( const OUString
& sURL
,
3003 const Sequence
< beans::PropertyValue
>& seqArguments
,
3006 if( sURL
.isEmpty() )
3007 throw frame::IllegalArgumentIOException();
3009 bool bSaved
= false;
3010 if ( !bSaveTo
&& m_pData
->m_pObjectShell
.is() && !sURL
.isEmpty()
3011 && !sURL
.startsWith( "private:stream" )
3012 && ::utl::UCBContentHelper::EqualURLs( getLocation(), sURL
) )
3014 // this is the same file URL as the current document location, try to use storeOwn if possible
3016 ::comphelper::SequenceAsHashMap
aArgHash( seqArguments
);
3017 static const OUStringLiteral
aFilterString( u
"FilterName" );
3018 const OUString
aFilterName( aArgHash
.getUnpackedValueOrDefault( aFilterString
, OUString() ) );
3019 if ( !aFilterName
.isEmpty() )
3021 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
3024 const std::shared_ptr
<const SfxFilter
>& pFilter
= pMedium
->GetFilter();
3025 if ( pFilter
&& aFilterName
== pFilter
->GetFilterName() )
3027 // #i119366# - If the former file saving with password, do not trying in StoreSelf anyway...
3028 bool bFormerPassword
= false;
3030 uno::Sequence
< beans::NamedValue
> aOldEncryptionData
;
3031 if (GetEncryptionData_Impl( pMedium
->GetItemSet(), aOldEncryptionData
))
3033 bFormerPassword
= true;
3036 if ( !bFormerPassword
)
3038 aArgHash
.erase( aFilterString
);
3039 aArgHash
.erase( "URL" );
3043 storeSelf( aArgHash
.getAsConstPropertyValueList() );
3046 catch( const lang::IllegalArgumentException
& )
3048 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
3049 // some additional arguments do not allow to use saving, SaveAs should be done
3050 // but only for normal documents, the shared documents would be overwritten in this case
3051 // that would mean an information loss
3052 // TODO/LATER: need a new interaction for this case
3053 if ( m_pData
->m_pObjectShell
->IsDocShared() )
3055 uno::Sequence
< beans::NamedValue
> aNewEncryptionData
= aArgHash
.getUnpackedValueOrDefault("EncryptionData", uno::Sequence
< beans::NamedValue
>() );
3056 if ( !aNewEncryptionData
.hasElements() )
3058 aNewEncryptionData
= ::comphelper::OStorageHelper::CreatePackageEncryptionData( aArgHash
.getUnpackedValueOrDefault("Password", OUString()) );
3061 uno::Sequence
< beans::NamedValue
> aOldEncryptionData
;
3062 (void)GetEncryptionData_Impl( pMedium
->GetItemSet(), aOldEncryptionData
);
3064 if ( !aOldEncryptionData
.hasElements() && !aNewEncryptionData
.hasElements() )
3068 // if the password is changed a special error should be used in case of shared document
3069 throw task::ErrorCodeIOException("Can not change password for shared document.", uno::Reference
< uno::XInterface
>(), sal_uInt32(ERRCODE_SFX_SHARED_NOPASSWORDCHANGE
) );
3080 if ( bSaved
|| !m_pData
->m_pObjectShell
.is() )
3083 SfxGetpApp()->NotifyEvent( SfxEventHint( bSaveTo
? SfxEventHintId::SaveToDoc
: SfxEventHintId::SaveAsDoc
, GlobalEventConfig::GetEventName( bSaveTo
? GlobalEventId::SAVETODOC
: GlobalEventId::SAVEASDOC
),
3084 m_pData
->m_pObjectShell
.get() ) );
3086 std::optional
<SfxAllItemSet
> pItemSet(SfxGetpApp()->GetPool());
3087 pItemSet
->Put(SfxStringItem(SID_FILE_NAME
, sURL
));
3089 pItemSet
->Put(SfxBoolItem(SID_SAVETO
, true));
3091 TransformParameters(SID_SAVEASDOC
, seqArguments
, *pItemSet
);
3093 const SfxBoolItem
* pCopyStreamItem
= pItemSet
->GetItem
<SfxBoolItem
>(SID_COPY_STREAM_IF_POSSIBLE
, false);
3095 if ( pCopyStreamItem
&& pCopyStreamItem
->GetValue() && !bSaveTo
)
3097 throw frame::IllegalArgumentIOException(
3098 "CopyStreamIfPossible parameter is not acceptable for storeAsURL() call!" );
3101 sal_uInt32 nModifyPasswordHash
= 0;
3102 Sequence
< beans::PropertyValue
> aModifyPasswordInfo
;
3103 const SfxUnoAnyItem
* pModifyPasswordInfoItem
= pItemSet
->GetItem
<SfxUnoAnyItem
>(SID_MODIFYPASSWORDINFO
, false);
3104 if ( pModifyPasswordInfoItem
)
3106 // it contains either a simple hash or a set of PropertyValues
3107 // TODO/LATER: the sequence of PropertyValue should replace the hash completely in future
3108 sal_Int32 nMPHTmp
= 0;
3109 pModifyPasswordInfoItem
->GetValue() >>= nMPHTmp
;
3110 nModifyPasswordHash
= static_cast<sal_uInt32
>(nMPHTmp
);
3111 pModifyPasswordInfoItem
->GetValue() >>= aModifyPasswordInfo
;
3113 pItemSet
->ClearItem(SID_MODIFYPASSWORDINFO
);
3114 sal_uInt32 nOldModifyPasswordHash
= m_pData
->m_pObjectShell
->GetModifyPasswordHash();
3115 m_pData
->m_pObjectShell
->SetModifyPasswordHash( nModifyPasswordHash
);
3116 Sequence
< beans::PropertyValue
> aOldModifyPasswordInfo
= m_pData
->m_pObjectShell
->GetModifyPasswordInfo();
3117 m_pData
->m_pObjectShell
->SetModifyPasswordInfo( aModifyPasswordInfo
);
3119 // since saving a document modifies its DocumentProperties, the current
3120 // DocumentProperties must be saved on "SaveTo", so it can be restored
3122 bool bCopyTo
= bSaveTo
||
3123 m_pData
->m_pObjectShell
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
;
3124 Reference
<document::XDocumentProperties
> xOldDocProps
;
3127 xOldDocProps
= getDocumentProperties();
3128 const Reference
<util::XCloneable
> xCloneable(xOldDocProps
,
3130 const Reference
<document::XDocumentProperties
> xNewDocProps(
3131 xCloneable
->createClone(), UNO_QUERY_THROW
);
3132 m_pData
->m_xDocumentProperties
= xNewDocProps
;
3135 bool bRet
= m_pData
->m_pObjectShell
->APISaveAs_Impl(sURL
, *pItemSet
, seqArguments
);
3139 // restore DocumentProperties if a copy was created
3140 m_pData
->m_xDocumentProperties
= xOldDocProps
;
3143 Reference
< task::XInteractionHandler
> xHandler
;
3144 const SfxUnoAnyItem
* pItem
= pItemSet
->GetItem
<SfxUnoAnyItem
>(SID_INTERACTIONHANDLER
, false);
3146 pItem
->GetValue() >>= xHandler
;
3150 ErrCode nErrCode
= m_pData
->m_pObjectShell
->GetErrorCode();
3151 if ( !bRet
&& !nErrCode
)
3153 SAL_WARN("sfx.doc", "Storing has failed, no error is set!");
3154 nErrCode
= ERRCODE_IO_CANTWRITE
;
3156 m_pData
->m_pObjectShell
->ResetError();
3162 // must be a warning - use Interactionhandler if possible or abandon
3163 if ( xHandler
.is() )
3165 // TODO/LATER: a general way to set the error context should be available
3166 SfxErrorContext
aEc( ERRCTX_SFX_SAVEASDOC
, m_pData
->m_pObjectShell
->GetTitle() );
3168 task::ErrorCodeRequest aErrorCode
;
3169 aErrorCode
.ErrCode
= sal_uInt32(nErrCode
);
3170 SfxMedium::CallApproveHandler( xHandler
, makeAny( aErrorCode
), false );
3176 m_pData
->m_aPreusedFilterName
= GetMediumFilterName_Impl();
3177 m_pData
->m_pObjectShell
->SetModifyPasswordEntered();
3179 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveAsDocDone
, GlobalEventConfig::GetEventName(GlobalEventId::SAVEASDOCDONE
), m_pData
->m_pObjectShell
.get() ) );
3183 m_pData
->m_pObjectShell
->SetModifyPasswordHash( nOldModifyPasswordHash
);
3184 m_pData
->m_pObjectShell
->SetModifyPasswordInfo( aOldModifyPasswordInfo
);
3186 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveToDocDone
, GlobalEventConfig::GetEventName(GlobalEventId::SAVETODOCDONE
), m_pData
->m_pObjectShell
.get() ) );
3191 m_pData
->m_pObjectShell
->SetModifyPasswordHash( nOldModifyPasswordHash
);
3192 m_pData
->m_pObjectShell
->SetModifyPasswordInfo( aOldModifyPasswordInfo
);
3195 SfxGetpApp()->NotifyEvent( SfxEventHint( bSaveTo
? SfxEventHintId::SaveToDocFailed
: SfxEventHintId::SaveAsDocFailed
, GlobalEventConfig::GetEventName( bSaveTo
? GlobalEventId::SAVETODOCFAILED
: GlobalEventId::SAVEASDOCFAILED
),
3196 m_pData
->m_pObjectShell
.get() ) );
3198 std::stringstream aErrCode
;
3199 aErrCode
<< nErrCode
;
3200 throw task::ErrorCodeIOException(
3201 "SfxBaseModel::impl_store <" + sURL
+ "> failed: " + OUString::fromUtf8(aErrCode
.str().c_str()),
3202 Reference
< XInterface
>(), sal_uInt32(nErrCode
));
3208 template< typename ListenerT
, typename EventT
>
3209 class NotifySingleListenerIgnoreRE
3212 typedef void ( SAL_CALL
ListenerT::*NotificationMethod
)( const EventT
& );
3213 NotificationMethod m_pMethod
;
3214 const EventT
& m_rEvent
;
3216 NotifySingleListenerIgnoreRE( NotificationMethod method
, const EventT
& event
) : m_pMethod( method
), m_rEvent( event
) { }
3218 void operator()( const Reference
<ListenerT
>& listener
) const
3222 (listener
.get()->*m_pMethod
)( m_rEvent
);
3224 catch( RuntimeException
& )
3226 // this exception is ignored to avoid problems with invalid listeners, the listener should be probably thrown away in future
3230 } // anonymous namespace
3232 void SfxBaseModel::postEvent_Impl( const OUString
& aName
, const Reference
< frame::XController2
>& xController
, const Any
& supplement
)
3234 // object already disposed?
3235 if ( impl_isDisposed() )
3238 // keep m_pData alive, if notified target would dispose the document
3239 std::shared_ptr
<IMPL_SfxBaseModel_DataContainer
> xKeepAlive(m_pData
);
3241 // also make sure this object doesn't self-destruct while notifying
3242 rtl::Reference
<SfxBaseModel
> xHoldAlive(this);
3244 DBG_ASSERT( !aName
.isEmpty(), "Empty event name!" );
3245 if (aName
.isEmpty())
3248 comphelper::OInterfaceContainerHelper2
* pIC
=
3249 m_pData
->m_aInterfaceContainer
.getContainer( cppu::UnoType
<document::XDocumentEventListener
>::get());
3252 SAL_INFO("sfx.doc", "SfxDocumentEvent: " + aName
);
3254 document::DocumentEvent
aDocumentEvent( static_cast<frame::XModel
*>(this), aName
, xController
, supplement
);
3256 pIC
->forEach
< document::XDocumentEventListener
, NotifySingleListenerIgnoreRE
< document::XDocumentEventListener
, document::DocumentEvent
> >(
3257 NotifySingleListenerIgnoreRE
< document::XDocumentEventListener
, document::DocumentEvent
>(
3258 &document::XDocumentEventListener::documentEventOccured
,
3262 pIC
= m_pData
->m_aInterfaceContainer
.getContainer( cppu::UnoType
<document::XEventListener
>::get());
3265 SAL_INFO("sfx.doc", "SfxEvent: " + aName
);
3267 document::EventObject
aEvent( static_cast<frame::XModel
*>(this), aName
);
3269 pIC
->forEach
< document::XEventListener
, NotifySingleListenerIgnoreRE
< document::XEventListener
, document::EventObject
> >(
3270 NotifySingleListenerIgnoreRE
< document::XEventListener
, document::EventObject
>(
3271 &document::XEventListener::notifyEvent
,
3277 Reference
< container::XIndexAccess
> SAL_CALL
SfxBaseModel::getViewData()
3279 SfxModelGuard
aGuard( *this );
3281 if ( m_pData
->m_pObjectShell
.is() && !m_pData
->m_contViewData
.is() )
3283 SfxViewFrame
*pActFrame
= SfxViewFrame::Current();
3284 if ( !pActFrame
|| pActFrame
->GetObjectShell() != m_pData
->m_pObjectShell
.get() )
3285 pActFrame
= SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get() );
3287 if ( !pActFrame
|| !pActFrame
->GetViewShell() )
3288 // currently no frame for this document at all or View is under construction
3289 return Reference
< container::XIndexAccess
>();
3291 m_pData
->m_contViewData
= document::IndexedPropertyValues::create( ::comphelper::getProcessComponentContext() );
3293 if ( !m_pData
->m_contViewData
.is() )
3295 // error: no container class available!
3296 return Reference
< container::XIndexAccess
>();
3299 Reference
< container::XIndexContainer
> xCont( m_pData
->m_contViewData
, UNO_QUERY
);
3300 sal_Int32 nCount
= 0;
3301 Sequence
< beans::PropertyValue
> aSeq
;
3302 for ( SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get() ); pFrame
;
3303 pFrame
= SfxViewFrame::GetNext( *pFrame
, m_pData
->m_pObjectShell
.get() ) )
3305 bool bIsActive
= ( pFrame
== pActFrame
);
3306 pFrame
->GetViewShell()->WriteUserDataSequence( aSeq
);
3307 xCont
->insertByIndex( bIsActive
? 0 : nCount
, Any(aSeq
) );
3312 return m_pData
->m_contViewData
;
3315 void SAL_CALL
SfxBaseModel::setViewData( const Reference
< container::XIndexAccess
>& aData
)
3317 SfxModelGuard
aGuard( *this );
3319 m_pData
->m_contViewData
= aData
;
3322 /** calls all XEventListeners */
3323 void SfxBaseModel::notifyEvent( const document::EventObject
& aEvent
) const
3325 // object already disposed?
3326 if ( impl_isDisposed() )
3329 comphelper::OInterfaceContainerHelper2
* pIC
= m_pData
->m_aInterfaceContainer
.getContainer(
3330 cppu::UnoType
<document::XEventListener
>::get());
3335 comphelper::OInterfaceIteratorHelper2
aIt( *pIC
);
3336 while( aIt
.hasMoreElements() )
3340 static_cast<document::XEventListener
*>(aIt
.next())->notifyEvent( aEvent
);
3342 catch( RuntimeException
& )
3347 // for right now, we're only doing the event that this particular performance problem needed
3348 if (aEvent
.EventName
== "ShapeModified")
3350 uno::Reference
<drawing::XShape
> xShape(aEvent
.Source
, uno::UNO_QUERY
);
3353 auto it
= m_pData
->maShapeListeners
.find(xShape
);
3354 if (it
!= m_pData
->maShapeListeners
.end())
3355 for (auto const & rListenerUnoRef
: it
->second
)
3356 rListenerUnoRef
->notifyShapeEvent(aEvent
);
3361 /** returns true if someone added a XEventListener to this XEventBroadcaster */
3362 bool SfxBaseModel::hasEventListeners() const
3364 return !impl_isDisposed()
3365 && ( (nullptr != m_pData
->m_aInterfaceContainer
.getContainer( cppu::UnoType
<document::XEventListener
>::get()) )
3366 || !m_pData
->maShapeListeners
.empty());
3369 void SAL_CALL
SfxBaseModel::addPrintJobListener( const Reference
< view::XPrintJobListener
>& xListener
)
3371 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
3373 impl_getPrintHelper();
3374 Reference
< view::XPrintJobBroadcaster
> xPJB( m_pData
->m_xPrintable
, UNO_QUERY
);
3376 xPJB
->addPrintJobListener( xListener
);
3379 void SAL_CALL
SfxBaseModel::removePrintJobListener( const Reference
< view::XPrintJobListener
>& xListener
)
3381 SfxModelGuard
aGuard( *this );
3383 impl_getPrintHelper();
3384 Reference
< view::XPrintJobBroadcaster
> xPJB( m_pData
->m_xPrintable
, UNO_QUERY
);
3386 xPJB
->removePrintJobListener( xListener
);
3389 sal_Int64 SAL_CALL
SfxBaseModel::getSomething( const Sequence
< sal_Int8
>& aIdentifier
)
3391 SvGlobalName
aName( aIdentifier
);
3392 if (aName
== SvGlobalName( SFX_GLOBAL_CLASSID
))
3394 SolarMutexGuard aGuard
;
3395 SfxObjectShell
*const pObjectShell(GetObjectShell());
3398 return comphelper::getSomething_cast(pObjectShell
);
3406 // XDocumentSubStorageSupplier
3409 void SfxBaseModel::ListenForStorage_Impl( const Reference
< embed::XStorage
>& xStorage
)
3411 Reference
< util::XModifiable
> xModifiable( xStorage
, UNO_QUERY
);
3412 if ( xModifiable
.is() )
3414 if ( !m_pData
->m_pStorageModifyListen
.is() )
3416 m_pData
->m_pStorageModifyListen
= new ::sfx2::DocumentStorageModifyListener( *m_pData
, Application::GetSolarMutex() );
3419 // no need to deregister the listening for old storage since it should be disposed automatically
3420 xModifiable
->addModifyListener( m_pData
->m_pStorageModifyListen
);
3424 Reference
< embed::XStorage
> SAL_CALL
SfxBaseModel::getDocumentSubStorage( const OUString
& aStorageName
, sal_Int32 nMode
)
3426 SfxModelGuard
aGuard( *this );
3428 Reference
< embed::XStorage
> xResult
;
3429 if ( m_pData
->m_pObjectShell
.is() )
3431 Reference
< embed::XStorage
> xStorage
= m_pData
->m_pObjectShell
->GetStorage();
3432 if ( xStorage
.is() )
3436 xResult
= xStorage
->openStorageElement( aStorageName
, nMode
);
3438 catch ( Exception
& )
3447 Sequence
< OUString
> SAL_CALL
SfxBaseModel::getDocumentSubStoragesNames()
3449 SfxModelGuard
aGuard( *this );
3451 Sequence
< OUString
> aResult
;
3452 bool bSuccess
= false;
3453 if ( m_pData
->m_pObjectShell
.is() )
3455 Reference
< embed::XStorage
> xStorage
= m_pData
->m_pObjectShell
->GetStorage();
3456 if ( xStorage
.is() )
3458 const Sequence
< OUString
> aTemp
= xStorage
->getElementNames();
3459 sal_Int32 nResultSize
= 0;
3460 for ( const auto& rName
: aTemp
)
3462 if ( xStorage
->isStorageElement( rName
) )
3464 aResult
.realloc( ++nResultSize
);
3465 aResult
.getArray()[ nResultSize
- 1 ] = rName
;
3474 throw io::IOException();
3480 // XScriptProviderSupplier
3483 Reference
< script::provider::XScriptProvider
> SAL_CALL
SfxBaseModel::getScriptProvider()
3485 SfxModelGuard
aGuard( *this );
3487 Reference
< script::provider::XScriptProviderFactory
> xScriptProviderFactory
=
3488 script::provider::theMasterScriptProviderFactory::get( ::comphelper::getProcessComponentContext() );
3490 Reference
< XScriptInvocationContext
> xScriptContext( this );
3492 Reference
< script::provider::XScriptProvider
> xScriptProvider(
3493 xScriptProviderFactory
->createScriptProvider( makeAny( xScriptContext
) ),
3496 return xScriptProvider
;
3500 // XUIConfigurationManagerSupplier
3503 OUString
const & SfxBaseModel::getRuntimeUID() const
3505 OSL_ENSURE( !m_pData
->m_sRuntimeUID
.isEmpty(),
3506 "SfxBaseModel::getRuntimeUID - ID is empty!" );
3507 return m_pData
->m_sRuntimeUID
;
3510 bool SfxBaseModel::hasValidSignatures() const
3512 SolarMutexGuard aGuard
;
3513 if ( m_pData
->m_pObjectShell
.is() )
3514 return ( m_pData
->m_pObjectShell
->ImplGetSignatureState() == SignatureState::OK
);
3518 void SfxBaseModel::getGrabBagItem(css::uno::Any
& rVal
) const
3520 if (m_pData
->m_xGrabBagItem
)
3521 m_pData
->m_xGrabBagItem
->QueryValue(rVal
);
3523 rVal
<<= uno::Sequence
<beans::PropertyValue
>();
3526 void SfxBaseModel::setGrabBagItem(const css::uno::Any
& rVal
)
3528 if (!m_pData
->m_xGrabBagItem
)
3529 m_pData
->m_xGrabBagItem
= std::make_shared
<SfxGrabBagItem
>();
3531 m_pData
->m_xGrabBagItem
->PutValue(rVal
, 0);
3534 static void GetCommandFromSequence( OUString
& rCommand
, sal_Int32
& nIndex
, const Sequence
< beans::PropertyValue
>& rSeqPropValue
)
3538 auto pPropValue
= std::find_if(rSeqPropValue
.begin(), rSeqPropValue
.end(),
3539 [](const beans::PropertyValue
& rPropValue
) { return rPropValue
.Name
== "Command"; });
3540 if (pPropValue
!= rSeqPropValue
.end())
3542 pPropValue
->Value
>>= rCommand
;
3543 nIndex
= static_cast<sal_Int32
>(std::distance(rSeqPropValue
.begin(), pPropValue
));
3547 static void ConvertSlotsToCommands( SfxObjectShell
const * pDoc
, Reference
< container::XIndexContainer
> const & rToolbarDefinition
)
3552 SfxModule
* pModule( pDoc
->GetFactory().GetModule() );
3553 Sequence
< beans::PropertyValue
> aSeqPropValue
;
3555 for ( sal_Int32 i
= 0; i
< rToolbarDefinition
->getCount(); i
++ )
3557 if ( rToolbarDefinition
->getByIndex( i
) >>= aSeqPropValue
)
3560 sal_Int32
nIndex( -1 );
3561 GetCommandFromSequence( aCommand
, nIndex
, aSeqPropValue
);
3562 if ( nIndex
>= 0 && aCommand
.startsWith( "slot:" ) )
3564 const sal_uInt16 nSlot
= aCommand
.copy( 5 ).toInt32();
3566 // We have to replace the old "slot-Command" with our new ".uno:-Command"
3567 const SfxSlot
* pSlot
= pModule
->GetSlotPool()->GetSlot( nSlot
);
3570 OUStringBuffer
aStrBuf( ".uno:" );
3571 aStrBuf
.appendAscii( pSlot
->GetUnoName() );
3573 aCommand
= aStrBuf
.makeStringAndClear();
3574 aSeqPropValue
.getArray()[nIndex
].Value
<<= aCommand
;
3575 rToolbarDefinition
->replaceByIndex( i
, Any( aSeqPropValue
));
3582 Reference
< ui::XUIConfigurationManager
> SAL_CALL
SfxBaseModel::getUIConfigurationManager()
3584 return Reference
< ui::XUIConfigurationManager
>( getUIConfigurationManager2(), UNO_QUERY_THROW
);
3587 Reference
< ui::XUIConfigurationManager2
> SfxBaseModel::getUIConfigurationManager2()
3589 SfxModelGuard
aGuard( *this );
3591 if ( !m_pData
->m_xUIConfigurationManager
.is() )
3593 Reference
< ui::XUIConfigurationManager2
> xNewUIConfMan
=
3594 ui::UIConfigurationManager::create( comphelper::getProcessComponentContext() );
3596 Reference
< embed::XStorage
> xConfigStorage
;
3598 OUString
aUIConfigFolderName( "Configurations2" );
3599 // First try to open with READWRITE and then READ
3600 xConfigStorage
= getDocumentSubStorage( aUIConfigFolderName
, embed::ElementModes::READWRITE
);
3601 if ( xConfigStorage
.is() )
3603 static const OUStringLiteral
aMediaTypeProp( u
"MediaType" );
3604 OUString aMediaType
;
3605 Reference
< beans::XPropertySet
> xPropSet( xConfigStorage
, UNO_QUERY
);
3606 Any a
= xPropSet
->getPropertyValue( aMediaTypeProp
);
3607 if ( !( a
>>= aMediaType
) || aMediaType
.isEmpty())
3609 xPropSet
->setPropertyValue( aMediaTypeProp
, Any(OUString("application/vnd.sun.xml.ui.configuration")) );
3613 xConfigStorage
= getDocumentSubStorage( aUIConfigFolderName
, embed::ElementModes::READ
);
3615 // initialize ui configuration manager with document substorage
3616 xNewUIConfMan
->setStorage( xConfigStorage
);
3618 // embedded objects did not support local configuration data until OOo 3.0, so there's nothing to
3620 if ( m_pData
->m_pObjectShell
->GetCreateMode() != SfxObjectCreateMode::EMBEDDED
)
3622 // Import old UI configuration from OOo 1.x
3624 // Try to open with READ
3625 Reference
< embed::XStorage
> xOOo1ConfigStorage
= getDocumentSubStorage( "Configurations", embed::ElementModes::READ
);
3626 if ( xOOo1ConfigStorage
.is() )
3628 Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
3629 std::vector
< Reference
< container::XIndexContainer
> > rToolbars
;
3631 bool bImported
= framework::UIConfigurationImporterOOo1x::ImportCustomToolbars(
3632 xNewUIConfMan
, rToolbars
, xContext
, xOOo1ConfigStorage
);
3635 SfxObjectShell
* pObjShell
= SfxBaseModel::GetObjectShell();
3637 for ( size_t i
= 0; i
< rToolbars
.size(); i
++ )
3639 const OUString
sId(OUString::number( i
+ 1 ));
3640 const OUString aCustomTbxName
= "private:resource/toolbar/custom_OOo1x_" + sId
;
3642 Reference
< container::XIndexContainer
> xToolbar
= rToolbars
[i
];
3643 ConvertSlotsToCommands( pObjShell
, xToolbar
);
3644 if ( !xNewUIConfMan
->hasSettings( aCustomTbxName
))
3646 // Set UIName for the toolbar with container property
3647 Reference
< beans::XPropertySet
> xPropSet( xToolbar
, UNO_QUERY
);
3648 if ( xPropSet
.is() )
3652 xPropSet
->setPropertyValue( "UIName", Any( "Toolbar " + sId
) );
3654 catch ( beans::UnknownPropertyException
& )
3659 xNewUIConfMan
->insertSettings( aCustomTbxName
, xToolbar
);
3660 xNewUIConfMan
->store();
3667 m_pData
->m_xUIConfigurationManager
= xNewUIConfMan
;
3670 return m_pData
->m_xUIConfigurationManager
;
3677 void SAL_CALL
SfxBaseModel::setVisualAreaSize( sal_Int64 nAspect
, const awt::Size
& aSize
)
3679 SfxModelGuard
aGuard( *this );
3681 if ( !m_pData
->m_pObjectShell
.is() )
3682 throw Exception("no object shell", nullptr); // TODO: error handling
3684 SfxViewFrame
* pViewFrm
= SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get(), false );
3685 if ( pViewFrm
&& m_pData
->m_pObjectShell
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
&& !pViewFrm
->GetFrame().IsInPlace() )
3687 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow( pViewFrm
->GetFrame().GetFrameInterface()->getContainerWindow() );
3688 Size aWinSize
= pWindow
->GetSizePixel();
3689 awt::Size aCurrent
= getVisualAreaSize( nAspect
);
3690 Size
aDiff( aSize
.Width
-aCurrent
.Width
, aSize
.Height
-aCurrent
.Height
);
3691 aDiff
= pViewFrm
->GetViewShell()->GetWindow()->LogicToPixel( aDiff
);
3692 aWinSize
.AdjustWidth(aDiff
.Width() );
3693 aWinSize
.AdjustHeight(aDiff
.Height() );
3694 pWindow
->SetSizePixel( aWinSize
);
3698 tools::Rectangle aTmpRect
= m_pData
->m_pObjectShell
->GetVisArea( ASPECT_CONTENT
);
3699 aTmpRect
.SetSize( Size( aSize
.Width
, aSize
.Height
) );
3700 m_pData
->m_pObjectShell
->SetVisArea( aTmpRect
);
3704 awt::Size SAL_CALL
SfxBaseModel::getVisualAreaSize( sal_Int64
/*nAspect*/ )
3706 SfxModelGuard
aGuard( *this );
3708 if ( !m_pData
->m_pObjectShell
.is() )
3709 throw Exception("no object shell", nullptr); // TODO: error handling
3711 tools::Rectangle aTmpRect
= m_pData
->m_pObjectShell
->GetVisArea( ASPECT_CONTENT
);
3713 return awt::Size( aTmpRect
.GetWidth(), aTmpRect
.GetHeight() );
3717 sal_Int32 SAL_CALL
SfxBaseModel::getMapUnit( sal_Int64
/*nAspect*/ )
3719 SfxModelGuard
aGuard( *this );
3721 if ( !m_pData
->m_pObjectShell
.is() )
3722 throw Exception("no object shell", nullptr); // TODO: error handling
3724 return VCLUnoHelper::VCL2UnoEmbedMapUnit( m_pData
->m_pObjectShell
->GetMapUnit() );
3727 embed::VisualRepresentation SAL_CALL
SfxBaseModel::getPreferredVisualRepresentation( ::sal_Int64
/*nAspect*/ )
3729 SfxModelGuard
aGuard( *this );
3731 datatransfer::DataFlavor
aDataFlavor(
3732 "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"",
3734 cppu::UnoType
<Sequence
< sal_Int8
>>::get() );
3736 embed::VisualRepresentation aVisualRepresentation
;
3737 aVisualRepresentation
.Data
= getTransferData( aDataFlavor
);
3738 aVisualRepresentation
.Flavor
= aDataFlavor
;
3740 return aVisualRepresentation
;
3744 // XStorageBasedDocument
3747 void SAL_CALL
SfxBaseModel::loadFromStorage( const Reference
< embed::XStorage
>& xStorage
,
3748 const Sequence
< beans::PropertyValue
>& aMediaDescriptor
)
3750 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
3751 if ( IsInitialized() )
3752 throw frame::DoubleInitializationException( OUString(), *this );
3754 // after i36090 is fixed the pool from object shell can be used
3755 // SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() );
3756 SfxAllItemSet
aSet( SfxGetpApp()->GetPool() );
3758 // the BaseURL is part of the ItemSet
3759 SfxMedium
* pMedium
= new SfxMedium( xStorage
, OUString() );
3760 TransformParameters( SID_OPENDOC
, aMediaDescriptor
, aSet
);
3761 pMedium
->GetItemSet()->Put( aSet
);
3763 // allow to use an interactionhandler (if there is one)
3764 pMedium
->UseInteractionHandler( true );
3766 const SfxBoolItem
* pTemplateItem
= aSet
.GetItem
<SfxBoolItem
>(SID_TEMPLATE
, false);
3767 bool bTemplate
= pTemplateItem
&& pTemplateItem
->GetValue();
3768 m_pData
->m_pObjectShell
->SetActivateEvent_Impl( bTemplate
? SfxEventHintId::CreateDoc
: SfxEventHintId::OpenDoc
);
3769 m_pData
->m_pObjectShell
->Get_Impl()->bOwnsStorage
= false;
3772 if ( !m_pData
->m_pObjectShell
->DoLoad(pMedium
) )
3774 ErrCode nError
= m_pData
->m_pObjectShell
->GetErrorCode();
3775 nError
= nError
? nError
: ERRCODE_IO_CANTREAD
;
3776 throw task::ErrorCodeIOException(
3777 "SfxBaseModel::loadFromStorage: " + nError
.toHexString(),
3778 Reference
< XInterface
>(), sal_uInt32(nError
));
3780 loadCmisProperties( );
3783 void SAL_CALL
SfxBaseModel::storeToStorage( const Reference
< embed::XStorage
>& xStorage
,
3784 const Sequence
< beans::PropertyValue
>& aMediaDescriptor
)
3786 SfxModelGuard
aGuard( *this );
3788 if ( !m_pData
->m_pObjectShell
.is() )
3789 throw io::IOException(); // TODO:
3791 auto xSet
= std::make_shared
<SfxAllItemSet
>(m_pData
->m_pObjectShell
->GetPool());
3792 TransformParameters( SID_SAVEASDOC
, aMediaDescriptor
, *xSet
);
3794 // TODO/LATER: maybe a special URL "private:storage" should be used
3795 const SfxStringItem
* pItem
= xSet
->GetItem
<SfxStringItem
>(SID_FILTER_NAME
, false);
3796 sal_Int32 nVersion
= SOFFICE_FILEFORMAT_CURRENT
;
3799 std::shared_ptr
<const SfxFilter
> pFilter
= SfxGetpApp()->GetFilterMatcher().GetFilter4FilterName( pItem
->GetValue() );
3800 if ( pFilter
&& pFilter
->UsesStorage() )
3801 nVersion
= pFilter
->GetVersion();
3804 bool bSuccess
= false;
3805 if ( xStorage
== m_pData
->m_pObjectShell
->GetStorage() )
3807 // storing to the own storage
3808 bSuccess
= m_pData
->m_pObjectShell
->DoSave();
3812 // TODO/LATER: if the provided storage has some data inside the storing might fail, probably the storage must be truncated
3813 // TODO/LATER: is it possible to have a template here?
3814 m_pData
->m_pObjectShell
->SetupStorage( xStorage
, nVersion
, false );
3816 // BaseURL is part of the ItemSet
3817 SfxMedium
aMedium( xStorage
, OUString(), xSet
);
3818 aMedium
.CanDisposeStorage_Impl( false );
3819 if ( aMedium
.GetFilter() )
3821 // storing without a valid filter will often crash
3822 bSuccess
= m_pData
->m_pObjectShell
->DoSaveObjectAs( aMedium
, true );
3823 m_pData
->m_pObjectShell
->DoSaveCompleted();
3827 ErrCode nError
= m_pData
->m_pObjectShell
->GetErrorCode();
3828 m_pData
->m_pObjectShell
->ResetError();
3830 // the warnings are currently not transported
3833 nError
= nError
? nError
: ERRCODE_IO_GENERAL
;
3834 throw task::ErrorCodeIOException(
3835 "SfxBaseModel::storeToStorage: " + nError
.toHexString(),
3836 Reference
< XInterface
>(), sal_uInt32(nError
));
3840 void SAL_CALL
SfxBaseModel::switchToStorage( const Reference
< embed::XStorage
>& xStorage
)
3842 SfxModelGuard
aGuard( *this );
3844 if ( !m_pData
->m_pObjectShell
.is() )
3845 throw io::IOException(); // TODO:
3847 // the persistence should be switched only if the storage is different
3848 if ( xStorage
!= m_pData
->m_pObjectShell
->GetStorage() )
3850 if ( !m_pData
->m_pObjectShell
->SwitchPersistence( xStorage
) )
3852 ErrCode nError
= m_pData
->m_pObjectShell
->GetErrorCode();
3853 nError
= nError
? nError
: ERRCODE_IO_GENERAL
;
3854 throw task::ErrorCodeIOException(
3855 "SfxBaseModel::switchToStorage: " + nError
.toHexString(),
3856 Reference
< XInterface
>(), sal_uInt32(nError
));
3860 // UICfgMgr has a reference to the old storage, update it
3861 getUIConfigurationManager2()->setStorage( xStorage
);
3864 m_pData
->m_pObjectShell
->Get_Impl()->bOwnsStorage
= false;
3867 Reference
< embed::XStorage
> SAL_CALL
SfxBaseModel::getDocumentStorage()
3869 SfxModelGuard
aGuard( *this );
3871 if ( !m_pData
->m_pObjectShell
.is() )
3872 throw io::IOException(); // TODO
3874 return m_pData
->m_pObjectShell
->GetStorage();
3877 void SAL_CALL
SfxBaseModel::addStorageChangeListener(
3878 const Reference
< document::XStorageChangeListener
>& xListener
)
3880 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
3882 m_pData
->m_aInterfaceContainer
.addInterface(
3883 cppu::UnoType
<document::XStorageChangeListener
>::get(), xListener
);
3886 void SAL_CALL
SfxBaseModel::removeStorageChangeListener(
3887 const Reference
< document::XStorageChangeListener
>& xListener
)
3889 SfxModelGuard
aGuard( *this );
3891 m_pData
->m_aInterfaceContainer
.removeInterface(
3892 cppu::UnoType
<document::XStorageChangeListener
>::get(), xListener
);
3895 void SfxBaseModel::impl_getPrintHelper()
3897 if ( m_pData
->m_xPrintable
.is() )
3899 m_pData
->m_xPrintable
= new SfxPrintHelper();
3900 Reference
< lang::XInitialization
> xInit( m_pData
->m_xPrintable
, UNO_QUERY
);
3901 xInit
->initialize( { Any(Reference
< frame::XModel
> (this)) } );
3902 Reference
< view::XPrintJobBroadcaster
> xBrd( m_pData
->m_xPrintable
, UNO_QUERY
);
3903 xBrd
->addPrintJobListener( new SfxPrintHelperListener_Impl( m_pData
.get() ) );
3907 // css.frame.XModule
3908 void SAL_CALL
SfxBaseModel::setIdentifier(const OUString
& Identifier
)
3910 SfxModelGuard
aGuard( *this );
3911 m_pData
->m_sModuleIdentifier
= Identifier
;
3915 // css.frame.XModule
3916 OUString SAL_CALL
SfxBaseModel::getIdentifier()
3918 SfxModelGuard
aGuard( *this );
3919 if (!m_pData
->m_sModuleIdentifier
.isEmpty())
3920 return m_pData
->m_sModuleIdentifier
;
3921 if (m_pData
->m_pObjectShell
.is())
3922 return m_pData
->m_pObjectShell
->GetFactory().GetDocumentServiceName();
3927 Reference
< frame::XTitle
> SfxBaseModel::impl_getTitleHelper ()
3929 SfxModelGuard
aGuard( *this );
3931 if ( ! m_pData
->m_xTitleHelper
.is ())
3933 Reference
< XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
3934 Reference
< frame::XUntitledNumbers
> xDesktop( frame::Desktop::create(xContext
), UNO_QUERY_THROW
);
3936 m_pData
->m_xTitleHelper
= new ::framework::TitleHelper(xContext
, Reference
< frame::XModel
>(this), xDesktop
);
3939 return m_pData
->m_xTitleHelper
;
3943 Reference
< frame::XUntitledNumbers
> SfxBaseModel::impl_getUntitledHelper ()
3945 SfxModelGuard
aGuard( *this );
3947 if ( ! m_pData
->m_xNumberedControllers
.is ())
3949 rtl::Reference
<::comphelper::NumberedCollection
> pHelper
= new ::comphelper::NumberedCollection();
3950 m_pData
->m_xNumberedControllers
= pHelper
;
3951 pHelper
->setOwner (Reference
< frame::XModel
>(this));
3952 pHelper
->setUntitledPrefix (" : ");
3955 return m_pData
->m_xNumberedControllers
;
3960 OUString SAL_CALL
SfxBaseModel::getTitle()
3963 SfxModelGuard
aGuard( *this );
3965 OUString aResult
= impl_getTitleHelper()->getTitle ();
3966 if ( !m_pData
->m_bExternalTitle
&& m_pData
->m_pObjectShell
)
3968 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
3972 ::ucbhelper::Content
aContent( pMedium
->GetName(),
3973 utl::UCBContentHelper::getDefaultCommandEnvironment(),
3974 comphelper::getProcessComponentContext() );
3975 const Reference
< beans::XPropertySetInfo
> xProps
3976 = aContent
.getProperties();
3979 static const OUStringLiteral
aServerTitle( u
"TitleOnServer" );
3980 if ( xProps
->hasPropertyByName( aServerTitle
) )
3982 Any aAny
= aContent
.getPropertyValue( aServerTitle
);
3987 catch (const ucb::ContentCreationException
&)
3990 catch (const ucb::CommandAbortedException
&)
3993 const SfxBoolItem
* pRepairedDocItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_REPAIRPACKAGE
, false);
3994 if ( pRepairedDocItem
&& pRepairedDocItem
->GetValue() )
3995 aResult
+= SfxResId(STR_REPAIREDDOCUMENT
);
3998 if ( m_pData
->m_pObjectShell
->IsReadOnlyUI() || (pMedium
&& pMedium
->IsReadOnly()) )
3999 aResult
+= SfxResId(STR_READONLY
);
4000 else if ( m_pData
->m_pObjectShell
->IsDocShared() )
4001 aResult
+= SfxResId(STR_SHARED
);
4003 if ( m_pData
->m_pObjectShell
->GetDocumentSignatureState() == SignatureState::OK
)
4004 aResult
+= SfxResId(RID_XMLSEC_DOCUMENTSIGNED
);
4012 void SAL_CALL
SfxBaseModel::setTitle( const OUString
& sTitle
)
4015 SfxModelGuard
aGuard( *this );
4017 impl_getTitleHelper()->setTitle (sTitle
);
4018 m_pData
->m_bExternalTitle
= true;
4022 // css.frame.XTitleChangeBroadcaster
4023 void SAL_CALL
SfxBaseModel::addTitleChangeListener( const Reference
< frame::XTitleChangeListener
>& xListener
)
4026 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
4028 Reference
< frame::XTitleChangeBroadcaster
> xBroadcaster(impl_getTitleHelper(), UNO_QUERY
);
4029 if (xBroadcaster
.is ())
4030 xBroadcaster
->addTitleChangeListener (xListener
);
4034 // css.frame.XTitleChangeBroadcaster
4035 void SAL_CALL
SfxBaseModel::removeTitleChangeListener( const Reference
< frame::XTitleChangeListener
>& xListener
)
4038 SfxModelGuard
aGuard( *this );
4040 Reference
< frame::XTitleChangeBroadcaster
> xBroadcaster(impl_getTitleHelper(), UNO_QUERY
);
4041 if (xBroadcaster
.is ())
4042 xBroadcaster
->removeTitleChangeListener (xListener
);
4046 // css.frame.XUntitledNumbers
4047 ::sal_Int32 SAL_CALL
SfxBaseModel::leaseNumber( const Reference
< XInterface
>& xComponent
)
4049 SfxModelGuard
aGuard( *this );
4051 return impl_getUntitledHelper ()->leaseNumber (xComponent
);
4055 // css.frame.XUntitledNumbers
4056 void SAL_CALL
SfxBaseModel::releaseNumber( ::sal_Int32 nNumber
)
4058 SfxModelGuard
aGuard( *this );
4059 impl_getUntitledHelper ()->releaseNumber (nNumber
);
4063 // css.frame.XUntitledNumbers
4064 void SAL_CALL
SfxBaseModel::releaseNumberForComponent( const Reference
< XInterface
>& xComponent
)
4066 SfxModelGuard
aGuard( *this );
4067 impl_getUntitledHelper ()->releaseNumberForComponent (xComponent
);
4071 // css.frame.XUntitledNumbers
4072 OUString SAL_CALL
SfxBaseModel::getUntitledPrefix()
4074 SfxModelGuard
aGuard( *this );
4075 return impl_getUntitledHelper ()->getUntitledPrefix ();
4080 Reference
< container::XEnumeration
> SAL_CALL
SfxBaseModel::getControllers()
4082 SfxModelGuard
aGuard( *this );
4084 sal_Int32 c
= m_pData
->m_seqControllers
.size();
4085 Sequence
< Any
> lEnum(c
);
4086 std::transform(m_pData
->m_seqControllers
.begin(), m_pData
->m_seqControllers
.end(),
4087 lEnum
.getArray(), [](const auto& x
) { return css::uno::makeAny(x
); });
4089 return new ::comphelper::OAnyEnumeration(lEnum
);
4094 Sequence
< OUString
> SAL_CALL
SfxBaseModel::getAvailableViewControllerNames()
4096 SfxModelGuard
aGuard( *this );
4098 const SfxObjectFactory
& rDocumentFactory
= GetObjectShell()->GetFactory();
4099 const sal_Int16 nViewFactoryCount
= rDocumentFactory
.GetViewFactoryCount();
4101 Sequence
< OUString
> aViewNames( nViewFactoryCount
);
4102 auto aViewNamesRange
= asNonConstRange(aViewNames
);
4103 for ( sal_Int16 nViewNo
= 0; nViewNo
< nViewFactoryCount
; ++nViewNo
)
4104 aViewNamesRange
[nViewNo
] = rDocumentFactory
.GetViewFactory( nViewNo
).GetAPIViewName();
4110 Reference
< frame::XController2
> SAL_CALL
SfxBaseModel::createDefaultViewController( const Reference
< frame::XFrame
>& i_rFrame
)
4112 SfxModelGuard
aGuard( *this );
4114 const SfxObjectFactory
& rDocumentFactory
= GetObjectShell()->GetFactory();
4115 const OUString sDefaultViewName
= rDocumentFactory
.GetViewFactory().GetAPIViewName();
4119 return createViewController( sDefaultViewName
, Sequence
< PropertyValue
>(), i_rFrame
);
4123 namespace sfx::intern
{
4125 /** a class which, in its dtor, cleans up various objects (well, at the moment only the frame) collected during
4126 the creation of a document view, unless the creation was successful.
4128 class ViewCreationGuard
4132 :m_bSuccess( false )
4136 ~ViewCreationGuard()
4138 if ( !m_bSuccess
&& m_aWeakFrame
&& !m_aWeakFrame
->GetCurrentDocument() )
4140 m_aWeakFrame
->SetFrameInterface_Impl( nullptr );
4141 m_aWeakFrame
->DoClose();
4145 void takeFrameOwnership( SfxFrame
* i_pFrame
)
4147 OSL_PRECOND( !m_aWeakFrame
, "ViewCreationGuard::takeFrameOwnership: already have a frame!" );
4148 OSL_PRECOND( i_pFrame
!= nullptr, "ViewCreationGuard::takeFrameOwnership: invalid frame!" );
4149 m_aWeakFrame
= i_pFrame
;
4159 SfxFrameWeakRef m_aWeakFrame
;
4164 SfxViewFrame
* SfxBaseModel::FindOrCreateViewFrame_Impl( const Reference
< XFrame
>& i_rFrame
, ::sfx::intern::ViewCreationGuard
& i_rGuard
) const
4166 SfxViewFrame
* pViewFrame
= nullptr;
4167 for ( pViewFrame
= SfxViewFrame::GetFirst( GetObjectShell(), false );
4169 pViewFrame
= SfxViewFrame::GetNext( *pViewFrame
, GetObjectShell(), false )
4172 if ( pViewFrame
->GetFrame().GetFrameInterface() == i_rFrame
)
4177 #if OSL_DEBUG_LEVEL > 0
4178 for ( SfxFrame
* pCheckFrame
= SfxFrame::GetFirst();
4180 pCheckFrame
= SfxFrame::GetNext( *pCheckFrame
)
4183 if ( pCheckFrame
->GetFrameInterface() == i_rFrame
)
4185 if ( ( pCheckFrame
->GetCurrentViewFrame() != nullptr )
4186 || ( pCheckFrame
->GetCurrentDocument() != nullptr )
4188 // Note that it is perfectly legitimate that during loading into an XFrame which already contains
4189 // a document, there exist two SfxFrame instances bound to this XFrame - the old one, which will be
4190 // destroyed later, and the new one, which we're going to create
4193 OSL_FAIL( "SfxBaseModel::FindOrCreateViewFrame_Impl: there already is an SfxFrame for the given XFrame, but no view in it!" );
4194 // nowadays, we're the only instance allowed to create an SfxFrame for an XFrame, so this case here should not happen
4200 SfxFrame
* pTargetFrame
= SfxFrame::Create( i_rFrame
);
4201 ENSURE_OR_THROW( pTargetFrame
, "could not create an SfxFrame" );
4202 i_rGuard
.takeFrameOwnership( pTargetFrame
);
4205 pTargetFrame
->PrepareForDoc_Impl( *GetObjectShell() );
4207 // create view frame
4208 pViewFrame
= new SfxViewFrame( *pTargetFrame
, GetObjectShell() );
4215 Reference
< frame::XController2
> SAL_CALL
SfxBaseModel::createViewController(
4216 const OUString
& i_rViewName
, const Sequence
< PropertyValue
>& i_rArguments
, const Reference
< XFrame
>& i_rFrame
)
4218 SfxModelGuard
aGuard( *this );
4220 if ( !i_rFrame
.is() )
4221 throw lang::IllegalArgumentException( OUString(), *this, 3 );
4223 // find the proper SFX view factory
4224 SfxViewFactory
* pViewFactory
= GetObjectShell()->GetFactory().GetViewFactoryByViewName( i_rViewName
);
4225 if ( !pViewFactory
)
4226 throw IllegalArgumentException( OUString(), *this, 1 );
4228 // determine previous shell (used in some special cases)
4229 Reference
< XController
> xPreviousController( i_rFrame
->getController() );
4230 const Reference
< XModel
> xMe( this );
4231 if ( ( xPreviousController
.is() )
4232 && ( xMe
!= xPreviousController
->getModel() )
4235 xPreviousController
.clear();
4237 SfxViewShell
* pOldViewShell
= SfxViewShell::Get( xPreviousController
);
4238 OSL_ENSURE( !xPreviousController
.is() || ( pOldViewShell
!= nullptr ),
4239 "SfxBaseModel::createViewController: invalid old controller!" );
4241 // a guard which will clean up in case of failure
4242 ::sfx::intern::ViewCreationGuard aViewCreationGuard
;
4244 // determine the ViewFrame belonging to the given XFrame
4245 SfxViewFrame
* pViewFrame
= FindOrCreateViewFrame_Impl( i_rFrame
, aViewCreationGuard
);
4246 SAL_WARN_IF( !pViewFrame
, "sfx.doc", "SfxBaseModel::createViewController: no frame?" );
4248 // delegate to SFX' view factory
4249 pViewFrame
->GetBindings().ENTERREGISTRATIONS();
4250 SfxViewShell
* pViewShell
= pViewFactory
->CreateInstance( pViewFrame
, pOldViewShell
);
4251 pViewFrame
->GetBindings().LEAVEREGISTRATIONS();
4252 ENSURE_OR_THROW( pViewShell
, "invalid view shell provided by factory" );
4254 // by setting the ViewShell it is prevented that disposing the Controller will destroy this ViewFrame also
4255 pViewFrame
->GetDispatcher()->SetDisableFlags( SfxDisableFlags::NONE
);
4256 pViewFrame
->SetViewShell_Impl( pViewShell
);
4259 pViewFrame
->SetCurViewId_Impl( pViewFactory
->GetOrdinal() );
4261 // ensure a default controller, if the view shell did not provide an own implementation
4262 if ( !pViewShell
->GetController().is() )
4263 pViewShell
->SetController( new SfxBaseController( pViewShell
) );
4265 // pass the creation arguments to the controller
4266 SfxBaseController
* pBaseController
= pViewShell
->GetBaseController_Impl();
4267 ENSURE_OR_THROW( pBaseController
, "invalid controller implementation!" );
4268 pBaseController
->SetCreationArguments_Impl( i_rArguments
);
4270 // some initial view settings, coming from our most recent attachResource call
4271 ::comphelper::NamedValueCollection
aDocumentLoadArgs( getArgs2( { "ViewOnly", "PluginMode" } ) );
4272 if ( aDocumentLoadArgs
.getOrDefault( "ViewOnly", false ) )
4273 pViewFrame
->GetFrame().SetMenuBarOn_Impl( false );
4275 const sal_Int16 nPluginMode
= aDocumentLoadArgs
.getOrDefault( "PluginMode", sal_Int16( 0 ) );
4276 if ( nPluginMode
== 1 )
4278 pViewFrame
->ForceOuterResize_Impl();
4279 pViewFrame
->GetBindings().HidePopups();
4281 SfxFrame
& rFrame
= pViewFrame
->GetFrame();
4282 // MBA: layoutmanager of inplace frame starts locked and invisible
4283 rFrame
.GetWorkWindow_Impl()->MakeVisible_Impl( false );
4284 rFrame
.GetWorkWindow_Impl()->Lock_Impl( true );
4286 rFrame
.GetWindow().SetBorderStyle( WindowBorderStyle::NOBORDER
);
4287 pViewFrame
->GetWindow().SetBorderStyle( WindowBorderStyle::NOBORDER
);
4290 // tell the guard we were successful
4291 aViewCreationGuard
.releaseAll();
4294 return pBaseController
;
4298 // RDF DocumentMetadataAccess
4300 // rdf::XRepositorySupplier:
4301 Reference
< rdf::XRepository
> SAL_CALL
4302 SfxBaseModel::getRDFRepository()
4304 SfxModelGuard
aGuard( *this );
4306 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4308 throw RuntimeException( "model has no document metadata", *this );
4311 return xDMA
->getRDFRepository();
4316 SfxBaseModel::getStringValue()
4318 SfxModelGuard
aGuard( *this );
4320 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4322 throw RuntimeException( "model has no document metadata", *this );
4325 return xDMA
->getStringValue();
4330 SfxBaseModel::getNamespace()
4332 SfxModelGuard
aGuard( *this );
4334 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4336 throw RuntimeException( "model has no document metadata", *this );
4339 return xDMA
->getNamespace();
4343 SfxBaseModel::getLocalName()
4345 SfxModelGuard
aGuard( *this );
4347 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4349 throw RuntimeException( "model has no document metadata", *this );
4352 return xDMA
->getLocalName();
4355 // rdf::XDocumentMetadataAccess:
4356 Reference
< rdf::XMetadatable
> SAL_CALL
4357 SfxBaseModel::getElementByMetadataReference(
4358 const beans::StringPair
& i_rReference
)
4360 SfxModelGuard
aGuard( *this );
4362 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4364 throw RuntimeException( "model has no document metadata", *this );
4367 return xDMA
->getElementByMetadataReference(i_rReference
);
4370 Reference
< rdf::XMetadatable
> SAL_CALL
4371 SfxBaseModel::getElementByURI(const Reference
< rdf::XURI
> & i_xURI
)
4373 SfxModelGuard
aGuard( *this );
4375 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4377 throw RuntimeException( "model has no document metadata", *this );
4380 return xDMA
->getElementByURI(i_xURI
);
4383 Sequence
< Reference
< rdf::XURI
> > SAL_CALL
4384 SfxBaseModel::getMetadataGraphsWithType(
4385 const Reference
<rdf::XURI
> & i_xType
)
4387 SfxModelGuard
aGuard( *this );
4389 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4391 throw RuntimeException( "model has no document metadata", *this );
4394 return xDMA
->getMetadataGraphsWithType(i_xType
);
4397 Reference
<rdf::XURI
> SAL_CALL
4398 SfxBaseModel::addMetadataFile(const OUString
& i_rFileName
,
4399 const Sequence
< Reference
< rdf::XURI
> > & i_rTypes
)
4401 SfxModelGuard
aGuard( *this );
4403 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4405 throw RuntimeException( "model has no document metadata", *this );
4408 return xDMA
->addMetadataFile(i_rFileName
, i_rTypes
);
4411 Reference
<rdf::XURI
> SAL_CALL
4412 SfxBaseModel::importMetadataFile(::sal_Int16 i_Format
,
4413 const Reference
< io::XInputStream
> & i_xInStream
,
4414 const OUString
& i_rFileName
,
4415 const Reference
< rdf::XURI
> & i_xBaseURI
,
4416 const Sequence
< Reference
< rdf::XURI
> > & i_rTypes
)
4418 SfxModelGuard
aGuard( *this );
4420 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4422 throw RuntimeException( "model has no document metadata", *this );
4425 return xDMA
->importMetadataFile(i_Format
,
4426 i_xInStream
, i_rFileName
, i_xBaseURI
, i_rTypes
);
4430 SfxBaseModel::removeMetadataFile(
4431 const Reference
< rdf::XURI
> & i_xGraphName
)
4433 SfxModelGuard
aGuard( *this );
4435 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4437 throw RuntimeException( "model has no document metadata", *this );
4440 return xDMA
->removeMetadataFile(i_xGraphName
);
4444 SfxBaseModel::addContentOrStylesFile(const OUString
& i_rFileName
)
4446 SfxModelGuard
aGuard( *this );
4448 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4450 throw RuntimeException( "model has no document metadata", *this );
4453 return xDMA
->addContentOrStylesFile(i_rFileName
);
4457 SfxBaseModel::removeContentOrStylesFile(const OUString
& i_rFileName
)
4459 SfxModelGuard
aGuard( *this );
4461 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4463 throw RuntimeException( "model has no document metadata", *this );
4466 return xDMA
->removeContentOrStylesFile(i_rFileName
);
4470 SfxBaseModel::loadMetadataFromStorage(
4471 Reference
< embed::XStorage
> const & i_xStorage
,
4472 Reference
<rdf::XURI
> const & i_xBaseURI
,
4473 Reference
<task::XInteractionHandler
> const & i_xHandler
)
4475 SfxModelGuard
aGuard( *this );
4477 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(
4478 m_pData
->CreateDMAUninitialized());
4480 throw RuntimeException( "model has no document metadata", *this );
4484 xDMA
->loadMetadataFromStorage(i_xStorage
, i_xBaseURI
, i_xHandler
);
4485 } catch (lang::IllegalArgumentException
&) {
4486 throw; // not initialized
4487 } catch (Exception
&) {
4488 // UGLY: if it's a RuntimeException, we can't be sure DMA is initialized
4489 m_pData
->m_xDocumentMetadata
= xDMA
;
4492 m_pData
->m_xDocumentMetadata
= xDMA
;
4497 SfxBaseModel::storeMetadataToStorage(
4498 Reference
< embed::XStorage
> const & i_xStorage
)
4500 SfxModelGuard
aGuard( *this );
4502 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4504 throw RuntimeException( "model has no document metadata", *this );
4507 return xDMA
->storeMetadataToStorage(i_xStorage
);
4511 SfxBaseModel::loadMetadataFromMedium(
4512 const Sequence
< beans::PropertyValue
> & i_rMedium
)
4514 SfxModelGuard
aGuard( *this );
4516 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(
4517 m_pData
->CreateDMAUninitialized());
4519 throw RuntimeException( "model has no document metadata", *this );
4523 xDMA
->loadMetadataFromMedium(i_rMedium
);
4524 } catch (lang::IllegalArgumentException
&) {
4525 throw; // not initialized
4526 } catch (Exception
&) {
4527 // UGLY: if it's a RuntimeException, we can't be sure DMA is initialized
4528 m_pData
->m_xDocumentMetadata
= xDMA
;
4531 m_pData
->m_xDocumentMetadata
= xDMA
;
4535 SfxBaseModel::storeMetadataToMedium(
4536 const Sequence
< beans::PropertyValue
> & i_rMedium
)
4538 SfxModelGuard
aGuard( *this );
4540 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4542 throw RuntimeException( "model has no document metadata", *this );
4545 return xDMA
->storeMetadataToMedium(i_rMedium
);
4549 // = SfxModelSubComponent
4552 SfxModelSubComponent::~SfxModelSubComponent()
4556 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */