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 .
21 #include <config_features.h>
23 #include <sfx2/sfxbasemodel.hxx>
25 #include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
26 #include <com/sun/star/task/XInteractionHandler.hpp>
27 #include <com/sun/star/task/ErrorCodeIOException.hpp>
28 #include <com/sun/star/task/ErrorCodeRequest.hpp>
29 #include <com/sun/star/view/XSelectionSupplier.hpp>
30 #include <com/sun/star/view/XPrintJobListener.hpp>
31 #include <com/sun/star/lang/DisposedException.hpp>
32 #include <com/sun/star/lang/IllegalArgumentException.hpp>
33 #include <com/sun/star/lang/NoSupportException.hpp>
34 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
35 #include <com/sun/star/lang/NotInitializedException.hpp>
36 #include <com/sun/star/frame/Desktop.hpp>
37 #include <com/sun/star/frame/IllegalArgumentIOException.hpp>
38 #include <com/sun/star/frame/XUntitledNumbers.hpp>
39 #include <com/sun/star/frame/DoubleInitializationException.hpp>
40 #include <com/sun/star/embed/XStorage.hpp>
41 #include <com/sun/star/document/XStorageChangeListener.hpp>
42 #include <com/sun/star/document/IndexedPropertyValues.hpp>
43 #include <com/sun/star/beans/XPropertySet.hpp>
44 #include <com/sun/star/beans/XPropertySetInfo.hpp>
45 #include <com/sun/star/container/XIndexContainer.hpp>
46 #include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp>
47 #include <com/sun/star/script/provider/XScriptProvider.hpp>
48 #include <com/sun/star/ui/UIConfigurationManager.hpp>
49 #include <com/sun/star/embed/ElementModes.hpp>
50 #include <com/sun/star/embed/Aspects.hpp>
51 #include <com/sun/star/document/DocumentProperties.hpp>
52 #include <com/sun/star/frame/XTransientDocumentsDocumentContentFactory.hpp>
53 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
54 #include <com/sun/star/ucb/ContentCreationException.hpp>
55 #include <com/sun/star/ucb/CommandAbortedException.hpp>
56 #include <com/sun/star/util/XCloneable.hpp>
57 #include <com/sun/star/util/InvalidStateException.hpp>
58 #include <com/sun/star/util/CloseVetoException.hpp>
59 #include <comphelper/enumhelper.hxx>
61 #include <cppuhelper/implbase.hxx>
62 #include <cppuhelper/interfacecontainer.hxx>
63 #include <cppuhelper/exc_hlp.hxx>
64 #include <comphelper/processfactory.hxx>
65 #include <comphelper/sequenceashashmap.hxx>
66 #include <comphelper/namedvaluecollection.hxx>
67 #include <svl/itemset.hxx>
68 #include <svl/stritem.hxx>
69 #include <svl/eitem.hxx>
70 #include <svl/grabbagitem.hxx>
71 #include <tools/urlobj.hxx>
72 #include <tools/debug.hxx>
73 #include <tools/diagnose_ex.h>
74 #include <tools/svborder.hxx>
75 #include <unotools/tempfile.hxx>
76 #include <osl/mutex.hxx>
77 #include <vcl/errcode.hxx>
78 #include <vcl/salctype.hxx>
79 #include <vcl/gdimtf.hxx>
80 #include <comphelper/fileformat.h>
81 #include <comphelper/storagehelper.hxx>
82 #include <toolkit/helper/vclunohelper.hxx>
83 #include <vcl/transfer.hxx>
84 #include <svtools/ehdl.hxx>
85 #include <svtools/sfxecode.hxx>
86 #include <sal/log.hxx>
87 #include <framework/configimporter.hxx>
88 #include <framework/titlehelper.hxx>
89 #include <comphelper/numberedcollection.hxx>
90 #include <unotools/ucbhelper.hxx>
91 #include <ucbhelper/content.hxx>
93 #include <sfx2/sfxbasecontroller.hxx>
94 #include <sfx2/viewfac.hxx>
95 #include <workwin.hxx>
96 #include <sfx2/signaturestate.hxx>
97 #include <sfx2/sfxuno.hxx>
98 #include <objshimp.hxx>
99 #include <sfx2/viewfrm.hxx>
100 #include <sfx2/viewsh.hxx>
101 #include <sfx2/docfile.hxx>
102 #include <sfx2/docfilt.hxx>
103 #include <sfx2/dispatch.hxx>
104 #include <sfx2/module.hxx>
105 #include <basic/basmgr.hxx>
106 #include <sfx2/event.hxx>
107 #include <eventsupplier.hxx>
108 #include <sfx2/sfxsids.hrc>
109 #include <sfx2/strings.hrc>
110 #include <sfx2/app.hxx>
111 #include <sfx2/docfac.hxx>
112 #include <sfx2/fcontnr.hxx>
113 #include <sfx2/docstoragemodifylistener.hxx>
114 #include <sfx2/brokenpackageint.hxx>
115 #include "graphhelp.hxx"
116 #include <docundomanager.hxx>
117 #include <openurlhint.hxx>
118 #include <sfx2/msgpool.hxx>
119 #include <sfx2/DocumentMetadataAccess.hxx>
120 #include "printhelper.hxx"
121 #include <sfx2/sfxresid.hxx>
122 #include <comphelper/profilezone.hxx>
123 #include <vcl/threadex.hxx>
124 #include <unotools/mediadescriptor.hxx>
129 using namespace ::com::sun::star
;
130 using namespace ::com::sun::star::uno
;
131 using ::com::sun::star::beans::PropertyValue
;
132 using ::com::sun::star::document::CmisProperty
;
133 using ::com::sun::star::frame::XFrame
;
134 using ::com::sun::star::frame::XController
;
135 using ::com::sun::star::frame::XController2
;
136 using ::com::sun::star::lang::IllegalArgumentException
;
137 using ::com::sun::star::io::IOException
;
138 using ::com::sun::star::uno::Sequence
;
139 using ::com::sun::star::document::XDocumentRecovery
;
140 using ::com::sun::star::document::XUndoManager
;
141 using ::com::sun::star::document::XUndoAction
;
142 using ::com::sun::star::frame::XModel
;
146 /** This Listener is used to get notified when the XDocumentProperties of the
149 class SfxDocInfoListener_Impl
: public ::cppu::WeakImplHelper
<
150 util::XModifyListener
>
154 SfxObjectShell
& m_rShell
;
156 explicit SfxDocInfoListener_Impl( SfxObjectShell
& i_rDoc
)
160 virtual void SAL_CALL
disposing( const lang::EventObject
& ) override
;
161 virtual void SAL_CALL
modified( const lang::EventObject
& ) override
;
166 void SAL_CALL
SfxDocInfoListener_Impl::modified( const lang::EventObject
& )
168 SolarMutexGuard aSolarGuard
;
170 // notify changes to the SfxObjectShell
171 m_rShell
.FlushDocInfo();
174 void SAL_CALL
SfxDocInfoListener_Impl::disposing( const lang::EventObject
& )
179 // impl. declarations
182 struct IMPL_SfxBaseModel_DataContainer
: public ::sfx2::IModifiableDocument
184 // counter for SfxBaseModel instances created.
185 static sal_Int64 g_nInstanceCounter
;
186 SfxObjectShellRef m_pObjectShell
;
188 OUString m_sRuntimeUID
;
189 OUString m_aPreusedFilterName
;
190 ::cppu::OMultiTypeInterfaceContainerHelper m_aInterfaceContainer
;
191 std::unordered_map
<css::uno::Reference
< css::drawing::XShape
>,
192 std::vector
<css::uno::Reference
< css::document::XShapeEventListener
>>> maShapeListeners
;
193 Reference
< XInterface
> m_xParent
;
194 Reference
< frame::XController
> m_xCurrent
;
195 Reference
< document::XDocumentProperties
> m_xDocumentProperties
;
196 Reference
< script::XStarBasicAccess
> m_xStarBasicAccess
;
197 Reference
< container::XNameReplace
> m_xEvents
;
198 Sequence
< beans::PropertyValue
> m_seqArguments
;
199 std::vector
< Reference
< frame::XController
> > m_seqControllers
;
200 Reference
< container::XIndexAccess
> m_contViewData
;
201 sal_uInt16 m_nControllerLockCount
;
206 bool m_bExternalTitle
;
207 bool m_bModifiedSinceLastSave
;
208 Reference
< view::XPrintable
> m_xPrintable
;
209 Reference
< ui::XUIConfigurationManager2
> m_xUIConfigurationManager
;
210 ::rtl::Reference
< ::sfx2::DocumentStorageModifyListener
> m_pStorageModifyListen
;
211 OUString m_sModuleIdentifier
;
212 Reference
< frame::XTitle
> m_xTitleHelper
;
213 Reference
< frame::XUntitledNumbers
> m_xNumberedControllers
;
214 Reference
< rdf::XDocumentMetadataAccess
> m_xDocumentMetadata
;
215 ::rtl::Reference
< ::sfx2::DocumentUndoManager
> m_pDocumentUndoManager
;
216 Sequence
< document::CmisProperty
> m_cmisProperties
;
217 std::shared_ptr
<SfxGrabBagItem
> m_xGrabBagItem
;
219 IMPL_SfxBaseModel_DataContainer( ::osl::Mutex
& rMutex
, SfxObjectShell
* pObjectShell
)
220 : m_pObjectShell ( pObjectShell
)
221 , m_aInterfaceContainer ( rMutex
)
222 , m_nControllerLockCount ( 0 )
223 , m_bClosed ( false )
224 , m_bClosing ( false )
225 , m_bSaving ( false )
226 , m_bSuicide ( false )
227 , m_bExternalTitle ( false )
228 , m_bModifiedSinceLastSave( false )
230 , m_xNumberedControllers ()
231 , m_xDocumentMetadata () // lazy
232 , m_pDocumentUndoManager ()
233 , m_cmisProperties ()
235 // increase global instance counter.
236 ++g_nInstanceCounter
;
237 // set own Runtime UID
238 m_sRuntimeUID
= OUString::number( g_nInstanceCounter
);
241 virtual ~IMPL_SfxBaseModel_DataContainer()
245 // ::sfx2::IModifiableDocument
246 virtual void storageIsModified() override
248 if ( m_pObjectShell
.is() && !m_pObjectShell
->IsModified() )
249 m_pObjectShell
->SetModified();
252 void impl_setDocumentProperties(
253 const Reference
< document::XDocumentProperties
>& );
255 Reference
<rdf::XDocumentMetadataAccess
> GetDMA()
257 if (!m_xDocumentMetadata
.is())
259 OSL_ENSURE(m_pObjectShell
.is(), "GetDMA: no object shell?");
260 if (!m_pObjectShell
.is())
265 const Reference
<XComponentContext
> xContext(
266 ::comphelper::getProcessComponentContext());
267 const Reference
<frame::XModel
> xModel(
268 m_pObjectShell
->GetModel());
269 const Reference
<lang::XMultiComponentFactory
> xMsf(
270 xContext
->getServiceManager());
271 const Reference
<frame::
272 XTransientDocumentsDocumentContentFactory
> xTDDCF(
273 xMsf
->createInstanceWithContext(
274 "com.sun.star.frame.TransientDocumentsDocumentContentFactory",
277 const Reference
<ucb::XContent
> xContent(
278 xTDDCF
->createDocumentContent(xModel
) );
279 OSL_ENSURE(xContent
.is(), "GetDMA: cannot create DocumentContent");
284 OUString uri
= xContent
->getIdentifier()->getContentIdentifier();
285 OSL_ENSURE(!uri
.isEmpty(), "GetDMA: empty uri?");
286 if (!uri
.isEmpty() && !uri
.endsWith("/"))
291 m_xDocumentMetadata
= new ::sfx2::DocumentMetadataAccess(
292 xContext
, *m_pObjectShell
, uri
);
294 return m_xDocumentMetadata
;
297 Reference
<rdf::XDocumentMetadataAccess
> CreateDMAUninitialized()
299 return (m_pObjectShell
.is())
300 ? new ::sfx2::DocumentMetadataAccess(
301 ::comphelper::getProcessComponentContext(), *m_pObjectShell
)
306 // static member initialization.
307 sal_Int64
IMPL_SfxBaseModel_DataContainer::g_nInstanceCounter
= 0;
311 // Listener that forwards notifications from the PrintHelper to the "real" listeners
312 class SfxPrintHelperListener_Impl
: public ::cppu::WeakImplHelper
< view::XPrintJobListener
>
315 IMPL_SfxBaseModel_DataContainer
* m_pData
;
316 explicit SfxPrintHelperListener_Impl( IMPL_SfxBaseModel_DataContainer
* pData
)
320 virtual void SAL_CALL
disposing( const lang::EventObject
& aEvent
) override
;
321 virtual void SAL_CALL
printJobEvent( const view::PrintJobEvent
& rEvent
) override
;
326 void SAL_CALL
SfxPrintHelperListener_Impl::disposing( const lang::EventObject
& )
328 m_pData
->m_xPrintable
= nullptr;
331 void SAL_CALL
SfxPrintHelperListener_Impl::printJobEvent( const view::PrintJobEvent
& rEvent
)
333 ::cppu::OInterfaceContainerHelper
* pContainer
= m_pData
->m_aInterfaceContainer
.getContainer( cppu::UnoType
<view::XPrintJobListener
>::get());
334 if ( pContainer
!=nullptr )
336 ::cppu::OInterfaceIteratorHelper
pIterator(*pContainer
);
337 while (pIterator
.hasMoreElements())
338 static_cast<view::XPrintJobListener
*>(pIterator
.next())->printJobEvent( rEvent
);
344 // SfxOwnFramesLocker ====================================================================================
345 // allows to lock all the frames related to the provided SfxObjectShell
346 class SfxOwnFramesLocker
348 Sequence
< Reference
< frame::XFrame
> > m_aLockedFrames
;
350 static vcl::Window
* GetVCLWindow( const Reference
< frame::XFrame
>& xFrame
);
352 explicit SfxOwnFramesLocker( SfxObjectShell
const * ObjechShell
);
353 ~SfxOwnFramesLocker();
358 SfxOwnFramesLocker::SfxOwnFramesLocker( SfxObjectShell
const * pObjectShell
)
363 for ( SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( pObjectShell
);
365 pFrame
= SfxViewFrame::GetNext( *pFrame
, pObjectShell
)
368 SfxFrame
& rSfxFrame
= pFrame
->GetFrame();
371 // get vcl window related to the frame and lock it if it is still not locked
372 const Reference
< frame::XFrame
>& xFrame
= rSfxFrame
.GetFrameInterface();
373 vcl::Window
* pWindow
= GetVCLWindow( xFrame
);
375 throw RuntimeException();
377 if ( pWindow
->IsEnabled() )
383 sal_Int32 nLen
= m_aLockedFrames
.getLength();
384 m_aLockedFrames
.realloc( nLen
+ 1 );
385 m_aLockedFrames
[nLen
] = xFrame
;
396 OSL_FAIL( "Not possible to lock the frame window!" );
401 SfxOwnFramesLocker::~SfxOwnFramesLocker()
403 for ( auto& rFrame
: m_aLockedFrames
)
409 // get vcl window related to the frame and unlock it
410 vcl::Window
* pWindow
= GetVCLWindow( rFrame
);
412 throw RuntimeException();
421 OSL_FAIL( "Can't unlock the frame window!" );
426 vcl::Window
* SfxOwnFramesLocker::GetVCLWindow( const Reference
< frame::XFrame
>& xFrame
)
428 VclPtr
<vcl::Window
> pWindow
;
432 Reference
< awt::XWindow
> xWindow
= xFrame
->getContainerWindow();
434 pWindow
= VCLUnoHelper::GetWindow( xWindow
);
442 // SfxSaveGuard ====================================================================================
446 Reference
< frame::XModel
> m_xModel
;
447 IMPL_SfxBaseModel_DataContainer
* m_pData
;
448 std::unique_ptr
<SfxOwnFramesLocker
> m_pFramesLock
;
450 SfxSaveGuard(SfxSaveGuard
const &) = delete;
451 void operator =(const SfxSaveGuard
&) = delete;
454 SfxSaveGuard(const Reference
< frame::XModel
>& xModel
,
455 IMPL_SfxBaseModel_DataContainer
* pData
);
461 SfxSaveGuard::SfxSaveGuard(const Reference
< frame::XModel
>& xModel
,
462 IMPL_SfxBaseModel_DataContainer
* pData
)
463 : m_xModel ( xModel
)
466 if ( m_pData
->m_bClosed
)
467 throw lang::DisposedException("Object already disposed.");
469 m_pData
->m_bSaving
= true;
470 m_pFramesLock
.reset(new SfxOwnFramesLocker( m_pData
->m_pObjectShell
.get() ));
473 SfxSaveGuard::~SfxSaveGuard()
475 m_pFramesLock
.reset();
477 m_pData
->m_bSaving
= false;
479 // m_bSuicide was set e.g. in case someone tried to close a document, while it was used for
480 // storing at the same time. Further m_bSuicide was set to sal_True only if close(sal_True) was called.
481 // So the ownership was delegated to the place where a veto exception was thrown.
482 // Now we have to call close() again and delegate the ownership to the next one, which
483 // can't accept that. Close(sal_False) can't work in this case. Because then the document will may be never closed...
485 if ( !m_pData
->m_bSuicide
)
488 // Reset this state. In case the new close() request is not accepted by someone else...
489 // it's not a good idea to have two "owners" for close.-)
490 m_pData
->m_bSuicide
= false;
493 Reference
< util::XCloseable
> xClose(m_xModel
, UNO_QUERY
);
497 catch(const util::CloseVetoException
&)
501 SfxBaseModel::SfxBaseModel( SfxObjectShell
*pObjectShell
)
503 , m_pData( std::make_shared
<IMPL_SfxBaseModel_DataContainer
>( m_aMutex
, pObjectShell
) )
504 , m_bSupportEmbeddedScripts( pObjectShell
&& pObjectShell
->Get_Impl() && !pObjectShell
->Get_Impl()->m_bNoBasicCapabilities
)
505 , m_bSupportDocRecovery( pObjectShell
&& pObjectShell
->Get_Impl() && pObjectShell
->Get_Impl()->m_bDocRecoverySupport
)
507 if ( pObjectShell
!= nullptr )
509 StartListening( *pObjectShell
) ;
514 SfxBaseModel::~SfxBaseModel()
519 Any SAL_CALL
SfxBaseModel::queryInterface( const uno::Type
& rType
)
521 if ( ( !m_bSupportEmbeddedScripts
&& rType
.equals( cppu::UnoType
<document::XEmbeddedScripts
>::get() ) )
522 || ( !m_bSupportDocRecovery
&& rType
.equals( cppu::UnoType
<XDocumentRecovery
>::get() ) )
526 return SfxBaseModel_Base::queryInterface( rType
);
535 void lcl_stripType( Sequence
< uno::Type
>& io_rTypes
, const uno::Type
& i_rTypeToStrip
)
537 Sequence
< uno::Type
> aStrippedTypes( io_rTypes
.getLength() - 1 );
538 ::std::remove_copy_if(
541 aStrippedTypes
.getArray(),
542 [&i_rTypeToStrip
](const uno::Type
& aType
) { return aType
== i_rTypeToStrip
; }
544 io_rTypes
= aStrippedTypes
;
548 Sequence
< uno::Type
> SAL_CALL
SfxBaseModel::getTypes()
550 Sequence
< uno::Type
> aTypes( SfxBaseModel_Base::getTypes() );
552 if ( !m_bSupportEmbeddedScripts
)
553 lcl_stripType( aTypes
, cppu::UnoType
<document::XEmbeddedScripts
>::get() );
555 if ( !m_bSupportDocRecovery
)
556 lcl_stripType( aTypes
, cppu::UnoType
<XDocumentRecovery
>::get() );
565 Sequence
< sal_Int8
> SAL_CALL
SfxBaseModel::getImplementationId()
567 return css::uno::Sequence
<sal_Int8
>();
573 #if HAVE_FEATURE_SCRIPTING
575 static Reference
< script::XStarBasicAccess
> implGetStarBasicAccess( SfxObjectShell
const * pObjectShell
)
577 Reference
< script::XStarBasicAccess
> xRet
;
579 #if !HAVE_FEATURE_SCRIPTING
584 BasicManager
* pMgr
= pObjectShell
->GetBasicManager();
585 xRet
= getStarBasicAccess( pMgr
);
593 Reference
< container::XNameContainer
> SAL_CALL
SfxBaseModel::getLibraryContainer()
595 #if !HAVE_FEATURE_SCRIPTING
596 Reference
< container::XNameContainer
> dummy
;
600 SfxModelGuard
aGuard( *this );
602 Reference
< script::XStarBasicAccess
>& rxAccess
= m_pData
->m_xStarBasicAccess
;
603 if( !rxAccess
.is() && m_pData
->m_pObjectShell
.is() )
604 rxAccess
= implGetStarBasicAccess( m_pData
->m_pObjectShell
.get() );
606 Reference
< container::XNameContainer
> xRet
;
608 xRet
= rxAccess
->getLibraryContainer();
613 /**___________________________________________________________________________________________________
614 @seealso XStarBasicAccess
616 void SAL_CALL
SfxBaseModel::createLibrary( const OUString
& LibName
, const OUString
& Password
,
617 const OUString
& ExternalSourceURL
, const OUString
& LinkTargetURL
)
619 #if !HAVE_FEATURE_SCRIPTING
622 (void) ExternalSourceURL
;
623 (void) LinkTargetURL
;
625 SfxModelGuard
aGuard( *this );
627 Reference
< script::XStarBasicAccess
>& rxAccess
= m_pData
->m_xStarBasicAccess
;
628 if( !rxAccess
.is() && m_pData
->m_pObjectShell
.is() )
629 rxAccess
= implGetStarBasicAccess( m_pData
->m_pObjectShell
.get() );
632 rxAccess
->createLibrary( LibName
, Password
, ExternalSourceURL
, LinkTargetURL
);
636 /**___________________________________________________________________________________________________
637 @seealso XStarBasicAccess
639 void SAL_CALL
SfxBaseModel::addModule( const OUString
& LibraryName
, const OUString
& ModuleName
,
640 const OUString
& Language
, const OUString
& Source
)
642 #if !HAVE_FEATURE_SCRIPTING
648 SfxModelGuard
aGuard( *this );
650 Reference
< script::XStarBasicAccess
>& rxAccess
= m_pData
->m_xStarBasicAccess
;
651 if( !rxAccess
.is() && m_pData
->m_pObjectShell
.is() )
652 rxAccess
= implGetStarBasicAccess( m_pData
->m_pObjectShell
.get() );
655 rxAccess
->addModule( LibraryName
, ModuleName
, Language
, Source
);
659 /**___________________________________________________________________________________________________
660 @seealso XStarBasicAccess
662 void SAL_CALL
SfxBaseModel::addDialog( const OUString
& LibraryName
, const OUString
& DialogName
,
663 const Sequence
< sal_Int8
>& Data
)
665 #if !HAVE_FEATURE_SCRIPTING
670 SfxModelGuard
aGuard( *this );
672 Reference
< script::XStarBasicAccess
>& rxAccess
= m_pData
->m_xStarBasicAccess
;
673 if( !rxAccess
.is() && m_pData
->m_pObjectShell
.is() )
674 rxAccess
= implGetStarBasicAccess( m_pData
->m_pObjectShell
.get() );
677 rxAccess
->addDialog( LibraryName
, DialogName
, Data
);
685 Reference
< XInterface
> SAL_CALL
SfxBaseModel::getParent()
687 SfxModelGuard
aGuard( *this );
689 return m_pData
->m_xParent
;
696 void SAL_CALL
SfxBaseModel::setParent(const Reference
< XInterface
>& Parent
)
698 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
699 m_pData
->m_xParent
= Parent
;
706 void SAL_CALL
SfxBaseModel::dispose()
708 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
710 if ( !m_pData
->m_bClosed
)
712 // gracefully accept wrong dispose calls instead of close call
713 // and try to make it work (may be really disposed later!)
718 catch ( util::CloseVetoException
& )
725 if ( m_pData
->m_pStorageModifyListen
.is() )
727 m_pData
->m_pStorageModifyListen
->dispose();
728 m_pData
->m_pStorageModifyListen
= nullptr;
731 if ( m_pData
->m_pDocumentUndoManager
.is() )
733 m_pData
->m_pDocumentUndoManager
->disposing();
734 m_pData
->m_pDocumentUndoManager
= nullptr;
737 lang::EventObject
aEvent( static_cast<frame::XModel
*>(this) );
738 m_pData
->m_aInterfaceContainer
.disposeAndClear( aEvent
);
740 m_pData
->m_xDocumentProperties
.clear();
742 m_pData
->m_xDocumentMetadata
.clear();
744 if ( m_pData
->m_pObjectShell
.is() )
746 EndListening( *m_pData
->m_pObjectShell
);
749 m_pData
->m_xCurrent
.clear();
750 m_pData
->m_seqControllers
.clear();
752 // m_pData member must be set to zero before delete is called to
753 // force disposed exception whenever someone tries to access our
754 // instance while in the dtor.
762 void SAL_CALL
SfxBaseModel::addEventListener( const Reference
< lang::XEventListener
>& aListener
)
764 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
765 m_pData
->m_aInterfaceContainer
.addInterface( cppu::UnoType
<lang::XEventListener
>::get(), aListener
);
772 void SAL_CALL
SfxBaseModel::removeEventListener( const Reference
< lang::XEventListener
>& aListener
)
774 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
775 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<lang::XEventListener
>::get(), aListener
);
779 IMPL_SfxBaseModel_DataContainer::impl_setDocumentProperties(
780 const Reference
< document::XDocumentProperties
>& rxNewDocProps
)
782 m_xDocumentProperties
.set(rxNewDocProps
, UNO_SET_THROW
);
783 if (m_pObjectShell
.is())
785 Reference
<util::XModifyBroadcaster
> const xMB(
786 m_xDocumentProperties
, UNO_QUERY_THROW
);
787 xMB
->addModifyListener(new SfxDocInfoListener_Impl(*m_pObjectShell
));
791 // document::XDocumentPropertiesSupplier:
792 Reference
< document::XDocumentProperties
> SAL_CALL
793 SfxBaseModel::getDocumentProperties()
795 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
796 if ( !m_pData
->m_xDocumentProperties
.is() )
798 Reference
< document::XDocumentProperties
> xDocProps(
799 document::DocumentProperties::create( ::comphelper::getProcessComponentContext() ) );
800 m_pData
->impl_setDocumentProperties(xDocProps
);
803 return m_pData
->m_xDocumentProperties
;
807 // lang::XEventListener
810 void SAL_CALL
SfxBaseModel::disposing( const lang::EventObject
& aObject
)
812 SolarMutexGuard aGuard
;
813 if ( impl_isDisposed() )
816 Reference
< util::XModifyListener
> xMod( aObject
.Source
, UNO_QUERY
);
817 Reference
< lang::XEventListener
> xListener( aObject
.Source
, UNO_QUERY
);
818 Reference
< document::XEventListener
> xDocListener( aObject
.Source
, UNO_QUERY
);
821 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<util::XModifyListener
>::get(), xMod
);
822 else if ( xListener
.is() )
823 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<lang::XEventListener
>::get(), xListener
);
824 else if ( xDocListener
.is() )
825 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<document::XEventListener
>::get(), xListener
);
832 sal_Bool SAL_CALL
SfxBaseModel::attachResource( const OUString
& rURL
,
833 const Sequence
< beans::PropertyValue
>& rArgs
)
835 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
836 if ( rURL
.isEmpty() && rArgs
.getLength() == 1 && rArgs
[0].Name
== "SetEmbedded" )
838 // allows to set a windowless document to EMBEDDED state
839 // but _only_ before load() or initNew() methods
840 if ( m_pData
->m_pObjectShell
.is() && !m_pData
->m_pObjectShell
->GetMedium() )
843 if ( ( rArgs
[0].Value
>>= bEmb
) && bEmb
)
844 m_pData
->m_pObjectShell
->SetCreateMode_Impl( SfxObjectCreateMode::EMBEDDED
);
850 if ( m_pData
->m_pObjectShell
.is() )
852 m_pData
->m_sURL
= rURL
;
854 SfxObjectShell
* pObjectShell
= m_pData
->m_pObjectShell
.get();
856 ::comphelper::NamedValueCollection
aArgs( rArgs
);
858 Sequence
< sal_Int32
> aWinExtent
;
859 if ( ( aArgs
.get( "WinExtent" ) >>= aWinExtent
)&& ( aWinExtent
.getLength() == 4 ) )
861 tools::Rectangle
aVisArea( aWinExtent
[0], aWinExtent
[1], aWinExtent
[2], aWinExtent
[3] );
862 aVisArea
= OutputDevice::LogicToLogic(aVisArea
, MapMode(MapUnit::Map100thMM
), MapMode(pObjectShell
->GetMapUnit()));
863 pObjectShell
->SetVisArea( aVisArea
);
866 bool bBreakMacroSign
= false;
867 if ( aArgs
.get( "BreakMacroSignature" ) >>= bBreakMacroSign
)
869 pObjectShell
->BreakMacroSign_Impl( bBreakMacroSign
);
872 bool bMacroEventRead
= false;
873 if ((aArgs
.get("MacroEventRead") >>= bMacroEventRead
) && bMacroEventRead
)
875 pObjectShell
->SetMacroCallsSeenWhileLoading();
878 aArgs
.remove( "WinExtent" );
879 aArgs
.remove( "BreakMacroSignature" );
880 aArgs
.remove( "MacroEventRead" );
881 aArgs
.remove( "Stream" );
882 aArgs
.remove( "InputStream" );
883 aArgs
.remove( "URL" );
884 aArgs
.remove( "Frame" );
885 aArgs
.remove( "Password" );
886 aArgs
.remove( "EncryptionData" );
888 // TODO/LATER: all the parameters that are accepted by ItemSet of the DocShell must be removed here
890 m_pData
->m_seqArguments
= aArgs
.getPropertyValues();
892 SfxMedium
* pMedium
= pObjectShell
->GetMedium();
895 SfxAllItemSet
aSet( pObjectShell
->GetPool() );
896 TransformParameters( SID_OPENDOC
, rArgs
, aSet
);
898 // the arguments are not allowed to reach the medium
899 aSet
.ClearItem( SID_FILE_NAME
);
900 aSet
.ClearItem( SID_FILLFRAME
);
902 pMedium
->GetItemSet()->Put( aSet
);
903 const SfxStringItem
* pItem
= aSet
.GetItem
<SfxStringItem
>(SID_FILTER_NAME
, false);
906 pObjectShell
->GetFactory().GetFilterContainer()->GetFilter4FilterName( pItem
->GetValue() ) );
908 const SfxStringItem
* pTitleItem
= aSet
.GetItem
<SfxStringItem
>(SID_DOCINFO_TITLE
, false);
911 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( pObjectShell
);
913 pFrame
->UpdateTitle();
925 OUString SAL_CALL
SfxBaseModel::getURL()
927 SfxModelGuard
aGuard( *this );
928 return m_pData
->m_sURL
;
935 Sequence
< beans::PropertyValue
> SAL_CALL
SfxBaseModel::getArgs()
937 SfxModelGuard
aGuard( *this );
939 if (!SfxApplication::Get()) // tdf#113755
941 SAL_WARN("sfx.appl", "Unexpected operations on model");
942 return m_pData
->m_seqArguments
;
945 if ( m_pData
->m_pObjectShell
.is() )
947 Sequence
< beans::PropertyValue
> seqArgsNew
;
948 Sequence
< beans::PropertyValue
> seqArgsOld
;
949 SfxAllItemSet
aSet( m_pData
->m_pObjectShell
->GetPool() );
951 // we need to know which properties are supported by the transformer
952 // hopefully it is a temporary solution, I guess nonconvertable properties
953 // should not be supported so then there will be only ItemSet from medium
955 TransformItems( SID_OPENDOC
, *(m_pData
->m_pObjectShell
->GetMedium()->GetItemSet()), seqArgsNew
);
956 TransformParameters( SID_OPENDOC
, m_pData
->m_seqArguments
, aSet
);
957 TransformItems( SID_OPENDOC
, aSet
, seqArgsOld
);
959 sal_Int32 nNewLength
= seqArgsNew
.getLength();
961 // "WinExtent" property should be updated always.
962 // We can store it now to overwrite an old value
963 // since it is not from ItemSet
964 tools::Rectangle aTmpRect
= m_pData
->m_pObjectShell
->GetVisArea( ASPECT_CONTENT
);
965 aTmpRect
= OutputDevice::LogicToLogic(aTmpRect
, MapMode(m_pData
->m_pObjectShell
->GetMapUnit()), MapMode(MapUnit::Map100thMM
));
967 Sequence
< sal_Int32
> aRectSeq(4);
968 aRectSeq
[0] = aTmpRect
.Left();
969 aRectSeq
[1] = aTmpRect
.Top();
970 aRectSeq
[2] = aTmpRect
.IsWidthEmpty() ? aTmpRect
.Left() : aTmpRect
.Right();
971 aRectSeq
[3] = aTmpRect
.IsHeightEmpty() ? aTmpRect
.Top() : aTmpRect
.Bottom();
973 seqArgsNew
.realloc( ++nNewLength
);
974 seqArgsNew
[ nNewLength
- 1 ].Name
= "WinExtent";
975 seqArgsNew
[ nNewLength
- 1 ].Value
<<= aRectSeq
;
977 if ( !m_pData
->m_aPreusedFilterName
.isEmpty() )
979 seqArgsNew
.realloc( ++nNewLength
);
980 seqArgsNew
[ nNewLength
- 1 ].Name
= "PreusedFilterName";
981 seqArgsNew
[ nNewLength
- 1 ].Value
<<= m_pData
->m_aPreusedFilterName
;
984 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get() );
987 SvBorder aBorder
= pFrame
->GetBorderPixelImpl();
989 Sequence
< sal_Int32
> aBorderSeq(4);
990 aBorderSeq
[0] = aBorder
.Left();
991 aBorderSeq
[1] = aBorder
.Top();
992 aBorderSeq
[2] = aBorder
.Right();
993 aBorderSeq
[3] = aBorder
.Bottom();
995 seqArgsNew
.realloc( ++nNewLength
);
996 seqArgsNew
[ nNewLength
- 1 ].Name
= "DocumentBorder";
997 seqArgsNew
[ nNewLength
- 1 ].Value
<<= aBorderSeq
;
1000 // only the values that are not supported by the ItemSet must be cached here
1001 Sequence
< beans::PropertyValue
> aFinalCache
;
1002 sal_Int32 nFinalLength
= 0;
1004 for ( const auto& rOrg
: std::as_const(m_pData
->m_seqArguments
) )
1006 auto bNew
= std::none_of(seqArgsOld
.begin(), seqArgsOld
.end(),
1007 [&rOrg
](const beans::PropertyValue
& rOld
){ return rOld
.Name
== rOrg
.Name
; });
1010 // the entity with this name should be new for seqArgsNew
1011 // since it is not supported by transformer
1013 seqArgsNew
.realloc( ++nNewLength
);
1014 seqArgsNew
[ nNewLength
- 1 ] = rOrg
;
1016 aFinalCache
.realloc( ++nFinalLength
);
1017 aFinalCache
[ nFinalLength
- 1 ] = rOrg
;
1021 m_pData
->m_seqArguments
= aFinalCache
;
1026 return m_pData
->m_seqArguments
;
1029 void SAL_CALL
SfxBaseModel::setArgs(const Sequence
<beans::PropertyValue
>& aArgs
)
1031 SfxModelGuard
aGuard( *this );
1033 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
1036 throw util::InvalidStateException(
1037 "Medium could not be retrieved, unable to execute setArgs");
1040 for (const auto& rArg
: aArgs
)
1045 if (rArg
.Name
== "SuggestedSaveAsName")
1047 if (rArg
.Value
>>= sValue
)
1049 pMedium
->GetItemSet()->Put(SfxStringItem(SID_SUGGESTEDSAVEASNAME
, sValue
));
1053 else if (rArg
.Name
== "SuggestedSaveAsDir")
1055 if (rArg
.Value
>>= sValue
)
1057 pMedium
->GetItemSet()->Put(SfxStringItem(SID_SUGGESTEDSAVEASDIR
, sValue
));
1061 else if (rArg
.Name
== "LockContentExtraction")
1063 if (rArg
.Value
>>= bValue
)
1065 pMedium
->GetItemSet()->Put(SfxBoolItem(SID_LOCK_CONTENT_EXTRACTION
, bValue
));
1069 else if (rArg
.Name
== "LockExport")
1071 if (rArg
.Value
>>= bValue
)
1073 pMedium
->GetItemSet()->Put(SfxBoolItem(SID_LOCK_EXPORT
, bValue
));
1077 else if (rArg
.Name
== "LockPrint")
1079 if (rArg
.Value
>>= bValue
)
1081 pMedium
->GetItemSet()->Put(SfxBoolItem(SID_LOCK_PRINT
, bValue
));
1085 else if (rArg
.Name
== "LockSave")
1087 if (rArg
.Value
>>= bValue
)
1089 pMedium
->GetItemSet()->Put(SfxBoolItem(SID_LOCK_SAVE
, bValue
));
1093 else if (rArg
.Name
== "LockEditDoc")
1095 if (rArg
.Value
>>= bValue
)
1097 pMedium
->GetItemSet()->Put(SfxBoolItem(SID_LOCK_EDITDOC
, bValue
));
1101 else if (rArg
.Name
== "Replaceable")
1103 if (rArg
.Value
>>= bValue
)
1105 pMedium
->GetItemSet()->Put(SfxBoolItem(SID_REPLACEABLE
, bValue
));
1109 else if (rArg
.Name
== "EncryptionData")
1111 pMedium
->GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA
, rArg
.Value
));
1116 throw lang::IllegalArgumentException("Setting property not supported: " + rArg
.Name
,
1117 comphelper::getProcessComponentContext(), 0);
1125 void SAL_CALL
SfxBaseModel::connectController( const Reference
< frame::XController
>& xController
)
1127 SfxModelGuard
aGuard( *this );
1128 OSL_PRECOND( xController
.is(), "SfxBaseModel::connectController: invalid controller!" );
1129 if ( !xController
.is() )
1132 m_pData
->m_seqControllers
.push_back(xController
);
1134 if ( m_pData
->m_seqControllers
.size() == 1 )
1136 SfxViewFrame
* pViewFrame
= SfxViewFrame::Get( xController
, GetObjectShell() );
1137 ENSURE_OR_THROW( pViewFrame
, "SFX document without SFX view!?" );
1138 pViewFrame
->UpdateDocument_Impl();
1139 const OUString sDocumentURL
= GetObjectShell()->GetMedium()->GetName();
1140 if ( !sDocumentURL
.isEmpty() )
1141 SfxGetpApp()->Broadcast( SfxOpenUrlHint( sDocumentURL
) );
1149 void SAL_CALL
SfxBaseModel::disconnectController( const Reference
< frame::XController
>& xController
)
1151 SfxModelGuard
aGuard( *this );
1153 if ( m_pData
->m_seqControllers
.empty() )
1156 auto& vec
= m_pData
->m_seqControllers
;
1157 vec
.erase(std::remove(vec
.begin(), vec
.end(), xController
), vec
.end());
1159 if ( xController
== m_pData
->m_xCurrent
)
1160 m_pData
->m_xCurrent
.clear();
1165 class ControllerLockUndoAction
: public ::cppu::WeakImplHelper
< XUndoAction
>
1168 ControllerLockUndoAction( const Reference
< XModel
>& i_model
, const bool i_undoIsUnlock
)
1169 :m_xModel( i_model
)
1170 ,m_bUndoIsUnlock( i_undoIsUnlock
)
1175 virtual OUString SAL_CALL
getTitle() override
;
1176 virtual void SAL_CALL
undo( ) override
;
1177 virtual void SAL_CALL
redo( ) override
;
1180 const Reference
< XModel
> m_xModel
;
1181 const bool m_bUndoIsUnlock
;
1184 OUString SAL_CALL
ControllerLockUndoAction::getTitle()
1186 // this action is intended to be used within an UndoContext only, so nobody will ever see this title ...
1190 void SAL_CALL
ControllerLockUndoAction::undo( )
1192 if ( m_bUndoIsUnlock
)
1193 m_xModel
->unlockControllers();
1195 m_xModel
->lockControllers();
1198 void SAL_CALL
ControllerLockUndoAction::redo( )
1200 if ( m_bUndoIsUnlock
)
1201 m_xModel
->lockControllers();
1203 m_xModel
->unlockControllers();
1211 void SAL_CALL
SfxBaseModel::lockControllers()
1213 SfxModelGuard
aGuard( *this );
1215 ++m_pData
->m_nControllerLockCount
;
1217 if ( m_pData
->m_pDocumentUndoManager
.is()
1218 && m_pData
->m_pDocumentUndoManager
->isInContext()
1219 && !m_pData
->m_pDocumentUndoManager
->isLocked()
1222 m_pData
->m_pDocumentUndoManager
->addUndoAction( new ControllerLockUndoAction( this, true ) );
1230 void SAL_CALL
SfxBaseModel::unlockControllers()
1232 SfxModelGuard
aGuard( *this );
1234 --m_pData
->m_nControllerLockCount
;
1236 if ( m_pData
->m_pDocumentUndoManager
.is()
1237 && m_pData
->m_pDocumentUndoManager
->isInContext()
1238 && !m_pData
->m_pDocumentUndoManager
->isLocked()
1241 m_pData
->m_pDocumentUndoManager
->addUndoAction( new ControllerLockUndoAction( this, false ) );
1249 sal_Bool SAL_CALL
SfxBaseModel::hasControllersLocked()
1251 SfxModelGuard
aGuard( *this );
1252 return ( m_pData
->m_nControllerLockCount
!= 0 ) ;
1259 Reference
< frame::XController
> SAL_CALL
SfxBaseModel::getCurrentController()
1261 SfxModelGuard
aGuard( *this );
1263 // get the last active controller of this model
1264 if ( m_pData
->m_xCurrent
.is() )
1265 return m_pData
->m_xCurrent
;
1267 // get the first controller of this model
1268 return !m_pData
->m_seqControllers
.empty() ? m_pData
->m_seqControllers
.front() : m_pData
->m_xCurrent
;
1275 void SAL_CALL
SfxBaseModel::setCurrentController( const Reference
< frame::XController
>& xCurrentController
)
1277 SfxModelGuard
aGuard( *this );
1279 m_pData
->m_xCurrent
= xCurrentController
;
1286 Reference
< XInterface
> SAL_CALL
SfxBaseModel::getCurrentSelection()
1288 SfxModelGuard
aGuard( *this );
1290 Reference
< XInterface
> xReturn
;
1291 Reference
< frame::XController
> xController
= getCurrentController() ;
1293 if ( xController
.is() )
1295 Reference
< view::XSelectionSupplier
> xDocView( xController
, UNO_QUERY
);
1296 if ( xDocView
.is() )
1298 Any aSel
= xDocView
->getSelection();
1310 sal_Bool SAL_CALL
SfxBaseModel::disableSetModified()
1312 SfxModelGuard
aGuard( *this );
1314 if ( !m_pData
->m_pObjectShell
.is() )
1315 throw RuntimeException();
1317 bool bResult
= m_pData
->m_pObjectShell
->IsEnableSetModified();
1318 m_pData
->m_pObjectShell
->EnableSetModified( false );
1323 sal_Bool SAL_CALL
SfxBaseModel::enableSetModified()
1325 SfxModelGuard
aGuard( *this );
1327 if ( !m_pData
->m_pObjectShell
.is() )
1328 throw RuntimeException();
1330 bool bResult
= m_pData
->m_pObjectShell
->IsEnableSetModified();
1331 m_pData
->m_pObjectShell
->EnableSetModified();
1336 sal_Bool SAL_CALL
SfxBaseModel::isSetModifiedEnabled()
1338 SfxModelGuard
aGuard( *this );
1340 if ( !m_pData
->m_pObjectShell
.is() )
1341 throw RuntimeException();
1343 return m_pData
->m_pObjectShell
->IsEnableSetModified();
1350 sal_Bool SAL_CALL
SfxBaseModel::isModified()
1352 SfxModelGuard
aGuard( *this );
1354 return m_pData
->m_pObjectShell
.is() && m_pData
->m_pObjectShell
->IsModified();
1361 void SAL_CALL
SfxBaseModel::setModified( sal_Bool bModified
)
1363 SfxModelGuard
aGuard( *this );
1365 if ( m_pData
->m_pObjectShell
.is() )
1366 m_pData
->m_pObjectShell
->SetModified(bModified
);
1373 void SAL_CALL
SfxBaseModel::addModifyListener(const Reference
< util::XModifyListener
>& xListener
)
1375 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
1377 m_pData
->m_aInterfaceContainer
.addInterface( cppu::UnoType
<util::XModifyListener
>::get(),xListener
);
1384 void SAL_CALL
SfxBaseModel::removeModifyListener(const Reference
< util::XModifyListener
>& xListener
)
1386 SfxModelGuard
aGuard( *this );
1388 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<util::XModifyListener
>::get(), xListener
);
1395 void SAL_CALL
SfxBaseModel::close( sal_Bool bDeliverOwnership
)
1397 SolarMutexGuard aGuard
;
1398 if ( impl_isDisposed() || m_pData
->m_bClosed
|| m_pData
->m_bClosing
)
1401 Reference
< XInterface
> xSelfHold( static_cast< ::cppu::OWeakObject
* >(this) );
1402 lang::EventObject
aSource ( static_cast< ::cppu::OWeakObject
* >(this) );
1403 ::cppu::OInterfaceContainerHelper
* pContainer
= m_pData
->m_aInterfaceContainer
.getContainer( cppu::UnoType
<util::XCloseListener
>::get());
1404 if (pContainer
!=nullptr)
1406 ::cppu::OInterfaceIteratorHelper
pIterator(*pContainer
);
1407 while (pIterator
.hasMoreElements())
1411 static_cast<util::XCloseListener
*>(pIterator
.next())->queryClosing( aSource
, bDeliverOwnership
);
1413 catch( RuntimeException
& )
1420 if ( m_pData
->m_bSaving
)
1422 if (bDeliverOwnership
)
1423 m_pData
->m_bSuicide
= true;
1424 throw util::CloseVetoException(
1425 "Can not close while saving.",
1426 static_cast< util::XCloseable
* >(this));
1429 // no own objections against closing!
1430 m_pData
->m_bClosing
= true;
1431 pContainer
= m_pData
->m_aInterfaceContainer
.getContainer( cppu::UnoType
<util::XCloseListener
>::get());
1432 if (pContainer
!=nullptr)
1434 ::cppu::OInterfaceIteratorHelper
pCloseIterator(*pContainer
);
1435 while (pCloseIterator
.hasMoreElements())
1439 static_cast<util::XCloseListener
*>(pCloseIterator
.next())->notifyClosing( aSource
);
1441 catch( RuntimeException
& )
1443 pCloseIterator
.remove();
1448 m_pData
->m_bClosed
= true;
1449 m_pData
->m_bClosing
= false;
1455 // XCloseBroadcaster
1458 void SAL_CALL
SfxBaseModel::addCloseListener( const Reference
< util::XCloseListener
>& xListener
)
1460 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
1462 m_pData
->m_aInterfaceContainer
.addInterface( cppu::UnoType
<util::XCloseListener
>::get(), xListener
);
1466 // XCloseBroadcaster
1469 void SAL_CALL
SfxBaseModel::removeCloseListener( const Reference
< util::XCloseListener
>& xListener
)
1471 SfxModelGuard
aGuard( *this );
1473 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<util::XCloseListener
>::get(), xListener
);
1480 Sequence
< beans::PropertyValue
> SAL_CALL
SfxBaseModel::getPrinter()
1482 SfxModelGuard
aGuard( *this );
1484 impl_getPrintHelper();
1485 return m_pData
->m_xPrintable
->getPrinter();
1488 void SAL_CALL
SfxBaseModel::setPrinter(const Sequence
< beans::PropertyValue
>& rPrinter
)
1490 SfxModelGuard
aGuard( *this );
1492 impl_getPrintHelper();
1493 m_pData
->m_xPrintable
->setPrinter( rPrinter
);
1496 void SAL_CALL
SfxBaseModel::print(const Sequence
< beans::PropertyValue
>& rOptions
)
1498 SfxModelGuard
aGuard( *this );
1500 impl_getPrintHelper();
1502 // tdf#123728 Always print on main thread to avoid deadlocks
1503 vcl::solarthread::syncExecute([this, &rOptions
]() { m_pData
->m_xPrintable
->print(rOptions
); });
1509 sal_Bool SAL_CALL
SfxBaseModel::hasLocation()
1511 SfxModelGuard
aGuard( *this );
1513 return m_pData
->m_pObjectShell
.is() && m_pData
->m_pObjectShell
->HasName();
1520 OUString SAL_CALL
SfxBaseModel::getLocation()
1522 SfxModelGuard
aGuard( *this );
1524 if ( m_pData
->m_pObjectShell
.is() )
1526 // TODO/LATER: is it correct that the shared document returns shared file location?
1527 if ( m_pData
->m_pObjectShell
->IsDocShared() )
1528 return m_pData
->m_pObjectShell
->GetSharedFileURL();
1530 return m_pData
->m_pObjectShell
->GetMedium()->GetName();
1533 return m_pData
->m_sURL
;
1540 sal_Bool SAL_CALL
SfxBaseModel::isReadonly()
1542 SfxModelGuard
aGuard( *this );
1544 return !m_pData
->m_pObjectShell
.is() || m_pData
->m_pObjectShell
->IsReadOnly();
1550 void SAL_CALL
SfxBaseModel::storeSelf( const Sequence
< beans::PropertyValue
>& aSeqArgs
)
1552 SfxModelGuard
aGuard( *this );
1554 if ( !m_pData
->m_pObjectShell
.is() )
1557 SfxSaveGuard
aSaveGuard(this, m_pData
.get());
1559 bool bCheckIn
= false;
1560 bool bOnMainThread
= false;
1561 for ( const auto& rArg
: aSeqArgs
)
1563 // check that only acceptable parameters are provided here
1564 if ( rArg
.Name
!= "VersionComment" && rArg
.Name
!= "Author"
1565 && rArg
.Name
!= "DontTerminateEdit"
1566 && rArg
.Name
!= "InteractionHandler" && rArg
.Name
!= "StatusIndicator"
1567 && rArg
.Name
!= "VersionMajor"
1568 && rArg
.Name
!= "FailOnWarning"
1569 && rArg
.Name
!= "CheckIn"
1570 && rArg
.Name
!= "NoFileSync"
1571 && rArg
.Name
!= "OnMainThread" )
1573 const OUString
aMessage( "Unexpected MediaDescriptor parameter: " + rArg
.Name
);
1574 throw lang::IllegalArgumentException( aMessage
, Reference
< XInterface
>(), 1 );
1576 else if ( rArg
.Name
== "CheckIn" )
1578 rArg
.Value
>>= bCheckIn
;
1580 else if (rArg
.Name
== "OnMainThread")
1582 rArg
.Value
>>= bOnMainThread
;
1586 // Remove CheckIn property if needed
1587 sal_uInt16 nSlotId
= SID_SAVEDOC
;
1588 Sequence
< beans::PropertyValue
> aArgs
= aSeqArgs
;
1591 nSlotId
= SID_CHECKIN
;
1592 sal_Int32 nLength
= aSeqArgs
.getLength( );
1593 aArgs
= Sequence
< beans::PropertyValue
>( nLength
- 1 );
1594 std::copy_if(aSeqArgs
.begin(), aSeqArgs
.end(), aArgs
.begin(),
1595 [](const beans::PropertyValue
& rProp
) { return rProp
.Name
!= "CheckIn"; });
1598 std::unique_ptr
<SfxAllItemSet
> pParams(new SfxAllItemSet( SfxGetpApp()->GetPool() ));
1599 TransformParameters( nSlotId
, aArgs
, *pParams
);
1601 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveDoc
, GlobalEventConfig::GetEventName(GlobalEventId::SAVEDOC
), m_pData
->m_pObjectShell
.get() ) );
1605 // TODO/LATER: let the embedded case of saving be handled more careful
1606 if ( m_pData
->m_pObjectShell
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
1608 // If this is an embedded object that has no URL based location it should be stored to own storage.
1609 // An embedded object can have a location based on URL in case it is a link, then it should be
1610 // stored in normal way.
1611 if ( !hasLocation() || getLocation().startsWith("private:") )
1613 // actually in this very rare case only UI parameters have sense
1614 // TODO/LATER: should be done later, after integration of sb19
1615 bRet
= m_pData
->m_pObjectShell
->DoSave()
1616 && m_pData
->m_pObjectShell
->DoSaveCompleted();
1620 bRet
= m_pData
->m_pObjectShell
->Save_Impl( pParams
.get() );
1625 // Tell the SfxMedium if we are in checkin instead of normal save
1626 m_pData
->m_pObjectShell
->GetMedium( )->SetInCheckIn( nSlotId
== SID_CHECKIN
);
1628 bRet
= vcl::solarthread::syncExecute(
1629 [this, &pParams
] { return m_pData
->m_pObjectShell
->Save_Impl(pParams
.get()); });
1631 bRet
= m_pData
->m_pObjectShell
->Save_Impl(pParams
.get());
1632 m_pData
->m_pObjectShell
->GetMedium( )->SetInCheckIn( nSlotId
!= SID_CHECKIN
);
1637 ErrCode nErrCode
= m_pData
->m_pObjectShell
->GetError() ? m_pData
->m_pObjectShell
->GetError()
1638 : ERRCODE_IO_CANTWRITE
;
1639 m_pData
->m_pObjectShell
->ResetError();
1643 m_pData
->m_aPreusedFilterName
= GetMediumFilterName_Impl();
1645 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveDocDone
, GlobalEventConfig::GetEventName(GlobalEventId::SAVEDOCDONE
), m_pData
->m_pObjectShell
.get() ) );
1649 // write the contents of the logger to the file
1650 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveDocFailed
, GlobalEventConfig::GetEventName(GlobalEventId::SAVEDOCFAILED
), m_pData
->m_pObjectShell
.get() ) );
1652 throw task::ErrorCodeIOException(
1653 "SfxBaseModel::storeSelf: " + nErrCode
.toHexString(),
1654 Reference
< XInterface
>(), sal_uInt32(nErrCode
));
1662 void SAL_CALL
SfxBaseModel::store()
1664 comphelper::ProfileZone
aZone("store");
1665 storeSelf( Sequence
< beans::PropertyValue
>() );
1672 void SAL_CALL
SfxBaseModel::storeAsURL( const OUString
& rURL
,
1673 const Sequence
< beans::PropertyValue
>& rArgs
)
1675 SfxModelGuard
aGuard( *this );
1676 comphelper::ProfileZone
aZone("storeAs");
1678 if ( !m_pData
->m_pObjectShell
.is() )
1681 SfxSaveGuard
aSaveGuard(this, m_pData
.get());
1683 impl_store( rURL
, rArgs
, false );
1685 Sequence
< beans::PropertyValue
> aSequence
;
1686 TransformItems( SID_OPENDOC
, *m_pData
->m_pObjectShell
->GetMedium()->GetItemSet(), aSequence
);
1687 attachResource( rURL
, aSequence
);
1689 loadCmisProperties( );
1691 #if OSL_DEBUG_LEVEL > 0
1692 const SfxStringItem
* pPasswdItem
= SfxItemSet::GetItem
<SfxStringItem
>(m_pData
->m_pObjectShell
->GetMedium()->GetItemSet(), SID_PASSWORD
, false);
1693 OSL_ENSURE( !pPasswdItem
, "There should be no Password property in the document MediaDescriptor!" );
1698 // XUndoManagerSupplier
1700 Reference
< XUndoManager
> SAL_CALL
SfxBaseModel::getUndoManager( )
1702 SfxModelGuard
aGuard( *this );
1703 if ( !m_pData
->m_pDocumentUndoManager
.is() )
1704 m_pData
->m_pDocumentUndoManager
.set( new ::sfx2::DocumentUndoManager( *this ) );
1705 return m_pData
->m_pDocumentUndoManager
.get();
1712 void SAL_CALL
SfxBaseModel::storeToURL( const OUString
& rURL
,
1713 const Sequence
< beans::PropertyValue
>& rArgs
)
1715 SfxModelGuard
aGuard( *this );
1716 comphelper::ProfileZone
aZone("storeToURL");
1718 if ( !m_pData
->m_pObjectShell
.is() )
1721 SfxSaveGuard
aSaveGuard(this, m_pData
.get());
1723 utl::MediaDescriptor
aDescriptor(rArgs
);
1724 bool bOnMainThread
= aDescriptor
.getUnpackedValueOrDefault("OnMainThread", false);
1726 vcl::solarthread::syncExecute([this, rURL
, rArgs
]() { impl_store(rURL
, rArgs
, true); });
1728 impl_store(rURL
, rArgs
, true);
1730 catch (const uno::Exception
&e
)
1732 // convert to the exception we announce in the throw
1733 // (eg. neon likes to throw InteractiveAugmentedIOException which
1734 // is not an io::IOException)
1735 throw io::IOException(e
.Message
, e
.Context
);
1739 sal_Bool SAL_CALL
SfxBaseModel::wasModifiedSinceLastSave()
1741 SfxModelGuard
aGuard( *this );
1742 return m_pData
->m_bModifiedSinceLastSave
;
1745 void SAL_CALL
SfxBaseModel::storeToRecoveryFile( const OUString
& i_TargetLocation
, const Sequence
< PropertyValue
>& i_MediaDescriptor
)
1747 SfxModelGuard
aGuard( *this );
1750 SfxSaveGuard
aSaveGuard( this, m_pData
.get() );
1751 impl_store( i_TargetLocation
, i_MediaDescriptor
, true );
1753 // no need for subsequent calls to storeToRecoveryFile, unless we're modified, again
1754 m_pData
->m_bModifiedSinceLastSave
= false;
1757 void SAL_CALL
SfxBaseModel::recoverFromFile( const OUString
& i_SourceLocation
, const OUString
& i_SalvagedFile
, const Sequence
< PropertyValue
>& i_MediaDescriptor
)
1759 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
1761 // delegate to our "load" method
1762 ::comphelper::NamedValueCollection
aMediaDescriptor( i_MediaDescriptor
);
1764 // our load implementation expects the SalvagedFile to be in the media descriptor
1765 OSL_ENSURE( !aMediaDescriptor
.has( "SalvagedFile" ) || ( aMediaDescriptor
.getOrDefault( "SalvagedFile", OUString() ) == i_SalvagedFile
),
1766 "SfxBaseModel::recoverFromFile: inconsistent information!" );
1767 aMediaDescriptor
.put( "SalvagedFile", i_SalvagedFile
);
1769 // similar for the to-be-loaded file
1770 OSL_ENSURE( !aMediaDescriptor
.has( "URL" ) || ( aMediaDescriptor
.getOrDefault( "URL", OUString() ) == i_SourceLocation
),
1771 "SfxBaseModel::recoverFromFile: inconsistent information!" );
1772 aMediaDescriptor
.put( "URL", i_SourceLocation
);
1774 load( aMediaDescriptor
.getPropertyValues() );
1776 // Note: The XDocumentRecovery interface specification requires us to do an attachResource after loading.
1777 // However, we will not do this here, as we know that our load implementation (respectively some method
1778 // called from there) already did so.
1779 // In particular, the load process might already have modified some elements of the media
1780 // descriptor, for instance the MacroExecMode (in case the user was involved to decide about it), and we do
1781 // not want to overwrite it with the "old" elements passed to this method here.
1788 void SAL_CALL
SfxBaseModel::initNew()
1790 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
1791 if ( IsInitialized() )
1792 throw frame::DoubleInitializationException( OUString(), *this );
1794 // the object shell should exist always
1795 DBG_ASSERT( m_pData
->m_pObjectShell
.is(), "Model is useless without an ObjectShell" );
1796 if ( !m_pData
->m_pObjectShell
.is() )
1799 if( m_pData
->m_pObjectShell
->GetMedium() )
1800 throw frame::DoubleInitializationException();
1802 bool bRes
= m_pData
->m_pObjectShell
->DoInitNew();
1803 ErrCode nErrCode
= m_pData
->m_pObjectShell
->GetError() ?
1804 m_pData
->m_pObjectShell
->GetError() : ERRCODE_IO_CANTCREATE
;
1805 m_pData
->m_pObjectShell
->ResetError();
1808 throw task::ErrorCodeIOException(
1809 "SfxBaseModel::initNew: " + nErrCode
.toHexString(),
1810 Reference
< XInterface
>(), sal_uInt32(nErrCode
));
1815 OUString
getFilterProvider( SfxMedium
const & rMedium
)
1817 const std::shared_ptr
<const SfxFilter
>& pFilter
= rMedium
.GetFilter();
1821 return pFilter
->GetProviderName();
1824 void setUpdatePickList( SfxMedium
* pMedium
)
1829 bool bHidden
= false;
1830 const SfxBoolItem
* pHidItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_HIDDEN
, false);
1832 bHidden
= pHidItem
->GetValue();
1834 pMedium
->SetUpdatePickList(!bHidden
);
1839 void SAL_CALL
SfxBaseModel::load( const Sequence
< beans::PropertyValue
>& seqArguments
)
1841 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
1842 if ( IsInitialized() )
1843 throw frame::DoubleInitializationException( OUString(), *this );
1845 // the object shell should exist always
1846 DBG_ASSERT( m_pData
->m_pObjectShell
.is(), "Model is useless without an ObjectShell" );
1848 if (!m_pData
->m_pObjectShell
.is())
1851 if( m_pData
->m_pObjectShell
->GetMedium() )
1852 // if a Medium is present, the document is already initialized
1853 throw frame::DoubleInitializationException();
1855 SfxMedium
* pMedium
= new SfxMedium( seqArguments
);
1857 ErrCode nError
= ERRCODE_NONE
;
1858 if (!getFilterProvider(*pMedium
).isEmpty())
1860 if (!m_pData
->m_pObjectShell
->DoLoadExternal(pMedium
))
1861 nError
= ERRCODE_IO_GENERAL
;
1863 pMedium
= handleLoadError(nError
, pMedium
);
1864 setUpdatePickList(pMedium
);
1868 OUString aFilterName
;
1869 const SfxStringItem
* pFilterNameItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_FILTER_NAME
, false);
1870 if( pFilterNameItem
)
1871 aFilterName
= pFilterNameItem
->GetValue();
1872 if( !m_pData
->m_pObjectShell
->GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName
) )
1874 // filtername is not valid
1876 throw frame::IllegalArgumentIOException();
1879 const SfxStringItem
* pSalvageItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_DOC_SALVAGE
, false);
1880 bool bSalvage
= pSalvageItem
!= nullptr;
1883 if ( !m_pData
->m_pObjectShell
->DoLoad(pMedium
) )
1884 nError
=ERRCODE_IO_GENERAL
;
1886 // QUESTION: if the following happens outside of DoLoad, something important is missing there!
1887 Reference
< task::XInteractionHandler
> xHandler
= pMedium
->GetInteractionHandler();
1888 if( m_pData
->m_pObjectShell
->GetErrorCode() )
1890 nError
= m_pData
->m_pObjectShell
->GetErrorCode();
1891 if ( nError
== ERRCODE_IO_BROKENPACKAGE
&& xHandler
.is() )
1893 const OUString
aDocName( pMedium
->GetURLObject().getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::WithCharset
) );
1894 const SfxBoolItem
* pRepairItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_REPAIRPACKAGE
, false);
1895 if ( !pRepairItem
|| !pRepairItem
->GetValue() )
1897 RequestPackageReparation
aRequest( aDocName
);
1898 xHandler
->handle( aRequest
.GetRequest() );
1899 if( aRequest
.isApproved() )
1901 // broken package: try second loading and allow repair
1902 pMedium
->GetItemSet()->Put( SfxBoolItem( SID_REPAIRPACKAGE
, true ) );
1903 pMedium
->GetItemSet()->Put( SfxBoolItem( SID_TEMPLATE
, true ) );
1904 pMedium
->GetItemSet()->Put( SfxStringItem( SID_DOCINFO_TITLE
, aDocName
) );
1906 // the error must be reset and the storage must be reopened in new mode
1907 pMedium
->ResetError();
1908 pMedium
->CloseStorage();
1909 m_pData
->m_pObjectShell
->PrepareSecondTryLoad_Impl();
1910 nError
= ERRCODE_NONE
;
1911 if ( !m_pData
->m_pObjectShell
->DoLoad(pMedium
) )
1912 nError
=ERRCODE_IO_GENERAL
;
1913 if (m_pData
->m_pObjectShell
->GetErrorCode())
1914 nError
= m_pData
->m_pObjectShell
->GetErrorCode();
1918 if ( nError
== ERRCODE_IO_BROKENPACKAGE
)
1920 // repair either not allowed or not successful
1921 NotifyBrokenPackage
aRequest( aDocName
);
1922 xHandler
->handle( aRequest
.GetRequest() );
1927 if( m_pData
->m_pObjectShell
->IsAbortingImport() )
1928 nError
= ERRCODE_ABORT
;
1932 // file recovery: restore original filter
1933 const SfxStringItem
* pFilterItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_FILTER_NAME
, false);
1934 SfxFilterMatcher
& rMatcher
= SfxGetpApp()->GetFilterMatcher();
1935 std::shared_ptr
<const SfxFilter
> pSetFilter
= rMatcher
.GetFilter4FilterName( pFilterItem
->GetValue() );
1936 pMedium
->SetFilter( pSetFilter
);
1937 m_pData
->m_pObjectShell
->SetModified();
1940 // TODO/LATER: maybe the mode should be retrieved from outside and the preused filter should not be set
1941 if ( m_pData
->m_pObjectShell
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
1943 const SfxStringItem
* pFilterItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_FILTER_NAME
, false);
1945 m_pData
->m_aPreusedFilterName
= pFilterItem
->GetValue();
1949 nError
= pMedium
->GetError();
1951 m_pData
->m_pObjectShell
->ResetError();
1953 pMedium
= handleLoadError(nError
, pMedium
);
1954 loadCmisProperties();
1955 setUpdatePickList(pMedium
);
1957 #if OSL_DEBUG_LEVEL > 0
1958 const SfxStringItem
* pPasswdItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_PASSWORD
, false);
1959 OSL_ENSURE( !pPasswdItem
, "There should be no Password property in the document MediaDescriptor!" );
1967 Any SAL_CALL
SfxBaseModel::getTransferData( const datatransfer::DataFlavor
& aFlavor
)
1969 SfxModelGuard
aGuard( *this );
1973 if ( m_pData
->m_pObjectShell
.is() )
1975 if ( aFlavor
.MimeType
== "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" )
1977 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
1978 throw datatransfer::UnsupportedFlavorException();
1980 TransferableObjectDescriptor aDesc
;
1982 aDesc
.maClassName
= m_pData
->m_pObjectShell
->GetClassName();
1983 aDesc
.maTypeName
= aFlavor
.HumanPresentableName
;
1985 // TODO/LATER: ViewAspect needs to be sal_Int64
1986 aDesc
.mnViewAspect
= sal::static_int_cast
< sal_uInt16
>( embed::Aspects::MSOLE_CONTENT
);
1988 Size aSize
= m_pData
->m_pObjectShell
->GetVisArea().GetSize();
1990 MapUnit aMapUnit
= m_pData
->m_pObjectShell
->GetMapUnit();
1991 aDesc
.maSize
= OutputDevice::LogicToLogic(aSize
, MapMode(aMapUnit
), MapMode(MapUnit::Map100thMM
));
1992 aDesc
.maDragStartPos
= Point();
1993 aDesc
.maDisplayName
.clear();
1995 SvMemoryStream
aMemStm( 1024, 1024 );
1996 WriteTransferableObjectDescriptor( aMemStm
, aDesc
);
1997 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( aMemStm
.GetData() ), aMemStm
.Tell() );
1999 else if ( aFlavor
.MimeType
== "application/x-openoffice-embed-source;windows_formatname=\"Star EMBS\"" )
2001 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2002 throw datatransfer::UnsupportedFlavorException();
2007 aTmp
.EnableKillingFile();
2008 storeToURL( aTmp
.GetURL(), Sequence
< beans::PropertyValue
>() );
2009 std::unique_ptr
<SvStream
> pStream(aTmp
.GetStream( StreamMode::READ
));
2010 const sal_uInt32 nLen
= pStream
->TellEnd();
2011 Sequence
< sal_Int8
> aSeq( nLen
);
2012 pStream
->ReadBytes(aSeq
.getArray(), nLen
);
2013 if( aSeq
.hasElements() )
2016 catch ( Exception
& )
2020 else if ( aFlavor
.MimeType
== "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2022 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2023 throw datatransfer::UnsupportedFlavorException();
2026 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2027 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2031 SvMemoryStream
aMemStm( 65535, 65535 );
2032 aMemStm
.SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2034 xMetaFile
->Write( aMemStm
);
2035 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( aMemStm
.GetData() ),
2036 aMemStm
.TellEnd() );
2039 else if ( aFlavor
.MimeType
== "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2041 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2042 throw datatransfer::UnsupportedFlavorException();
2044 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2045 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2049 SvMemoryStream
aMemStm( 65535, 65535 );
2050 aMemStm
.SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2052 xMetaFile
->Write( aMemStm
);
2053 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( aMemStm
.GetData() ),
2054 aMemStm
.TellEnd() );
2057 else if ( aFlavor
.MimeType
== "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" )
2059 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2061 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2062 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2066 std::unique_ptr
<SvMemoryStream
> xStream(
2067 GraphicHelper::getFormatStrFromGDI_Impl(
2068 xMetaFile
.get(), ConvertDataFormat::EMF
) );
2071 xStream
->SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2072 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( xStream
->GetData() ),
2073 xStream
->TellEnd() );
2077 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2078 && aFlavor
.DataType
== cppu::UnoType
<sal_uInt64
>::get())
2080 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2081 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2085 aAny
<<= reinterpret_cast< sal_uInt64
>(
2086 GraphicHelper::getEnhMetaFileFromGDI_Impl( xMetaFile
.get() ) );
2090 throw datatransfer::UnsupportedFlavorException();
2092 else if ( aFlavor
.MimeType
== "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" )
2094 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2096 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2097 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2101 std::unique_ptr
<SvMemoryStream
> xStream(
2102 GraphicHelper::getFormatStrFromGDI_Impl(
2103 xMetaFile
.get(), ConvertDataFormat::WMF
) );
2107 xStream
->SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2108 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( xStream
->GetData() ),
2109 xStream
->TellEnd() );
2113 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2114 && aFlavor
.DataType
== cppu::UnoType
<sal_uInt64
>::get())
2116 // means HGLOBAL handler to memory storage containing METAFILEPICT structure
2118 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2119 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2123 Size aMetaSize
= xMetaFile
->GetPrefSize();
2124 aAny
<<= reinterpret_cast< sal_uInt64
>(
2125 GraphicHelper::getWinMetaFileFromGDI_Impl(
2126 xMetaFile
.get(), aMetaSize
) );
2130 throw datatransfer::UnsupportedFlavorException();
2132 else if ( aFlavor
.MimeType
== "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" )
2134 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2135 throw datatransfer::UnsupportedFlavorException();
2137 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2138 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2142 std::unique_ptr
<SvMemoryStream
> xStream(
2143 GraphicHelper::getFormatStrFromGDI_Impl(
2144 xMetaFile
.get(), ConvertDataFormat::BMP
) );
2148 xStream
->SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2149 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( xStream
->GetData() ),
2150 xStream
->TellEnd() );
2154 else if ( aFlavor
.MimeType
== "image/png" )
2156 if ( aFlavor
.DataType
!= cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2157 throw datatransfer::UnsupportedFlavorException();
2159 std::shared_ptr
<GDIMetaFile
> xMetaFile
=
2160 m_pData
->m_pObjectShell
->GetPreviewMetaFile( true );
2164 std::unique_ptr
<SvMemoryStream
> xStream(
2165 GraphicHelper::getFormatStrFromGDI_Impl(
2166 xMetaFile
.get(), ConvertDataFormat::PNG
) );
2170 xStream
->SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
2171 aAny
<<= Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( xStream
->GetData() ),
2172 xStream
->TellEnd() );
2177 throw datatransfer::UnsupportedFlavorException();
2187 Sequence
< datatransfer::DataFlavor
> SAL_CALL
SfxBaseModel::getTransferDataFlavors()
2189 SfxModelGuard
aGuard( *this );
2191 const sal_Int32 nSuppFlavors
= GraphicHelper::supportsMetaFileHandle_Impl() ? 10 : 8;
2192 Sequence
< datatransfer::DataFlavor
> aFlavorSeq( nSuppFlavors
);
2194 aFlavorSeq
[0].MimeType
=
2195 "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"";
2196 aFlavorSeq
[0].HumanPresentableName
= "GDIMetaFile";
2197 aFlavorSeq
[0].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2199 aFlavorSeq
[1].MimeType
=
2200 "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"";
2201 aFlavorSeq
[1].HumanPresentableName
= "GDIMetaFile";
2202 aFlavorSeq
[1].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2204 aFlavorSeq
[2].MimeType
=
2205 "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ;
2206 aFlavorSeq
[2].HumanPresentableName
= "Enhanced Windows MetaFile";
2207 aFlavorSeq
[2].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2209 aFlavorSeq
[3].MimeType
=
2210 "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"";
2211 aFlavorSeq
[3].HumanPresentableName
= "Windows MetaFile";
2212 aFlavorSeq
[3].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2214 aFlavorSeq
[4].MimeType
=
2215 "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"";
2216 aFlavorSeq
[4].HumanPresentableName
= "Star Object Descriptor (XML)";
2217 aFlavorSeq
[4].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2219 aFlavorSeq
[5].MimeType
=
2220 "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
2221 aFlavorSeq
[5].HumanPresentableName
= "Star Embed Source (XML)";
2222 aFlavorSeq
[5].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2224 aFlavorSeq
[6].MimeType
=
2225 "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"";
2226 aFlavorSeq
[6].HumanPresentableName
= "Bitmap";
2227 aFlavorSeq
[6].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2229 aFlavorSeq
[7].MimeType
= "image/png";
2230 aFlavorSeq
[7].HumanPresentableName
= "PNG";
2231 aFlavorSeq
[7].DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
2233 if ( nSuppFlavors
== 10 )
2235 aFlavorSeq
[8].MimeType
=
2236 "application/x-openoffice-emf;windows_formatname=\"Image EMF\"";
2237 aFlavorSeq
[8].HumanPresentableName
= "Enhanced Windows MetaFile";
2238 aFlavorSeq
[8].DataType
= cppu::UnoType
<sal_uInt64
>::get();
2240 aFlavorSeq
[9].MimeType
=
2241 "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"";
2242 aFlavorSeq
[9].HumanPresentableName
= "Windows MetaFile";
2243 aFlavorSeq
[9].DataType
= cppu::UnoType
<sal_uInt64
>::get();
2253 sal_Bool SAL_CALL
SfxBaseModel::isDataFlavorSupported( const datatransfer::DataFlavor
& aFlavor
)
2255 SfxModelGuard
aGuard( *this );
2257 if ( aFlavor
.MimeType
== "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2259 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2262 else if ( aFlavor
.MimeType
== "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2264 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2267 else if ( aFlavor
.MimeType
== "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" )
2269 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2271 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2272 && aFlavor
.DataType
== cppu::UnoType
<sal_uInt64
>::get())
2275 else if ( aFlavor
.MimeType
== "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" )
2277 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2279 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2280 && aFlavor
.DataType
== cppu::UnoType
<sal_uInt64
>::get())
2283 else if ( aFlavor
.MimeType
== "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" )
2285 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2288 else if ( aFlavor
.MimeType
== "application/x-openoffice-embed-source;windows_formatname=\"Star EMBS\"" )
2290 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2293 else if ( aFlavor
.MimeType
== "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" )
2295 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2298 else if ( aFlavor
.MimeType
== "image/png" )
2300 if ( aFlavor
.DataType
== cppu::UnoType
<Sequence
< sal_Int8
>>::get() )
2311 Reference
< container::XNameReplace
> SAL_CALL
SfxBaseModel::getEvents()
2313 SfxModelGuard
aGuard( *this );
2315 if ( ! m_pData
->m_xEvents
.is() )
2317 m_pData
->m_xEvents
= new SfxEvents_Impl( m_pData
->m_pObjectShell
.get(), this );
2320 return m_pData
->m_xEvents
;
2327 Reference
< script::XStorageBasedLibraryContainer
> SAL_CALL
SfxBaseModel::getBasicLibraries()
2329 SfxModelGuard
aGuard( *this );
2331 Reference
< script::XStorageBasedLibraryContainer
> xBasicLibraries
;
2332 if ( m_pData
->m_pObjectShell
.is() )
2333 xBasicLibraries
.set(m_pData
->m_pObjectShell
->GetBasicContainer(), UNO_QUERY
);
2334 return xBasicLibraries
;
2337 Reference
< script::XStorageBasedLibraryContainer
> SAL_CALL
SfxBaseModel::getDialogLibraries()
2339 SfxModelGuard
aGuard( *this );
2341 Reference
< script::XStorageBasedLibraryContainer
> xDialogLibraries
;
2342 if ( m_pData
->m_pObjectShell
.is() )
2343 xDialogLibraries
.set(m_pData
->m_pObjectShell
->GetDialogContainer(), UNO_QUERY
);
2344 return xDialogLibraries
;
2347 sal_Bool SAL_CALL
SfxBaseModel::getAllowMacroExecution()
2349 SfxModelGuard
aGuard( *this );
2351 if ( m_pData
->m_pObjectShell
.is() )
2352 return m_pData
->m_pObjectShell
->AdjustMacroMode();
2357 // XScriptInvocationContext
2360 Reference
< document::XEmbeddedScripts
> SAL_CALL
SfxBaseModel::getScriptContainer()
2362 SfxModelGuard
aGuard( *this );
2364 Reference
< document::XEmbeddedScripts
> xDocumentScripts
;
2368 Reference
< frame::XModel
> xDocument( this );
2369 xDocumentScripts
.set( xDocument
, UNO_QUERY
);
2370 while ( !xDocumentScripts
.is() && xDocument
.is() )
2372 Reference
< container::XChild
> xDocAsChild( xDocument
, UNO_QUERY
);
2373 if ( !xDocAsChild
.is() )
2375 xDocument
= nullptr;
2379 xDocument
.set( xDocAsChild
->getParent(), UNO_QUERY
);
2380 xDocumentScripts
.set( xDocument
, UNO_QUERY
);
2383 catch( const Exception
& )
2385 DBG_UNHANDLED_EXCEPTION("sfx.doc");
2386 xDocumentScripts
= nullptr;
2389 return xDocumentScripts
;
2393 // XEventBroadcaster
2396 void SAL_CALL
SfxBaseModel::addEventListener( const Reference
< document::XEventListener
>& aListener
)
2398 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
2400 m_pData
->m_aInterfaceContainer
.addInterface( cppu::UnoType
<document::XEventListener
>::get(), aListener
);
2404 // XEventBroadcaster
2407 void SAL_CALL
SfxBaseModel::removeEventListener( const Reference
< document::XEventListener
>& aListener
)
2409 SfxModelGuard
aGuard( *this );
2411 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<document::XEventListener
>::get(), aListener
);
2414 // XShapeEventBroadcaster
2416 void SAL_CALL
SfxBaseModel::addShapeEventListener( const css::uno::Reference
< css::drawing::XShape
>& xShape
, const Reference
< document::XShapeEventListener
>& xListener
)
2418 assert(xShape
.is() && "no shape?");
2419 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
2421 m_pData
->maShapeListeners
[xShape
].push_back(xListener
);
2425 // XShapeEventBroadcaster
2428 void SAL_CALL
SfxBaseModel::removeShapeEventListener( const css::uno::Reference
< css::drawing::XShape
>& xShape
, const Reference
< document::XShapeEventListener
>& xListener
)
2430 SfxModelGuard
aGuard( *this );
2432 auto it
= m_pData
->maShapeListeners
.find(xShape
);
2433 if (it
!= m_pData
->maShapeListeners
.end())
2435 auto rVec
= it
->second
;
2436 auto it2
= std::find(rVec
.begin(), rVec
.end(), xListener
);
2437 if (it2
!= rVec
.end())
2441 m_pData
->maShapeListeners
.erase(it
);
2446 // XDocumentEventBroadcaster
2449 void SAL_CALL
SfxBaseModel::addDocumentEventListener( const Reference
< document::XDocumentEventListener
>& aListener
)
2451 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
2452 m_pData
->m_aInterfaceContainer
.addInterface( cppu::UnoType
<document::XDocumentEventListener
>::get(), aListener
);
2456 void SAL_CALL
SfxBaseModel::removeDocumentEventListener( const Reference
< document::XDocumentEventListener
>& aListener
)
2458 SfxModelGuard
aGuard( *this );
2459 m_pData
->m_aInterfaceContainer
.removeInterface( cppu::UnoType
<document::XDocumentEventListener
>::get(), aListener
);
2463 void SAL_CALL
SfxBaseModel::notifyDocumentEvent( const OUString
&, const Reference
< frame::XController2
>&, const Any
& )
2465 throw lang::NoSupportException("SfxBaseModel controls all the sent notifications itself!" );
2468 Sequence
<document::CmisProperty
> SAL_CALL
SfxBaseModel::getCmisProperties()
2470 if (impl_isDisposed())
2471 return Sequence
<document::CmisProperty
>();
2472 return m_pData
->m_cmisProperties
;
2475 void SAL_CALL
SfxBaseModel::setCmisProperties( const Sequence
< document::CmisProperty
>& _cmisproperties
)
2477 m_pData
->m_cmisProperties
= _cmisproperties
;
2480 void SAL_CALL
SfxBaseModel::updateCmisProperties( const Sequence
< document::CmisProperty
>& aProperties
)
2482 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2488 ::ucbhelper::Content
aContent( pMedium
->GetName( ),
2489 Reference
<ucb::XCommandEnvironment
>(),
2490 comphelper::getProcessComponentContext() );
2492 aContent
.executeCommand( "updateProperties", uno::makeAny( aProperties
) );
2493 loadCmisProperties( );
2495 catch (const Exception
& e
)
2497 css::uno::Any anyEx
= cppu::getCaughtException();
2498 throw lang::WrappedTargetRuntimeException( e
.Message
,
2504 void SAL_CALL
SfxBaseModel::checkOut( )
2506 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2512 ::ucbhelper::Content
aContent( pMedium
->GetName(),
2513 Reference
<ucb::XCommandEnvironment
>(),
2514 comphelper::getProcessComponentContext() );
2516 Any aResult
= aContent
.executeCommand( "checkout", Any( ) );
2520 m_pData
->m_pObjectShell
->GetMedium( )->SetName( sURL
);
2521 m_pData
->m_pObjectShell
->GetMedium( )->GetMedium_Impl( );
2522 m_pData
->m_xDocumentProperties
->setTitle( getTitle( ) );
2523 Sequence
< beans::PropertyValue
> aSequence
;
2524 TransformItems( SID_OPENDOC
, *pMedium
->GetItemSet(), aSequence
);
2525 attachResource( sURL
, aSequence
);
2527 // Reload the CMIS properties
2528 loadCmisProperties( );
2530 catch ( const Exception
& e
)
2532 css::uno::Any anyEx
= cppu::getCaughtException();
2533 throw lang::WrappedTargetRuntimeException( e
.Message
,
2538 void SAL_CALL
SfxBaseModel::cancelCheckOut( )
2540 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2546 ::ucbhelper::Content
aContent( pMedium
->GetName(),
2547 Reference
<ucb::XCommandEnvironment
>(),
2548 comphelper::getProcessComponentContext() );
2550 Any aResult
= aContent
.executeCommand( "cancelCheckout", Any( ) );
2554 m_pData
->m_pObjectShell
->GetMedium( )->SetName( sURL
);
2556 catch ( const Exception
& e
)
2558 css::uno::Any anyEx
= cppu::getCaughtException();
2559 throw lang::WrappedTargetRuntimeException( e
.Message
,
2564 void SAL_CALL
SfxBaseModel::checkIn( sal_Bool bIsMajor
, const OUString
& rMessage
)
2566 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2572 Sequence
< beans::PropertyValue
> aProps( 3 );
2573 aProps
[0].Name
= "VersionMajor";
2574 aProps
[0].Value
<<= bIsMajor
;
2575 aProps
[1].Name
= "VersionComment";
2576 aProps
[1].Value
<<= rMessage
;
2577 aProps
[2].Name
= "CheckIn";
2578 aProps
[2].Value
<<= true;
2580 const OUString
sName( pMedium
->GetName( ) );
2581 storeSelf( aProps
);
2583 // Refresh pMedium as it has probably changed during the storeSelf call
2584 pMedium
= m_pData
->m_pObjectShell
->GetMedium( );
2585 const OUString
sNewName( pMedium
->GetName( ) );
2587 // URL has changed, update the document
2588 if ( sName
!= sNewName
)
2590 m_pData
->m_xDocumentProperties
->setTitle( getTitle( ) );
2591 Sequence
< beans::PropertyValue
> aSequence
;
2592 TransformItems( SID_OPENDOC
, *pMedium
->GetItemSet(), aSequence
);
2593 attachResource( sNewName
, aSequence
);
2595 // Reload the CMIS properties
2596 loadCmisProperties( );
2599 catch ( const Exception
& e
)
2601 css::uno::Any anyEx
= cppu::getCaughtException();
2602 throw lang::WrappedTargetRuntimeException( e
.Message
,
2607 uno::Sequence
< document::CmisVersion
> SAL_CALL
SfxBaseModel::getAllVersions( )
2609 uno::Sequence
<document::CmisVersion
> aVersions
;
2610 if (impl_isDisposed())
2612 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2617 ::ucbhelper::Content
aContent( pMedium
->GetName(),
2618 Reference
<ucb::XCommandEnvironment
>(),
2619 comphelper::getProcessComponentContext() );
2621 Any aResult
= aContent
.executeCommand( "getAllVersions", Any( ) );
2622 aResult
>>= aVersions
;
2624 catch ( const Exception
& e
)
2626 css::uno::Any anyEx
= cppu::getCaughtException();
2627 throw lang::WrappedTargetRuntimeException( e
.Message
,
2634 bool SfxBaseModel::getBoolPropertyValue( const OUString
& rName
)
2636 bool bValue
= false;
2637 if ( m_pData
->m_pObjectShell
.is() )
2639 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2644 ::ucbhelper::Content
aContent( pMedium
->GetName( ),
2645 utl::UCBContentHelper::getDefaultCommandEnvironment(),
2646 comphelper::getProcessComponentContext() );
2647 Reference
< beans::XPropertySetInfo
> xProps
= aContent
.getProperties();
2648 if ( xProps
->hasPropertyByName( rName
) )
2650 aContent
.getPropertyValue( rName
) >>= bValue
;
2653 catch ( const Exception
& )
2655 // Simply ignore it: it's likely the document isn't versionable in that case
2663 sal_Bool SAL_CALL
SfxBaseModel::isVersionable( )
2665 return getBoolPropertyValue( "IsVersionable" );
2668 sal_Bool SAL_CALL
SfxBaseModel::canCheckOut( )
2670 return getBoolPropertyValue( "CanCheckOut" );
2673 sal_Bool SAL_CALL
SfxBaseModel::canCancelCheckOut( )
2675 return getBoolPropertyValue( "CanCancelCheckOut" );
2678 sal_Bool SAL_CALL
SfxBaseModel::canCheckIn( )
2680 return getBoolPropertyValue( "CanCheckIn" );
2683 void SfxBaseModel::loadCmisProperties( )
2685 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2691 ::ucbhelper::Content
aContent( pMedium
->GetName( ),
2692 utl::UCBContentHelper::getDefaultCommandEnvironment(),
2693 comphelper::getProcessComponentContext() );
2694 Reference
< beans::XPropertySetInfo
> xProps
= aContent
.getProperties();
2695 const OUString
aCmisProps( "CmisProperties" );
2696 if ( xProps
->hasPropertyByName( aCmisProps
) )
2698 Sequence
< document::CmisProperty
> aCmisProperties
;
2699 aContent
.getPropertyValue( aCmisProps
) >>= aCmisProperties
;
2700 setCmisProperties( aCmisProperties
);
2703 catch (const ucb::ContentCreationException
&)
2706 catch (const ucb::CommandAbortedException
&)
2711 SfxMedium
* SfxBaseModel::handleLoadError( ErrCode nError
, SfxMedium
* pMedium
)
2715 // No error condition.
2719 bool bSilent
= false;
2720 const SfxBoolItem
* pSilentItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_SILENT
, false);
2722 bSilent
= pSilentItem
->GetValue();
2724 bool bWarning
= nError
.IsWarning();
2725 if ( nError
!= ERRCODE_IO_BROKENPACKAGE
&& !bSilent
)
2727 // broken package was handled already
2728 if ( SfxObjectShell::UseInteractionToHandleError(pMedium
->GetInteractionHandler(), nError
) && !bWarning
)
2730 // abort loading (except for warnings)
2731 nError
= ERRCODE_IO_ABORT
;
2735 if ( m_pData
->m_pObjectShell
->GetMedium() != pMedium
)
2737 // for whatever reason document now has another medium
2738 OSL_FAIL("Document has rejected the medium?!");
2743 if ( !bWarning
) // #i30711# don't abort loading if it's only a warning
2745 nError
= nError
? nError
: ERRCODE_IO_CANTREAD
;
2746 throw task::ErrorCodeIOException(
2747 "SfxBaseModel::handleLoadError: 0x" + nError
.toHexString(),
2748 Reference
< XInterface
>(), sal_uInt32(nError
));
2758 static void addTitle_Impl( Sequence
< beans::PropertyValue
>& rSeq
, const OUString
& rTitle
)
2760 auto pProp
= std::find_if(rSeq
.begin(), rSeq
.end(),
2761 [](const beans::PropertyValue
& rProp
) { return rProp
.Name
== "Title"; });
2762 if (pProp
!= rSeq
.end())
2764 pProp
->Value
<<= rTitle
;
2768 sal_Int32 nCount
= rSeq
.getLength();
2769 rSeq
.realloc( nCount
+1 );
2770 rSeq
[nCount
].Name
= "Title";
2771 rSeq
[nCount
].Value
<<= rTitle
;
2775 void SfxBaseModel::Notify( SfxBroadcaster
& rBC
,
2776 const SfxHint
& rHint
)
2781 if ( &rBC
!= m_pData
->m_pObjectShell
.get() )
2784 if ( rHint
.GetId() == SfxHintId::DocChanged
)
2787 const SfxEventHint
* pNamedHint
= dynamic_cast<const SfxEventHint
*>(&rHint
);
2791 switch ( pNamedHint
->GetEventId() )
2793 case SfxEventHintId::StorageChanged
:
2795 if ( m_pData
->m_xUIConfigurationManager
.is()
2796 && m_pData
->m_pObjectShell
->GetCreateMode() != SfxObjectCreateMode::EMBEDDED
)
2798 Reference
< embed::XStorage
> xConfigStorage
;
2799 const OUString
aUIConfigFolderName( "Configurations2" );
2801 xConfigStorage
= getDocumentSubStorage( aUIConfigFolderName
, embed::ElementModes::READWRITE
);
2802 if ( !xConfigStorage
.is() )
2803 xConfigStorage
= getDocumentSubStorage( aUIConfigFolderName
, embed::ElementModes::READ
);
2805 if ( xConfigStorage
.is() || !m_pData
->m_pObjectShell
->GetStorage()->hasByName( aUIConfigFolderName
) )
2807 // the storage is different, since otherwise it could not be opened, so it must be exchanged
2808 m_pData
->m_xUIConfigurationManager
->setStorage( xConfigStorage
);
2812 OSL_FAIL( "Unexpected scenario!" );
2816 ListenForStorage_Impl( m_pData
->m_pObjectShell
->GetStorage() );
2820 case SfxEventHintId::LoadFinished
:
2822 impl_getPrintHelper();
2823 ListenForStorage_Impl( m_pData
->m_pObjectShell
->GetStorage() );
2824 m_pData
->m_bModifiedSinceLastSave
= false;
2828 case SfxEventHintId::SaveAsDocDone
:
2830 m_pData
->m_sURL
= m_pData
->m_pObjectShell
->GetMedium()->GetName();
2832 SfxItemSet
*pSet
= m_pData
->m_pObjectShell
->GetMedium()->GetItemSet();
2833 Sequence
< beans::PropertyValue
> aArgs
;
2834 TransformItems( SID_SAVEASDOC
, *pSet
, aArgs
);
2835 addTitle_Impl( aArgs
, m_pData
->m_pObjectShell
->GetTitle() );
2836 attachResource( m_pData
->m_pObjectShell
->GetMedium()->GetName(), aArgs
);
2840 case SfxEventHintId::DocCreated
:
2842 impl_getPrintHelper();
2843 m_pData
->m_bModifiedSinceLastSave
= false;
2847 case SfxEventHintId::ModifyChanged
:
2849 m_pData
->m_bModifiedSinceLastSave
= isModified();
2855 const SfxViewEventHint
* pViewHint
= dynamic_cast<const SfxViewEventHint
*>(&rHint
);
2856 postEvent_Impl( pNamedHint
->GetEventName(), pViewHint
? pViewHint
->GetController() : Reference
< frame::XController2
>() );
2859 if ( rHint
.GetId() == SfxHintId::TitleChanged
)
2861 addTitle_Impl( m_pData
->m_seqArguments
, m_pData
->m_pObjectShell
->GetTitle() );
2862 postEvent_Impl( GlobalEventConfig::GetEventName( GlobalEventId::TITLECHANGED
) );
2864 else if ( rHint
.GetId() == SfxHintId::ModeChanged
)
2866 postEvent_Impl( GlobalEventConfig::GetEventName( GlobalEventId::MODECHANGED
) );
2874 void SfxBaseModel::NotifyModifyListeners_Impl() const
2876 ::cppu::OInterfaceContainerHelper
* pIC
= m_pData
->m_aInterfaceContainer
.getContainer( cppu::UnoType
<util::XModifyListener
>::get());
2879 lang::EventObject
aEvent( static_cast<frame::XModel
*>(const_cast<SfxBaseModel
*>(this)) );
2880 pIC
->notifyEach( &util::XModifyListener::modified
, aEvent
);
2883 // this notification here is done too generously, we cannot simply assume that we're really modified
2884 // now, but we need to check it ...
2885 m_pData
->m_bModifiedSinceLastSave
= const_cast< SfxBaseModel
* >( this )->isModified();
2888 void SfxBaseModel::changing()
2890 SfxModelGuard
aGuard( *this );
2892 // the notification should not be sent if the document can not be modified
2893 if ( !m_pData
->m_pObjectShell
.is() || !m_pData
->m_pObjectShell
->IsEnableSetModified() )
2896 NotifyModifyListeners_Impl();
2903 SfxObjectShell
* SfxBaseModel::GetObjectShell() const
2905 return m_pData
? m_pData
->m_pObjectShell
.get() : nullptr;
2912 bool SfxBaseModel::IsInitialized() const
2914 if ( !m_pData
|| !m_pData
->m_pObjectShell
.is() )
2916 OSL_FAIL( "SfxBaseModel::IsInitialized: this should have been caught earlier!" );
2920 return m_pData
->m_pObjectShell
->GetMedium() != nullptr;
2923 void SfxBaseModel::MethodEntryCheck( const bool i_mustBeInitialized
) const
2925 if ( impl_isDisposed() )
2926 throw lang::DisposedException( OUString(), *const_cast< SfxBaseModel
* >( this ) );
2927 if ( i_mustBeInitialized
&& !IsInitialized() )
2928 throw lang::NotInitializedException( OUString(), *const_cast< SfxBaseModel
* >( this ) );
2931 bool SfxBaseModel::impl_isDisposed() const
2933 return ( m_pData
== nullptr ) ;
2940 OUString
SfxBaseModel::GetMediumFilterName_Impl() const
2942 std::shared_ptr
<const SfxFilter
> pFilter
;
2943 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2945 pFilter
= pMedium
->GetFilter();
2948 return pFilter
->GetName();
2953 void SfxBaseModel::impl_store( const OUString
& sURL
,
2954 const Sequence
< beans::PropertyValue
>& seqArguments
,
2957 if( sURL
.isEmpty() )
2958 throw frame::IllegalArgumentIOException();
2960 bool bSaved
= false;
2961 if ( !bSaveTo
&& m_pData
->m_pObjectShell
.is() && !sURL
.isEmpty()
2962 && !sURL
.startsWith( "private:stream" )
2963 && ::utl::UCBContentHelper::EqualURLs( getLocation(), sURL
) )
2965 // this is the same file URL as the current document location, try to use storeOwn if possible
2967 ::comphelper::SequenceAsHashMap
aArgHash( seqArguments
);
2968 const OUString
aFilterString( "FilterName" );
2969 const OUString
aFilterName( aArgHash
.getUnpackedValueOrDefault( aFilterString
, OUString() ) );
2970 if ( !aFilterName
.isEmpty() )
2972 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
2975 const std::shared_ptr
<const SfxFilter
>& pFilter
= pMedium
->GetFilter();
2976 if ( pFilter
&& aFilterName
== pFilter
->GetFilterName() )
2978 // #i119366# - If the former file saving with password, do not trying in StoreSelf anyway...
2979 bool bFormerPassword
= false;
2981 uno::Sequence
< beans::NamedValue
> aOldEncryptionData
;
2982 if (GetEncryptionData_Impl( pMedium
->GetItemSet(), aOldEncryptionData
))
2984 bFormerPassword
= true;
2987 if ( !bFormerPassword
)
2989 aArgHash
.erase( aFilterString
);
2990 aArgHash
.erase( "URL" );
2994 storeSelf( aArgHash
.getAsConstPropertyValueList() );
2997 catch( const lang::IllegalArgumentException
& )
2999 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
3000 // some additional arguments do not allow to use saving, SaveAs should be done
3001 // but only for normal documents, the shared documents would be overwritten in this case
3002 // that would mean an information loss
3003 // TODO/LATER: need a new interaction for this case
3004 if ( m_pData
->m_pObjectShell
->IsDocShared() )
3006 uno::Sequence
< beans::NamedValue
> aNewEncryptionData
= aArgHash
.getUnpackedValueOrDefault("EncryptionData", uno::Sequence
< beans::NamedValue
>() );
3007 if ( !aNewEncryptionData
.hasElements() )
3009 aNewEncryptionData
= ::comphelper::OStorageHelper::CreatePackageEncryptionData( aArgHash
.getUnpackedValueOrDefault("Password", OUString()) );
3012 uno::Sequence
< beans::NamedValue
> aOldEncryptionData
;
3013 (void)GetEncryptionData_Impl( pMedium
->GetItemSet(), aOldEncryptionData
);
3015 if ( !aOldEncryptionData
.hasElements() && !aNewEncryptionData
.hasElements() )
3019 // if the password is changed a special error should be used in case of shared document
3020 throw task::ErrorCodeIOException("Can not change password for shared document.", uno::Reference
< uno::XInterface
>(), sal_uInt32(ERRCODE_SFX_SHARED_NOPASSWORDCHANGE
) );
3031 if ( bSaved
|| !m_pData
->m_pObjectShell
.is() )
3034 SfxGetpApp()->NotifyEvent( SfxEventHint( bSaveTo
? SfxEventHintId::SaveToDoc
: SfxEventHintId::SaveAsDoc
, GlobalEventConfig::GetEventName( bSaveTo
? GlobalEventId::SAVETODOC
: GlobalEventId::SAVEASDOC
),
3035 m_pData
->m_pObjectShell
.get() ) );
3037 std::unique_ptr
<SfxAllItemSet
> pItemSet(new SfxAllItemSet(SfxGetpApp()->GetPool()));
3038 pItemSet
->Put(SfxStringItem(SID_FILE_NAME
, sURL
));
3040 pItemSet
->Put(SfxBoolItem(SID_SAVETO
, true));
3042 TransformParameters(SID_SAVEASDOC
, seqArguments
, *pItemSet
);
3044 const SfxBoolItem
* pCopyStreamItem
= pItemSet
->GetItem
<SfxBoolItem
>(SID_COPY_STREAM_IF_POSSIBLE
, false);
3046 if ( pCopyStreamItem
&& pCopyStreamItem
->GetValue() && !bSaveTo
)
3048 throw frame::IllegalArgumentIOException(
3049 "CopyStreamIfPossible parameter is not acceptable for storeAsURL() call!" );
3052 sal_uInt32 nModifyPasswordHash
= 0;
3053 Sequence
< beans::PropertyValue
> aModifyPasswordInfo
;
3054 const SfxUnoAnyItem
* pModifyPasswordInfoItem
= pItemSet
->GetItem
<SfxUnoAnyItem
>(SID_MODIFYPASSWORDINFO
, false);
3055 if ( pModifyPasswordInfoItem
)
3057 // it contains either a simple hash or a set of PropertyValues
3058 // TODO/LATER: the sequence of PropertyValue should replace the hash completely in future
3059 sal_Int32 nMPHTmp
= 0;
3060 pModifyPasswordInfoItem
->GetValue() >>= nMPHTmp
;
3061 nModifyPasswordHash
= static_cast<sal_uInt32
>(nMPHTmp
);
3062 pModifyPasswordInfoItem
->GetValue() >>= aModifyPasswordInfo
;
3064 pItemSet
->ClearItem(SID_MODIFYPASSWORDINFO
);
3065 sal_uInt32 nOldModifyPasswordHash
= m_pData
->m_pObjectShell
->GetModifyPasswordHash();
3066 m_pData
->m_pObjectShell
->SetModifyPasswordHash( nModifyPasswordHash
);
3067 Sequence
< beans::PropertyValue
> aOldModifyPasswordInfo
= m_pData
->m_pObjectShell
->GetModifyPasswordInfo();
3068 m_pData
->m_pObjectShell
->SetModifyPasswordInfo( aModifyPasswordInfo
);
3070 // since saving a document modifies its DocumentProperties, the current
3071 // DocumentProperties must be saved on "SaveTo", so it can be restored
3073 bool bCopyTo
= bSaveTo
||
3074 m_pData
->m_pObjectShell
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
;
3075 Reference
<document::XDocumentProperties
> xOldDocProps
;
3078 xOldDocProps
= getDocumentProperties();
3079 const Reference
<util::XCloneable
> xCloneable(xOldDocProps
,
3081 const Reference
<document::XDocumentProperties
> xNewDocProps(
3082 xCloneable
->createClone(), UNO_QUERY_THROW
);
3083 m_pData
->m_xDocumentProperties
= xNewDocProps
;
3086 bool bRet
= m_pData
->m_pObjectShell
->APISaveAs_Impl(sURL
, *pItemSet
, seqArguments
);
3090 // restore DocumentProperties if a copy was created
3091 m_pData
->m_xDocumentProperties
= xOldDocProps
;
3094 Reference
< task::XInteractionHandler
> xHandler
;
3095 const SfxUnoAnyItem
* pItem
= pItemSet
->GetItem
<SfxUnoAnyItem
>(SID_INTERACTIONHANDLER
, false);
3097 pItem
->GetValue() >>= xHandler
;
3101 ErrCode nErrCode
= m_pData
->m_pObjectShell
->GetErrorCode();
3102 if ( !bRet
&& !nErrCode
)
3104 SAL_WARN("sfx.doc", "Storing has failed, no error is set!");
3105 nErrCode
= ERRCODE_IO_CANTWRITE
;
3107 m_pData
->m_pObjectShell
->ResetError();
3113 // must be a warning - use Interactionhandler if possible or abandon
3114 if ( xHandler
.is() )
3116 // TODO/LATER: a general way to set the error context should be available
3117 SfxErrorContext
aEc( ERRCTX_SFX_SAVEASDOC
, m_pData
->m_pObjectShell
->GetTitle() );
3119 task::ErrorCodeRequest aErrorCode
;
3120 aErrorCode
.ErrCode
= sal_uInt32(nErrCode
);
3121 SfxMedium::CallApproveHandler( xHandler
, makeAny( aErrorCode
), false );
3127 m_pData
->m_aPreusedFilterName
= GetMediumFilterName_Impl();
3128 m_pData
->m_pObjectShell
->SetModifyPasswordEntered();
3130 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveAsDocDone
, GlobalEventConfig::GetEventName(GlobalEventId::SAVEASDOCDONE
), m_pData
->m_pObjectShell
.get() ) );
3134 m_pData
->m_pObjectShell
->SetModifyPasswordHash( nOldModifyPasswordHash
);
3135 m_pData
->m_pObjectShell
->SetModifyPasswordInfo( aOldModifyPasswordInfo
);
3137 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveToDocDone
, GlobalEventConfig::GetEventName(GlobalEventId::SAVETODOCDONE
), m_pData
->m_pObjectShell
.get() ) );
3142 m_pData
->m_pObjectShell
->SetModifyPasswordHash( nOldModifyPasswordHash
);
3143 m_pData
->m_pObjectShell
->SetModifyPasswordInfo( aOldModifyPasswordInfo
);
3146 SfxGetpApp()->NotifyEvent( SfxEventHint( bSaveTo
? SfxEventHintId::SaveToDocFailed
: SfxEventHintId::SaveAsDocFailed
, GlobalEventConfig::GetEventName( bSaveTo
? GlobalEventId::SAVETODOCFAILED
: GlobalEventId::SAVEASDOCFAILED
),
3147 m_pData
->m_pObjectShell
.get() ) );
3149 std::stringstream aErrCode
;
3150 aErrCode
<< nErrCode
;
3151 throw task::ErrorCodeIOException(
3152 "SfxBaseModel::impl_store <" + sURL
+ "> failed: " + OUString::fromUtf8(aErrCode
.str().c_str()),
3153 Reference
< XInterface
>(), sal_uInt32(nErrCode
));
3159 template< typename ListenerT
, typename EventT
>
3160 class NotifySingleListenerIgnoreRE
3163 typedef void ( SAL_CALL
ListenerT::*NotificationMethod
)( const EventT
& );
3164 NotificationMethod m_pMethod
;
3165 const EventT
& m_rEvent
;
3167 NotifySingleListenerIgnoreRE( NotificationMethod method
, const EventT
& event
) : m_pMethod( method
), m_rEvent( event
) { }
3169 void operator()( const Reference
<ListenerT
>& listener
) const
3173 (listener
.get()->*m_pMethod
)( m_rEvent
);
3175 catch( RuntimeException
& )
3177 // this exception is ignored to avoid problems with invalid listeners, the listener should be probably thrown away in future
3181 } // anonymous namespace
3183 void SfxBaseModel::postEvent_Impl( const OUString
& aName
, const Reference
< frame::XController2
>& xController
)
3185 // object already disposed?
3186 if ( impl_isDisposed() )
3189 // keep m_pData alive, if notified target would dispose the document
3190 std::shared_ptr
<IMPL_SfxBaseModel_DataContainer
> xKeepAlive(m_pData
);
3192 // also make sure this object doesn't self-destruct while notifying
3193 rtl::Reference
<SfxBaseModel
> xHoldAlive(this);
3195 DBG_ASSERT( !aName
.isEmpty(), "Empty event name!" );
3196 if (aName
.isEmpty())
3199 ::cppu::OInterfaceContainerHelper
* pIC
=
3200 m_pData
->m_aInterfaceContainer
.getContainer( cppu::UnoType
<document::XDocumentEventListener
>::get());
3203 SAL_INFO("sfx.doc", "SfxDocumentEvent: " + aName
);
3205 document::DocumentEvent
aDocumentEvent( static_cast<frame::XModel
*>(this), aName
, xController
, Any() );
3207 pIC
->forEach
< document::XDocumentEventListener
, NotifySingleListenerIgnoreRE
< document::XDocumentEventListener
, document::DocumentEvent
> >(
3208 NotifySingleListenerIgnoreRE
< document::XDocumentEventListener
, document::DocumentEvent
>(
3209 &document::XDocumentEventListener::documentEventOccured
,
3213 pIC
= m_pData
->m_aInterfaceContainer
.getContainer( cppu::UnoType
<document::XEventListener
>::get());
3216 SAL_INFO("sfx.doc", "SfxEvent: " + aName
);
3218 document::EventObject
aEvent( static_cast<frame::XModel
*>(this), aName
);
3220 pIC
->forEach
< document::XEventListener
, NotifySingleListenerIgnoreRE
< document::XEventListener
, document::EventObject
> >(
3221 NotifySingleListenerIgnoreRE
< document::XEventListener
, document::EventObject
>(
3222 &document::XEventListener::notifyEvent
,
3228 Reference
< container::XIndexAccess
> SAL_CALL
SfxBaseModel::getViewData()
3230 SfxModelGuard
aGuard( *this );
3232 if ( m_pData
->m_pObjectShell
.is() && !m_pData
->m_contViewData
.is() )
3234 SfxViewFrame
*pActFrame
= SfxViewFrame::Current();
3235 if ( !pActFrame
|| pActFrame
->GetObjectShell() != m_pData
->m_pObjectShell
.get() )
3236 pActFrame
= SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get() );
3238 if ( !pActFrame
|| !pActFrame
->GetViewShell() )
3239 // currently no frame for this document at all or View is under construction
3240 return Reference
< container::XIndexAccess
>();
3242 m_pData
->m_contViewData
= document::IndexedPropertyValues::create( ::comphelper::getProcessComponentContext() );
3244 if ( !m_pData
->m_contViewData
.is() )
3246 // error: no container class available!
3247 return Reference
< container::XIndexAccess
>();
3250 Reference
< container::XIndexContainer
> xCont( m_pData
->m_contViewData
, UNO_QUERY
);
3251 sal_Int32 nCount
= 0;
3252 Sequence
< beans::PropertyValue
> aSeq
;
3253 for ( SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get() ); pFrame
;
3254 pFrame
= SfxViewFrame::GetNext( *pFrame
, m_pData
->m_pObjectShell
.get() ) )
3256 bool bIsActive
= ( pFrame
== pActFrame
);
3257 pFrame
->GetViewShell()->WriteUserDataSequence( aSeq
);
3258 xCont
->insertByIndex( bIsActive
? 0 : nCount
, Any(aSeq
) );
3263 return m_pData
->m_contViewData
;
3266 void SAL_CALL
SfxBaseModel::setViewData( const Reference
< container::XIndexAccess
>& aData
)
3268 SfxModelGuard
aGuard( *this );
3270 m_pData
->m_contViewData
= aData
;
3273 /** calls all XEventListeners */
3274 void SfxBaseModel::notifyEvent( const document::EventObject
& aEvent
) const
3276 // object already disposed?
3277 if ( impl_isDisposed() )
3280 ::cppu::OInterfaceContainerHelper
* pIC
= m_pData
->m_aInterfaceContainer
.getContainer(
3281 cppu::UnoType
<document::XEventListener
>::get());
3286 ::cppu::OInterfaceIteratorHelper
aIt( *pIC
);
3287 while( aIt
.hasMoreElements() )
3291 static_cast<document::XEventListener
*>(aIt
.next())->notifyEvent( aEvent
);
3293 catch( RuntimeException
& )
3298 // for right now, we're only doing the event that this particular performance problem needed
3299 if (aEvent
.EventName
== "ShapeModified")
3301 uno::Reference
<drawing::XShape
> xShape(aEvent
.Source
, uno::UNO_QUERY
);
3304 auto it
= m_pData
->maShapeListeners
.find(xShape
);
3305 if (it
!= m_pData
->maShapeListeners
.end())
3306 for (auto const & rListenerUnoRef
: it
->second
)
3307 rListenerUnoRef
->notifyShapeEvent(aEvent
);
3312 /** returns true if someone added a XEventListener to this XEventBroadcaster */
3313 bool SfxBaseModel::hasEventListeners() const
3315 return !impl_isDisposed()
3316 && ( (nullptr != m_pData
->m_aInterfaceContainer
.getContainer( cppu::UnoType
<document::XEventListener
>::get()) )
3317 || !m_pData
->maShapeListeners
.empty());
3320 void SAL_CALL
SfxBaseModel::addPrintJobListener( const Reference
< view::XPrintJobListener
>& xListener
)
3322 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
3324 impl_getPrintHelper();
3325 Reference
< view::XPrintJobBroadcaster
> xPJB( m_pData
->m_xPrintable
, UNO_QUERY
);
3327 xPJB
->addPrintJobListener( xListener
);
3330 void SAL_CALL
SfxBaseModel::removePrintJobListener( const Reference
< view::XPrintJobListener
>& xListener
)
3332 SfxModelGuard
aGuard( *this );
3334 impl_getPrintHelper();
3335 Reference
< view::XPrintJobBroadcaster
> xPJB( m_pData
->m_xPrintable
, UNO_QUERY
);
3337 xPJB
->removePrintJobListener( xListener
);
3340 sal_Int64 SAL_CALL
SfxBaseModel::getSomething( const Sequence
< sal_Int8
>& aIdentifier
)
3342 SvGlobalName
aName( aIdentifier
);
3343 if (aName
== SvGlobalName( SFX_GLOBAL_CLASSID
))
3345 SolarMutexGuard aGuard
;
3346 SfxObjectShell
*const pObjectShell(GetObjectShell());
3349 return reinterpret_cast<sal_Int64
>(pObjectShell
);
3357 // XDocumentSubStorageSupplier
3360 void SfxBaseModel::ListenForStorage_Impl( const Reference
< embed::XStorage
>& xStorage
)
3362 Reference
< util::XModifiable
> xModifiable( xStorage
, UNO_QUERY
);
3363 if ( xModifiable
.is() )
3365 if ( !m_pData
->m_pStorageModifyListen
.is() )
3367 m_pData
->m_pStorageModifyListen
= new ::sfx2::DocumentStorageModifyListener( *m_pData
, Application::GetSolarMutex() );
3370 // no need to deregister the listening for old storage since it should be disposed automatically
3371 xModifiable
->addModifyListener( m_pData
->m_pStorageModifyListen
.get() );
3375 Reference
< embed::XStorage
> SAL_CALL
SfxBaseModel::getDocumentSubStorage( const OUString
& aStorageName
, sal_Int32 nMode
)
3377 SfxModelGuard
aGuard( *this );
3379 Reference
< embed::XStorage
> xResult
;
3380 if ( m_pData
->m_pObjectShell
.is() )
3382 Reference
< embed::XStorage
> xStorage
= m_pData
->m_pObjectShell
->GetStorage();
3383 if ( xStorage
.is() )
3387 xResult
= xStorage
->openStorageElement( aStorageName
, nMode
);
3389 catch ( Exception
& )
3398 Sequence
< OUString
> SAL_CALL
SfxBaseModel::getDocumentSubStoragesNames()
3400 SfxModelGuard
aGuard( *this );
3402 Sequence
< OUString
> aResult
;
3403 bool bSuccess
= false;
3404 if ( m_pData
->m_pObjectShell
.is() )
3406 Reference
< embed::XStorage
> xStorage
= m_pData
->m_pObjectShell
->GetStorage();
3407 if ( xStorage
.is() )
3409 const Sequence
< OUString
> aTemp
= xStorage
->getElementNames();
3410 sal_Int32 nResultSize
= 0;
3411 for ( const auto& rName
: aTemp
)
3413 if ( xStorage
->isStorageElement( rName
) )
3415 aResult
.realloc( ++nResultSize
);
3416 aResult
[ nResultSize
- 1 ] = rName
;
3425 throw io::IOException();
3431 // XScriptProviderSupplier
3434 Reference
< script::provider::XScriptProvider
> SAL_CALL
SfxBaseModel::getScriptProvider()
3436 SfxModelGuard
aGuard( *this );
3438 Reference
< script::provider::XScriptProviderFactory
> xScriptProviderFactory
=
3439 script::provider::theMasterScriptProviderFactory::get( ::comphelper::getProcessComponentContext() );
3441 Reference
< XScriptInvocationContext
> xScriptContext( this );
3443 Reference
< script::provider::XScriptProvider
> xScriptProvider(
3444 xScriptProviderFactory
->createScriptProvider( makeAny( xScriptContext
) ),
3447 return xScriptProvider
;
3451 // XUIConfigurationManagerSupplier
3454 OUString
const & SfxBaseModel::getRuntimeUID() const
3456 OSL_ENSURE( !m_pData
->m_sRuntimeUID
.isEmpty(),
3457 "SfxBaseModel::getRuntimeUID - ID is empty!" );
3458 return m_pData
->m_sRuntimeUID
;
3461 bool SfxBaseModel::hasValidSignatures() const
3463 SolarMutexGuard aGuard
;
3464 if ( m_pData
->m_pObjectShell
.is() )
3465 return ( m_pData
->m_pObjectShell
->ImplGetSignatureState() == SignatureState::OK
);
3469 void SfxBaseModel::getGrabBagItem(css::uno::Any
& rVal
) const
3471 if (m_pData
->m_xGrabBagItem
)
3472 m_pData
->m_xGrabBagItem
->QueryValue(rVal
);
3474 rVal
<<= uno::Sequence
<beans::PropertyValue
>();
3477 void SfxBaseModel::setGrabBagItem(const css::uno::Any
& rVal
)
3479 if (!m_pData
->m_xGrabBagItem
)
3480 m_pData
->m_xGrabBagItem
= std::make_shared
<SfxGrabBagItem
>();
3482 m_pData
->m_xGrabBagItem
->PutValue(rVal
, 0);
3485 static void GetCommandFromSequence( OUString
& rCommand
, sal_Int32
& nIndex
, const Sequence
< beans::PropertyValue
>& rSeqPropValue
)
3489 auto pPropValue
= std::find_if(rSeqPropValue
.begin(), rSeqPropValue
.end(),
3490 [](const beans::PropertyValue
& rPropValue
) { return rPropValue
.Name
== "Command"; });
3491 if (pPropValue
!= rSeqPropValue
.end())
3493 pPropValue
->Value
>>= rCommand
;
3494 nIndex
= static_cast<sal_Int32
>(std::distance(rSeqPropValue
.begin(), pPropValue
));
3498 static void ConvertSlotsToCommands( SfxObjectShell
const * pDoc
, Reference
< container::XIndexContainer
> const & rToolbarDefinition
)
3503 SfxModule
* pModule( pDoc
->GetFactory().GetModule() );
3504 Sequence
< beans::PropertyValue
> aSeqPropValue
;
3506 for ( sal_Int32 i
= 0; i
< rToolbarDefinition
->getCount(); i
++ )
3508 if ( rToolbarDefinition
->getByIndex( i
) >>= aSeqPropValue
)
3511 sal_Int32
nIndex( -1 );
3512 GetCommandFromSequence( aCommand
, nIndex
, aSeqPropValue
);
3513 if ( nIndex
>= 0 && aCommand
.startsWith( "slot:" ) )
3515 const sal_uInt16 nSlot
= aCommand
.copy( 5 ).toInt32();
3517 // We have to replace the old "slot-Command" with our new ".uno:-Command"
3518 const SfxSlot
* pSlot
= pModule
->GetSlotPool()->GetSlot( nSlot
);
3521 OUStringBuffer
aStrBuf( ".uno:" );
3522 aStrBuf
.appendAscii( pSlot
->GetUnoName() );
3524 aCommand
= aStrBuf
.makeStringAndClear();
3525 aSeqPropValue
[nIndex
].Value
<<= aCommand
;
3526 rToolbarDefinition
->replaceByIndex( i
, Any( aSeqPropValue
));
3533 Reference
< ui::XUIConfigurationManager
> SAL_CALL
SfxBaseModel::getUIConfigurationManager()
3535 return Reference
< ui::XUIConfigurationManager
>( getUIConfigurationManager2(), UNO_QUERY_THROW
);
3538 Reference
< ui::XUIConfigurationManager2
> SfxBaseModel::getUIConfigurationManager2()
3540 SfxModelGuard
aGuard( *this );
3542 if ( !m_pData
->m_xUIConfigurationManager
.is() )
3544 Reference
< ui::XUIConfigurationManager2
> xNewUIConfMan
=
3545 ui::UIConfigurationManager::create( comphelper::getProcessComponentContext() );
3547 Reference
< embed::XStorage
> xConfigStorage
;
3549 OUString
aUIConfigFolderName( "Configurations2" );
3550 // First try to open with READWRITE and then READ
3551 xConfigStorage
= getDocumentSubStorage( aUIConfigFolderName
, embed::ElementModes::READWRITE
);
3552 if ( xConfigStorage
.is() )
3554 const OUString
aMediaTypeProp( "MediaType" );
3555 OUString aMediaType
;
3556 Reference
< beans::XPropertySet
> xPropSet( xConfigStorage
, UNO_QUERY
);
3557 Any a
= xPropSet
->getPropertyValue( aMediaTypeProp
);
3558 if ( !( a
>>= aMediaType
) || aMediaType
.isEmpty())
3560 xPropSet
->setPropertyValue( aMediaTypeProp
, Any(OUString("application/vnd.sun.xml.ui.configuration")) );
3564 xConfigStorage
= getDocumentSubStorage( aUIConfigFolderName
, embed::ElementModes::READ
);
3566 // initialize ui configuration manager with document substorage
3567 xNewUIConfMan
->setStorage( xConfigStorage
);
3569 // embedded objects did not support local configuration data until OOo 3.0, so there's nothing to
3571 if ( m_pData
->m_pObjectShell
->GetCreateMode() != SfxObjectCreateMode::EMBEDDED
)
3573 // Import old UI configuration from OOo 1.x
3575 // Try to open with READ
3576 Reference
< embed::XStorage
> xOOo1ConfigStorage
= getDocumentSubStorage( "Configurations", embed::ElementModes::READ
);
3577 if ( xOOo1ConfigStorage
.is() )
3579 Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
3580 std::vector
< Reference
< container::XIndexContainer
> > rToolbars
;
3582 bool bImported
= framework::UIConfigurationImporterOOo1x::ImportCustomToolbars(
3583 xNewUIConfMan
, rToolbars
, xContext
, xOOo1ConfigStorage
);
3586 SfxObjectShell
* pObjShell
= SfxBaseModel::GetObjectShell();
3588 for ( size_t i
= 0; i
< rToolbars
.size(); i
++ )
3590 const OUString
sId(OUString::number( i
+ 1 ));
3591 const OUString aCustomTbxName
= "private:resource/toolbar/custom_OOo1x_" + sId
;
3593 Reference
< container::XIndexContainer
> xToolbar
= rToolbars
[i
];
3594 ConvertSlotsToCommands( pObjShell
, xToolbar
);
3595 if ( !xNewUIConfMan
->hasSettings( aCustomTbxName
))
3597 // Set UIName for the toolbar with container property
3598 Reference
< beans::XPropertySet
> xPropSet( xToolbar
, UNO_QUERY
);
3599 if ( xPropSet
.is() )
3603 xPropSet
->setPropertyValue( "UIName", Any( "Toolbar " + sId
) );
3605 catch ( beans::UnknownPropertyException
& )
3610 xNewUIConfMan
->insertSettings( aCustomTbxName
, xToolbar
);
3611 xNewUIConfMan
->store();
3618 m_pData
->m_xUIConfigurationManager
= xNewUIConfMan
;
3621 return m_pData
->m_xUIConfigurationManager
;
3628 void SAL_CALL
SfxBaseModel::setVisualAreaSize( sal_Int64 nAspect
, const awt::Size
& aSize
)
3630 SfxModelGuard
aGuard( *this );
3632 if ( !m_pData
->m_pObjectShell
.is() )
3633 throw Exception("no object shell", nullptr); // TODO: error handling
3635 SfxViewFrame
* pViewFrm
= SfxViewFrame::GetFirst( m_pData
->m_pObjectShell
.get(), false );
3636 if ( pViewFrm
&& m_pData
->m_pObjectShell
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
&& !pViewFrm
->GetFrame().IsInPlace() )
3638 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow( pViewFrm
->GetFrame().GetFrameInterface()->getContainerWindow() );
3639 Size aWinSize
= pWindow
->GetSizePixel();
3640 awt::Size aCurrent
= getVisualAreaSize( nAspect
);
3641 Size
aDiff( aSize
.Width
-aCurrent
.Width
, aSize
.Height
-aCurrent
.Height
);
3642 aDiff
= pViewFrm
->GetViewShell()->GetWindow()->LogicToPixel( aDiff
);
3643 aWinSize
.AdjustWidth(aDiff
.Width() );
3644 aWinSize
.AdjustHeight(aDiff
.Height() );
3645 pWindow
->SetSizePixel( aWinSize
);
3649 tools::Rectangle aTmpRect
= m_pData
->m_pObjectShell
->GetVisArea( ASPECT_CONTENT
);
3650 aTmpRect
.SetSize( Size( aSize
.Width
, aSize
.Height
) );
3651 m_pData
->m_pObjectShell
->SetVisArea( aTmpRect
);
3655 awt::Size SAL_CALL
SfxBaseModel::getVisualAreaSize( sal_Int64
/*nAspect*/ )
3657 SfxModelGuard
aGuard( *this );
3659 if ( !m_pData
->m_pObjectShell
.is() )
3660 throw Exception("no object shell", nullptr); // TODO: error handling
3662 tools::Rectangle aTmpRect
= m_pData
->m_pObjectShell
->GetVisArea( ASPECT_CONTENT
);
3664 return awt::Size( aTmpRect
.GetWidth(), aTmpRect
.GetHeight() );
3668 sal_Int32 SAL_CALL
SfxBaseModel::getMapUnit( sal_Int64
/*nAspect*/ )
3670 SfxModelGuard
aGuard( *this );
3672 if ( !m_pData
->m_pObjectShell
.is() )
3673 throw Exception("no object shell", nullptr); // TODO: error handling
3675 return VCLUnoHelper::VCL2UnoEmbedMapUnit( m_pData
->m_pObjectShell
->GetMapUnit() );
3678 embed::VisualRepresentation SAL_CALL
SfxBaseModel::getPreferredVisualRepresentation( ::sal_Int64
/*nAspect*/ )
3680 SfxModelGuard
aGuard( *this );
3682 datatransfer::DataFlavor
aDataFlavor(
3683 "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"",
3685 cppu::UnoType
<Sequence
< sal_Int8
>>::get() );
3687 embed::VisualRepresentation aVisualRepresentation
;
3688 aVisualRepresentation
.Data
= getTransferData( aDataFlavor
);
3689 aVisualRepresentation
.Flavor
= aDataFlavor
;
3691 return aVisualRepresentation
;
3695 // XStorageBasedDocument
3698 void SAL_CALL
SfxBaseModel::loadFromStorage( const Reference
< embed::XStorage
>& xStorage
,
3699 const Sequence
< beans::PropertyValue
>& aMediaDescriptor
)
3701 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
3702 if ( IsInitialized() )
3703 throw frame::DoubleInitializationException( OUString(), *this );
3705 // after i36090 is fixed the pool from object shell can be used
3706 // SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() );
3707 SfxAllItemSet
aSet( SfxGetpApp()->GetPool() );
3709 // the BaseURL is part of the ItemSet
3710 SfxMedium
* pMedium
= new SfxMedium( xStorage
, OUString() );
3711 TransformParameters( SID_OPENDOC
, aMediaDescriptor
, aSet
);
3712 pMedium
->GetItemSet()->Put( aSet
);
3714 // allow to use an interactionhandler (if there is one)
3715 pMedium
->UseInteractionHandler( true );
3717 const SfxBoolItem
* pTemplateItem
= aSet
.GetItem
<SfxBoolItem
>(SID_TEMPLATE
, false);
3718 bool bTemplate
= pTemplateItem
&& pTemplateItem
->GetValue();
3719 m_pData
->m_pObjectShell
->SetActivateEvent_Impl( bTemplate
? SfxEventHintId::CreateDoc
: SfxEventHintId::OpenDoc
);
3720 m_pData
->m_pObjectShell
->Get_Impl()->bOwnsStorage
= false;
3723 if ( !m_pData
->m_pObjectShell
->DoLoad(pMedium
) )
3725 ErrCode nError
= m_pData
->m_pObjectShell
->GetErrorCode();
3726 nError
= nError
? nError
: ERRCODE_IO_CANTREAD
;
3727 throw task::ErrorCodeIOException(
3728 "SfxBaseModel::loadFromStorage: " + nError
.toHexString(),
3729 Reference
< XInterface
>(), sal_uInt32(nError
));
3731 loadCmisProperties( );
3734 void SAL_CALL
SfxBaseModel::storeToStorage( const Reference
< embed::XStorage
>& xStorage
,
3735 const Sequence
< beans::PropertyValue
>& aMediaDescriptor
)
3737 SfxModelGuard
aGuard( *this );
3739 if ( !m_pData
->m_pObjectShell
.is() )
3740 throw io::IOException(); // TODO:
3742 auto xSet
= std::make_shared
<SfxAllItemSet
>(m_pData
->m_pObjectShell
->GetPool());
3743 TransformParameters( SID_SAVEASDOC
, aMediaDescriptor
, *xSet
);
3745 // TODO/LATER: maybe a special URL "private:storage" should be used
3746 const SfxStringItem
* pItem
= xSet
->GetItem
<SfxStringItem
>(SID_FILTER_NAME
, false);
3747 sal_Int32 nVersion
= SOFFICE_FILEFORMAT_CURRENT
;
3750 std::shared_ptr
<const SfxFilter
> pFilter
= SfxGetpApp()->GetFilterMatcher().GetFilter4FilterName( pItem
->GetValue() );
3751 if ( pFilter
&& pFilter
->UsesStorage() )
3752 nVersion
= pFilter
->GetVersion();
3755 bool bSuccess
= false;
3756 if ( xStorage
== m_pData
->m_pObjectShell
->GetStorage() )
3758 // storing to the own storage
3759 bSuccess
= m_pData
->m_pObjectShell
->DoSave();
3763 // TODO/LATER: if the provided storage has some data inside the storing might fail, probably the storage must be truncated
3764 // TODO/LATER: is it possible to have a template here?
3765 m_pData
->m_pObjectShell
->SetupStorage( xStorage
, nVersion
, false );
3767 // BaseURL is part of the ItemSet
3768 SfxMedium
aMedium( xStorage
, OUString(), xSet
);
3769 aMedium
.CanDisposeStorage_Impl( false );
3770 if ( aMedium
.GetFilter() )
3772 // storing without a valid filter will often crash
3773 bSuccess
= m_pData
->m_pObjectShell
->DoSaveObjectAs( aMedium
, true );
3774 m_pData
->m_pObjectShell
->DoSaveCompleted();
3778 ErrCode nError
= m_pData
->m_pObjectShell
->GetErrorCode();
3779 m_pData
->m_pObjectShell
->ResetError();
3781 // the warnings are currently not transported
3784 nError
= nError
? nError
: ERRCODE_IO_GENERAL
;
3785 throw task::ErrorCodeIOException(
3786 "SfxBaseModel::storeToStorage: " + nError
.toHexString(),
3787 Reference
< XInterface
>(), sal_uInt32(nError
));
3791 void SAL_CALL
SfxBaseModel::switchToStorage( const Reference
< embed::XStorage
>& xStorage
)
3793 SfxModelGuard
aGuard( *this );
3795 if ( !m_pData
->m_pObjectShell
.is() )
3796 throw io::IOException(); // TODO:
3798 // the persistence should be switched only if the storage is different
3799 if ( xStorage
!= m_pData
->m_pObjectShell
->GetStorage() )
3801 if ( !m_pData
->m_pObjectShell
->SwitchPersistance( xStorage
) )
3803 ErrCode nError
= m_pData
->m_pObjectShell
->GetErrorCode();
3804 nError
= nError
? nError
: ERRCODE_IO_GENERAL
;
3805 throw task::ErrorCodeIOException(
3806 "SfxBaseModel::switchToStorage: " + nError
.toHexString(),
3807 Reference
< XInterface
>(), sal_uInt32(nError
));
3811 // UICfgMgr has a reference to the old storage, update it
3812 getUIConfigurationManager2()->setStorage( xStorage
);
3815 m_pData
->m_pObjectShell
->Get_Impl()->bOwnsStorage
= false;
3818 Reference
< embed::XStorage
> SAL_CALL
SfxBaseModel::getDocumentStorage()
3820 SfxModelGuard
aGuard( *this );
3822 if ( !m_pData
->m_pObjectShell
.is() )
3823 throw io::IOException(); // TODO
3825 return m_pData
->m_pObjectShell
->GetStorage();
3828 void SAL_CALL
SfxBaseModel::addStorageChangeListener(
3829 const Reference
< document::XStorageChangeListener
>& xListener
)
3831 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
3833 m_pData
->m_aInterfaceContainer
.addInterface(
3834 cppu::UnoType
<document::XStorageChangeListener
>::get(), xListener
);
3837 void SAL_CALL
SfxBaseModel::removeStorageChangeListener(
3838 const Reference
< document::XStorageChangeListener
>& xListener
)
3840 SfxModelGuard
aGuard( *this );
3842 m_pData
->m_aInterfaceContainer
.removeInterface(
3843 cppu::UnoType
<document::XStorageChangeListener
>::get(), xListener
);
3846 void SfxBaseModel::impl_getPrintHelper()
3848 if ( m_pData
->m_xPrintable
.is() )
3850 m_pData
->m_xPrintable
= new SfxPrintHelper();
3851 Reference
< lang::XInitialization
> xInit( m_pData
->m_xPrintable
, UNO_QUERY
);
3852 Sequence
< Any
> aValues(1);
3853 aValues
[0] <<= Reference
< frame::XModel
> (static_cast< frame::XModel
* >(this), UNO_QUERY
);
3854 xInit
->initialize( aValues
);
3855 Reference
< view::XPrintJobBroadcaster
> xBrd( m_pData
->m_xPrintable
, UNO_QUERY
);
3856 xBrd
->addPrintJobListener( new SfxPrintHelperListener_Impl( m_pData
.get() ) );
3860 // css.frame.XModule
3861 void SAL_CALL
SfxBaseModel::setIdentifier(const OUString
& Identifier
)
3863 SfxModelGuard
aGuard( *this );
3864 m_pData
->m_sModuleIdentifier
= Identifier
;
3868 // css.frame.XModule
3869 OUString SAL_CALL
SfxBaseModel::getIdentifier()
3871 SfxModelGuard
aGuard( *this );
3872 if (!m_pData
->m_sModuleIdentifier
.isEmpty())
3873 return m_pData
->m_sModuleIdentifier
;
3874 if (m_pData
->m_pObjectShell
.is())
3875 return m_pData
->m_pObjectShell
->GetFactory().GetDocumentServiceName();
3880 Reference
< frame::XTitle
> SfxBaseModel::impl_getTitleHelper ()
3882 SfxModelGuard
aGuard( *this );
3884 if ( ! m_pData
->m_xTitleHelper
.is ())
3886 Reference
< XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
3887 Reference
< frame::XUntitledNumbers
> xDesktop( frame::Desktop::create(xContext
), UNO_QUERY_THROW
);
3888 Reference
< frame::XModel
> xThis (static_cast< frame::XModel
* >(this), UNO_QUERY_THROW
);
3890 ::framework::TitleHelper
* pHelper
= new ::framework::TitleHelper(xContext
);
3891 m_pData
->m_xTitleHelper
.set(static_cast< ::cppu::OWeakObject
* >(pHelper
), UNO_QUERY_THROW
);
3892 pHelper
->setOwner (xThis
);
3893 pHelper
->connectWithUntitledNumbers (xDesktop
);
3896 return m_pData
->m_xTitleHelper
;
3900 Reference
< frame::XUntitledNumbers
> SfxBaseModel::impl_getUntitledHelper ()
3902 SfxModelGuard
aGuard( *this );
3904 if ( ! m_pData
->m_xNumberedControllers
.is ())
3906 Reference
< frame::XModel
> xThis (static_cast< frame::XModel
* >(this), UNO_QUERY_THROW
);
3907 ::comphelper::NumberedCollection
* pHelper
= new ::comphelper::NumberedCollection();
3909 m_pData
->m_xNumberedControllers
.set(static_cast< ::cppu::OWeakObject
* >(pHelper
), UNO_QUERY_THROW
);
3911 pHelper
->setOwner (xThis
);
3912 pHelper
->setUntitledPrefix (" : ");
3915 return m_pData
->m_xNumberedControllers
;
3920 OUString SAL_CALL
SfxBaseModel::getTitle()
3923 SfxModelGuard
aGuard( *this );
3925 OUString aResult
= impl_getTitleHelper()->getTitle ();
3926 if ( !m_pData
->m_bExternalTitle
&& m_pData
->m_pObjectShell
)
3928 SfxMedium
* pMedium
= m_pData
->m_pObjectShell
->GetMedium();
3932 ::ucbhelper::Content
aContent( pMedium
->GetName(),
3933 utl::UCBContentHelper::getDefaultCommandEnvironment(),
3934 comphelper::getProcessComponentContext() );
3935 const Reference
< beans::XPropertySetInfo
> xProps
3936 = aContent
.getProperties();
3939 const OUString
aServerTitle( "TitleOnServer" );
3940 if ( xProps
->hasPropertyByName( aServerTitle
) )
3942 Any aAny
= aContent
.getPropertyValue( aServerTitle
);
3947 catch (const ucb::ContentCreationException
&)
3950 catch (const ucb::CommandAbortedException
&)
3953 const SfxBoolItem
* pRepairedDocItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_REPAIRPACKAGE
, false);
3954 if ( pRepairedDocItem
&& pRepairedDocItem
->GetValue() )
3955 aResult
+= SfxResId(STR_REPAIREDDOCUMENT
);
3958 if ( m_pData
->m_pObjectShell
->IsReadOnlyUI() || (pMedium
&& pMedium
->IsReadOnly()) )
3959 aResult
+= SfxResId(STR_READONLY
);
3960 else if ( m_pData
->m_pObjectShell
->IsDocShared() )
3961 aResult
+= SfxResId(STR_SHARED
);
3963 if ( m_pData
->m_pObjectShell
->GetDocumentSignatureState() == SignatureState::OK
)
3964 aResult
+= SfxResId(RID_XMLSEC_DOCUMENTSIGNED
);
3972 void SAL_CALL
SfxBaseModel::setTitle( const OUString
& sTitle
)
3975 SfxModelGuard
aGuard( *this );
3977 impl_getTitleHelper()->setTitle (sTitle
);
3978 m_pData
->m_bExternalTitle
= true;
3982 // css.frame.XTitleChangeBroadcaster
3983 void SAL_CALL
SfxBaseModel::addTitleChangeListener( const Reference
< frame::XTitleChangeListener
>& xListener
)
3986 SfxModelGuard
aGuard( *this, SfxModelGuard::E_INITIALIZING
);
3988 Reference
< frame::XTitleChangeBroadcaster
> xBroadcaster(impl_getTitleHelper(), UNO_QUERY
);
3989 if (xBroadcaster
.is ())
3990 xBroadcaster
->addTitleChangeListener (xListener
);
3994 // css.frame.XTitleChangeBroadcaster
3995 void SAL_CALL
SfxBaseModel::removeTitleChangeListener( const Reference
< frame::XTitleChangeListener
>& xListener
)
3998 SfxModelGuard
aGuard( *this );
4000 Reference
< frame::XTitleChangeBroadcaster
> xBroadcaster(impl_getTitleHelper(), UNO_QUERY
);
4001 if (xBroadcaster
.is ())
4002 xBroadcaster
->removeTitleChangeListener (xListener
);
4006 // css.frame.XUntitledNumbers
4007 ::sal_Int32 SAL_CALL
SfxBaseModel::leaseNumber( const Reference
< XInterface
>& xComponent
)
4009 SfxModelGuard
aGuard( *this );
4011 return impl_getUntitledHelper ()->leaseNumber (xComponent
);
4015 // css.frame.XUntitledNumbers
4016 void SAL_CALL
SfxBaseModel::releaseNumber( ::sal_Int32 nNumber
)
4018 SfxModelGuard
aGuard( *this );
4019 impl_getUntitledHelper ()->releaseNumber (nNumber
);
4023 // css.frame.XUntitledNumbers
4024 void SAL_CALL
SfxBaseModel::releaseNumberForComponent( const Reference
< XInterface
>& xComponent
)
4026 SfxModelGuard
aGuard( *this );
4027 impl_getUntitledHelper ()->releaseNumberForComponent (xComponent
);
4031 // css.frame.XUntitledNumbers
4032 OUString SAL_CALL
SfxBaseModel::getUntitledPrefix()
4034 SfxModelGuard
aGuard( *this );
4035 return impl_getUntitledHelper ()->getUntitledPrefix ();
4040 Reference
< container::XEnumeration
> SAL_CALL
SfxBaseModel::getControllers()
4042 SfxModelGuard
aGuard( *this );
4044 sal_Int32 c
= m_pData
->m_seqControllers
.size();
4046 Sequence
< Any
> lEnum(c
);
4048 lEnum
[i
] <<= m_pData
->m_seqControllers
[i
];
4050 ::comphelper::OAnyEnumeration
* pEnum
= new ::comphelper::OAnyEnumeration(lEnum
);
4051 Reference
< container::XEnumeration
> xEnum(static_cast< container::XEnumeration
* >(pEnum
), UNO_QUERY_THROW
);
4057 Sequence
< OUString
> SAL_CALL
SfxBaseModel::getAvailableViewControllerNames()
4059 SfxModelGuard
aGuard( *this );
4061 const SfxObjectFactory
& rDocumentFactory
= GetObjectShell()->GetFactory();
4062 const sal_Int16 nViewFactoryCount
= rDocumentFactory
.GetViewFactoryCount();
4064 Sequence
< OUString
> aViewNames( nViewFactoryCount
);
4065 for ( sal_Int16 nViewNo
= 0; nViewNo
< nViewFactoryCount
; ++nViewNo
)
4066 aViewNames
[nViewNo
] = rDocumentFactory
.GetViewFactory( nViewNo
).GetAPIViewName();
4072 Reference
< frame::XController2
> SAL_CALL
SfxBaseModel::createDefaultViewController( const Reference
< frame::XFrame
>& i_rFrame
)
4074 SfxModelGuard
aGuard( *this );
4076 const SfxObjectFactory
& rDocumentFactory
= GetObjectShell()->GetFactory();
4077 const OUString sDefaultViewName
= rDocumentFactory
.GetViewFactory().GetAPIViewName();
4081 return createViewController( sDefaultViewName
, Sequence
< PropertyValue
>(), i_rFrame
);
4085 namespace sfx::intern
{
4087 /** a class which, in its dtor, cleans up various objects (well, at the moment only the frame) collected during
4088 the creation of a document view, unless the creation was successful.
4090 class ViewCreationGuard
4094 :m_bSuccess( false )
4098 ~ViewCreationGuard()
4100 if ( !m_bSuccess
&& m_aWeakFrame
&& !m_aWeakFrame
->GetCurrentDocument() )
4102 m_aWeakFrame
->SetFrameInterface_Impl( nullptr );
4103 m_aWeakFrame
->DoClose();
4107 void takeFrameOwnership( SfxFrame
* i_pFrame
)
4109 OSL_PRECOND( !m_aWeakFrame
, "ViewCreationGuard::takeFrameOwnership: already have a frame!" );
4110 OSL_PRECOND( i_pFrame
!= nullptr, "ViewCreationGuard::takeFrameOwnership: invalid frame!" );
4111 m_aWeakFrame
= i_pFrame
;
4121 SfxFrameWeakRef m_aWeakFrame
;
4126 SfxViewFrame
* SfxBaseModel::FindOrCreateViewFrame_Impl( const Reference
< XFrame
>& i_rFrame
, ::sfx::intern::ViewCreationGuard
& i_rGuard
) const
4128 SfxViewFrame
* pViewFrame
= nullptr;
4129 for ( pViewFrame
= SfxViewFrame::GetFirst( GetObjectShell(), false );
4131 pViewFrame
= SfxViewFrame::GetNext( *pViewFrame
, GetObjectShell(), false )
4134 if ( pViewFrame
->GetFrame().GetFrameInterface() == i_rFrame
)
4139 #if OSL_DEBUG_LEVEL > 0
4140 for ( SfxFrame
* pCheckFrame
= SfxFrame::GetFirst();
4142 pCheckFrame
= SfxFrame::GetNext( *pCheckFrame
)
4145 if ( pCheckFrame
->GetFrameInterface() == i_rFrame
)
4147 if ( ( pCheckFrame
->GetCurrentViewFrame() != nullptr )
4148 || ( pCheckFrame
->GetCurrentDocument() != nullptr )
4150 // Note that it is perfectly legitimate that during loading into an XFrame which already contains
4151 // a document, there exist two SfxFrame instances bound to this XFrame - the old one, which will be
4152 // destroyed later, and the new one, which we're going to create
4155 OSL_FAIL( "SfxBaseModel::FindOrCreateViewFrame_Impl: there already is an SfxFrame for the given XFrame, but no view in it!" );
4156 // nowadays, we're the only instance allowed to create an SfxFrame for an XFrame, so this case here should not happen
4162 SfxFrame
* pTargetFrame
= SfxFrame::Create( i_rFrame
);
4163 ENSURE_OR_THROW( pTargetFrame
, "could not create an SfxFrame" );
4164 i_rGuard
.takeFrameOwnership( pTargetFrame
);
4167 pTargetFrame
->PrepareForDoc_Impl( *GetObjectShell() );
4169 // create view frame
4170 pViewFrame
= new SfxViewFrame( *pTargetFrame
, GetObjectShell() );
4177 Reference
< frame::XController2
> SAL_CALL
SfxBaseModel::createViewController(
4178 const OUString
& i_rViewName
, const Sequence
< PropertyValue
>& i_rArguments
, const Reference
< XFrame
>& i_rFrame
)
4180 SfxModelGuard
aGuard( *this );
4182 if ( !i_rFrame
.is() )
4183 throw lang::IllegalArgumentException( OUString(), *this, 3 );
4185 // find the proper SFX view factory
4186 SfxViewFactory
* pViewFactory
= GetObjectShell()->GetFactory().GetViewFactoryByViewName( i_rViewName
);
4187 if ( !pViewFactory
)
4188 throw IllegalArgumentException( OUString(), *this, 1 );
4190 // determine previous shell (used in some special cases)
4191 Reference
< XController
> xPreviousController( i_rFrame
->getController() );
4192 const Reference
< XModel
> xMe( this );
4193 if ( ( xPreviousController
.is() )
4194 && ( xMe
!= xPreviousController
->getModel() )
4197 xPreviousController
.clear();
4199 SfxViewShell
* pOldViewShell
= SfxViewShell::Get( xPreviousController
);
4200 OSL_ENSURE( !xPreviousController
.is() || ( pOldViewShell
!= nullptr ),
4201 "SfxBaseModel::createViewController: invalid old controller!" );
4203 // a guard which will clean up in case of failure
4204 ::sfx::intern::ViewCreationGuard aViewCreationGuard
;
4206 // determine the ViewFrame belonging to the given XFrame
4207 SfxViewFrame
* pViewFrame
= FindOrCreateViewFrame_Impl( i_rFrame
, aViewCreationGuard
);
4208 SAL_WARN_IF( !pViewFrame
, "sfx.doc", "SfxBaseModel::createViewController: no frame?" );
4210 // delegate to SFX' view factory
4211 pViewFrame
->GetBindings().ENTERREGISTRATIONS();
4212 SfxViewShell
* pViewShell
= pViewFactory
->CreateInstance( pViewFrame
, pOldViewShell
);
4213 pViewFrame
->GetBindings().LEAVEREGISTRATIONS();
4214 ENSURE_OR_THROW( pViewShell
, "invalid view shell provided by factory" );
4216 // by setting the ViewShell it is prevented that disposing the Controller will destroy this ViewFrame also
4217 pViewFrame
->GetDispatcher()->SetDisableFlags( SfxDisableFlags::NONE
);
4218 pViewFrame
->SetViewShell_Impl( pViewShell
);
4221 pViewFrame
->SetCurViewId_Impl( pViewFactory
->GetOrdinal() );
4223 // ensure a default controller, if the view shell did not provide an own implementation
4224 if ( !pViewShell
->GetController().is() )
4225 pViewShell
->SetController( new SfxBaseController( pViewShell
) );
4227 // pass the creation arguments to the controller
4228 SfxBaseController
* pBaseController
= pViewShell
->GetBaseController_Impl();
4229 ENSURE_OR_THROW( pBaseController
, "invalid controller implementation!" );
4230 pBaseController
->SetCreationArguments_Impl( i_rArguments
);
4232 // some initial view settings, coming from our most recent attachResource call
4233 ::comphelper::NamedValueCollection
aDocumentLoadArgs( getArgs() );
4234 if ( aDocumentLoadArgs
.getOrDefault( "ViewOnly", false ) )
4235 pViewFrame
->GetFrame().SetMenuBarOn_Impl( false );
4237 const sal_Int16 nPluginMode
= aDocumentLoadArgs
.getOrDefault( "PluginMode", sal_Int16( 0 ) );
4238 if ( nPluginMode
== 1 )
4240 pViewFrame
->ForceOuterResize_Impl();
4241 pViewFrame
->GetBindings().HidePopups();
4243 SfxFrame
& rFrame
= pViewFrame
->GetFrame();
4244 // MBA: layoutmanager of inplace frame starts locked and invisible
4245 rFrame
.GetWorkWindow_Impl()->MakeVisible_Impl( false );
4246 rFrame
.GetWorkWindow_Impl()->Lock_Impl( true );
4248 rFrame
.GetWindow().SetBorderStyle( WindowBorderStyle::NOBORDER
);
4249 pViewFrame
->GetWindow().SetBorderStyle( WindowBorderStyle::NOBORDER
);
4252 // tell the guard we were successful
4253 aViewCreationGuard
.releaseAll();
4256 return pBaseController
;
4260 // RDF DocumentMetadataAccess
4262 // rdf::XRepositorySupplier:
4263 Reference
< rdf::XRepository
> SAL_CALL
4264 SfxBaseModel::getRDFRepository()
4266 SfxModelGuard
aGuard( *this );
4268 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4270 throw RuntimeException( "model has no document metadata", *this );
4273 return xDMA
->getRDFRepository();
4278 SfxBaseModel::getStringValue()
4280 SfxModelGuard
aGuard( *this );
4282 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4284 throw RuntimeException( "model has no document metadata", *this );
4287 return xDMA
->getStringValue();
4292 SfxBaseModel::getNamespace()
4294 SfxModelGuard
aGuard( *this );
4296 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4298 throw RuntimeException( "model has no document metadata", *this );
4301 return xDMA
->getNamespace();
4305 SfxBaseModel::getLocalName()
4307 SfxModelGuard
aGuard( *this );
4309 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4311 throw RuntimeException( "model has no document metadata", *this );
4314 return xDMA
->getLocalName();
4317 // rdf::XDocumentMetadataAccess:
4318 Reference
< rdf::XMetadatable
> SAL_CALL
4319 SfxBaseModel::getElementByMetadataReference(
4320 const beans::StringPair
& i_rReference
)
4322 SfxModelGuard
aGuard( *this );
4324 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4326 throw RuntimeException( "model has no document metadata", *this );
4329 return xDMA
->getElementByMetadataReference(i_rReference
);
4332 Reference
< rdf::XMetadatable
> SAL_CALL
4333 SfxBaseModel::getElementByURI(const Reference
< rdf::XURI
> & i_xURI
)
4335 SfxModelGuard
aGuard( *this );
4337 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4339 throw RuntimeException( "model has no document metadata", *this );
4342 return xDMA
->getElementByURI(i_xURI
);
4345 Sequence
< Reference
< rdf::XURI
> > SAL_CALL
4346 SfxBaseModel::getMetadataGraphsWithType(
4347 const Reference
<rdf::XURI
> & i_xType
)
4349 SfxModelGuard
aGuard( *this );
4351 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4353 throw RuntimeException( "model has no document metadata", *this );
4356 return xDMA
->getMetadataGraphsWithType(i_xType
);
4359 Reference
<rdf::XURI
> SAL_CALL
4360 SfxBaseModel::addMetadataFile(const OUString
& i_rFileName
,
4361 const Sequence
< Reference
< rdf::XURI
> > & i_rTypes
)
4363 SfxModelGuard
aGuard( *this );
4365 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4367 throw RuntimeException( "model has no document metadata", *this );
4370 return xDMA
->addMetadataFile(i_rFileName
, i_rTypes
);
4373 Reference
<rdf::XURI
> SAL_CALL
4374 SfxBaseModel::importMetadataFile(::sal_Int16 i_Format
,
4375 const Reference
< io::XInputStream
> & i_xInStream
,
4376 const OUString
& i_rFileName
,
4377 const Reference
< rdf::XURI
> & i_xBaseURI
,
4378 const Sequence
< Reference
< rdf::XURI
> > & i_rTypes
)
4380 SfxModelGuard
aGuard( *this );
4382 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4384 throw RuntimeException( "model has no document metadata", *this );
4387 return xDMA
->importMetadataFile(i_Format
,
4388 i_xInStream
, i_rFileName
, i_xBaseURI
, i_rTypes
);
4392 SfxBaseModel::removeMetadataFile(
4393 const Reference
< rdf::XURI
> & i_xGraphName
)
4395 SfxModelGuard
aGuard( *this );
4397 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4399 throw RuntimeException( "model has no document metadata", *this );
4402 return xDMA
->removeMetadataFile(i_xGraphName
);
4406 SfxBaseModel::addContentOrStylesFile(const OUString
& i_rFileName
)
4408 SfxModelGuard
aGuard( *this );
4410 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4412 throw RuntimeException( "model has no document metadata", *this );
4415 return xDMA
->addContentOrStylesFile(i_rFileName
);
4419 SfxBaseModel::removeContentOrStylesFile(const OUString
& i_rFileName
)
4421 SfxModelGuard
aGuard( *this );
4423 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4425 throw RuntimeException( "model has no document metadata", *this );
4428 return xDMA
->removeContentOrStylesFile(i_rFileName
);
4432 SfxBaseModel::loadMetadataFromStorage(
4433 Reference
< embed::XStorage
> const & i_xStorage
,
4434 Reference
<rdf::XURI
> const & i_xBaseURI
,
4435 Reference
<task::XInteractionHandler
> const & i_xHandler
)
4437 SfxModelGuard
aGuard( *this );
4439 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(
4440 m_pData
->CreateDMAUninitialized());
4442 throw RuntimeException( "model has no document metadata", *this );
4446 xDMA
->loadMetadataFromStorage(i_xStorage
, i_xBaseURI
, i_xHandler
);
4447 } catch (lang::IllegalArgumentException
&) {
4448 throw; // not initialized
4449 } catch (Exception
&) {
4450 // UGLY: if it's a RuntimeException, we can't be sure DMA is initialized
4451 m_pData
->m_xDocumentMetadata
= xDMA
;
4454 m_pData
->m_xDocumentMetadata
= xDMA
;
4459 SfxBaseModel::storeMetadataToStorage(
4460 Reference
< embed::XStorage
> const & i_xStorage
)
4462 SfxModelGuard
aGuard( *this );
4464 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(m_pData
->GetDMA());
4466 throw RuntimeException( "model has no document metadata", *this );
4469 return xDMA
->storeMetadataToStorage(i_xStorage
);
4473 SfxBaseModel::loadMetadataFromMedium(
4474 const Sequence
< beans::PropertyValue
> & i_rMedium
)
4476 SfxModelGuard
aGuard( *this );
4478 const Reference
<rdf::XDocumentMetadataAccess
> xDMA(
4479 m_pData
->CreateDMAUninitialized());
4481 throw RuntimeException( "model has no document metadata", *this );
4485 xDMA
->loadMetadataFromMedium(i_rMedium
);
4486 } catch (lang::IllegalArgumentException
&) {
4487 throw; // not initialized
4488 } catch (Exception
&) {
4489 // UGLY: if it's a RuntimeException, we can't be sure DMA is initialized
4490 m_pData
->m_xDocumentMetadata
= xDMA
;
4493 m_pData
->m_xDocumentMetadata
= xDMA
;
4497 SfxBaseModel::storeMetadataToMedium(
4498 const Sequence
< beans::PropertyValue
> & i_rMedium
)
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
->storeMetadataToMedium(i_rMedium
);
4511 // = SfxModelSubComponent
4514 SfxModelSubComponent::~SfxModelSubComponent()
4518 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */