LibreOffice Module sfx2 (master) 1
sfxbasemodel.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <algorithm>
23#include <chrono>
24#include <memory>
25#include <optional>
26#include <config_features.h>
27
28#include <sfx2/sfxbasemodel.hxx>
29
30#include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
31#include <com/sun/star/task/XInteractionHandler.hpp>
32#include <com/sun/star/task/ErrorCodeIOException.hpp>
33#include <com/sun/star/task/ErrorCodeRequest.hpp>
34#include <com/sun/star/view/XSelectionSupplier.hpp>
35#include <com/sun/star/view/XPrintJobListener.hpp>
36#include <com/sun/star/lang/DisposedException.hpp>
37#include <com/sun/star/lang/IllegalArgumentException.hpp>
38#include <com/sun/star/lang/NoSupportException.hpp>
39#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
40#include <com/sun/star/lang/NotInitializedException.hpp>
41#include <com/sun/star/frame/Desktop.hpp>
42#include <com/sun/star/frame/IllegalArgumentIOException.hpp>
43#include <com/sun/star/frame/XUntitledNumbers.hpp>
44#include <com/sun/star/frame/DoubleInitializationException.hpp>
45#include <com/sun/star/embed/XStorage.hpp>
46#include <com/sun/star/document/XStorageChangeListener.hpp>
47#include <com/sun/star/beans/XPropertySet.hpp>
48#include <com/sun/star/beans/XPropertySetInfo.hpp>
49#include <com/sun/star/container/XIndexContainer.hpp>
50#include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp>
51#include <com/sun/star/script/provider/XScriptProvider.hpp>
52#include <com/sun/star/ui/UIConfigurationManager.hpp>
53#include <com/sun/star/embed/ElementModes.hpp>
54#include <com/sun/star/embed/Aspects.hpp>
55#include <com/sun/star/document/DocumentProperties.hpp>
56#include <com/sun/star/frame/XTransientDocumentsDocumentContentFactory.hpp>
57#include <com/sun/star/ucb/XCommandEnvironment.hpp>
58#include <com/sun/star/ucb/ContentCreationException.hpp>
59#include <com/sun/star/ucb/CommandAbortedException.hpp>
60#include <com/sun/star/util/XCloneable.hpp>
61#include <com/sun/star/util/InvalidStateException.hpp>
62#include <com/sun/star/util/CloseVetoException.hpp>
65#include <comphelper/string.hxx>
66
68#include <comphelper/lok.hxx>
75#include <o3tl/safeint.hxx>
76#include <o3tl/string_view.hxx>
77#include <svl/itemset.hxx>
78#include <svl/stritem.hxx>
79#include <svl/eitem.hxx>
80#include <svl/grabbagitem.hxx>
81#include <tools/urlobj.hxx>
82#include <tools/debug.hxx>
84#include <tools/svborder.hxx>
85#include <unotools/tempfile.hxx>
86#include <osl/mutex.hxx>
89#include <vcl/salctype.hxx>
90#include <vcl/gdimtf.hxx>
95#include <vcl/transfer.hxx>
96#include <svtools/ehdl.hxx>
97#include <svtools/sfxecode.hxx>
98#include <sal/log.hxx>
102#include <unotools/ucbhelper.hxx>
103#include <ucbhelper/content.hxx>
104
106#include <sfx2/viewfac.hxx>
107#include <workwin.hxx>
109#include <sfx2/sfxuno.hxx>
110#include <objshimp.hxx>
111#include <sfx2/viewfrm.hxx>
112#include <sfx2/viewsh.hxx>
113#include <sfx2/docfile.hxx>
114#include <sfx2/docfilt.hxx>
115#include <sfx2/dispatch.hxx>
116#include <sfx2/module.hxx>
117#include <basic/basmgr.hxx>
118#include <sfx2/event.hxx>
119#include <eventsupplier.hxx>
120#include <sfx2/sfxsids.hrc>
121#include <sfx2/strings.hrc>
122#include <sfx2/app.hxx>
123#include <sfx2/docfac.hxx>
124#include <sfx2/fcontnr.hxx>
127#include "graphhelp.hxx"
128#include <docundomanager.hxx>
129#include <openurlhint.hxx>
130#include <sfx2/msgpool.hxx>
132#include "printhelper.hxx"
133#include <sfx2/sfxresid.hxx>
134#include <sfx2/filedlghelper.hxx>
136#include <vcl/threadex.hxx>
138
139#include <LibreOfficeKit/LibreOfficeKitEnums.h>
140
141// namespaces
142
143
144using namespace ::com::sun::star;
145using namespace ::com::sun::star::uno;
146using ::com::sun::star::beans::PropertyValue;
147using ::com::sun::star::document::CmisProperty;
148using ::com::sun::star::frame::XFrame;
149using ::com::sun::star::frame::XController;
150using ::com::sun::star::frame::XController2;
151using ::com::sun::star::lang::IllegalArgumentException;
152using ::com::sun::star::io::IOException;
153using ::com::sun::star::uno::Sequence;
154using ::com::sun::star::document::XDocumentRecovery;
155using ::com::sun::star::document::XUndoManager;
156using ::com::sun::star::document::XUndoAction;
157using ::com::sun::star::frame::XModel;
158
159namespace {
160
164class SfxDocInfoListener_Impl : public ::cppu::WeakImplHelper<
165 util::XModifyListener >
166{
167
168public:
169 SfxObjectShell& m_rShell;
170
171 explicit SfxDocInfoListener_Impl( SfxObjectShell& i_rDoc )
172 : m_rShell(i_rDoc)
173 { };
174
175 virtual void SAL_CALL disposing( const lang::EventObject& ) override;
176 virtual void SAL_CALL modified( const lang::EventObject& ) override;
177};
178
179}
180
181void SAL_CALL SfxDocInfoListener_Impl::modified( const lang::EventObject& )
182{
183 SolarMutexGuard aSolarGuard;
184
185 // notify changes to the SfxObjectShell
186 m_rShell.FlushDocInfo();
187}
188
189void SAL_CALL SfxDocInfoListener_Impl::disposing( const lang::EventObject& )
190{
191}
192
193
194// impl. declarations
195
196
198{
199 // counter for SfxBaseModel instances created.
200 static sal_Int64 g_nInstanceCounter ;
202 OUString m_sURL ;
203 OUString m_sRuntimeUID ;
206 std::unordered_map<css::uno::Reference< css::drawing::XShape >,
207 std::vector<css::uno::Reference< css::document::XShapeEventListener >>> maShapeListeners;
208 Reference< XInterface > m_xParent ;
209 Reference< frame::XController > m_xCurrent ;
210 Reference< document::XDocumentProperties > m_xDocumentProperties ;
211 Reference< script::XStarBasicAccess > m_xStarBasicAccess ;
212 Reference< container::XNameReplace > m_xEvents ;
213 Sequence< beans::PropertyValue> m_seqArguments ;
214 std::vector< Reference< frame::XController > > m_seqControllers ;
215 Reference< container::XIndexAccess > m_contViewData ;
223 Reference< view::XPrintable> m_xPrintable ;
224 Reference< ui::XUIConfigurationManager2 > m_xUIConfigurationManager;
227 Reference< frame::XTitle > m_xTitleHelper ;
228 Reference< frame::XUntitledNumbers > m_xNumberedControllers ;
229 Reference< rdf::XDocumentMetadataAccess> m_xDocumentMetadata ;
231 Sequence< document::CmisProperty> m_cmisProperties ;
232 std::shared_ptr<SfxGrabBagItem> m_xGrabBagItem ;
233 std::optional<std::chrono::steady_clock::time_point> m_oDirtyTimestamp ;
234
235 IMPL_SfxBaseModel_DataContainer( ::osl::Mutex& rMutex, SfxObjectShell* pObjectShell )
236 : m_pObjectShell ( pObjectShell )
237 , m_aInterfaceContainer ( rMutex )
239 , m_bClosed ( false )
240 , m_bClosing ( false )
241 , m_bSaving ( false )
242 , m_bSuicide ( false )
243 , m_bExternalTitle ( false )
244 , m_bDisposing ( false )
245 {
246 // increase global instance counter.
248 // set own Runtime UID
249 m_sRuntimeUID = OUString::number( g_nInstanceCounter );
250 }
251
253 {
254 }
255
256 // ::sfx2::IModifiableDocument
257 virtual void storageIsModified() override
258 {
259 if ( m_pObjectShell.is() && !m_pObjectShell->IsModified() )
260 m_pObjectShell->SetModified();
261 }
262
264 const Reference< document::XDocumentProperties >& );
265
266 Reference<rdf::XDocumentMetadataAccess> GetDMA()
267 {
268 if (!m_xDocumentMetadata.is())
269 {
270 OSL_ENSURE(m_pObjectShell.is(), "GetDMA: no object shell?");
271 if (!m_pObjectShell.is())
272 {
273 return nullptr;
274 }
275
276 const Reference<XComponentContext> xContext(
277 ::comphelper::getProcessComponentContext());
278 const Reference<frame::XModel> xModel(
279 m_pObjectShell->GetModel());
280 const Reference<lang::XMultiComponentFactory> xMsf(
281 xContext->getServiceManager());
282 const Reference<frame::
283 XTransientDocumentsDocumentContentFactory> xTDDCF(
284 xMsf->createInstanceWithContext(
285 "com.sun.star.frame.TransientDocumentsDocumentContentFactory",
286 xContext),
287 UNO_QUERY_THROW);
288 const Reference<ucb::XContent> xContent(
289 xTDDCF->createDocumentContent(xModel) );
290 OSL_ENSURE(xContent.is(), "GetDMA: cannot create DocumentContent");
291 if (!xContent.is())
292 {
293 return nullptr;
294 }
295 OUString uri = xContent->getIdentifier()->getContentIdentifier();
296 OSL_ENSURE(!uri.isEmpty(), "GetDMA: empty uri?");
297 if (!uri.isEmpty() && !uri.endsWith("/"))
298 {
299 uri += "/";
300 }
301
302 m_xDocumentMetadata = new ::sfx2::DocumentMetadataAccess(
303 xContext, *m_pObjectShell, uri);
304 }
305 return m_xDocumentMetadata;
306 }
307
308 Reference<rdf::XDocumentMetadataAccess> CreateDMAUninitialized()
309 {
310 return (m_pObjectShell.is())
311 ? new ::sfx2::DocumentMetadataAccess(
312 ::comphelper::getProcessComponentContext(), *m_pObjectShell)
313 : nullptr;
314 }
315
317 {
318 if (val)
319 {
321 m_oDirtyTimestamp.emplace(std::chrono::steady_clock::now());
322 }
323 else
324 {
325 m_oDirtyTimestamp.reset();
326 }
327 }
328};
329
330// static member initialization.
332
333namespace {
334
335// Listener that forwards notifications from the PrintHelper to the "real" listeners
336class SfxPrintHelperListener_Impl : public ::cppu::WeakImplHelper< view::XPrintJobListener >
337{
338public:
340 explicit SfxPrintHelperListener_Impl( IMPL_SfxBaseModel_DataContainer* pData )
341 : m_pData( pData )
342 {}
343
344 virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) override ;
345 virtual void SAL_CALL printJobEvent( const view::PrintJobEvent& rEvent ) override;
346};
347
348}
349
350void SAL_CALL SfxPrintHelperListener_Impl::disposing( const lang::EventObject& )
351{
352 m_pData->m_xPrintable = nullptr;
353}
354
355void SAL_CALL SfxPrintHelperListener_Impl::printJobEvent( const view::PrintJobEvent& rEvent )
356{
357 ::comphelper::OInterfaceContainerHelper2* pContainer = m_pData->m_aInterfaceContainer.getContainer( cppu::UnoType<view::XPrintJobListener>::get());
358 if ( pContainer!=nullptr )
359 {
360 ::comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer);
361 while (pIterator.hasMoreElements())
362 static_cast<view::XPrintJobListener*>(pIterator.next())->printJobEvent( rEvent );
363 }
364}
365
366namespace {
367
368// SfxOwnFramesLocker ====================================================================================
369// allows to lock all the frames related to the provided SfxObjectShell
370class SfxOwnFramesLocker
371{
372 Sequence< Reference< frame::XFrame > > m_aLockedFrames;
373
374 static vcl::Window* GetVCLWindow( const Reference< frame::XFrame >& xFrame );
375public:
376 explicit SfxOwnFramesLocker( SfxObjectShell const * ObjechShell );
377 ~SfxOwnFramesLocker();
378};
379
380}
381
382SfxOwnFramesLocker::SfxOwnFramesLocker( SfxObjectShell const * pObjectShell )
383{
384 if ( !pObjectShell )
385 return;
386
387 for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst( pObjectShell );
388 pFrame;
389 pFrame = SfxViewFrame::GetNext( *pFrame, pObjectShell )
390 )
391 {
392 SfxFrame& rSfxFrame = pFrame->GetFrame();
393 try
394 {
395 // get vcl window related to the frame and lock it if it is still not locked
396 const Reference< frame::XFrame >& xFrame = rSfxFrame.GetFrameInterface();
397 vcl::Window* pWindow = GetVCLWindow( xFrame );
398 if ( !pWindow )
399 throw RuntimeException();
400
401 if ( pWindow->IsEnabled() )
402 {
403 pWindow->Disable();
404
405 try
406 {
407 sal_Int32 nLen = m_aLockedFrames.getLength();
408 m_aLockedFrames.realloc( nLen + 1 );
409 m_aLockedFrames.getArray()[nLen] = xFrame;
410 }
411 catch( Exception& )
412 {
413 pWindow->Enable();
414 throw;
415 }
416 }
417 }
418 catch( Exception& )
419 {
420 OSL_FAIL( "Not possible to lock the frame window!" );
421 }
422 }
423}
424
425SfxOwnFramesLocker::~SfxOwnFramesLocker()
426{
427 for ( auto& rFrame : asNonConstRange(m_aLockedFrames) )
428 {
429 try
430 {
431 if ( rFrame.is() )
432 {
433 // get vcl window related to the frame and unlock it
434 vcl::Window* pWindow = GetVCLWindow( rFrame );
435 if ( !pWindow )
436 throw RuntimeException();
437
438 pWindow->Enable();
439
440 rFrame.clear();
441 }
442 }
443 catch( Exception& )
444 {
445 OSL_FAIL( "Can't unlock the frame window!" );
446 }
447 }
448}
449
450vcl::Window* SfxOwnFramesLocker::GetVCLWindow( const Reference< frame::XFrame >& xFrame )
451{
452 VclPtr<vcl::Window> pWindow;
453
454 if ( xFrame.is() )
455 {
456 Reference< awt::XWindow > xWindow = xFrame->getContainerWindow();
457 if ( xWindow.is() )
458 pWindow = VCLUnoHelper::GetWindow( xWindow );
459 }
460
461 return pWindow;
462}
463
464namespace {
465
466// SfxSaveGuard ====================================================================================
467class SfxSaveGuard
468{
469 private:
470 Reference< frame::XModel > m_xModel;
472 std::unique_ptr<SfxOwnFramesLocker> m_pFramesLock;
473
474 SfxSaveGuard(SfxSaveGuard const &) = delete;
475 void operator =(const SfxSaveGuard&) = delete;
476
477 public:
478 SfxSaveGuard(const Reference< frame::XModel >& xModel ,
480 ~SfxSaveGuard();
481};
482
483}
484
485SfxSaveGuard::SfxSaveGuard(const Reference< frame::XModel >& xModel ,
487 : m_xModel ( xModel )
488 , m_pData ( pData )
489{
490 if ( m_pData->m_bClosed )
491 throw lang::DisposedException("Object already disposed.");
492
493 m_pData->m_bSaving = true;
494 m_pFramesLock.reset(new SfxOwnFramesLocker( m_pData->m_pObjectShell.get() ));
495}
496
497SfxSaveGuard::~SfxSaveGuard()
498{
499 m_pFramesLock.reset();
500
501 m_pData->m_bSaving = false;
502
503 // m_bSuicide was set e.g. in case someone tried to close a document, while it was used for
504 // storing at the same time. Further m_bSuicide was set to sal_True only if close(sal_True) was called.
505 // So the ownership was delegated to the place where a veto exception was thrown.
506 // Now we have to call close() again and delegate the ownership to the next one, which
507 // can't accept that. Close(sal_False) can't work in this case. Because then the document will may be never closed...
508
509 if ( !m_pData->m_bSuicide )
510 return;
511
512 // Reset this state. In case the new close() request is not accepted by someone else...
513 // it's not a good idea to have two "owners" for close.-)
514 m_pData->m_bSuicide = false;
515 try
516 {
517 Reference< util::XCloseable > xClose(m_xModel, UNO_QUERY);
518 if (xClose.is())
519 xClose->close(true);
520 }
521 catch(const util::CloseVetoException&)
522 {}
523}
524
526: BaseMutex()
528, m_bSupportEmbeddedScripts( pObjectShell && pObjectShell->Get_Impl() && !pObjectShell->Get_Impl()->m_bNoBasicCapabilities )
529, m_bSupportDocRecovery( pObjectShell && pObjectShell->Get_Impl() && pObjectShell->Get_Impl()->m_bDocRecoverySupport )
530{
531 if ( pObjectShell != nullptr )
532 {
533 StartListening( *pObjectShell ) ;
534 }
535}
536
537// destructor
539{
540}
541
542// XInterface
544{
547 )
548 return Any();
549
550 return SfxBaseModel_Base::queryInterface( rType );
551}
552
553
554// XTypeProvider
555
556
557namespace
558{
559 void lcl_stripType( Sequence< uno::Type >& io_rTypes, const uno::Type& i_rTypeToStrip )
560 {
561 Sequence< uno::Type > aStrippedTypes( io_rTypes.getLength() - 1 );
562 ::std::remove_copy_if(
563 std::cbegin(io_rTypes),
564 std::cend(io_rTypes),
565 aStrippedTypes.getArray(),
566 [&i_rTypeToStrip](const uno::Type& aType) { return aType == i_rTypeToStrip; }
567 );
568 io_rTypes = aStrippedTypes;
569 }
570}
571
572Sequence< uno::Type > SAL_CALL SfxBaseModel::getTypes()
573{
574 Sequence< uno::Type > aTypes( SfxBaseModel_Base::getTypes() );
575
578
581
582 return aTypes;
583}
584
585
586// XTypeProvider
587
588
590{
591 return css::uno::Sequence<sal_Int8>();
592}
593
594
595// XStarBasicAccess
596
597#if HAVE_FEATURE_SCRIPTING
598
599static Reference< script::XStarBasicAccess > implGetStarBasicAccess( SfxObjectShell const * pObjectShell )
600{
601 Reference< script::XStarBasicAccess > xRet;
602
603#if !HAVE_FEATURE_SCRIPTING
604 (void) pObjectShell;
605#else
606 if( pObjectShell )
607 {
608 BasicManager* pMgr = pObjectShell->GetBasicManager();
609 xRet = getStarBasicAccess( pMgr );
610 }
611#endif
612 return xRet;
613}
614
615#endif
616
617Reference< container::XNameContainer > SAL_CALL SfxBaseModel::getLibraryContainer()
618{
619#if !HAVE_FEATURE_SCRIPTING
620 Reference< container::XNameContainer > dummy;
621
622 return dummy;
623#else
624 SfxModelGuard aGuard( *this );
625
626 Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess;
627 if( !rxAccess.is() && m_pData->m_pObjectShell.is() )
628 rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell.get() );
629
630 Reference< container::XNameContainer > xRet;
631 if( rxAccess.is() )
632 xRet = rxAccess->getLibraryContainer();
633 return xRet;
634#endif
635}
636
640void SAL_CALL SfxBaseModel::createLibrary( const OUString& LibName, const OUString& Password,
641 const OUString& ExternalSourceURL, const OUString& LinkTargetURL )
642{
643#if !HAVE_FEATURE_SCRIPTING
644 (void) LibName;
645 (void) Password;
646 (void) ExternalSourceURL;
647 (void) LinkTargetURL;
648#else
649 SfxModelGuard aGuard( *this );
650
651 Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess;
652 if( !rxAccess.is() && m_pData->m_pObjectShell.is() )
653 rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell.get() );
654
655 if( rxAccess.is() )
656 rxAccess->createLibrary( LibName, Password, ExternalSourceURL, LinkTargetURL );
657#endif
658}
659
663void SAL_CALL SfxBaseModel::addModule( const OUString& LibraryName, const OUString& ModuleName,
664 const OUString& Language, const OUString& Source )
665{
666#if !HAVE_FEATURE_SCRIPTING
667 (void) LibraryName;
668 (void) ModuleName;
669 (void) Language;
670 (void) Source;
671#else
672 SfxModelGuard aGuard( *this );
673
674 Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess;
675 if( !rxAccess.is() && m_pData->m_pObjectShell.is() )
676 rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell.get() );
677
678 if( rxAccess.is() )
679 rxAccess->addModule( LibraryName, ModuleName, Language, Source );
680#endif
681}
682
686void SAL_CALL SfxBaseModel::addDialog( const OUString& LibraryName, const OUString& DialogName,
687 const Sequence< sal_Int8 >& Data )
688{
689#if !HAVE_FEATURE_SCRIPTING
690 (void) LibraryName;
691 (void) DialogName;
692 (void) Data;
693#else
694 SfxModelGuard aGuard( *this );
695
696 Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess;
697 if( !rxAccess.is() && m_pData->m_pObjectShell.is() )
698 rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell.get() );
699
700 if( rxAccess.is() )
701 rxAccess->addDialog( LibraryName, DialogName, Data );
702#endif
703}
704
705
706// XChild
707
708
709Reference< XInterface > SAL_CALL SfxBaseModel::getParent()
710{
711 SfxModelGuard aGuard( *this );
712
713 return m_pData->m_xParent;
714}
715
716
717// XChild
718
719
720void SAL_CALL SfxBaseModel::setParent(const Reference< XInterface >& Parent)
721{
723 m_pData->m_xParent = Parent;
724}
725
726
727// XChild
728
729
731{
733
734 if ( !m_pData->m_bClosed )
735 {
736 // gracefully accept wrong dispose calls instead of close call
737 // and try to make it work (may be really disposed later!)
738 try
739 {
740 close( true );
741 }
742 catch ( util::CloseVetoException& )
743 {
744 }
745
746 return;
747 }
748
749 if ( m_pData->m_bDisposing )
750 return;
751 m_pData->m_bDisposing = true;
752
753 if ( m_pData->m_pStorageModifyListen.is() )
754 {
755 m_pData->m_pStorageModifyListen->dispose();
756 m_pData->m_pStorageModifyListen = nullptr;
757 }
758
759 if ( m_pData->m_pDocumentUndoManager.is() )
760 {
761 m_pData->m_pDocumentUndoManager->disposing();
762 m_pData->m_pDocumentUndoManager = nullptr;
763 }
764
765 lang::EventObject aEvent( static_cast<frame::XModel *>(this) );
766 m_pData->m_aInterfaceContainer.disposeAndClear( aEvent );
767
768 m_pData->m_xDocumentProperties.clear();
769
770 m_pData->m_xDocumentMetadata.clear();
771
772 if ( m_pData->m_pObjectShell.is() )
773 {
774 EndListening( *m_pData->m_pObjectShell );
775 }
776
777 m_pData->m_xCurrent.clear();
778 m_pData->m_seqControllers.clear();
779
780 // m_pData member must be set to zero before delete is called to
781 // force disposed exception whenever someone tries to access our
782 // instance while in the dtor.
783 m_pData.reset();
784}
785
786
787// XChild
788
789
790void SAL_CALL SfxBaseModel::addEventListener( const Reference< lang::XEventListener >& aListener )
791{
793 m_pData->m_aInterfaceContainer.addInterface( cppu::UnoType<lang::XEventListener>::get(), aListener );
794}
795
796
797// XChild
798
799
800void SAL_CALL SfxBaseModel::removeEventListener( const Reference< lang::XEventListener >& aListener )
801{
803 m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<lang::XEventListener>::get(), aListener );
804}
805
806void
808 const Reference< document::XDocumentProperties >& rxNewDocProps)
809{
810 m_xDocumentProperties.set(rxNewDocProps, UNO_SET_THROW);
811 if (m_pObjectShell.is())
812 {
813 Reference<util::XModifyBroadcaster> const xMB(
814 m_xDocumentProperties, UNO_QUERY_THROW);
815 xMB->addModifyListener(new SfxDocInfoListener_Impl(*m_pObjectShell));
816 }
817}
818
819// document::XDocumentPropertiesSupplier:
820Reference< document::XDocumentProperties > SAL_CALL
822{
824 if ( !m_pData->m_xDocumentProperties.is() )
825 {
826 Reference< document::XDocumentProperties > xDocProps(
827 document::DocumentProperties::create( ::comphelper::getProcessComponentContext() ) );
828 m_pData->impl_setDocumentProperties(xDocProps);
829 }
830
831 return m_pData->m_xDocumentProperties;
832}
833
834
835// lang::XEventListener
836
837
838void SAL_CALL SfxBaseModel::disposing( const lang::EventObject& aObject )
839{
840 SolarMutexGuard aGuard;
841 if ( impl_isDisposed() )
842 return;
843
844 Reference< util::XModifyListener > xMod( aObject.Source, UNO_QUERY );
845 Reference< lang::XEventListener > xListener( aObject.Source, UNO_QUERY );
846 Reference< document::XEventListener > xDocListener( aObject.Source, UNO_QUERY );
847
848 if ( xMod.is() )
849 m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<util::XModifyListener>::get(), xMod );
850 else if ( xListener.is() )
851 m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<lang::XEventListener>::get(), xListener );
852 else if ( xDocListener.is() )
853 m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<document::XEventListener>::get(), xListener );
854}
855
856
857// frame::XModel
858
859
860sal_Bool SAL_CALL SfxBaseModel::attachResource( const OUString& rURL ,
861 const Sequence< beans::PropertyValue >& rArgs )
862{
864 if ( rURL.isEmpty() && rArgs.getLength() == 1 && rArgs[0].Name == "SetEmbedded" )
865 {
866 // allows to set a windowless document to EMBEDDED state
867 // but _only_ before load() or initNew() methods
868 if ( m_pData->m_pObjectShell.is() && !m_pData->m_pObjectShell->GetMedium() )
869 {
870 bool bEmb(false);
871 if ( ( rArgs[0].Value >>= bEmb ) && bEmb )
872 m_pData->m_pObjectShell->SetCreateMode_Impl( SfxObjectCreateMode::EMBEDDED );
873 }
874
875 return true;
876 }
877
878 if ( m_pData->m_pObjectShell.is() )
879 {
880 m_pData->m_sURL = rURL;
881
882 SfxObjectShell* pObjectShell = m_pData->m_pObjectShell.get();
883
884 Sequence< sal_Int32 > aWinExtent;
885 for (const beans::PropertyValue & rProp : rArgs)
886 {
887 if (rProp.Name == "WinExtent" && (rProp.Value >>= aWinExtent) && ( aWinExtent.getLength() == 4 ) )
888 {
889 tools::Rectangle aVisArea( aWinExtent[0], aWinExtent[1], aWinExtent[2], aWinExtent[3] );
890 aVisArea = OutputDevice::LogicToLogic(aVisArea, MapMode(MapUnit::Map100thMM), MapMode(pObjectShell->GetMapUnit()));
891 pObjectShell->SetVisArea( aVisArea );
892 }
893 bool bBreakMacroSign = false;
894 if ( rProp.Name == "BreakMacroSignature" && (rProp.Value >>= bBreakMacroSign) )
895 {
896 pObjectShell->BreakMacroSign_Impl( bBreakMacroSign );
897 }
898 bool bMacroEventRead = false;
899 if ( rProp.Name == "MacroEventRead" && (rProp.Value >>= bMacroEventRead) && bMacroEventRead)
900 {
901 pObjectShell->SetMacroCallsSeenWhileLoading();
902 }
903 }
904 Sequence<beans::PropertyValue> aStrippedArgs(rArgs.getLength());
905 beans::PropertyValue* pStripped = aStrippedArgs.getArray();
906 for (const beans::PropertyValue & rProp : rArgs)
907 {
908 if (rProp.Name == "WinExtent"
909 || rProp.Name == "BreakMacroSignature"
910 || rProp.Name == "MacroEventRead"
911 || rProp.Name == "Stream"
912 || rProp.Name == "InputStream"
913 || rProp.Name == "URL"
914 || rProp.Name == "Frame"
915 || rProp.Name == "Password"
916 || rProp.Name == "EncryptionData")
917 continue;
918 *pStripped++ = rProp;
919 }
920 aStrippedArgs.realloc(pStripped - aStrippedArgs.getArray());
921
922 // TODO/LATER: all the parameters that are accepted by ItemSet of the DocShell must be removed here
923
924 m_pData->m_seqArguments = aStrippedArgs;
925
926 SfxMedium* pMedium = pObjectShell->GetMedium();
927 if ( pMedium )
928 {
929 SfxAllItemSet aSet( pObjectShell->GetPool() );
930 TransformParameters( SID_OPENDOC, rArgs, aSet );
931
932 // the arguments are not allowed to reach the medium
933 aSet.ClearItem( SID_FILE_NAME );
934 aSet.ClearItem( SID_FILLFRAME );
935
936 pMedium->GetItemSet().Put( aSet );
937 const SfxStringItem* pItem = aSet.GetItem<SfxStringItem>(SID_FILTER_NAME, false);
938 if ( pItem )
939 pMedium->SetFilter(
940 pObjectShell->GetFactory().GetFilterContainer()->GetFilter4FilterName( pItem->GetValue() ) );
941
942 const SfxStringItem* pTitleItem = aSet.GetItem<SfxStringItem>(SID_DOCINFO_TITLE, false);
943 if ( pTitleItem )
944 {
945 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pObjectShell );
946 if ( pFrame )
947 pFrame->UpdateTitle();
948 }
949 }
950 }
951
952 return true ;
953}
954
955
956// frame::XModel
957
958
959OUString SAL_CALL SfxBaseModel::getURL()
960{
961 SfxModelGuard aGuard( *this );
962 return m_pData->m_sURL ;
963}
964
965
966// frame::XModel
967
968Sequence< beans::PropertyValue > SAL_CALL SfxBaseModel::getArgs()
969{
970 return getArgs2({});
971}
972
973// frame::XModel3
974
975Sequence< beans::PropertyValue > SAL_CALL SfxBaseModel::getArgs2(const Sequence<OUString> & requestedArgsSeq )
976{
977 SfxModelGuard aGuard( *this );
978
979 if (!SfxApplication::Get()) // tdf#113755
980 {
981 SAL_WARN("sfx.appl", "Unexpected operations on model");
982 return m_pData->m_seqArguments;
983 }
984
985 std::set<std::u16string_view> requestedArgs;
986 for (OUString const & s : requestedArgsSeq)
987 requestedArgs.insert(s);
988
989 if ( m_pData->m_pObjectShell.is() )
990 {
991 Sequence< beans::PropertyValue > seqArgsNew;
992 Sequence< beans::PropertyValue > seqArgsOld;
993 SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() );
994
995 // we need to know which properties are supported by the transformer
996 // hopefully it is a temporary solution, I guess nonconvertable properties
997 // should not be supported so then there will be only ItemSet from medium
998
999 TransformItems( SID_OPENDOC, m_pData->m_pObjectShell->GetMedium()->GetItemSet(), seqArgsNew );
1000 TransformParameters( SID_OPENDOC, m_pData->m_seqArguments, aSet );
1001 TransformItems( SID_OPENDOC, aSet, seqArgsOld );
1002
1003 sal_Int32 nNewLength = seqArgsNew.getLength();
1004
1005 if (requestedArgs.empty() || requestedArgs.count(u"WinExtent"))
1006 {
1007 // "WinExtent" property should be updated always.
1008 // We can store it now to overwrite an old value
1009 // since it is not from ItemSet
1010 tools::Rectangle aTmpRect = m_pData->m_pObjectShell->GetVisArea( ASPECT_CONTENT );
1011 aTmpRect = OutputDevice::LogicToLogic(aTmpRect, MapMode(m_pData->m_pObjectShell->GetMapUnit()), MapMode(MapUnit::Map100thMM));
1012
1013 Sequence< sal_Int32 > aRectSeq
1014 {
1015 o3tl::narrowing<int>(aTmpRect.Left()),
1016 o3tl::narrowing<int>(aTmpRect.Top()),
1017 o3tl::narrowing<int>(aTmpRect.IsWidthEmpty() ? aTmpRect.Left() : aTmpRect.Right()),
1018 o3tl::narrowing<int>(aTmpRect.IsHeightEmpty() ? aTmpRect.Top() : aTmpRect.Bottom())
1019 };
1020
1021 seqArgsNew.realloc( ++nNewLength );
1022 auto pseqArgsNew = seqArgsNew.getArray();
1023 pseqArgsNew[ nNewLength - 1 ].Name = "WinExtent";
1024 pseqArgsNew[ nNewLength - 1 ].Value <<= aRectSeq;
1025 }
1026
1027 if (requestedArgs.empty() || requestedArgs.count(u"PreusedFilterName"))
1028 {
1029 if ( !m_pData->m_aPreusedFilterName.isEmpty() )
1030 {
1031 seqArgsNew.realloc( ++nNewLength );
1032 auto pseqArgsNew = seqArgsNew.getArray();
1033 pseqArgsNew[ nNewLength - 1 ].Name = "PreusedFilterName";
1034 pseqArgsNew[ nNewLength - 1 ].Value <<= m_pData->m_aPreusedFilterName;
1035 }
1036 }
1037
1038 if (requestedArgs.empty() || requestedArgs.count(u"DocumentBorder"))
1039 {
1040 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( m_pData->m_pObjectShell.get() );
1041 if ( pFrame )
1042 {
1043 SvBorder aBorder = pFrame->GetBorderPixelImpl();
1044
1045 Sequence< sal_Int32 > aBorderSeq
1046 {
1047 o3tl::narrowing<int>(aBorder.Left()),
1048 o3tl::narrowing<int>(aBorder.Top()),
1049 o3tl::narrowing<int>(aBorder.Right()),
1050 o3tl::narrowing<int>(aBorder.Bottom())
1051 };
1052
1053 seqArgsNew.realloc( ++nNewLength );
1054 auto pseqArgsNew = seqArgsNew.getArray();
1055 pseqArgsNew[ nNewLength - 1 ].Name = "DocumentBorder";
1056 pseqArgsNew[ nNewLength - 1 ].Value <<= aBorderSeq;
1057 }
1058 }
1059
1060 if (requestedArgs.empty())
1061 {
1062 // only the values that are not supported by the ItemSet must be cached here
1063 Sequence< beans::PropertyValue > aFinalCache;
1064 sal_Int32 nFinalLength = 0;
1065
1066 for ( const auto& rOrg : std::as_const(m_pData->m_seqArguments) )
1067 {
1068 auto bNew = std::none_of(std::cbegin(seqArgsOld), std::cend(seqArgsOld),
1069 [&rOrg](const beans::PropertyValue& rOld){ return rOld.Name == rOrg.Name; });
1070 if ( bNew )
1071 {
1072 // the entity with this name should be new for seqArgsNew
1073 // since it is not supported by transformer
1074
1075 seqArgsNew.realloc( ++nNewLength );
1076 seqArgsNew.getArray()[ nNewLength - 1 ] = rOrg;
1077
1078 aFinalCache.realloc( ++nFinalLength );
1079 aFinalCache.getArray()[ nFinalLength - 1 ] = rOrg;
1080 }
1081 }
1082
1083 m_pData->m_seqArguments = aFinalCache;
1084 }
1085
1086 return seqArgsNew;
1087 }
1088
1089 return m_pData->m_seqArguments;
1090}
1091
1092void SAL_CALL SfxBaseModel::setArgs(const Sequence<beans::PropertyValue>& aArgs)
1093{
1094 SfxModelGuard aGuard( *this );
1095
1096 SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
1097 if (!pMedium)
1098 {
1099 throw util::InvalidStateException(
1100 "Medium could not be retrieved, unable to execute setArgs");
1101 }
1102
1103 for (const auto& rArg : aArgs)
1104 {
1105 OUString sValue;
1106 bool bValue;
1107 bool ok = false;
1108 if (rArg.Name == "SuggestedSaveAsName")
1109 {
1110 if (rArg.Value >>= sValue)
1111 {
1112 pMedium->GetItemSet().Put(SfxStringItem(SID_SUGGESTEDSAVEASNAME, sValue));
1113 ok = true;
1114 }
1115 }
1116 else if (rArg.Name == "SuggestedSaveAsDir")
1117 {
1118 if (rArg.Value >>= sValue)
1119 {
1120 pMedium->GetItemSet().Put(SfxStringItem(SID_SUGGESTEDSAVEASDIR, sValue));
1121 ok = true;
1122 }
1123 }
1124 else if (rArg.Name == "LockContentExtraction")
1125 {
1126 if (rArg.Value >>= bValue)
1127 {
1128 pMedium->GetItemSet().Put(SfxBoolItem(SID_LOCK_CONTENT_EXTRACTION, bValue));
1129 ok = true;
1130 }
1131 }
1132 else if (rArg.Name == "LockExport")
1133 {
1134 if (rArg.Value >>= bValue)
1135 {
1136 pMedium->GetItemSet().Put(SfxBoolItem(SID_LOCK_EXPORT, bValue));
1137 ok = true;
1138 }
1139 }
1140 else if (rArg.Name == "LockPrint")
1141 {
1142 if (rArg.Value >>= bValue)
1143 {
1144 pMedium->GetItemSet().Put(SfxBoolItem(SID_LOCK_PRINT, bValue));
1145 ok = true;
1146 }
1147 }
1148 else if (rArg.Name == "LockSave")
1149 {
1150 if (rArg.Value >>= bValue)
1151 {
1152 pMedium->GetItemSet().Put(SfxBoolItem(SID_LOCK_SAVE, bValue));
1153 ok = true;
1154 }
1155 }
1156 else if (rArg.Name == "LockEditDoc")
1157 {
1158 if (rArg.Value >>= bValue)
1159 {
1160 pMedium->GetItemSet().Put(SfxBoolItem(SID_LOCK_EDITDOC, bValue));
1161 ok = true;
1162 }
1163 }
1164 else if (rArg.Name == "Replaceable")
1165 {
1166 if (rArg.Value >>= bValue)
1167 {
1168 pMedium->GetItemSet().Put(SfxBoolItem(SID_REPLACEABLE, bValue));
1169 ok = true;
1170 }
1171 }
1172 else if (rArg.Name == "EncryptionData")
1173 {
1174 pMedium->GetItemSet().Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, rArg.Value));
1175 ok = true;
1176 }
1177 if (!ok)
1178 {
1179 throw lang::IllegalArgumentException("Setting property not supported: " + rArg.Name,
1181 }
1182 }
1183}
1184
1185// frame::XModel
1186
1187
1188void SAL_CALL SfxBaseModel::connectController( const Reference< frame::XController >& xController )
1189{
1190 SfxModelGuard aGuard( *this );
1191 OSL_PRECOND( xController.is(), "SfxBaseModel::connectController: invalid controller!" );
1192 if ( !xController.is() )
1193 return;
1194
1195 m_pData->m_seqControllers.push_back(xController);
1196
1197 if ( m_pData->m_seqControllers.size() == 1 )
1198 {
1200 ENSURE_OR_THROW( pViewFrame, "SFX document without SFX view!?" );
1201 pViewFrame->UpdateDocument_Impl();
1202 const OUString sDocumentURL = GetObjectShell()->GetMedium()->GetName();
1203 if ( !sDocumentURL.isEmpty() )
1204 SfxGetpApp()->Broadcast( SfxOpenUrlHint( sDocumentURL ) );
1205 }
1206}
1207
1208
1209// frame::XModel
1210
1211
1212void SAL_CALL SfxBaseModel::disconnectController( const Reference< frame::XController >& xController )
1213{
1214 SfxModelGuard aGuard( *this );
1215
1216 if ( m_pData->m_seqControllers.empty() )
1217 return;
1218
1219 auto& vec = m_pData->m_seqControllers;
1220 vec.erase(std::remove(vec.begin(), vec.end(), xController), vec.end());
1221
1222 if ( xController == m_pData->m_xCurrent )
1223 m_pData->m_xCurrent.clear();
1224}
1225
1226namespace
1227{
1228 class ControllerLockUndoAction : public ::cppu::WeakImplHelper< XUndoAction >
1229 {
1230 public:
1231 ControllerLockUndoAction( const Reference< XModel >& i_model, const bool i_undoIsUnlock )
1232 :m_xModel( i_model )
1233 ,m_bUndoIsUnlock( i_undoIsUnlock )
1234 {
1235 }
1236
1237 // XUndoAction
1238 virtual OUString SAL_CALL getTitle() override;
1239 virtual void SAL_CALL undo( ) override;
1240 virtual void SAL_CALL redo( ) override;
1241
1242 private:
1243 const Reference< XModel > m_xModel;
1244 const bool m_bUndoIsUnlock;
1245 };
1246
1247 OUString SAL_CALL ControllerLockUndoAction::getTitle()
1248 {
1249 // this action is intended to be used within an UndoContext only, so nobody will ever see this title ...
1250 return OUString();
1251 }
1252
1253 void SAL_CALL ControllerLockUndoAction::undo( )
1254 {
1255 if ( m_bUndoIsUnlock )
1256 m_xModel->unlockControllers();
1257 else
1258 m_xModel->lockControllers();
1259 }
1260
1261 void SAL_CALL ControllerLockUndoAction::redo( )
1262 {
1263 if ( m_bUndoIsUnlock )
1264 m_xModel->lockControllers();
1265 else
1266 m_xModel->unlockControllers();
1267 }
1268}
1269
1270
1271// frame::XModel
1272
1273
1275{
1276 SfxModelGuard aGuard( *this );
1277
1278 ++m_pData->m_nControllerLockCount ;
1279
1280 if ( m_pData->m_pDocumentUndoManager.is()
1281 && m_pData->m_pDocumentUndoManager->isInContext()
1282 && !m_pData->m_pDocumentUndoManager->isLocked()
1283 )
1284 {
1285 m_pData->m_pDocumentUndoManager->addUndoAction( new ControllerLockUndoAction( this, true ) );
1286 }
1287}
1288
1289
1290// frame::XModel
1291
1292
1294{
1295 SfxModelGuard aGuard( *this );
1296
1297 --m_pData->m_nControllerLockCount ;
1298
1299 if ( m_pData->m_pDocumentUndoManager.is()
1300 && m_pData->m_pDocumentUndoManager->isInContext()
1301 && !m_pData->m_pDocumentUndoManager->isLocked()
1302 )
1303 {
1304 m_pData->m_pDocumentUndoManager->addUndoAction( new ControllerLockUndoAction( this, false ) );
1305 }
1306}
1307
1308
1309// frame::XModel
1310
1311
1313{
1314 SfxModelGuard aGuard( *this );
1315 return ( m_pData->m_nControllerLockCount != 0 ) ;
1316}
1317
1318
1319// frame::XModel
1320
1321
1322Reference< frame::XController > SAL_CALL SfxBaseModel::getCurrentController()
1323{
1324 SfxModelGuard aGuard( *this );
1325
1326 // get the last active controller of this model
1327 if ( m_pData->m_xCurrent.is() )
1328 return m_pData->m_xCurrent;
1329
1330 // get the first controller of this model
1331 return !m_pData->m_seqControllers.empty() ? m_pData->m_seqControllers.front() : m_pData->m_xCurrent;
1332}
1333
1334
1335// frame::XModel
1336
1337
1338void SAL_CALL SfxBaseModel::setCurrentController( const Reference< frame::XController >& xCurrentController )
1339{
1340 SfxModelGuard aGuard( *this );
1341
1342 m_pData->m_xCurrent = xCurrentController;
1343}
1344
1345
1346// frame::XModel
1347
1348
1349Reference< XInterface > SAL_CALL SfxBaseModel::getCurrentSelection()
1350{
1351 SfxModelGuard aGuard( *this );
1352
1353 Reference< XInterface > xReturn;
1354 Reference< frame::XController > xController = getCurrentController() ;
1355
1356 if ( xController.is() )
1357 {
1358 Reference< view::XSelectionSupplier > xDocView( xController, UNO_QUERY );
1359 if ( xDocView.is() )
1360 {
1361 Any aSel = xDocView->getSelection();
1362 aSel >>= xReturn ;
1363 }
1364 }
1365
1366 return xReturn ;
1367}
1368
1369
1370// XModifiable2
1371
1372
1374{
1375 SfxModelGuard aGuard( *this );
1376
1377 if ( !m_pData->m_pObjectShell.is() )
1378 throw RuntimeException();
1379
1380 bool bResult = m_pData->m_pObjectShell->IsEnableSetModified();
1381 m_pData->m_pObjectShell->EnableSetModified( false );
1382
1383 return bResult;
1384}
1385
1387{
1388 SfxModelGuard aGuard( *this );
1389
1390 if ( !m_pData->m_pObjectShell.is() )
1391 throw RuntimeException();
1392
1393 bool bResult = m_pData->m_pObjectShell->IsEnableSetModified();
1394 m_pData->m_pObjectShell->EnableSetModified();
1395
1396 return bResult;
1397}
1398
1400{
1401 SfxModelGuard aGuard( *this );
1402
1403 if ( !m_pData->m_pObjectShell.is() )
1404 throw RuntimeException();
1405
1406 return m_pData->m_pObjectShell->IsEnableSetModified();
1407}
1408
1409
1410// XModifiable
1411
1412
1414{
1415 SfxModelGuard aGuard( *this );
1416
1417 return m_pData->m_pObjectShell.is() && m_pData->m_pObjectShell->IsModified();
1418}
1419
1420
1421// XModifiable
1422
1423
1424void SAL_CALL SfxBaseModel::setModified( sal_Bool bModified )
1425{
1426 SfxModelGuard aGuard( *this );
1427
1428 if ( m_pData->m_pObjectShell.is() )
1429 m_pData->m_pObjectShell->SetModified(bModified);
1430}
1431
1432
1433// XModifiable
1434
1435
1436void SAL_CALL SfxBaseModel::addModifyListener(const Reference< util::XModifyListener >& xListener)
1437{
1439
1440 m_pData->m_aInterfaceContainer.addInterface( cppu::UnoType<util::XModifyListener>::get(),xListener );
1441}
1442
1443
1444// XModifiable
1445
1446
1447void SAL_CALL SfxBaseModel::removeModifyListener(const Reference< util::XModifyListener >& xListener)
1448{
1449 SfxModelGuard aGuard( *this );
1450
1451 m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<util::XModifyListener>::get(), xListener );
1452}
1453
1454
1455// XCloseable
1456
1457
1458void SAL_CALL SfxBaseModel::close( sal_Bool bDeliverOwnership )
1459{
1460 SolarMutexGuard aGuard;
1461 if ( impl_isDisposed() || m_pData->m_bClosed || m_pData->m_bClosing )
1462 return;
1463
1464 Reference< XInterface > xSelfHold( getXWeak() );
1465 lang::EventObject aSource ( getXWeak() );
1466 comphelper::OInterfaceContainerHelper2* pContainer = m_pData->m_aInterfaceContainer.getContainer( cppu::UnoType<util::XCloseListener>::get());
1467 if (pContainer!=nullptr)
1468 {
1469 comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer);
1470 while (pIterator.hasMoreElements())
1471 {
1472 try
1473 {
1474 static_cast<util::XCloseListener*>(pIterator.next())->queryClosing( aSource, bDeliverOwnership );
1475 }
1476 catch( RuntimeException& )
1477 {
1478 pIterator.remove();
1479 }
1480 }
1481 }
1482
1483 if ( m_pData->m_bSaving )
1484 {
1485 if (bDeliverOwnership)
1486 m_pData->m_bSuicide = true;
1487 throw util::CloseVetoException(
1488 "Can not close while saving.",
1489 static_cast< util::XCloseable* >(this));
1490 }
1491
1492 // no own objections against closing!
1493 m_pData->m_bClosing = true;
1494 pContainer = m_pData->m_aInterfaceContainer.getContainer( cppu::UnoType<util::XCloseListener>::get());
1495 if (pContainer!=nullptr)
1496 {
1497 comphelper::OInterfaceIteratorHelper2 pCloseIterator(*pContainer);
1498 while (pCloseIterator.hasMoreElements())
1499 {
1500 try
1501 {
1502 static_cast<util::XCloseListener*>(pCloseIterator.next())->notifyClosing( aSource );
1503 }
1504 catch( RuntimeException& )
1505 {
1506 pCloseIterator.remove();
1507 }
1508 }
1509 }
1510
1511 m_pData->m_bClosed = true;
1512 m_pData->m_bClosing = false;
1513
1514 dispose();
1515}
1516
1517
1518// XCloseBroadcaster
1519
1520
1521void SAL_CALL SfxBaseModel::addCloseListener( const Reference< util::XCloseListener >& xListener )
1522{
1524
1525 m_pData->m_aInterfaceContainer.addInterface( cppu::UnoType<util::XCloseListener>::get(), xListener );
1526}
1527
1528
1529// XCloseBroadcaster
1530
1531
1532void SAL_CALL SfxBaseModel::removeCloseListener( const Reference< util::XCloseListener >& xListener )
1533{
1534 SfxModelGuard aGuard( *this );
1535
1536 m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<util::XCloseListener>::get(), xListener );
1537}
1538
1539
1540// XPrintable
1541
1542
1543Sequence< beans::PropertyValue > SAL_CALL SfxBaseModel::getPrinter()
1544{
1545 SfxModelGuard aGuard( *this );
1546
1548 return m_pData->m_xPrintable->getPrinter();
1549}
1550
1551void SAL_CALL SfxBaseModel::setPrinter(const Sequence< beans::PropertyValue >& rPrinter)
1552{
1553 SfxModelGuard aGuard( *this );
1554
1556 m_pData->m_xPrintable->setPrinter( rPrinter );
1557}
1558
1559void SAL_CALL SfxBaseModel::print(const Sequence< beans::PropertyValue >& rOptions)
1560{
1561 SfxModelGuard aGuard( *this );
1562
1564
1565 // tdf#123728 Always print on main thread to avoid deadlocks
1566 vcl::solarthread::syncExecute([this, &rOptions]() { m_pData->m_xPrintable->print(rOptions); });
1567}
1568
1569// XStorable
1570
1571
1573{
1574 SfxModelGuard aGuard( *this );
1575
1576 return m_pData->m_pObjectShell.is() && m_pData->m_pObjectShell->HasName();
1577}
1578
1579
1580// XStorable
1581
1582
1583OUString SAL_CALL SfxBaseModel::getLocation()
1584{
1585 SfxModelGuard aGuard( *this );
1586
1587 if ( m_pData->m_pObjectShell.is() )
1588 {
1589 // TODO/LATER: is it correct that the shared document returns shared file location?
1590 if ( m_pData->m_pObjectShell->IsDocShared() )
1591 return m_pData->m_pObjectShell->GetSharedFileURL();
1592 else
1593 return m_pData->m_pObjectShell->GetMedium()->GetName();
1594 }
1595
1596 return m_pData->m_sURL;
1597}
1598
1599
1600// XStorable
1601
1602
1604{
1605 SfxModelGuard aGuard( *this );
1606
1607 return !m_pData->m_pObjectShell.is() || m_pData->m_pObjectShell->IsReadOnly();
1608}
1609
1610// XStorable2
1611
1612
1613void SAL_CALL SfxBaseModel::storeSelf( const Sequence< beans::PropertyValue >& aSeqArgs )
1614{
1615 SfxModelGuard aGuard( *this );
1616
1617 if ( !m_pData->m_pObjectShell.is() )
1618 return;
1619
1620 SfxSaveGuard aSaveGuard(this, m_pData.get());
1621
1622 bool bCheckIn = false;
1623 bool bOnMainThread = false;
1624 for ( const auto& rArg : aSeqArgs )
1625 {
1626 // check that only acceptable parameters are provided here
1627 if ( rArg.Name != "VersionComment" && rArg.Name != "Author"
1628 && rArg.Name != "DontTerminateEdit"
1629 && rArg.Name != "InteractionHandler" && rArg.Name != "StatusIndicator"
1630 && rArg.Name != "VersionMajor"
1631 && rArg.Name != "FailOnWarning"
1632 && rArg.Name != "CheckIn"
1633 && rArg.Name != "NoFileSync"
1634 && rArg.Name != "OnMainThread" )
1635 {
1636 const OUString aMessage( "Unexpected MediaDescriptor parameter: " + rArg.Name );
1637 throw lang::IllegalArgumentException( aMessage, Reference< XInterface >(), 1 );
1638 }
1639 else if ( rArg.Name == "CheckIn" )
1640 {
1641 rArg.Value >>= bCheckIn;
1642 }
1643 else if (rArg.Name == "OnMainThread")
1644 {
1645 rArg.Value >>= bOnMainThread;
1646 }
1647 }
1648
1649 // Remove CheckIn property if needed
1650 sal_uInt16 nSlotId = SID_SAVEDOC;
1651 Sequence< beans::PropertyValue > aArgs = aSeqArgs;
1652 if ( bCheckIn )
1653 {
1654 nSlotId = SID_CHECKIN;
1655 sal_Int32 nLength = aSeqArgs.getLength( );
1656 aArgs = Sequence< beans::PropertyValue >( nLength - 1 );
1657 std::copy_if(aSeqArgs.begin(), aSeqArgs.end(), aArgs.getArray(),
1658 [](const beans::PropertyValue& rProp) { return rProp.Name != "CheckIn"; });
1659 }
1660
1661 std::optional<SfxAllItemSet> pParams(SfxGetpApp()->GetPool() );
1662 TransformParameters( nSlotId, aArgs, *pParams );
1663
1664 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveDoc, GlobalEventConfig::GetEventName(GlobalEventId::SAVEDOC), m_pData->m_pObjectShell.get() ) );
1665
1666 bool bRet = false;
1667
1668 // TODO/LATER: let the embedded case of saving be handled more careful
1669 if ( m_pData->m_pObjectShell->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
1670 {
1671 // If this is an embedded object that has no URL based location it should be stored to own storage.
1672 // An embedded object can have a location based on URL in case it is a link, then it should be
1673 // stored in normal way.
1674 if ( !hasLocation() || getLocation().startsWith("private:") )
1675 {
1676 // actually in this very rare case only UI parameters have sense
1677 // TODO/LATER: should be done later, after integration of sb19
1678 bRet = m_pData->m_pObjectShell->DoSave()
1679 && m_pData->m_pObjectShell->DoSaveCompleted();
1680 }
1681 else
1682 {
1683 bRet = m_pData->m_pObjectShell->Save_Impl( &*pParams );
1684 }
1685 }
1686 else
1687 {
1688 // Tell the SfxMedium if we are in checkin instead of normal save
1689 m_pData->m_pObjectShell->GetMedium( )->SetInCheckIn( nSlotId == SID_CHECKIN );
1690 if (bOnMainThread)
1692 [this, &pParams] { return m_pData->m_pObjectShell->Save_Impl(&*pParams); });
1693 else
1694 bRet = m_pData->m_pObjectShell->Save_Impl(&*pParams);
1695 m_pData->m_pObjectShell->GetMedium( )->SetInCheckIn( nSlotId != SID_CHECKIN );
1696 }
1697
1698 pParams.reset();
1699
1700 ErrCode nErrCode = m_pData->m_pObjectShell->GetError() ? m_pData->m_pObjectShell->GetError()
1702 m_pData->m_pObjectShell->ResetError();
1703
1704 if ( bRet )
1705 {
1706 m_pData->m_aPreusedFilterName = GetMediumFilterName_Impl();
1707
1708 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveDocDone, GlobalEventConfig::GetEventName(GlobalEventId::SAVEDOCDONE), m_pData->m_pObjectShell.get() ) );
1709 }
1710 else
1711 {
1712 // write the contents of the logger to the file
1713 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveDocFailed, GlobalEventConfig::GetEventName(GlobalEventId::SAVEDOCFAILED), m_pData->m_pObjectShell.get() ) );
1714
1715 throw task::ErrorCodeIOException(
1716 "SfxBaseModel::storeSelf: " + nErrCode.toString(),
1717 Reference< XInterface >(), sal_uInt32(nErrCode));
1718 }
1719}
1720
1721
1722// XStorable
1723
1724
1725void SAL_CALL SfxBaseModel::store()
1726{
1727 comphelper::ProfileZone aZone("store");
1728 storeSelf( Sequence< beans::PropertyValue >() );
1729}
1730
1731
1732// XStorable
1733
1734
1735void SAL_CALL SfxBaseModel::storeAsURL( const OUString& rURL ,
1736 const Sequence< beans::PropertyValue >& rArgs )
1737{
1738 SfxModelGuard aGuard( *this );
1739 comphelper::ProfileZone aZone("storeAs");
1740
1741 if ( !m_pData->m_pObjectShell.is() )
1742 return;
1743
1744 SfxSaveGuard aSaveGuard(this, m_pData.get());
1745
1746 utl::MediaDescriptor aDescriptor(rArgs);
1747 bool bOnMainThread = aDescriptor.getUnpackedValueOrDefault("OnMainThread", false);
1748 if (bOnMainThread)
1749 {
1750 vcl::solarthread::syncExecute([this, rURL, rArgs]() { impl_store(rURL, rArgs, false); });
1751 }
1752 else
1753 {
1754 impl_store(rURL, rArgs, false);
1755 }
1756
1757 Sequence< beans::PropertyValue > aSequence ;
1758 TransformItems( SID_OPENDOC, m_pData->m_pObjectShell->GetMedium()->GetItemSet(), aSequence );
1759 attachResource( rURL, aSequence );
1760
1762
1763#if OSL_DEBUG_LEVEL > 0
1764 const SfxStringItem* pPasswdItem = m_pData->m_pObjectShell->GetMedium()->GetItemSet().GetItem(SID_PASSWORD, false);
1765 OSL_ENSURE( !pPasswdItem, "There should be no Password property in the document MediaDescriptor!" );
1766#endif
1767}
1768
1769
1770// XUndoManagerSupplier
1771
1772Reference< XUndoManager > SAL_CALL SfxBaseModel::getUndoManager( )
1773{
1774 SfxModelGuard aGuard( *this );
1775 if ( !m_pData->m_pDocumentUndoManager.is() )
1776 m_pData->m_pDocumentUndoManager.set( new ::sfx2::DocumentUndoManager( *this ) );
1777 return m_pData->m_pDocumentUndoManager;
1778}
1779
1780
1781// XStorable
1782
1783
1784void SAL_CALL SfxBaseModel::storeToURL( const OUString& rURL ,
1785 const Sequence< beans::PropertyValue >& rArgs )
1786{
1787 SfxModelGuard aGuard( *this );
1788 comphelper::ProfileZone aZone("storeToURL");
1789
1790 if ( !m_pData->m_pObjectShell.is() )
1791 return;
1792
1793 SfxSaveGuard aSaveGuard(this, m_pData.get());
1794 try {
1795 utl::MediaDescriptor aDescriptor(rArgs);
1796 bool bOnMainThread = aDescriptor.getUnpackedValueOrDefault("OnMainThread", false);
1797 if (bOnMainThread)
1798 vcl::solarthread::syncExecute([this, rURL, rArgs]() { impl_store(rURL, rArgs, true); });
1799 else
1800 impl_store(rURL, rArgs, true);
1801 }
1802 catch (const uno::Exception &e)
1803 {
1804 // convert to the exception we announce in the throw
1805 // (eg. neon likes to throw InteractiveAugmentedIOException which
1806 // is not an io::IOException)
1807 throw io::IOException(e.Message, e.Context);
1808 }
1809}
1810
1812{
1813 SfxModelGuard aGuard( *this );
1814 return m_pData->m_oDirtyTimestamp.has_value();
1815}
1816
1817void SAL_CALL SfxBaseModel::storeToRecoveryFile( const OUString& i_TargetLocation, const Sequence< PropertyValue >& i_MediaDescriptor )
1818{
1819 SfxModelGuard aGuard( *this );
1820
1821 // delegate
1822 SfxSaveGuard aSaveGuard( this, m_pData.get() );
1823 impl_store( i_TargetLocation, i_MediaDescriptor, true );
1824
1825 // no need for subsequent calls to storeToRecoveryFile, unless we're modified, again
1826 m_pData->setModifiedForAutoSave(false);
1827}
1828
1830{
1831 SfxModelGuard aGuard(*this);
1832 if (!m_pData->m_oDirtyTimestamp)
1833 return -1;
1834 auto ms = std::chrono::ceil<std::chrono::milliseconds>(std::chrono::steady_clock::now()
1835 - *m_pData->m_oDirtyTimestamp);
1836 return ms.count();
1837}
1838
1839void SAL_CALL SfxBaseModel::recoverFromFile( const OUString& i_SourceLocation, const OUString& i_SalvagedFile, const Sequence< PropertyValue >& i_MediaDescriptor )
1840{
1842
1843 // delegate to our "load" method
1844 ::comphelper::NamedValueCollection aMediaDescriptor( i_MediaDescriptor );
1845
1846 // our load implementation expects the SalvagedFile to be in the media descriptor
1847 OSL_ENSURE( !aMediaDescriptor.has( "SalvagedFile" ) || ( aMediaDescriptor.getOrDefault( "SalvagedFile", OUString() ) == i_SalvagedFile ),
1848 "SfxBaseModel::recoverFromFile: inconsistent information!" );
1849 aMediaDescriptor.put( "SalvagedFile", i_SalvagedFile );
1850
1851 // similar for the to-be-loaded file
1852 OSL_ENSURE( !aMediaDescriptor.has( "URL" ) || ( aMediaDescriptor.getOrDefault( "URL", OUString() ) == i_SourceLocation ),
1853 "SfxBaseModel::recoverFromFile: inconsistent information!" );
1854 aMediaDescriptor.put( "URL", i_SourceLocation );
1855
1856 load( aMediaDescriptor.getPropertyValues() );
1857
1858 // Note: The XDocumentRecovery interface specification requires us to do an attachResource after loading.
1859 // However, we will not do this here, as we know that our load implementation (respectively some method
1860 // called from there) already did so.
1861 // In particular, the load process might already have modified some elements of the media
1862 // descriptor, for instance the MacroExecMode (in case the user was involved to decide about it), and we do
1863 // not want to overwrite it with the "old" elements passed to this method here.
1864}
1865
1866
1867// XLoadable
1868
1869
1871{
1873 if ( IsInitialized() )
1874 throw frame::DoubleInitializationException( OUString(), *this );
1875
1876 // the object shell should exist always
1877 DBG_ASSERT( m_pData->m_pObjectShell.is(), "Model is useless without an ObjectShell" );
1878 if ( !m_pData->m_pObjectShell.is() )
1879 return;
1880
1881 if( m_pData->m_pObjectShell->GetMedium() )
1882 throw frame::DoubleInitializationException();
1883
1884 bool bRes = m_pData->m_pObjectShell->DoInitNew();
1885 ErrCode nErrCode = m_pData->m_pObjectShell->GetError() ?
1886 m_pData->m_pObjectShell->GetError() : ERRCODE_IO_CANTCREATE;
1887 m_pData->m_pObjectShell->ResetError();
1888
1889 if ( !bRes )
1890 throw task::ErrorCodeIOException(
1891 "SfxBaseModel::initNew: " + nErrCode.toString(),
1892 Reference< XInterface >(), sal_uInt32(nErrCode));
1893}
1894
1895namespace {
1896
1897OUString getFilterProvider( SfxMedium const & rMedium )
1898{
1899 const std::shared_ptr<const SfxFilter>& pFilter = rMedium.GetFilter();
1900 if (!pFilter)
1901 return OUString();
1902
1903 return pFilter->GetProviderName();
1904}
1905
1906void setUpdatePickList( SfxMedium* pMedium )
1907{
1908 if (!pMedium)
1909 return;
1910
1911 bool bHidden = false;
1912 const SfxBoolItem* pHidItem = pMedium->GetItemSet().GetItem(SID_HIDDEN, false);
1913 if (pHidItem)
1914 bHidden = pHidItem->GetValue();
1915
1916 pMedium->SetUpdatePickList(!bHidden);
1917}
1918
1919}
1920
1921void SAL_CALL SfxBaseModel::load( const Sequence< beans::PropertyValue >& seqArguments )
1922{
1924 if ( IsInitialized() )
1925 throw frame::DoubleInitializationException( OUString(), *this );
1926
1927 // the object shell should exist always
1928 DBG_ASSERT( m_pData->m_pObjectShell.is(), "Model is useless without an ObjectShell" );
1929
1930 if (!m_pData->m_pObjectShell.is())
1931 return;
1932
1933 if( m_pData->m_pObjectShell->GetMedium() )
1934 // if a Medium is present, the document is already initialized
1935 throw frame::DoubleInitializationException();
1936
1937 SfxMedium* pMedium = new SfxMedium( seqArguments );
1938
1939 ErrCode nError = ERRCODE_NONE;
1940 if (!getFilterProvider(*pMedium).isEmpty())
1941 {
1942 if (!m_pData->m_pObjectShell->DoLoadExternal(pMedium))
1943 nError = ERRCODE_IO_GENERAL;
1944
1945 pMedium = handleLoadError(nError, pMedium);
1946 setUpdatePickList(pMedium);
1947 return;
1948 }
1949
1950 OUString aFilterName;
1951 const SfxStringItem* pFilterNameItem = pMedium->GetItemSet().GetItem(SID_FILTER_NAME, false);
1952 if( pFilterNameItem )
1953 aFilterName = pFilterNameItem->GetValue();
1954 if( !m_pData->m_pObjectShell->GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName ) )
1955 {
1956 // filtername is not valid
1957 delete pMedium;
1958 throw frame::IllegalArgumentIOException();
1959 }
1960
1961 const SfxStringItem* pSalvageItem = pMedium->GetItemSet().GetItem(SID_DOC_SALVAGE, false);
1962 bool bSalvage = pSalvageItem != nullptr;
1963
1964 // load document
1965 if ( !m_pData->m_pObjectShell->DoLoad(pMedium) )
1966 nError=ERRCODE_IO_GENERAL;
1967
1968 // QUESTION: if the following happens outside of DoLoad, something important is missing there!
1969 Reference< task::XInteractionHandler > xHandler = pMedium->GetInteractionHandler();
1970 if( m_pData->m_pObjectShell->GetErrorCode() )
1971 {
1972 nError = m_pData->m_pObjectShell->GetErrorCode();
1973 if ( nError == ERRCODE_IO_BROKENPACKAGE && xHandler.is() )
1974 {
1976 const SfxBoolItem* pRepairItem = pMedium->GetItemSet().GetItem(SID_REPAIRPACKAGE, false);
1977 if ( !pRepairItem || !pRepairItem->GetValue() )
1978 {
1979 RequestPackageReparation aRequest( aDocName );
1980 xHandler->handle( aRequest.GetRequest() );
1981 if( aRequest.isApproved() )
1982 {
1983 // broken package: try second loading and allow repair
1984 pMedium->GetItemSet().Put( SfxBoolItem( SID_REPAIRPACKAGE, true ) );
1985 pMedium->GetItemSet().Put( SfxBoolItem( SID_TEMPLATE, true ) );
1986 pMedium->GetItemSet().Put( SfxStringItem( SID_DOCINFO_TITLE, aDocName ) );
1987
1988 // the error must be reset and the storage must be reopened in new mode
1989 pMedium->ResetError();
1990 pMedium->CloseStorage();
1991 m_pData->m_pObjectShell->PrepareSecondTryLoad_Impl();
1992 nError = ERRCODE_NONE;
1993 if ( !m_pData->m_pObjectShell->DoLoad(pMedium) )
1994 nError=ERRCODE_IO_GENERAL;
1995 if (m_pData->m_pObjectShell->GetErrorCode())
1996 nError = m_pData->m_pObjectShell->GetErrorCode();
1997 }
1998 }
1999
2000 if ( nError == ERRCODE_IO_BROKENPACKAGE )
2001 {
2002 // repair either not allowed or not successful
2003 NotifyBrokenPackage aRequest( aDocName );
2004 xHandler->handle( aRequest.GetRequest() );
2005 }
2006 }
2007 }
2008
2009 if( m_pData->m_pObjectShell->IsAbortingImport() )
2010 nError = ERRCODE_ABORT;
2011
2012 if( bSalvage )
2013 {
2014 // file recovery: restore original filter
2015 const SfxStringItem* pFilterItem = pMedium->GetItemSet().GetItem(SID_FILTER_NAME, false);
2017 std::shared_ptr<const SfxFilter> pSetFilter = rMatcher.GetFilter4FilterName( pFilterItem->GetValue() );
2018 pMedium->SetFilter( pSetFilter );
2019 m_pData->m_pObjectShell->SetModified();
2020 }
2021
2022 // TODO/LATER: maybe the mode should be retrieved from outside and the preused filter should not be set
2023 if ( m_pData->m_pObjectShell->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
2024 {
2025 const SfxStringItem* pFilterItem = pMedium->GetItemSet().GetItem(SID_FILTER_NAME, false);
2026 if ( pFilterItem )
2027 m_pData->m_aPreusedFilterName = pFilterItem->GetValue();
2028 }
2029
2030 if ( !nError )
2031 nError = pMedium->GetError();
2032
2033 m_pData->m_pObjectShell->ResetError();
2034
2035 pMedium = handleLoadError(nError, pMedium);
2037 setUpdatePickList(pMedium);
2038
2039#if OSL_DEBUG_LEVEL > 0
2040 const SfxStringItem* pPasswdItem = pMedium->GetItemSet().GetItem(SID_PASSWORD, false);
2041 OSL_ENSURE( !pPasswdItem, "There should be no Password property in the document MediaDescriptor!" );
2042#endif
2043}
2044
2045
2046// XTransferable
2047
2048
2049Any SAL_CALL SfxBaseModel::getTransferData( const datatransfer::DataFlavor& aFlavor )
2050{
2051 SfxModelGuard aGuard( *this );
2052
2053 Any aAny;
2054
2055 if ( m_pData->m_pObjectShell.is() )
2056 {
2057 if ( aFlavor.MimeType == "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" )
2058 {
2059 if ( aFlavor.DataType != cppu::UnoType<Sequence< sal_Int8 >>::get() )
2060 throw datatransfer::UnsupportedFlavorException();
2061
2063
2064 aDesc.maClassName = m_pData->m_pObjectShell->GetClassName();
2065 aDesc.maTypeName = aFlavor.HumanPresentableName;
2066
2067 // TODO/LATER: ViewAspect needs to be sal_Int64
2068 aDesc.mnViewAspect = sal::static_int_cast< sal_uInt16 >( embed::Aspects::MSOLE_CONTENT );
2069
2070 Size aSize = m_pData->m_pObjectShell->GetVisArea().GetSize();
2071
2072 MapUnit aMapUnit = m_pData->m_pObjectShell->GetMapUnit();
2073 aDesc.maSize = OutputDevice::LogicToLogic(aSize, MapMode(aMapUnit), MapMode(MapUnit::Map100thMM));
2074 aDesc.maDragStartPos = Point();
2075 aDesc.maDisplayName.clear();
2076
2077 SvMemoryStream aMemStm( 1024, 1024 );
2078 WriteTransferableObjectDescriptor( aMemStm, aDesc );
2079 aAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Tell() );
2080 }
2081 else if ( aFlavor.MimeType == "application/x-openoffice-embed-source;windows_formatname=\"Star EMBS\"" )
2082 {
2083 if ( aFlavor.DataType != cppu::UnoType<Sequence< sal_Int8 >>::get() )
2084 throw datatransfer::UnsupportedFlavorException();
2085
2086 try
2087 {
2088 utl::TempFileNamed aTmp;
2089 aTmp.EnableKillingFile();
2090 storeToURL( aTmp.GetURL(), Sequence < beans::PropertyValue >() );
2091 std::unique_ptr<SvStream> pStream(aTmp.GetStream( StreamMode::READ ));
2092 const sal_uInt32 nLen = pStream->TellEnd();
2093 Sequence< sal_Int8 > aSeq( nLen );
2094 pStream->ReadBytes(aSeq.getArray(), nLen);
2095 if( aSeq.hasElements() )
2096 aAny <<= aSeq;
2097 }
2098 catch ( Exception& )
2099 {
2100 }
2101 }
2102 else if ( aFlavor.MimeType == "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2103 {
2104 if ( aFlavor.DataType != cppu::UnoType<Sequence< sal_Int8 >>::get() )
2105 throw datatransfer::UnsupportedFlavorException();
2106
2107
2108 std::shared_ptr<GDIMetaFile> xMetaFile =
2109 m_pData->m_pObjectShell->GetPreviewMetaFile( true );
2110
2111 if (xMetaFile)
2112 {
2113 SvMemoryStream aMemStm( 65535, 65535 );
2115
2116 SvmWriter aWriter( aMemStm );
2117 aWriter.Write( *xMetaFile );
2118 aAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ),
2119 aMemStm.TellEnd() );
2120 }
2121 }
2122 else if ( aFlavor.MimeType == "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2123 {
2124 if ( aFlavor.DataType != cppu::UnoType<Sequence< sal_Int8 >>::get() )
2125 throw datatransfer::UnsupportedFlavorException();
2126
2127 std::shared_ptr<GDIMetaFile> xMetaFile =
2128 m_pData->m_pObjectShell->GetPreviewMetaFile( true );
2129
2130 if (xMetaFile)
2131 {
2132 SvMemoryStream aMemStm( 65535, 65535 );
2134
2135 SvmWriter aWriter( aMemStm );
2136 aWriter.Write( *xMetaFile );
2137 aAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ),
2138 aMemStm.TellEnd() );
2139 }
2140 }
2141 else if ( aFlavor.MimeType == "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" )
2142 {
2143 if ( aFlavor.DataType == cppu::UnoType<Sequence< sal_Int8 >>::get() )
2144 {
2145 std::shared_ptr<GDIMetaFile> xMetaFile =
2146 m_pData->m_pObjectShell->GetPreviewMetaFile( true );
2147
2148 if (xMetaFile)
2149 {
2150 std::unique_ptr<SvMemoryStream> xStream(
2151 GraphicHelper::getFormatStrFromGDI_Impl(
2152 xMetaFile.get(), ConvertDataFormat::EMF ) );
2153 if (xStream)
2154 {
2155 xStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT );
2156 aAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( xStream->GetData() ),
2157 xStream->TellEnd() );
2158 }
2159 }
2160 }
2161 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2162 && aFlavor.DataType == cppu::UnoType<sal_uInt64>::get())
2163 {
2164 std::shared_ptr<GDIMetaFile> xMetaFile =
2165 m_pData->m_pObjectShell->GetPreviewMetaFile( true );
2166
2167 if (xMetaFile)
2168 {
2169 aAny <<= reinterpret_cast< sal_uInt64 >(
2170 GraphicHelper::getEnhMetaFileFromGDI_Impl( xMetaFile.get() ) );
2171 }
2172 }
2173 else
2174 throw datatransfer::UnsupportedFlavorException();
2175 }
2176 else if ( aFlavor.MimeType == "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" )
2177 {
2178 if ( aFlavor.DataType == cppu::UnoType<Sequence< sal_Int8 >>::get() )
2179 {
2180 std::shared_ptr<GDIMetaFile> xMetaFile =
2181 m_pData->m_pObjectShell->GetPreviewMetaFile( true );
2182
2183 if (xMetaFile)
2184 {
2185 std::unique_ptr<SvMemoryStream> xStream(
2186 GraphicHelper::getFormatStrFromGDI_Impl(
2187 xMetaFile.get(), ConvertDataFormat::WMF ) );
2188
2189 if (xStream)
2190 {
2191 xStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT );
2192 aAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( xStream->GetData() ),
2193 xStream->TellEnd() );
2194 }
2195 }
2196 }
2197 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2198 && aFlavor.DataType == cppu::UnoType<sal_uInt64>::get())
2199 {
2200 // means HGLOBAL handler to memory storage containing METAFILEPICT structure
2201
2202 std::shared_ptr<GDIMetaFile> xMetaFile =
2203 m_pData->m_pObjectShell->GetPreviewMetaFile( true );
2204
2205 if (xMetaFile)
2206 {
2207 Size aMetaSize = xMetaFile->GetPrefSize();
2208 aAny <<= reinterpret_cast< sal_uInt64 >(
2209 GraphicHelper::getWinMetaFileFromGDI_Impl(
2210 xMetaFile.get(), aMetaSize ) );
2211 }
2212 }
2213 else
2214 throw datatransfer::UnsupportedFlavorException();
2215 }
2216 else if ( aFlavor.MimeType == "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" )
2217 {
2218 if ( aFlavor.DataType != cppu::UnoType<Sequence< sal_Int8 >>::get() )
2219 throw datatransfer::UnsupportedFlavorException();
2220
2221 std::shared_ptr<GDIMetaFile> xMetaFile =
2222 m_pData->m_pObjectShell->GetPreviewMetaFile( true );
2223
2224 if (xMetaFile)
2225 {
2226 std::unique_ptr<SvMemoryStream> xStream(
2227 GraphicHelper::getFormatStrFromGDI_Impl(
2228 xMetaFile.get(), ConvertDataFormat::BMP ) );
2229
2230 if (xStream)
2231 {
2232 xStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT );
2233 aAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( xStream->GetData() ),
2234 xStream->TellEnd() );
2235 }
2236 }
2237 }
2238 else if ( aFlavor.MimeType == "image/png" )
2239 {
2240 if ( aFlavor.DataType != cppu::UnoType<Sequence< sal_Int8 >>::get() )
2241 throw datatransfer::UnsupportedFlavorException();
2242
2243 std::shared_ptr<GDIMetaFile> xMetaFile =
2244 m_pData->m_pObjectShell->GetPreviewMetaFile( true );
2245
2246 if (xMetaFile)
2247 {
2248 std::unique_ptr<SvMemoryStream> xStream(
2249 GraphicHelper::getFormatStrFromGDI_Impl(
2250 xMetaFile.get(), ConvertDataFormat::PNG ) );
2251
2252 if (xStream)
2253 {
2254 xStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT );
2255 aAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( xStream->GetData() ),
2256 xStream->TellEnd() );
2257 }
2258 }
2259 }
2260 else
2261 throw datatransfer::UnsupportedFlavorException();
2262 }
2263
2264 return aAny;
2265}
2266
2267
2268// XTransferable
2269
2270
2271Sequence< datatransfer::DataFlavor > SAL_CALL SfxBaseModel::getTransferDataFlavors()
2272{
2273 SfxModelGuard aGuard( *this );
2274
2275 const sal_Int32 nSuppFlavors = GraphicHelper::supportsMetaFileHandle_Impl() ? 10 : 8;
2276 Sequence< datatransfer::DataFlavor > aFlavorSeq( nSuppFlavors );
2277 auto pFlavorSeq = aFlavorSeq.getArray();
2278
2279 pFlavorSeq[0].MimeType =
2280 "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"";
2281 pFlavorSeq[0].HumanPresentableName = "GDIMetaFile";
2282 pFlavorSeq[0].DataType = cppu::UnoType<Sequence< sal_Int8 >>::get();
2283
2284 pFlavorSeq[1].MimeType =
2285 "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"";
2286 pFlavorSeq[1].HumanPresentableName = "GDIMetaFile";
2287 pFlavorSeq[1].DataType = cppu::UnoType<Sequence< sal_Int8 >>::get();
2288
2289 pFlavorSeq[2].MimeType =
2290 "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ;
2291 pFlavorSeq[2].HumanPresentableName = "Enhanced Windows MetaFile";
2292 pFlavorSeq[2].DataType = cppu::UnoType<Sequence< sal_Int8 >>::get();
2293
2294 pFlavorSeq[3].MimeType =
2295 "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"";
2296 pFlavorSeq[3].HumanPresentableName = "Windows MetaFile";
2297 pFlavorSeq[3].DataType = cppu::UnoType<Sequence< sal_Int8 >>::get();
2298
2299 pFlavorSeq[4].MimeType =
2300 "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"";
2301 pFlavorSeq[4].HumanPresentableName = "Star Object Descriptor (XML)";
2302 pFlavorSeq[4].DataType = cppu::UnoType<Sequence< sal_Int8 >>::get();
2303
2304 pFlavorSeq[5].MimeType =
2305 "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
2306 pFlavorSeq[5].HumanPresentableName = "Star Embed Source (XML)";
2307 pFlavorSeq[5].DataType = cppu::UnoType<Sequence< sal_Int8 >>::get();
2308
2309 pFlavorSeq[6].MimeType =
2310 "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"";
2311 pFlavorSeq[6].HumanPresentableName = "Bitmap";
2312 pFlavorSeq[6].DataType = cppu::UnoType<Sequence< sal_Int8 >>::get();
2313
2314 pFlavorSeq[7].MimeType = "image/png";
2315 pFlavorSeq[7].HumanPresentableName = "PNG";
2316 pFlavorSeq[7].DataType = cppu::UnoType<Sequence< sal_Int8 >>::get();
2317
2318 if ( nSuppFlavors == 10 )
2319 {
2320 pFlavorSeq[8].MimeType =
2321 "application/x-openoffice-emf;windows_formatname=\"Image EMF\"";
2322 pFlavorSeq[8].HumanPresentableName = "Enhanced Windows MetaFile";
2323 pFlavorSeq[8].DataType = cppu::UnoType<sal_uInt64>::get();
2324
2325 pFlavorSeq[9].MimeType =
2326 "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"";
2327 pFlavorSeq[9].HumanPresentableName = "Windows MetaFile";
2328 pFlavorSeq[9].DataType = cppu::UnoType<sal_uInt64>::get();
2329 }
2330
2331 return aFlavorSeq;
2332}
2333
2334
2335// XTransferable
2336
2337
2338sal_Bool SAL_CALL SfxBaseModel::isDataFlavorSupported( const datatransfer::DataFlavor& aFlavor )
2339{
2340 SfxModelGuard aGuard( *this );
2341
2342 if ( aFlavor.MimeType == "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2343 {
2344 if ( aFlavor.DataType == cppu::UnoType<Sequence< sal_Int8 >>::get() )
2345 return true;
2346 }
2347 else if ( aFlavor.MimeType == "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" )
2348 {
2349 if ( aFlavor.DataType == cppu::UnoType<Sequence< sal_Int8 >>::get() )
2350 return true;
2351 }
2352 else if ( aFlavor.MimeType == "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" )
2353 {
2354 if ( aFlavor.DataType == cppu::UnoType<Sequence< sal_Int8 >>::get() )
2355 return true;
2356 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2357 && aFlavor.DataType == cppu::UnoType<sal_uInt64>::get())
2358 return true;
2359 }
2360 else if ( aFlavor.MimeType == "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" )
2361 {
2362 if ( aFlavor.DataType == cppu::UnoType<Sequence< sal_Int8 >>::get() )
2363 return true;
2364 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2365 && aFlavor.DataType == cppu::UnoType<sal_uInt64>::get())
2366 return true;
2367 }
2368 else if ( aFlavor.MimeType == "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" )
2369 {
2370 if ( aFlavor.DataType == cppu::UnoType<Sequence< sal_Int8 >>::get() )
2371 return true;
2372 }
2373 else if ( aFlavor.MimeType == "application/x-openoffice-embed-source;windows_formatname=\"Star EMBS\"" )
2374 {
2375 if ( aFlavor.DataType == cppu::UnoType<Sequence< sal_Int8 >>::get() )
2376 return true;
2377 }
2378 else if ( aFlavor.MimeType == "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" )
2379 {
2380 if ( aFlavor.DataType == cppu::UnoType<Sequence< sal_Int8 >>::get() )
2381 return true;
2382 }
2383 else if ( aFlavor.MimeType == "image/png" )
2384 {
2385 if ( aFlavor.DataType == cppu::UnoType<Sequence< sal_Int8 >>::get() )
2386 return true;
2387 }
2388
2389 return false;
2390}
2391
2392
2393// XEventsSupplier
2394
2395
2396Reference< container::XNameReplace > SAL_CALL SfxBaseModel::getEvents()
2397{
2398 SfxModelGuard aGuard( *this );
2399
2400 if ( ! m_pData->m_xEvents.is() )
2401 {
2402 m_pData->m_xEvents = new SfxEvents_Impl( m_pData->m_pObjectShell.get(), this );
2403 }
2404
2405 return m_pData->m_xEvents;
2406}
2407
2408
2409// XEmbeddedScripts
2410
2411
2412Reference< script::XStorageBasedLibraryContainer > SAL_CALL SfxBaseModel::getBasicLibraries()
2413{
2414 SfxModelGuard aGuard( *this );
2415
2416 Reference< script::XStorageBasedLibraryContainer > xBasicLibraries;
2417 if ( m_pData->m_pObjectShell.is() )
2418 xBasicLibraries.set(m_pData->m_pObjectShell->GetBasicContainer(), UNO_QUERY);
2419 return xBasicLibraries;
2420}
2421
2422Reference< script::XStorageBasedLibraryContainer > SAL_CALL SfxBaseModel::getDialogLibraries()
2423{
2424 SfxModelGuard aGuard( *this );
2425
2426 Reference< script::XStorageBasedLibraryContainer > xDialogLibraries;
2427 if ( m_pData->m_pObjectShell.is() )
2428 xDialogLibraries.set(m_pData->m_pObjectShell->GetDialogContainer(), UNO_QUERY);
2429 return xDialogLibraries;
2430}
2431
2433{
2434 SfxModelGuard aGuard( *this );
2435
2436 if ( m_pData->m_pObjectShell.is() )
2437 return m_pData->m_pObjectShell->AdjustMacroMode();
2438 return false;
2439}
2440
2441
2442// XScriptInvocationContext
2443
2444
2445Reference< document::XEmbeddedScripts > SAL_CALL SfxBaseModel::getScriptContainer()
2446{
2447 SfxModelGuard aGuard( *this );
2448
2449 Reference< document::XEmbeddedScripts > xDocumentScripts;
2450
2451 try
2452 {
2453 Reference< frame::XModel > xDocument( this );
2454 xDocumentScripts.set( xDocument, UNO_QUERY );
2455 while ( !xDocumentScripts.is() && xDocument.is() )
2456 {
2457 Reference< container::XChild > xDocAsChild( xDocument, UNO_QUERY );
2458 if ( !xDocAsChild.is() )
2459 {
2460 xDocument = nullptr;
2461 break;
2462 }
2463
2464 xDocument.set( xDocAsChild->getParent(), UNO_QUERY );
2465 xDocumentScripts.set( xDocument, UNO_QUERY );
2466 }
2467 }
2468 catch( const Exception& )
2469 {
2470 DBG_UNHANDLED_EXCEPTION("sfx.doc");
2471 xDocumentScripts = nullptr;
2472 }
2473
2474 return xDocumentScripts;
2475}
2476
2477
2478// XEventBroadcaster
2479
2480
2481void SAL_CALL SfxBaseModel::addEventListener( const Reference< document::XEventListener >& aListener )
2482{
2484
2485 m_pData->m_aInterfaceContainer.addInterface( cppu::UnoType<document::XEventListener>::get(), aListener );
2486}
2487
2488
2489// XEventBroadcaster
2490
2491
2492void SAL_CALL SfxBaseModel::removeEventListener( const Reference< document::XEventListener >& aListener )
2493{
2494 SfxModelGuard aGuard( *this );
2495
2496 m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<document::XEventListener>::get(), aListener );
2497}
2498
2499// XShapeEventBroadcaster
2500
2501void SAL_CALL SfxBaseModel::addShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape, const Reference< document::XShapeEventListener >& xListener )
2502{
2503 assert(xShape.is() && "no shape?");
2505
2506 m_pData->maShapeListeners[xShape].push_back(xListener);
2507}
2508
2509
2510// XShapeEventBroadcaster
2511
2512
2513void SAL_CALL SfxBaseModel::removeShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape, const Reference< document::XShapeEventListener >& xListener )
2514{
2515 SfxModelGuard aGuard( *this );
2516
2517 auto it = m_pData->maShapeListeners.find(xShape);
2518 if (it != m_pData->maShapeListeners.end())
2519 {
2520 auto rVec = it->second;
2521 auto it2 = std::find(rVec.begin(), rVec.end(), xListener);
2522 if (it2 != rVec.end())
2523 {
2524 rVec.erase(it2);
2525 if (rVec.empty())
2526 m_pData->maShapeListeners.erase(it);
2527 }
2528 }
2529}
2530
2531// XDocumentEventBroadcaster
2532
2533
2534void SAL_CALL SfxBaseModel::addDocumentEventListener( const Reference< document::XDocumentEventListener >& aListener )
2535{
2537 m_pData->m_aInterfaceContainer.addInterface( cppu::UnoType<document::XDocumentEventListener>::get(), aListener );
2538}
2539
2540
2541void SAL_CALL SfxBaseModel::removeDocumentEventListener( const Reference< document::XDocumentEventListener >& aListener )
2542{
2543 SfxModelGuard aGuard( *this );
2544 m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<document::XDocumentEventListener>::get(), aListener );
2545}
2546
2547
2548void SAL_CALL SfxBaseModel::notifyDocumentEvent( const OUString&, const Reference< frame::XController2 >&, const Any& )
2549{
2550 throw lang::NoSupportException("SfxBaseModel controls all the sent notifications itself!" );
2551}
2552
2553Sequence<document::CmisProperty> SAL_CALL SfxBaseModel::getCmisProperties()
2554{
2555 if (impl_isDisposed())
2556 return Sequence<document::CmisProperty>();
2557 return m_pData->m_cmisProperties;
2558}
2559
2560void SAL_CALL SfxBaseModel::setCmisProperties( const Sequence< document::CmisProperty >& _cmisproperties )
2561{
2562 m_pData->m_cmisProperties = _cmisproperties;
2563}
2564
2565void SAL_CALL SfxBaseModel::updateCmisProperties( const Sequence< document::CmisProperty >& aProperties )
2566{
2567 SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
2568 if ( !pMedium )
2569 return;
2570
2571 try
2572 {
2573 ::ucbhelper::Content aContent( pMedium->GetName( ),
2574 Reference<ucb::XCommandEnvironment>(),
2576
2577 aContent.executeCommand( "updateProperties", uno::Any( aProperties ) );
2579 }
2580 catch (const Exception & e)
2581 {
2582 css::uno::Any anyEx = cppu::getCaughtException();
2583 throw lang::WrappedTargetRuntimeException( e.Message,
2584 e.Context, anyEx );
2585 }
2586
2587}
2588
2590{
2591 SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
2592 if ( !pMedium )
2593 return;
2594
2595 try
2596 {
2597 ::ucbhelper::Content aContent( pMedium->GetName(),
2598 Reference<ucb::XCommandEnvironment>(),
2600
2601 Any aResult = aContent.executeCommand( "checkout", Any( ) );
2602 OUString sURL;
2603 aResult >>= sURL;
2604
2605 m_pData->m_pObjectShell->GetMedium( )->SetName( sURL );
2606 m_pData->m_pObjectShell->GetMedium( )->GetMedium_Impl( );
2607 m_pData->m_xDocumentProperties->setTitle( getTitle( ) );
2608 Sequence< beans::PropertyValue > aSequence ;
2609 TransformItems( SID_OPENDOC, pMedium->GetItemSet(), aSequence );
2610 attachResource( sURL, aSequence );
2611
2612 // Reload the CMIS properties
2614 }
2615 catch ( const Exception & e )
2616 {
2617 css::uno::Any anyEx = cppu::getCaughtException();
2618 throw lang::WrappedTargetRuntimeException( e.Message,
2619 e.Context, anyEx );
2620 }
2621}
2622
2624{
2625 SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
2626 if ( !pMedium )
2627 return;
2628
2629 try
2630 {
2631 ::ucbhelper::Content aContent( pMedium->GetName(),
2632 Reference<ucb::XCommandEnvironment>(),
2634
2635 Any aResult = aContent.executeCommand( "cancelCheckout", Any( ) );
2636 OUString sURL;
2637 aResult >>= sURL;
2638
2639 m_pData->m_pObjectShell->GetMedium( )->SetName( sURL );
2640 }
2641 catch ( const Exception & e )
2642 {
2643 css::uno::Any anyEx = cppu::getCaughtException();
2644 throw lang::WrappedTargetRuntimeException( e.Message,
2645 e.Context, anyEx );
2646 }
2647}
2648
2649void SAL_CALL SfxBaseModel::checkIn( sal_Bool bIsMajor, const OUString& rMessage )
2650{
2651 SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
2652 if ( !pMedium )
2653 return;
2654
2655 try
2656 {
2657 Sequence< beans::PropertyValue > aProps{
2658 comphelper::makePropertyValue("VersionMajor", bIsMajor),
2659 comphelper::makePropertyValue("VersionComment", rMessage),
2660 comphelper::makePropertyValue("CheckIn", true)
2661 };
2662
2663 const OUString sName( pMedium->GetName( ) );
2664 storeSelf( aProps );
2665
2666 // Refresh pMedium as it has probably changed during the storeSelf call
2667 pMedium = m_pData->m_pObjectShell->GetMedium( );
2668 const OUString sNewName( pMedium->GetName( ) );
2669
2670 // URL has changed, update the document
2671 if ( sName != sNewName )
2672 {
2673 m_pData->m_xDocumentProperties->setTitle( getTitle( ) );
2674 Sequence< beans::PropertyValue > aSequence ;
2675 TransformItems( SID_OPENDOC, pMedium->GetItemSet(), aSequence );
2676 attachResource( sNewName, aSequence );
2677
2678 // Reload the CMIS properties
2680 }
2681 }
2682 catch ( const Exception & e )
2683 {
2684 css::uno::Any anyEx = cppu::getCaughtException();
2685 throw lang::WrappedTargetRuntimeException( e.Message,
2686 e.Context, anyEx );
2687 }
2688}
2689
2690uno::Sequence< document::CmisVersion > SAL_CALL SfxBaseModel::getAllVersions( )
2691{
2692 uno::Sequence<document::CmisVersion> aVersions;
2693 if (impl_isDisposed())
2694 return aVersions;
2695 SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
2696 if ( pMedium )
2697 {
2698 try
2699 {
2700 ::ucbhelper::Content aContent( pMedium->GetName(),
2701 Reference<ucb::XCommandEnvironment>(),
2703
2704 Any aResult = aContent.executeCommand( "getAllVersions", Any( ) );
2705 aResult >>= aVersions;
2706 }
2707 catch ( const Exception & e )
2708 {
2709 css::uno::Any anyEx = cppu::getCaughtException();
2710 throw lang::WrappedTargetRuntimeException( e.Message,
2711 e.Context, anyEx );
2712 }
2713 }
2714 return aVersions;
2715}
2716
2717bool SfxBaseModel::getBoolPropertyValue( const OUString& rName )
2718{
2719 bool bValue = false;
2720 if ( m_pData->m_pObjectShell.is() )
2721 {
2722 SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
2723 if ( pMedium )
2724 {
2725 try
2726 {
2727 ::ucbhelper::Content aContent( pMedium->GetName( ),
2730 Reference < beans::XPropertySetInfo > xProps = aContent.getProperties();
2731 if ( xProps->hasPropertyByName( rName ) )
2732 {
2733 aContent.getPropertyValue( rName ) >>= bValue;
2734 }
2735 }
2736 catch ( const Exception & )
2737 {
2738 // Simply ignore it: it's likely the document isn't versionable in that case
2739 bValue = false;
2740 }
2741 }
2742 }
2743 return bValue;
2744}
2745
2747{
2748 return getBoolPropertyValue( "IsVersionable" );
2749}
2750
2752{
2753 return getBoolPropertyValue( "CanCheckOut" );
2754}
2755
2757{
2758 return getBoolPropertyValue( "CanCancelCheckOut" );
2759}
2760
2762{
2763 return getBoolPropertyValue( "CanCheckIn" );
2764}
2765
2767{
2768 SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
2769 if ( !pMedium )
2770 return;
2771
2772 try
2773 {
2774 ::ucbhelper::Content aContent( pMedium->GetName( ),
2777 Reference < beans::XPropertySetInfo > xProps = aContent.getProperties();
2778 static constexpr OUStringLiteral aCmisProps( u"CmisProperties" );
2779 if ( xProps->hasPropertyByName( aCmisProps ) )
2780 {
2781 Sequence< document::CmisProperty> aCmisProperties;
2782 aContent.getPropertyValue( aCmisProps ) >>= aCmisProperties;
2783 setCmisProperties( aCmisProperties );
2784 }
2785 }
2786 catch (const ucb::ContentCreationException &)
2787 {
2788 }
2789 catch (const ucb::CommandAbortedException &)
2790 {
2791 }
2792}
2793
2795{
2796 if (!nError)
2797 {
2798 // No error condition.
2799 return pMedium;
2800 }
2801
2802 bool bSilent = false;
2803 const SfxBoolItem* pSilentItem = pMedium->GetItemSet().GetItem(SID_SILENT, false);
2804 if( pSilentItem )
2805 bSilent = pSilentItem->GetValue();
2806
2807 bool bWarning = nError.IsWarning();
2808 if ( nError != ERRCODE_IO_BROKENPACKAGE && !bSilent )
2809 {
2810 // broken package was handled already
2811 if ( SfxObjectShell::UseInteractionToHandleError(pMedium->GetInteractionHandler(), nError) && !bWarning)
2812 {
2813 // abort loading (except for warnings)
2814 nError = ERRCODE_IO_ABORT;
2815 }
2816 }
2817
2818 if ( m_pData->m_pObjectShell->GetMedium() != pMedium )
2819 {
2820 // for whatever reason document now has another medium
2821 OSL_FAIL("Document has rejected the medium?!");
2822 delete pMedium;
2823 pMedium = nullptr;
2824 }
2825
2826 if ( !bWarning ) // #i30711# don't abort loading if it's only a warning
2827 {
2828 nError = nError ? nError : ERRCODE_IO_CANTREAD;
2829 throw task::ErrorCodeIOException(
2830 "SfxBaseModel::handleLoadError: 0x" + nError.toString(),
2831 Reference< XInterface >(), sal_uInt32(nError));
2832 }
2833 else
2834 pMedium->SetWarningError(nError);
2835
2836 return pMedium;
2837}
2838
2839
2840// SfxListener
2841
2842
2843static void addTitle_Impl( Sequence < beans::PropertyValue >& rSeq, const OUString& rTitle )
2844{
2845 auto [begin, end] = asNonConstRange(rSeq);
2846 auto pProp = std::find_if(begin, end,
2847 [](const beans::PropertyValue& rProp) { return rProp.Name == "Title"; });
2848 if (pProp != end)
2849 {
2850 pProp->Value <<= rTitle;
2851 }
2852 else
2853 {
2854 sal_Int32 nCount = rSeq.getLength();
2855 rSeq.realloc( nCount+1 );
2856 auto& el = rSeq.getArray()[nCount];
2857 el.Name = "Title";
2858 el.Value <<= rTitle;
2859 }
2860}
2861
2863 const SfxHint& rHint )
2864{
2865 if ( !m_pData )
2866 return;
2867
2868 if ( &rBC != m_pData->m_pObjectShell.get() )
2869 return;
2870
2871 if ( rHint.GetId() == SfxHintId::DocChanged )
2872 changing();
2873
2874 const SfxEventHint* pNamedHint = dynamic_cast<const SfxEventHint*>(&rHint);
2875 if ( pNamedHint )
2876 {
2877
2878 switch ( pNamedHint->GetEventId() )
2879 {
2881 {
2882 if ( m_pData->m_xUIConfigurationManager.is()
2883 && m_pData->m_pObjectShell->GetCreateMode() != SfxObjectCreateMode::EMBEDDED )
2884 {
2885 Reference< embed::XStorage > xConfigStorage;
2886 static constexpr OUStringLiteral aUIConfigFolderName( u"Configurations2" );
2887
2888 xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, embed::ElementModes::READWRITE );
2889 if ( !xConfigStorage.is() )
2890 xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, embed::ElementModes::READ );
2891
2892 if ( xConfigStorage.is() || !m_pData->m_pObjectShell->GetStorage()->hasByName( aUIConfigFolderName ) )
2893 {
2894 // the storage is different, since otherwise it could not be opened, so it must be exchanged
2895 m_pData->m_xUIConfigurationManager->setStorage( xConfigStorage );
2896 }
2897 else
2898 {
2899 OSL_FAIL( "Unexpected scenario!" );
2900 }
2901 }
2902
2903 ListenForStorage_Impl( m_pData->m_pObjectShell->GetStorage() );
2904 }
2905 break;
2906
2908 {
2910 ListenForStorage_Impl( m_pData->m_pObjectShell->GetStorage() );
2911 m_pData->setModifiedForAutoSave(false);
2912 }
2913 break;
2914
2916 {
2917 m_pData->m_sURL = m_pData->m_pObjectShell->GetMedium()->GetName();
2918
2919 Sequence< beans::PropertyValue > aArgs;
2920 TransformItems( SID_SAVEASDOC, m_pData->m_pObjectShell->GetMedium()->GetItemSet(), aArgs );
2921 addTitle_Impl( aArgs, m_pData->m_pObjectShell->GetTitle() );
2922 attachResource( m_pData->m_pObjectShell->GetMedium()->GetName(), aArgs );
2923 }
2924 break;
2925
2927 {
2929 m_pData->setModifiedForAutoSave(false);
2930 }
2931 break;
2932
2934 {
2935 m_pData->setModifiedForAutoSave(isModified());
2936 }
2937 break;
2938 default: break;
2939 }
2940
2941 Any aSupplement;
2942 if (const SfxPrintingHint* pPrintingHint = dynamic_cast<const SfxPrintingHint*>(&rHint))
2943 aSupplement <<= pPrintingHint->GetWhich();
2944 const SfxViewEventHint* pViewHint = dynamic_cast<const SfxViewEventHint*>(&rHint);
2945 postEvent_Impl( pNamedHint->GetEventName(), pViewHint ? pViewHint->GetController() : Reference< frame::XController2 >(), aSupplement );
2946 }
2947
2948 if ( rHint.GetId() == SfxHintId::TitleChanged )
2949 {
2950 addTitle_Impl( m_pData->m_seqArguments, m_pData->m_pObjectShell->GetTitle() );
2951 postEvent_Impl( GlobalEventConfig::GetEventName( GlobalEventId::TITLECHANGED ) );
2952 }
2953 else if ( rHint.GetId() == SfxHintId::ModeChanged )
2954 {
2955 postEvent_Impl( GlobalEventConfig::GetEventName( GlobalEventId::MODECHANGED ) );
2956 }
2957}
2958
2959
2960// public impl.
2961
2962
2964{
2966 if ( pIC )
2967 {
2968 lang::EventObject aEvent( static_cast<frame::XModel *>(const_cast<SfxBaseModel *>(this)) );
2969 pIC->notifyEach( &util::XModifyListener::modified, aEvent );
2970 }
2971
2972 // this notification here is done too generously, we cannot simply assume that we're really modified
2973 // now, but we need to check it ...
2974 m_pData->setModifiedForAutoSave(const_cast<SfxBaseModel*>(this)->isModified());
2975}
2976
2978{
2979 SfxModelGuard aGuard( *this );
2980
2981 // the notification should not be sent if the document can not be modified
2982 if ( !m_pData->m_pObjectShell.is() || !m_pData->m_pObjectShell->IsEnableSetModified() )
2983 return;
2984
2986}
2987
2988
2989// public impl.
2990
2991
2993{
2994 return m_pData ? m_pData->m_pObjectShell.get() : nullptr;
2995}
2996
2997
2998// public impl.
2999
3000
3002{
3003 if ( !m_pData || !m_pData->m_pObjectShell.is() )
3004 {
3005 OSL_FAIL( "SfxBaseModel::IsInitialized: this should have been caught earlier!" );
3006 return false;
3007 }
3008
3009 return m_pData->m_pObjectShell->GetMedium() != nullptr;
3010}
3011
3012void SfxBaseModel::MethodEntryCheck( const bool i_mustBeInitialized ) const
3013{
3014 if ( impl_isDisposed() )
3015 throw lang::DisposedException( OUString(), *const_cast< SfxBaseModel* >( this ) );
3016 if ( i_mustBeInitialized && !IsInitialized() )
3017 throw lang::NotInitializedException( OUString(), *const_cast< SfxBaseModel* >( this ) );
3018}
3019
3021{
3022 return ( m_pData == nullptr ) ;
3023}
3024
3025
3026// private impl.
3027
3028
3030{
3031 std::shared_ptr<const SfxFilter> pFilter;
3032 SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
3033 if ( pMedium )
3034 pFilter = pMedium->GetFilter();
3035
3036 if ( pFilter )
3037 return pFilter->GetName();
3038
3039 return OUString();
3040}
3041
3042void SfxBaseModel::impl_store( const OUString& sURL ,
3043 const Sequence< beans::PropertyValue >& seqArguments ,
3044 bool bSaveTo )
3045{
3046 if( sURL.isEmpty() )
3047 throw frame::IllegalArgumentIOException();
3048
3049 bool bSaved = false;
3050 ::comphelper::SequenceAsHashMap aArgHash(seqArguments);
3051 if ( !bSaveTo && m_pData->m_pObjectShell.is() && !sURL.isEmpty()
3052 && !sURL.startsWith( "private:stream" )
3053 && ::utl::UCBContentHelper::EqualURLs( getLocation(), sURL ) )
3054 {
3055 // this is the same file URL as the current document location, try to use storeOwn if possible
3056
3057 static constexpr OUStringLiteral aFilterString( u"FilterName" );
3058 const OUString aFilterName( aArgHash.getUnpackedValueOrDefault( aFilterString, OUString() ) );
3059 if ( !aFilterName.isEmpty() )
3060 {
3061 SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
3062 if ( pMedium )
3063 {
3064 const std::shared_ptr<const SfxFilter>& pFilter = pMedium->GetFilter();
3065 if ( pFilter && aFilterName == pFilter->GetFilterName() )
3066 {
3067 // #i119366# - If the former file saving with password, do not trying in StoreSelf anyway...
3068 bool bFormerPassword = false;
3069 {
3070 uno::Sequence< beans::NamedValue > aOldEncryptionData;
3071 if (GetEncryptionData_Impl( &pMedium->GetItemSet(), aOldEncryptionData ))
3072 {
3073 bFormerPassword = true;
3074 }
3075 }
3076 if ( !bFormerPassword )
3077 {
3078 aArgHash.erase( aFilterString );
3079 aArgHash.erase( "URL" );
3080
3081 try
3082 {
3084 bSaved = true;
3085 }
3086 catch( const lang::IllegalArgumentException& )
3087 {
3088#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
3089 // some additional arguments do not allow to use saving, SaveAs should be done
3090 // but only for normal documents, the shared documents would be overwritten in this case
3091 // that would mean an information loss
3092 // TODO/LATER: need a new interaction for this case
3093 if ( m_pData->m_pObjectShell->IsDocShared() )
3094 {
3095 uno::Sequence< beans::NamedValue > aNewEncryptionData = aArgHash.getUnpackedValueOrDefault("EncryptionData", uno::Sequence< beans::NamedValue >() );
3096 if ( !aNewEncryptionData.hasElements() )
3097 {
3098 aNewEncryptionData = ::comphelper::OStorageHelper::CreatePackageEncryptionData( aArgHash.getUnpackedValueOrDefault("Password", OUString()) );
3099 }
3100
3101 uno::Sequence< beans::NamedValue > aOldEncryptionData;
3102 (void)GetEncryptionData_Impl( &pMedium->GetItemSet(), aOldEncryptionData );
3103
3104 if ( !aOldEncryptionData.hasElements() && !aNewEncryptionData.hasElements() )
3105 throw;
3106 else
3107 {
3108 // if the password is changed a special error should be used in case of shared document
3109 throw task::ErrorCodeIOException("Can not change password for shared document.", uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_SFX_SHARED_NOPASSWORDCHANGE) );
3110 }
3111 }
3112#endif
3113 }
3114 }
3115 }
3116 }
3117 }
3118 }
3119
3120 if ( bSaved || !m_pData->m_pObjectShell.is() )
3121 return;
3122
3123 SfxGetpApp()->NotifyEvent( SfxEventHint( bSaveTo ? SfxEventHintId::SaveToDoc : SfxEventHintId::SaveAsDoc, GlobalEventConfig::GetEventName( bSaveTo ? GlobalEventId::SAVETODOC : GlobalEventId::SAVEASDOC ),
3124 m_pData->m_pObjectShell.get() ) );
3125
3126 const OUString aFilterName(aArgHash.getUnpackedValueOrDefault("FilterName", OUString()));
3127 OUString aPassword, aPasswordToModify;
3128 if (!aArgHash.getUnpackedValueOrDefault("EncryptionData", Sequence<beans::NamedValue>())
3129 .hasElements())
3130 aPassword = aArgHash.getUnpackedValueOrDefault("Password", OUString());
3131 if (!aArgHash.getUnpackedValueOrDefault("ModifyPasswordInfo", Sequence<beans::PropertyValue>())
3132 .hasElements()
3133 && aArgHash.getUnpackedValueOrDefault("ModifyPasswordInfo", static_cast<sal_Int32>(0)) == 0)
3134 aPasswordToModify = aArgHash.getUnpackedValueOrDefault("PasswordToModify", OUString());
3135 aArgHash.erase("PasswordToModify");
3136
3137 std::optional<SfxAllItemSet> pItemSet(SfxGetpApp()->GetPool());
3138 pItemSet->Put(SfxStringItem(SID_FILE_NAME, sURL));
3139 if ( bSaveTo )
3140 pItemSet->Put(SfxBoolItem(SID_SAVETO, true));
3141
3142 if (!aFilterName.isEmpty() && (!aPassword.isEmpty() || !aPasswordToModify.isEmpty()))
3143 sfx2::SetPassword(SfxGetpApp()->GetFilterMatcher().GetFilter4FilterName(aFilterName),
3144 &*pItemSet, aPassword, aPasswordToModify, false);
3145
3146 TransformParameters(SID_SAVEASDOC, seqArguments, *pItemSet);
3147
3148 const SfxBoolItem* pCopyStreamItem = pItemSet->GetItem<SfxBoolItem>(SID_COPY_STREAM_IF_POSSIBLE, false);
3149
3150 if ( pCopyStreamItem && pCopyStreamItem->GetValue() && !bSaveTo )
3151 {
3152 throw frame::IllegalArgumentIOException(
3153 "CopyStreamIfPossible parameter is not acceptable for storeAsURL() call!" );
3154 }
3155
3156 sal_uInt32 nModifyPasswordHash = 0;
3157 Sequence< beans::PropertyValue > aModifyPasswordInfo;
3158 const SfxUnoAnyItem* pModifyPasswordInfoItem = pItemSet->GetItem<SfxUnoAnyItem>(SID_MODIFYPASSWORDINFO, false);
3159 if ( pModifyPasswordInfoItem )
3160 {
3161 // it contains either a simple hash or a set of PropertyValues
3162 // TODO/LATER: the sequence of PropertyValue should replace the hash completely in future
3163 sal_Int32 nMPHTmp = 0;
3164 pModifyPasswordInfoItem->GetValue() >>= nMPHTmp;
3165 nModifyPasswordHash = static_cast<sal_uInt32>(nMPHTmp);
3166 pModifyPasswordInfoItem->GetValue() >>= aModifyPasswordInfo;
3167 }
3168 pItemSet->ClearItem(SID_MODIFYPASSWORDINFO);
3169 sal_uInt32 nOldModifyPasswordHash = m_pData->m_pObjectShell->GetModifyPasswordHash();
3170 m_pData->m_pObjectShell->SetModifyPasswordHash( nModifyPasswordHash );
3171 Sequence< beans::PropertyValue > aOldModifyPasswordInfo = m_pData->m_pObjectShell->GetModifyPasswordInfo();
3172 m_pData->m_pObjectShell->SetModifyPasswordInfo( aModifyPasswordInfo );
3173
3174 // since saving a document modifies its DocumentProperties, the current
3175 // DocumentProperties must be saved on "SaveTo", so it can be restored
3176 // after saving
3177 bool bCopyTo = bSaveTo ||
3178 m_pData->m_pObjectShell->GetCreateMode() == SfxObjectCreateMode::EMBEDDED;
3179 Reference<document::XDocumentProperties> xOldDocProps;
3180 if ( bCopyTo )
3181 {
3182 xOldDocProps = getDocumentProperties();
3183 const Reference<util::XCloneable> xCloneable(xOldDocProps,
3184 UNO_QUERY_THROW);
3185 const Reference<document::XDocumentProperties> xNewDocProps(
3186 xCloneable->createClone(), UNO_QUERY_THROW);
3187 m_pData->m_xDocumentProperties = xNewDocProps;
3188 }
3189
3190 bool bRet = m_pData->m_pObjectShell->APISaveAs_Impl(sURL, *pItemSet, seqArguments);
3191
3192 if ( bCopyTo )
3193 {
3194 // restore DocumentProperties if a copy was created
3195 m_pData->m_xDocumentProperties = xOldDocProps;
3196 }
3197
3198 Reference < task::XInteractionHandler > xHandler;
3199 const SfxUnoAnyItem* pItem = pItemSet->GetItem<SfxUnoAnyItem>(SID_INTERACTIONHANDLER, false);
3200 if ( pItem )
3201 pItem->GetValue() >>= xHandler;
3202
3203 pItemSet.reset();
3204
3205 ErrCode nErrCode = m_pData->m_pObjectShell->GetErrorCode();
3206 if ( !bRet && !nErrCode )
3207 {
3208 SAL_WARN("sfx.doc", "Storing has failed, no error is set!");
3209 nErrCode = ERRCODE_IO_CANTWRITE;
3210 }
3211 m_pData->m_pObjectShell->ResetError();
3212
3213 if ( bRet )
3214 {
3215 if ( nErrCode )
3216 {
3217 // must be a warning - use Interactionhandler if possible or abandon
3218 if ( xHandler.is() )
3219 {
3220 // TODO/LATER: a general way to set the error context should be available
3221 SfxErrorContext aEc( ERRCTX_SFX_SAVEASDOC, m_pData->m_pObjectShell->GetTitle() );
3222
3223 task::ErrorCodeRequest aErrorCode;
3224 aErrorCode.ErrCode = sal_uInt32(nErrCode);
3225 SfxMedium::CallApproveHandler( xHandler, Any( aErrorCode ), false );
3226 }
3227 }
3228
3229 if ( !bSaveTo )
3230 {
3231 m_pData->m_aPreusedFilterName = GetMediumFilterName_Impl();
3232 m_pData->m_pObjectShell->SetModifyPasswordEntered();
3233
3234 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveAsDocDone, GlobalEventConfig::GetEventName(GlobalEventId::SAVEASDOCDONE), m_pData->m_pObjectShell.get() ) );
3235 }
3236 else
3237 {
3238 m_pData->m_pObjectShell->SetModifyPasswordHash( nOldModifyPasswordHash );
3239 m_pData->m_pObjectShell->SetModifyPasswordInfo( aOldModifyPasswordInfo );
3240
3241 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::SaveToDocDone, GlobalEventConfig::GetEventName(GlobalEventId::SAVETODOCDONE), m_pData->m_pObjectShell.get() ) );
3242 }
3243 }
3244 else
3245 {
3246 m_pData->m_pObjectShell->SetModifyPasswordHash( nOldModifyPasswordHash );
3247 m_pData->m_pObjectShell->SetModifyPasswordInfo( aOldModifyPasswordInfo );
3248
3249
3250 SfxGetpApp()->NotifyEvent( SfxEventHint( bSaveTo ? SfxEventHintId::SaveToDocFailed : SfxEventHintId::SaveAsDocFailed, GlobalEventConfig::GetEventName( bSaveTo ? GlobalEventId::SAVETODOCFAILED : GlobalEventId::SAVEASDOCFAILED),
3251 m_pData->m_pObjectShell.get() ) );
3252
3254 SfxViewShell::Current()->libreOfficeKitViewCallback( LOK_CALLBACK_EXPORT_FILE, "ERROR" );
3255
3256 std::stringstream aErrCode;
3257 aErrCode << nErrCode;
3258 throw task::ErrorCodeIOException(
3259 "SfxBaseModel::impl_store <" + sURL + "> failed: " + OUString::fromUtf8(aErrCode.str()),
3260 Reference< XInterface >(), sal_uInt32(nErrCode));
3261 }
3262}
3263
3264
3265namespace {
3266template< typename ListenerT, typename EventT >
3267class NotifySingleListenerIgnoreRE
3268{
3269private:
3270 typedef void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& );
3271 NotificationMethod m_pMethod;
3272 const EventT& m_rEvent;
3273public:
3274 NotifySingleListenerIgnoreRE( NotificationMethod method, const EventT& event ) : m_pMethod( method ), m_rEvent( event ) { }
3275
3276 void operator()( const Reference<ListenerT>& listener ) const
3277 {
3278 try
3279 {
3280 (listener.get()->*m_pMethod)( m_rEvent );
3281 }
3282 catch( RuntimeException& )
3283 {
3284 // this exception is ignored to avoid problems with invalid listeners, the listener should be probably thrown away in future
3285 }
3286 }
3287};
3288} // anonymous namespace
3289
3290void SfxBaseModel::postEvent_Impl( const OUString& aName, const Reference< frame::XController2 >& xController, const Any& supplement )
3291{
3292 // object already disposed?
3293 if ( impl_isDisposed() )
3294 return;
3295
3296 // keep m_pData alive, if notified target would dispose the document
3297 std::shared_ptr<IMPL_SfxBaseModel_DataContainer> xKeepAlive(m_pData);
3298
3299 // also make sure this object doesn't self-destruct while notifying
3300 rtl::Reference<SfxBaseModel> xHoldAlive(this);
3301
3302 DBG_ASSERT( !aName.isEmpty(), "Empty event name!" );
3303 if (aName.isEmpty())
3304 return;
3305
3307 xKeepAlive->m_aInterfaceContainer.getContainer( cppu::UnoType<document::XDocumentEventListener>::get());
3308 if ( pIC )
3309 {
3310 SAL_INFO("sfx.doc", "SfxDocumentEvent: " + aName);
3311
3312 document::DocumentEvent aDocumentEvent( static_cast<frame::XModel*>(this), aName, xController, supplement );
3313
3314 pIC->forEach< document::XDocumentEventListener, NotifySingleListenerIgnoreRE< document::XDocumentEventListener, document::DocumentEvent > >(
3315 NotifySingleListenerIgnoreRE< document::XDocumentEventListener, document::DocumentEvent >(
3316 &document::XDocumentEventListener::documentEventOccured,
3317 aDocumentEvent ) );
3318 }
3319
3320 pIC = xKeepAlive->m_aInterfaceContainer.getContainer( cppu::UnoType<document::XEventListener>::get());
3321 if ( pIC )
3322 {
3323 SAL_INFO("sfx.doc", "SfxEvent: " + aName);
3324
3325 document::EventObject aEvent( static_cast<frame::XModel*>(this), aName );
3326
3327 pIC->forEach< document::XEventListener, NotifySingleListenerIgnoreRE< document::XEventListener, document::EventObject > >(
3328 NotifySingleListenerIgnoreRE< document::XEventListener, document::EventObject >(
3329 &document::XEventListener::notifyEvent,
3330 aEvent ) );
3331 }
3332
3333}
3334
3335Reference < container::XIndexAccess > SAL_CALL SfxBaseModel::getViewData()
3336{
3337 SfxModelGuard aGuard( *this );
3338
3339 if ( m_pData->m_pObjectShell.is() && !m_pData->m_contViewData.is() )
3340 {
3341 SfxViewFrame *pActFrame = SfxViewFrame::Current();
3342 if ( !pActFrame || pActFrame->GetObjectShell() != m_pData->m_pObjectShell.get() )
3343 pActFrame = SfxViewFrame::GetFirst( m_pData->m_pObjectShell.get() );
3344
3345 if ( !pActFrame || !pActFrame->GetViewShell() )
3346 // currently no frame for this document at all or View is under construction
3347 return Reference < container::XIndexAccess >();
3348
3350
3351 if ( !m_pData->m_contViewData.is() )
3352 {
3353 // error: no container class available!
3354 return Reference < container::XIndexAccess >();
3355 }
3356
3357 Reference < container::XIndexContainer > xCont( m_pData->m_contViewData, UNO_QUERY );
3358 sal_Int32 nCount = 0;
3359 Sequence < beans::PropertyValue > aSeq;
3360 for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst( m_pData->m_pObjectShell.get() ); pFrame;
3361 pFrame = SfxViewFrame::GetNext( *pFrame, m_pData->m_pObjectShell.get() ) )
3362 {
3363 bool bIsActive = ( pFrame == pActFrame );
3364 pFrame->GetViewShell()->WriteUserDataSequence( aSeq );
3365 xCont->insertByIndex( bIsActive ? 0 : nCount, Any(aSeq) );
3366 nCount++;
3367 }
3368 }
3369
3370 return m_pData->m_contViewData;
3371}
3372
3373void SAL_CALL SfxBaseModel::setViewData( const Reference < container::XIndexAccess >& aData )
3374{
3375 SfxModelGuard aGuard( *this );
3376
3377 m_pData->m_contViewData = aData;
3378}
3379
3381void SfxBaseModel::notifyEvent( const document::EventObject& aEvent ) const
3382{
3383 // object already disposed?
3384 if ( impl_isDisposed() )
3385 return;
3386
3387 comphelper::OInterfaceContainerHelper2* pIC = m_pData->m_aInterfaceContainer.getContainer(
3389 if( !pIC )
3390
3391 return;
3392
3394 while( aIt.hasMoreElements() )
3395 {
3396 try
3397 {
3398 static_cast<document::XEventListener *>(aIt.next())->notifyEvent( aEvent );
3399 }
3400 catch( RuntimeException& )
3401 {
3402 aIt.remove();
3403 }
3404 }
3405 // for right now, we're only doing the event that this particular performance problem needed
3406 if (aEvent.EventName == "ShapeModified")
3407 {
3408 uno::Reference<drawing::XShape> xShape(aEvent.Source, uno::UNO_QUERY);
3409 if (xShape.is())
3410 {
3411 auto it = m_pData->maShapeListeners.find(xShape);
3412 if (it != m_pData->maShapeListeners.end())
3413 for (auto const & rListenerUnoRef : it->second)
3414 rListenerUnoRef->notifyShapeEvent(aEvent);
3415 }
3416 }
3417}
3418
3421{
3422 return !impl_isDisposed()
3423 && ( (nullptr != m_pData->m_aInterfaceContainer.getContainer( cppu::UnoType<document::XEventListener>::get()) )
3424 || !m_pData->maShapeListeners.empty());
3425}
3426
3427void SAL_CALL SfxBaseModel::addPrintJobListener( const Reference< view::XPrintJobListener >& xListener )
3428{
3430
3432 Reference < view::XPrintJobBroadcaster > xPJB( m_pData->m_xPrintable, UNO_QUERY );
3433 if ( xPJB.is() )
3434 xPJB->addPrintJobListener( xListener );
3435}
3436
3437void SAL_CALL SfxBaseModel::removePrintJobListener( const Reference< view::XPrintJobListener >& xListener )
3438{
3439 SfxModelGuard aGuard( *this );
3440
3442 Reference < view::XPrintJobBroadcaster > xPJB( m_pData->m_xPrintable, UNO_QUERY );
3443 if ( xPJB.is() )
3444 xPJB->removePrintJobListener( xListener );
3445}
3446
3447sal_Int64 SAL_CALL SfxBaseModel::getSomething( const Sequence< sal_Int8 >& aIdentifier )
3448{
3449 SvGlobalName aName( aIdentifier );
3451 {
3452 SolarMutexGuard aGuard;
3453 SfxObjectShell *const pObjectShell(GetObjectShell());
3454 if (pObjectShell)
3455 {
3456 return comphelper::getSomething_cast(pObjectShell);
3457 }
3458 }
3459
3460 return 0;
3461}
3462
3463
3464// XDocumentSubStorageSupplier
3465
3466
3467void SfxBaseModel::ListenForStorage_Impl( const Reference< embed::XStorage >& xStorage )
3468{
3469 Reference< util::XModifiable > xModifiable( xStorage, UNO_QUERY );
3470 if ( xModifiable.is() )
3471 {
3472 if ( !m_pData->m_pStorageModifyListen.is() )
3473 {
3474 m_pData->m_pStorageModifyListen = new ::sfx2::DocumentStorageModifyListener( *m_pData, Application::GetSolarMutex() );
3475 }
3476
3477 // no need to deregister the listening for old storage since it should be disposed automatically
3478 xModifiable->addModifyListener( m_pData->m_pStorageModifyListen );
3479 }
3480}
3481
3482Reference< embed::XStorage > SAL_CALL SfxBaseModel::getDocumentSubStorage( const OUString& aStorageName, sal_Int32 nMode )
3483{
3484 SfxModelGuard aGuard( *this );
3485
3486 Reference< embed::XStorage > xResult;
3487 if ( m_pData->m_pObjectShell.is() )
3488 {
3489 Reference< embed::XStorage > xStorage = m_pData->m_pObjectShell->GetStorage();
3490 if ( xStorage.is() )
3491 {
3492 try
3493 {
3494 xResult = xStorage->openStorageElement( aStorageName, nMode );
3495 }
3496 catch ( Exception& )
3497 {
3498 }
3499 }
3500 }
3501
3502 return xResult;
3503}
3504
3505Sequence< OUString > SAL_CALL SfxBaseModel::getDocumentSubStoragesNames()
3506{
3507 SfxModelGuard aGuard( *this );
3508
3509 Sequence< OUString > aResult;
3510 bool bSuccess = false;
3511 if ( m_pData->m_pObjectShell.is() )
3512 {
3513 Reference < embed::XStorage > xStorage = m_pData->m_pObjectShell->GetStorage();
3514 if ( xStorage.is() )
3515 {
3516 const Sequence< OUString > aTemp = xStorage->getElementNames();
3517 sal_Int32 nResultSize = 0;
3518 for ( const auto& rName : aTemp )
3519 {
3520 if ( xStorage->isStorageElement( rName ) )
3521 {
3522 aResult.realloc( ++nResultSize );
3523 aResult.getArray()[ nResultSize - 1 ] = rName;
3524 }
3525 }
3526
3527 bSuccess = true;
3528 }
3529 }
3530
3531 if ( !bSuccess )
3532 throw io::IOException();
3533
3534 return aResult;
3535}
3536
3537
3538// XScriptProviderSupplier
3539
3540
3541Reference< script::provider::XScriptProvider > SAL_CALL SfxBaseModel::getScriptProvider()
3542{
3543 SfxModelGuard aGuard( *this );
3544
3545 Reference< script::provider::XScriptProviderFactory > xScriptProviderFactory =
3546 script::provider::theMasterScriptProviderFactory::get( ::comphelper::getProcessComponentContext() );
3547
3548 Reference< XScriptInvocationContext > xScriptContext( this );
3549
3550 Reference< script::provider::XScriptProvider > xScriptProvider(
3551 xScriptProviderFactory->createScriptProvider( Any( xScriptContext ) ),
3552 UNO_SET_THROW );
3553
3554 return xScriptProvider;
3555}
3556
3557
3558// XUIConfigurationManagerSupplier
3559
3560
3561OUString const & SfxBaseModel::getRuntimeUID() const
3562{
3563 OSL_ENSURE( !m_pData->m_sRuntimeUID.isEmpty(),
3564 "SfxBaseModel::getRuntimeUID - ID is empty!" );
3565 return m_pData->m_sRuntimeUID;
3566}
3567
3569{
3570 SolarMutexGuard aGuard;
3571 if ( m_pData->m_pObjectShell.is() )
3572 return ( m_pData->m_pObjectShell->ImplGetSignatureState() == SignatureState::OK );
3573 return false;
3574}
3575
3576void SfxBaseModel::getGrabBagItem(css::uno::Any& rVal) const
3577{
3578 if (m_pData->m_xGrabBagItem)
3579 m_pData->m_xGrabBagItem->QueryValue(rVal);
3580 else
3581 rVal <<= uno::Sequence<beans::PropertyValue>();
3582}
3583
3584void SfxBaseModel::setGrabBagItem(const css::uno::Any& rVal)
3585{
3586 if (!m_pData->m_xGrabBagItem)
3587 m_pData->m_xGrabBagItem = std::make_shared<SfxGrabBagItem>();
3588
3589 m_pData->m_xGrabBagItem->PutValue(rVal, 0);
3590}
3591
3592static void GetCommandFromSequence( OUString& rCommand, sal_Int32& nIndex, const Sequence< beans::PropertyValue >& rSeqPropValue )
3593{
3594 nIndex = -1;
3595
3596 auto pPropValue = std::find_if(rSeqPropValue.begin(), rSeqPropValue.end(),
3597 [](const beans::PropertyValue& rPropValue) { return rPropValue.Name == "Command"; });
3598 if (pPropValue != rSeqPropValue.end())
3599 {
3600 pPropValue->Value >>= rCommand;
3601 nIndex = static_cast<sal_Int32>(std::distance(rSeqPropValue.begin(), pPropValue));
3602 }
3603}
3604
3605static void ConvertSlotsToCommands( SfxObjectShell const * pDoc, Reference< container::XIndexContainer > const & rToolbarDefinition )
3606{
3607 if ( !pDoc )
3608 return;
3609
3610 SfxModule* pModule( pDoc->GetFactory().GetModule() );
3611 Sequence< beans::PropertyValue > aSeqPropValue;
3612
3613 for ( sal_Int32 i = 0; i < rToolbarDefinition->getCount(); i++ )
3614 {
3615 if ( rToolbarDefinition->getByIndex( i ) >>= aSeqPropValue )
3616 {
3617 OUString aCommand;
3618 sal_Int32 nIndex( -1 );
3619 GetCommandFromSequence( aCommand, nIndex, aSeqPropValue );
3620 if ( nIndex >= 0 && aCommand.startsWith( "slot:" ) )
3621 {
3622 const sal_uInt16 nSlot = o3tl::toInt32(aCommand.subView( 5 ));
3623
3624 // We have to replace the old "slot-Command" with our new ".uno:-Command"
3625 const SfxSlot* pSlot = pModule->GetSlotPool()->GetSlot( nSlot );
3626 if ( pSlot )
3627 {
3628 aCommand = pSlot->GetCommand();
3629 aSeqPropValue.getArray()[nIndex].Value <<= aCommand;
3630 rToolbarDefinition->replaceByIndex( i, Any( aSeqPropValue ));
3631 }
3632 }
3633 }
3634 }
3635}
3636
3637Reference< ui::XUIConfigurationManager > SAL_CALL SfxBaseModel::getUIConfigurationManager()
3638{
3639 return Reference< ui::XUIConfigurationManager >( getUIConfigurationManager2(), UNO_QUERY_THROW );
3640}
3641
3642Reference< ui::XUIConfigurationManager2 > SfxBaseModel::getUIConfigurationManager2()
3643{
3644 SfxModelGuard aGuard( *this );
3645
3646 if ( !m_pData->m_xUIConfigurationManager.is() )
3647 {
3648 Reference< ui::XUIConfigurationManager2 > xNewUIConfMan =
3649 ui::UIConfigurationManager::create( comphelper::getProcessComponentContext() );
3650
3651 Reference< embed::XStorage > xConfigStorage;
3652
3653 OUString aUIConfigFolderName( "Configurations2" );
3654 // First try to open with READWRITE and then READ
3655 xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, embed::ElementModes::READWRITE );
3656 if ( xConfigStorage.is() )
3657 {
3658 static constexpr OUStringLiteral aMediaTypeProp( u"MediaType" );
3659 OUString aMediaType;
3660 Reference< beans::XPropertySet > xPropSet( xConfigStorage, UNO_QUERY );
3661 Any a = xPropSet->getPropertyValue( aMediaTypeProp );
3662 if ( !( a >>= aMediaType ) || aMediaType.isEmpty())
3663 {
3664 xPropSet->setPropertyValue( aMediaTypeProp, Any(OUString("application/vnd.sun.xml.ui.configuration")) );
3665 }
3666 }
3667 else
3668 xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, embed::ElementModes::READ );
3669
3670 // initialize ui configuration manager with document substorage
3671 xNewUIConfMan->setStorage( xConfigStorage );
3672
3673 // embedded objects did not support local configuration data until OOo 3.0, so there's nothing to
3674 // migrate
3675 if ( m_pData->m_pObjectShell->GetCreateMode() != SfxObjectCreateMode::EMBEDDED )
3676 {
3677 // Import old UI configuration from OOo 1.x
3678
3679 // Try to open with READ
3680 Reference< embed::XStorage > xOOo1ConfigStorage = getDocumentSubStorage( "Configurations", embed::ElementModes::READ );
3681 if ( xOOo1ConfigStorage.is() )
3682 {
3683 Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
3684 std::vector< Reference< container::XIndexContainer > > rToolbars;
3685
3686 bool bImported = framework::UIConfigurationImporterOOo1x::ImportCustomToolbars(
3687 xNewUIConfMan, rToolbars, xContext, xOOo1ConfigStorage );
3688 if ( bImported )
3689 {
3691
3692 for ( size_t i = 0; i < rToolbars.size(); i++ )
3693 {
3694 const OUString sId(OUString::number( i + 1 ));
3695 const OUString aCustomTbxName = "private:resource/toolbar/custom_OOo1x_" + sId;
3696
3697 Reference< container::XIndexContainer > xToolbar = rToolbars[i];
3698 ConvertSlotsToCommands( pObjShell, xToolbar );
3699 if ( !xNewUIConfMan->hasSettings( aCustomTbxName ))
3700 {
3701 // Set UIName for the toolbar with container property
3702 Reference< beans::XPropertySet > xPropSet( xToolbar, UNO_QUERY );
3703 if ( xPropSet.is() )
3704 {
3705 try
3706 {
3707 xPropSet->setPropertyValue( "UIName", Any( "Toolbar " + sId ) );
3708 }
3709 catch ( beans::UnknownPropertyException& )
3710 {
3711 }
3712 }
3713
3714 xNewUIConfMan->insertSettings( aCustomTbxName, xToolbar );
3715 xNewUIConfMan->store();
3716 }
3717 }
3718 }
3719 }
3720 }
3721
3722 m_pData->m_xUIConfigurationManager = xNewUIConfMan;
3723 }
3724
3725 return m_pData->m_xUIConfigurationManager;
3726}
3727
3728
3729// XVisualObject
3730
3731
3732void SAL_CALL SfxBaseModel::setVisualAreaSize( sal_Int64 nAspect, const awt::Size& aSize )
3733{
3734 SfxModelGuard aGuard( *this );
3735
3736 if ( !m_pData->m_pObjectShell.is() )
3737 throw Exception("no object shell", nullptr); // TODO: error handling
3738
3739 SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst( m_pData->m_pObjectShell.get(), false );
3740 if ( pViewFrm && m_pData->m_pObjectShell->GetCreateMode() == SfxObjectCreateMode::EMBEDDED && !pViewFrm->GetFrame().IsInPlace() )
3741 {
3742 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( pViewFrm->GetFrame().GetFrameInterface()->getContainerWindow() );
3743 Size aWinSize = pWindow->GetSizePixel();
3744 awt::Size aCurrent = getVisualAreaSize( nAspect );
3745 Size aDiff( aSize.Width-aCurrent.Width, aSize.Height-aCurrent.Height );
3746 aDiff = pViewFrm->GetViewShell()->GetWindow()->LogicToPixel( aDiff );
3747 aWinSize.AdjustWidth(aDiff.Width() );
3748 aWinSize.AdjustHeight(aDiff.Height() );
3749 pWindow->SetSizePixel( aWinSize );
3750 }
3751 else
3752 {
3753 tools::Rectangle aTmpRect = m_pData->m_pObjectShell->GetVisArea( ASPECT_CONTENT );
3754 aTmpRect.SetSize( Size( aSize.Width, aSize.Height ) );
3755 m_pData->m_pObjectShell->SetVisArea( aTmpRect );
3756 }
3757}
3758
3759awt::Size SAL_CALL SfxBaseModel::getVisualAreaSize( sal_Int64 /*nAspect*/ )
3760{
3761 SfxModelGuard aGuard( *this );
3762
3763 if ( !m_pData->m_pObjectShell.is() )
3764 throw Exception("no object shell", nullptr); // TODO: error handling
3765
3766 tools::Rectangle aTmpRect = m_pData->m_pObjectShell->GetVisArea( ASPECT_CONTENT );
3767
3768 return awt::Size( aTmpRect.GetWidth(), aTmpRect.GetHeight() );
3769}
3770
3771
3772sal_Int32 SAL_CALL SfxBaseModel::getMapUnit( sal_Int64 /*nAspect*/ )
3773{
3774 SfxModelGuard aGuard( *this );
3775
3776 if ( !m_pData->m_pObjectShell.is() )
3777 throw Exception("no object shell", nullptr); // TODO: error handling
3778
3779 return VCLUnoHelper::VCL2UnoEmbedMapUnit( m_pData->m_pObjectShell->GetMapUnit() );
3780}
3781
3782embed::VisualRepresentation SAL_CALL SfxBaseModel::getPreferredVisualRepresentation( ::sal_Int64 /*nAspect*/ )
3783{
3784 SfxModelGuard aGuard( *this );
3785
3786 datatransfer::DataFlavor aDataFlavor(
3787 "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"",
3788 "GDIMetaFile",
3790
3791 embed::VisualRepresentation aVisualRepresentation;
3792 aVisualRepresentation.Data = getTransferData( aDataFlavor );
3793 aVisualRepresentation.Flavor = aDataFlavor;
3794
3795 return aVisualRepresentation;
3796}
3797
3798
3799// XStorageBasedDocument
3800
3801
3802void SAL_CALL SfxBaseModel::loadFromStorage( const Reference< embed::XStorage >& xStorage,
3803 const Sequence< beans::PropertyValue >& aMediaDescriptor )
3804{
3806 if ( IsInitialized() )
3807 throw frame::DoubleInitializationException( OUString(), *this );
3808
3809 // after i36090 is fixed the pool from object shell can be used
3810 // SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() );
3811 SfxAllItemSet aSet( SfxGetpApp()->GetPool() );
3812
3813 // the BaseURL is part of the ItemSet
3814 SfxMedium* pMedium = new SfxMedium( xStorage, OUString() );
3815 TransformParameters( SID_OPENDOC, aMediaDescriptor, aSet );
3816 pMedium->GetItemSet().Put( aSet );
3817
3818 // allow to use an interactionhandler (if there is one)
3819 pMedium->UseInteractionHandler( true );
3820
3821 const SfxBoolItem* pTemplateItem = aSet.GetItem<SfxBoolItem>(SID_TEMPLATE, false);
3822 bool bTemplate = pTemplateItem && pTemplateItem->GetValue();
3823 m_pData->m_pObjectShell->SetActivateEvent_Impl( bTemplate ? SfxEventHintId::CreateDoc : SfxEventHintId::OpenDoc );
3824 m_pData->m_pObjectShell->Get_Impl()->bOwnsStorage = false;
3825
3826 // load document
3827 if ( !m_pData->m_pObjectShell->DoLoad(pMedium) )
3828 {
3829 ErrCode nError = m_pData->m_pObjectShell->GetErrorCode();
3830 nError = nError ? nError : ERRCODE_IO_CANTREAD;
3831 throw task::ErrorCodeIOException(
3832 "SfxBaseModel::loadFromStorage: " + nError.toString(),
3833 Reference< XInterface >(), sal_uInt32(nError));
3834 }
3836}
3837
3838void SAL_CALL SfxBaseModel::storeToStorage( const Reference< embed::XStorage >& xStorage,
3839 const Sequence< beans::PropertyValue >& aMediaDescriptor )
3840{
3841 SfxModelGuard aGuard( *this );
3842
3843 if ( !m_pData->m_pObjectShell.is() )
3844 throw io::IOException(); // TODO:
3845
3846 auto xSet = std::make_shared<SfxAllItemSet>(m_pData->m_pObjectShell->GetPool());
3847 TransformParameters( SID_SAVEASDOC, aMediaDescriptor, *xSet );
3848
3849 // TODO/LATER: maybe a special URL "private:storage" should be used
3850 const SfxStringItem* pItem = xSet->GetItem<SfxStringItem>(SID_FILTER_NAME, false);
3852 if( pItem )
3853 {
3854 std::shared_ptr<const SfxFilter> pFilter = SfxGetpApp()->GetFilterMatcher().GetFilter4FilterName( pItem->GetValue() );
3855 if ( pFilter && pFilter->UsesStorage() )
3856 nVersion = pFilter->GetVersion();
3857 }
3858
3859 bool bSuccess = false;
3860 if ( xStorage == m_pData->m_pObjectShell->GetStorage() )
3861 {
3862 // storing to the own storage
3863 bSuccess = m_pData->m_pObjectShell->DoSave();
3864 }
3865 else
3866 {
3867 // TODO/LATER: if the provided storage has some data inside the storing might fail, probably the storage must be truncated
3868 // TODO/LATER: is it possible to have a template here?
3869 m_pData->m_pObjectShell->SetupStorage( xStorage, nVersion, false );
3870
3871 // BaseURL is part of the ItemSet
3872 SfxMedium aMedium( xStorage, OUString(), xSet );
3873 aMedium.CanDisposeStorage_Impl( false );
3874 if ( aMedium.GetFilter() )
3875 {
3876 // storing without a valid filter will often crash
3877 bSuccess = m_pData->m_pObjectShell->DoSaveObjectAs( aMedium, true );
3878 m_pData->m_pObjectShell->DoSaveCompleted();
3879 }
3880 }
3881
3882 ErrCode nError = m_pData->m_pObjectShell->GetErrorCode();
3883 m_pData->m_pObjectShell->ResetError();
3884
3885 // the warnings are currently not transported
3886 if ( !bSuccess )
3887 {
3888 nError = nError ? nError : ERRCODE_IO_GENERAL;
3889 throw task::ErrorCodeIOException(
3890 "SfxBaseModel::storeToStorage: " + nError.toString(),
3891 Reference< XInterface >(), sal_uInt32(nError));
3892 }
3893}
3894
3895void SAL_CALL SfxBaseModel::switchToStorage( const Reference< embed::XStorage >& xStorage )
3896{
3897 SfxModelGuard aGuard( *this );
3898
3899 if ( !m_pData->m_pObjectShell.is() )
3900 throw io::IOException(); // TODO:
3901
3902 // the persistence should be switched only if the storage is different
3903 if ( xStorage != m_pData->m_pObjectShell->GetStorage() )
3904 {
3905 if ( !m_pData->m_pObjectShell->SwitchPersistence( xStorage ) )
3906 {
3907 ErrCode nError = m_pData->m_pObjectShell->GetErrorCode();
3908 nError = nError ? nError : ERRCODE_IO_GENERAL;
3909 throw task::ErrorCodeIOException(
3910 "SfxBaseModel::switchToStorage: " + nError.toString(),
3911 Reference< XInterface >(), sal_uInt32(nError));
3912 }
3913 else
3914 {
3915 // UICfgMgr has a reference to the old storage, update it
3916 getUIConfigurationManager2()->setStorage( xStorage );
3917 }
3918 }
3919 m_pData->m_pObjectShell->Get_Impl()->bOwnsStorage = false;
3920}
3921
3922Reference< embed::XStorage > SAL_CALL SfxBaseModel::getDocumentStorage()
3923{
3924 SfxModelGuard aGuard( *this );
3925
3926 if ( !m_pData->m_pObjectShell.is() )
3927 throw io::IOException(); // TODO
3928
3929 return m_pData->m_pObjectShell->GetStorage();
3930}
3931
3933 const Reference< document::XStorageChangeListener >& xListener )
3934{
3936
3937 m_pData->m_aInterfaceContainer.addInterface(
3939}
3940
3942 const Reference< document::XStorageChangeListener >& xListener )
3943{
3944 SfxModelGuard aGuard( *this );
3945
3946 m_pData->m_aInterfaceContainer.removeInterface(
3948}
3949
3951{
3952 if ( m_pData->m_xPrintable.is() )
3953 return;
3954 m_pData->m_xPrintable = new SfxPrintHelper();
3955 Reference < lang::XInitialization > xInit( m_pData->m_xPrintable, UNO_QUERY );
3956 xInit->initialize( { Any(Reference < frame::XModel > (this)) } );
3957 Reference < view::XPrintJobBroadcaster > xBrd( m_pData->m_xPrintable, UNO_QUERY );
3958 xBrd->addPrintJobListener( new SfxPrintHelperListener_Impl( m_pData.get() ) );
3959}
3960
3961
3962// css.frame.XModule
3963 void SAL_CALL SfxBaseModel::setIdentifier(const OUString& Identifier)
3964{
3965 SfxModelGuard aGuard( *this );
3966 m_pData->m_sModuleIdentifier = Identifier;
3967}
3968
3969
3970// css.frame.XModule
3972{
3973 SfxModelGuard aGuard( *this );
3974 if (!m_pData->m_sModuleIdentifier.isEmpty())
3975 return m_pData->m_sModuleIdentifier;
3976 if (m_pData->m_pObjectShell.is())
3977 return m_pData->m_pObjectShell->GetFactory().GetDocumentServiceName();
3978 return OUString();
3979}
3980
3981
3982Reference< frame::XTitle > SfxBaseModel::impl_getTitleHelper ()
3983{
3984 SfxModelGuard aGuard( *this );
3985
3986 if ( ! m_pData->m_xTitleHelper.is ())
3987 {
3988 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
3989 Reference< frame::XUntitledNumbers > xDesktop( frame::Desktop::create(xContext), UNO_QUERY_THROW);
3990
3991 m_pData->m_xTitleHelper = new ::framework::TitleHelper(xContext, Reference< frame::XModel >(this), xDesktop);
3992 }
3993
3994 return m_pData->m_xTitleHelper;
3995}
3996
3997
3998Reference< frame::XUntitledNumbers > SfxBaseModel::impl_getUntitledHelper ()
3999{
4000 SfxModelGuard aGuard( *this );
4001
4002 if ( ! m_pData->m_xNumberedControllers.is ())
4003 {
4004 rtl::Reference<::comphelper::NumberedCollection> pHelper = new ::comphelper::NumberedCollection();
4005 m_pData->m_xNumberedControllers = pHelper;
4006 pHelper->setOwner (Reference< frame::XModel >(this));
4007 pHelper->setUntitledPrefix (" : ");
4008 }
4009
4010 return m_pData->m_xNumberedControllers;
4011}
4012
4013
4014// css.frame.XTitle
4015OUString SAL_CALL SfxBaseModel::getTitle()
4016{
4017 // SYNCHRONIZED ->
4018 SfxModelGuard aGuard( *this );
4019
4020 OUString aResult = impl_getTitleHelper()->getTitle ();
4021 if ( !m_pData->m_bExternalTitle && m_pData->m_pObjectShell )
4022 {
4023 SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
4024 if ( pMedium )
4025 {
4026 try {
4027 ::ucbhelper::Content aContent( pMedium->GetName(),
4030 const Reference < beans::XPropertySetInfo > xProps
4031 = aContent.getProperties();
4032 if ( xProps.is() )
4033 {
4034 static constexpr OUStringLiteral aServerTitle( u"TitleOnServer" );
4035 if ( xProps->hasPropertyByName( aServerTitle ) )
4036 {
4037 Any aAny = aContent.getPropertyValue( aServerTitle );
4038 aAny >>= aResult;
4039 }
4040 }
4041 }
4042 catch (const ucb::ContentCreationException &)
4043 {
4044 }
4045 catch (const ucb::CommandAbortedException &)
4046 {
4047 }
4048 const SfxBoolItem* pRepairedDocItem = pMedium->GetItemSet().GetItem(SID_REPAIRPACKAGE, false);
4049 if ( pRepairedDocItem && pRepairedDocItem->GetValue() )
4050 aResult += SfxResId(STR_REPAIREDDOCUMENT);
4051 }
4052
4053 if ( m_pData->m_pObjectShell->IsReadOnlyUI() || (pMedium && pMedium->IsReadOnly()) )
4054 aResult += SfxResId(STR_READONLY);
4055 else if ( m_pData->m_pObjectShell->IsDocShared() )
4056 aResult += SfxResId(STR_SHARED);
4057
4058 if ( m_pData->m_pObjectShell->GetDocumentSignatureState() == SignatureState::OK )
4059 aResult += SfxResId(RID_XMLSEC_DOCUMENTSIGNED);
4060 }
4061
4062 return aResult;
4063}
4064
4065
4066// css.frame.XTitle
4067void SAL_CALL SfxBaseModel::setTitle( const OUString& sTitle )
4068{
4069 // SYNCHRONIZED ->
4070 SfxModelGuard aGuard( *this );
4071
4072 impl_getTitleHelper()->setTitle (sTitle);
4073 m_pData->m_bExternalTitle = true;
4074}
4075
4076
4077// css.frame.XTitleChangeBroadcaster
4078void SAL_CALL SfxBaseModel::addTitleChangeListener( const Reference< frame::XTitleChangeListener >& xListener )
4079{
4080 // SYNCHRONIZED ->
4082
4083 Reference< frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper(), UNO_QUERY);
4084 if (xBroadcaster.is ())
4085 xBroadcaster->addTitleChangeListener (xListener);
4086}
4087
4088
4089// css.frame.XTitleChangeBroadcaster
4090void SAL_CALL SfxBaseModel::removeTitleChangeListener( const Reference< frame::XTitleChangeListener >& xListener )
4091{
4092 // SYNCHRONIZED ->
4093 SfxModelGuard aGuard( *this );
4094
4095 Reference< frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper(), UNO_QUERY);
4096 if (xBroadcaster.is ())
4097 xBroadcaster->removeTitleChangeListener (xListener);
4098}
4099
4100
4101// css.frame.XUntitledNumbers
4102::sal_Int32 SAL_CALL SfxBaseModel::leaseNumber( const Reference< XInterface >& xComponent )
4103{
4104 SfxModelGuard aGuard( *this );
4105
4106 return impl_getUntitledHelper ()->leaseNumber (xComponent);
4107}
4108
4109
4110// css.frame.XUntitledNumbers
4111void SAL_CALL SfxBaseModel::releaseNumber( ::sal_Int32 nNumber )
4112{
4113 SfxModelGuard aGuard( *this );
4114 impl_getUntitledHelper ()->releaseNumber (nNumber);
4115}
4116
4117
4118// css.frame.XUntitledNumbers
4119void SAL_CALL SfxBaseModel::releaseNumberForComponent( const Reference< XInterface >& xComponent )
4120{
4121 SfxModelGuard aGuard( *this );
4122 impl_getUntitledHelper ()->releaseNumberForComponent (xComponent);
4123}
4124
4125
4126// css.frame.XUntitledNumbers
4128{
4129 SfxModelGuard aGuard( *this );
4130 return impl_getUntitledHelper ()->getUntitledPrefix ();
4131}
4132
4133
4134// frame::XModel2
4135Reference< container::XEnumeration > SAL_CALL SfxBaseModel::getControllers()
4136{
4137 SfxModelGuard aGuard( *this );
4138
4139 sal_Int32 c = m_pData->m_seqControllers.size();
4140 Sequence< Any > lEnum(c);
4141 std::transform(m_pData->m_seqControllers.begin(), m_pData->m_seqControllers.end(),
4142 lEnum.getArray(), [](const auto& x) { return css::uno::Any(x); });
4143
4144 return new ::comphelper::OAnyEnumeration(lEnum);
4145}
4146
4147
4148// frame::XModel2
4150{
4151 SfxModelGuard aGuard( *this );
4152
4153 const SfxObjectFactory& rDocumentFactory = GetObjectShell()->GetFactory();
4154 const sal_Int16 nViewFactoryCount = rDocumentFactory.GetViewFactoryCount();
4155
4156 Sequence< OUString > aViewNames( nViewFactoryCount );
4157 auto aViewNamesRange = asNonConstRange(aViewNames);
4158 for ( sal_Int16 nViewNo = 0; nViewNo < nViewFactoryCount; ++nViewNo )
4159 aViewNamesRange[nViewNo] = rDocumentFactory.GetViewFactory( nViewNo ).GetAPIViewName();
4160 return aViewNames;
4161}
4162
4163
4164// frame::XModel2
4165Reference< frame::XController2 > SAL_CALL SfxBaseModel::createDefaultViewController( const Reference< frame::XFrame >& i_rFrame )
4166{
4167 SfxModelGuard aGuard( *this );
4168
4169 const SfxObjectFactory& rDocumentFactory = GetObjectShell()->GetFactory();
4170 const OUString sDefaultViewName = rDocumentFactory.GetViewFactory().GetAPIViewName();
4171
4172 aGuard.clear();
4173
4174 return createViewController( sDefaultViewName, Sequence< PropertyValue >(), i_rFrame );
4175}
4176
4177
4178namespace sfx::intern {
4179
4184 {
4185 public:
4187 :m_bSuccess( false )
4188 {
4189 }
4190
4192 {
4193 if ( !m_bSuccess && m_aWeakFrame && !m_aWeakFrame->GetCurrentDocument() )
4194 {
4195 m_aWeakFrame->SetFrameInterface_Impl( nullptr );
4196 m_aWeakFrame->DoClose();
4197 }
4198 }
4199
4201 {
4202 OSL_PRECOND( !m_aWeakFrame, "ViewCreationGuard::takeFrameOwnership: already have a frame!" );
4203 OSL_PRECOND( i_pFrame != nullptr, "ViewCreationGuard::takeFrameOwnership: invalid frame!" );
4204 m_aWeakFrame = i_pFrame;
4205 }
4206
4208 {
4209 m_bSuccess = true;
4210 }
4211
4212 private:
4215 };
4216}
4217
4218
4220{
4221 SfxViewFrame* pViewFrame = nullptr;
4222 for ( pViewFrame = SfxViewFrame::GetFirst( GetObjectShell(), false );
4223 pViewFrame;
4224 pViewFrame= SfxViewFrame::GetNext( *pViewFrame, GetObjectShell(), false )
4225 )
4226 {
4227 if ( pViewFrame->GetFrame().GetFrameInterface() == i_rFrame )
4228 break;
4229 }
4230 if ( !pViewFrame )
4231 {
4232 #if OSL_DEBUG_LEVEL > 0
4233 for ( SfxFrame* pCheckFrame = SfxFrame::GetFirst();
4234 pCheckFrame;
4235 pCheckFrame = SfxFrame::GetNext( *pCheckFrame )
4236 )
4237 {
4238 if ( pCheckFrame->GetFrameInterface() == i_rFrame )
4239 {
4240 if ( ( pCheckFrame->GetCurrentViewFrame() != nullptr )
4241 || ( pCheckFrame->GetCurrentDocument() != nullptr )
4242 )
4243 // Note that it is perfectly legitimate that during loading into an XFrame which already contains
4244 // a document, there exist two SfxFrame instances bound to this XFrame - the old one, which will be
4245 // destroyed later, and the new one, which we're going to create
4246 continue;
4247
4248 OSL_FAIL( "SfxBaseModel::FindOrCreateViewFrame_Impl: there already is an SfxFrame for the given XFrame, but no view in it!" );
4249 // nowadays, we're the only instance allowed to create an SfxFrame for an XFrame, so this case here should not happen
4250 break;
4251 }
4252 }
4253 #endif
4254
4255 SfxFrame* pTargetFrame = SfxFrame::Create( i_rFrame );
4256 ENSURE_OR_THROW( pTargetFrame, "could not create an SfxFrame" );
4257 i_rGuard.takeFrameOwnership( pTargetFrame );
4258
4259 // prepare it
4260 pTargetFrame->PrepareForDoc_Impl( *GetObjectShell() );
4261
4262 // create view frame
4263 pViewFrame = new SfxViewFrame( *pTargetFrame, GetObjectShell() );
4264 }
4265 return pViewFrame;
4266}
4267
4268
4269// frame::XModel2
4270Reference< frame::XController2 > SAL_CALL SfxBaseModel::createViewController(
4271 const OUString& i_rViewName, const Sequence< PropertyValue >& i_rArguments, const Reference< XFrame >& i_rFrame )
4272{
4273 SfxModelGuard aGuard( *this );
4274
4275 if ( !i_rFrame.is() )
4276 throw lang::IllegalArgumentException( OUString(), *this, 3 );
4277
4278 // find the proper SFX view factory
4279 SfxViewFactory* pViewFactory = GetObjectShell()->GetFactory().GetViewFactoryByViewName( i_rViewName );
4280 if ( !pViewFactory )
4281 throw IllegalArgumentException( OUString(), *this, 1 );
4282
4283 // determine previous shell (used in some special cases)
4284 Reference< XController > xPreviousController( i_rFrame->getController() );
4285 const Reference< XModel > xMe( this );
4286 if ( ( xPreviousController.is() )
4287 && ( xMe != xPreviousController->getModel() )
4288 )
4289 {
4290 xPreviousController.clear();
4291 }
4292 SfxViewShell* pOldViewShell = SfxViewShell::Get( xPreviousController );
4293 OSL_ENSURE( !xPreviousController.is() || ( pOldViewShell != nullptr ),
4294 "SfxBaseModel::createViewController: invalid old controller!" );
4295
4296 // a guard which will clean up in case of failure
4297 ::sfx::intern::ViewCreationGuard aViewCreationGuard;
4298
4299 // determine the ViewFrame belonging to the given XFrame
4300 SfxViewFrame* pViewFrame = FindOrCreateViewFrame_Impl( i_rFrame, aViewCreationGuard );
4301 assert(pViewFrame && "SfxBaseModel::createViewController: no frame");
4302
4303 // delegate to SFX' view factory
4304 pViewFrame->GetBindings().ENTERREGISTRATIONS();
4305 SfxViewShell* pViewShell = pViewFactory->CreateInstance(*pViewFrame, pOldViewShell);
4306 pViewFrame->GetBindings().LEAVEREGISTRATIONS();
4307 ENSURE_OR_THROW( pViewShell, "invalid view shell provided by factory" );
4308
4309 // by setting the ViewShell it is prevented that disposing the Controller will destroy this ViewFrame also
4311 pViewFrame->SetViewShell_Impl( pViewShell );
4312
4313 // remember ViewID
4314 pViewFrame->SetCurViewId_Impl( pViewFactory->GetOrdinal() );
4315
4316 // ensure a default controller, if the view shell did not provide an own implementation
4317 if ( !pViewShell->GetController().is() )
4318 pViewShell->SetController( new SfxBaseController( pViewShell ) );
4319
4320 // pass the creation arguments to the controller
4321 SfxBaseController* pBaseController = pViewShell->GetBaseController_Impl();
4322 ENSURE_OR_THROW( pBaseController, "invalid controller implementation!" );
4323 pBaseController->SetCreationArguments_Impl( i_rArguments );
4324
4325 // some initial view settings, coming from our most recent attachResource call
4326 ::comphelper::NamedValueCollection aDocumentLoadArgs( getArgs2( { "ViewOnly", "PluginMode" } ) );
4327 if ( aDocumentLoadArgs.getOrDefault( "ViewOnly", false ) )
4328 pViewFrame->GetFrame().SetMenuBarOn_Impl( false );
4329
4330 const sal_Int16 nPluginMode = aDocumentLoadArgs.getOrDefault( "PluginMode", sal_Int16( 0 ) );
4331 if ( nPluginMode == 1 )
4332 {
4333 pViewFrame->ForceOuterResize_Impl();
4334 pViewFrame->GetBindings().HidePopups();
4335
4336 SfxFrame& rFrame = pViewFrame->GetFrame();
4337 // MBA: layoutmanager of inplace frame starts locked and invisible
4338 rFrame.GetWorkWindow_Impl()->MakeVisible_Impl( false );
4339 rFrame.GetWorkWindow_Impl()->Lock_Impl( true );
4340
4341 rFrame.GetWindow().SetBorderStyle( WindowBorderStyle::NOBORDER );
4342 pViewFrame->GetWindow().SetBorderStyle( WindowBorderStyle::NOBORDER );
4343 }
4344
4345 // tell the guard we were successful
4346 aViewCreationGuard.releaseAll();
4347
4348 // outta here
4349 return pBaseController;
4350}
4351
4352
4353// RDF DocumentMetadataAccess
4354
4355// rdf::XRepositorySupplier:
4356Reference< rdf::XRepository > SAL_CALL
4358{
4359 SfxModelGuard aGuard( *this );
4360
4361 const Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4362 if (!xDMA.is()) {
4363 throw RuntimeException( "model has no document metadata", *this );
4364 }
4365
4366 return xDMA->getRDFRepository();
4367}
4368
4369// rdf::XNode:
4370OUString SAL_CALL
4372{
4373 SfxModelGuard aGuard( *this );
4374
4375 const Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4376 if (!xDMA.is()) {
4377 throw RuntimeException( "model has no document metadata", *this );
4378 }
4379
4380 return xDMA->getStringValue();
4381}
4382
4383// rdf::XURI:
4384OUString SAL_CALL
4386{
4387 SfxModelGuard aGuard( *this );
4388
4389 const Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4390 if (!xDMA.is()) {
4391 throw RuntimeException( "model has no document metadata", *this );
4392 }
4393
4394 return xDMA->getNamespace();
4395}
4396
4397OUString SAL_CALL
4399{
4400 SfxModelGuard aGuard( *this );
4401
4402 const Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4403 if (!xDMA.is()) {
4404 throw RuntimeException( "model has no document metadata", *this );
4405 }
4406
4407 return xDMA->getLocalName();
4408}
4409
4410// rdf::XDocumentMetadataAccess:
4411Reference< rdf::XMetadatable > SAL_CALL
4413 const beans::StringPair & i_rReference)
4414{
4415 SfxModelGuard aGuard( *this );
4416
4417 const Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4418 if (!xDMA.is()) {
4419 throw RuntimeException( "model has no document metadata", *this );
4420 }
4421
4422 return xDMA->getElementByMetadataReference(i_rReference);
4423}
4424
4425Reference< rdf::XMetadatable > SAL_CALL
4426SfxBaseModel::getElementByURI(const Reference< rdf::XURI > & i_xURI)
4427{
4428 SfxModelGuard aGuard( *this );
4429
4430 const Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4431 if (!xDMA.is()) {
4432 throw RuntimeException( "model has no document metadata", *this );
4433 }
4434
4435 return xDMA->getElementByURI(i_xURI);
4436}
4437
4438Sequence< Reference< rdf::XURI > > SAL_CALL
4440 const Reference<rdf::XURI> & i_xType)
4441{
4442 SfxModelGuard aGuard( *this );
4443
4444 const Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4445 if (!xDMA.is()) {
4446 throw RuntimeException( "model has no document metadata", *this );
4447 }
4448
4449 return xDMA->getMetadataGraphsWithType(i_xType);
4450}
4451
4452Reference<rdf::XURI> SAL_CALL
4453SfxBaseModel::addMetadataFile(const OUString & i_rFileName,
4454 const Sequence < Reference< rdf::XURI > > & i_rTypes)
4455{
4456 SfxModelGuard aGuard( *this );
4457
4458 const Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4459 if (!xDMA.is()) {
4460 throw RuntimeException( "model has no document metadata", *this );
4461 }
4462
4463 return xDMA->addMetadataFile(i_rFileName, i_rTypes);
4464}
4465
4466Reference<rdf::XURI> SAL_CALL
4468 const Reference< io::XInputStream > & i_xInStream,
4469 const OUString & i_rFileName,
4470 const Reference< rdf::XURI > & i_xBaseURI,
4471 const Sequence < Reference< rdf::XURI > > & i_rTypes)
4472{
4473 SfxModelGuard aGuard( *this );
4474
4475 const Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4476 if (!xDMA.is()) {
4477 throw RuntimeException( "model has no document metadata", *this );
4478 }
4479
4480 return xDMA->importMetadataFile(i_Format,
4481 i_xInStream, i_rFileName, i_xBaseURI, i_rTypes);
4482}
4483
4484void SAL_CALL
4486 const Reference< rdf::XURI > & i_xGraphName)
4487{
4488 SfxModelGuard aGuard( *this );
4489
4490 const Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4491 if (!xDMA.is()) {
4492 throw RuntimeException( "model has no document metadata", *this );
4493 }
4494
4495 return xDMA->removeMetadataFile(i_xGraphName);
4496}
4497
4498void SAL_CALL
4499SfxBaseModel::addContentOrStylesFile(const OUString & i_rFileName)
4500{
4501 SfxModelGuard aGuard( *this );
4502
4503 const Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4504 if (!xDMA.is()) {
4505 throw RuntimeException( "model has no document metadata", *this );
4506 }
4507
4508 return xDMA->addContentOrStylesFile(i_rFileName);
4509}
4510
4511void SAL_CALL
4512SfxBaseModel::removeContentOrStylesFile(const OUString & i_rFileName)
4513{
4514 SfxModelGuard aGuard( *this );
4515
4516 const Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4517 if (!xDMA.is()) {
4518 throw RuntimeException( "model has no document metadata", *this );
4519 }
4520
4521 return xDMA->removeContentOrStylesFile(i_rFileName);
4522}
4523
4524void SAL_CALL
4526 Reference< embed::XStorage > const & i_xStorage,
4527 Reference<rdf::XURI> const & i_xBaseURI,
4528 Reference<task::XInteractionHandler> const & i_xHandler)
4529{
4530 SfxModelGuard aGuard( *this );
4531
4532 const Reference<rdf::XDocumentMetadataAccess> xDMA(
4533 m_pData->CreateDMAUninitialized());
4534 if (!xDMA.is()) {
4535 throw RuntimeException( "model has no document metadata", *this );
4536 }
4537
4538 try {
4539 xDMA->loadMetadataFromStorage(i_xStorage, i_xBaseURI, i_xHandler);
4540 } catch (lang::IllegalArgumentException &) {
4541 throw; // not initialized
4542 } catch (Exception &) {
4543 // UGLY: if it's a RuntimeException, we can't be sure DMA is initialized
4544 m_pData->m_xDocumentMetadata = xDMA;
4545 throw;
4546 }
4547 m_pData->m_xDocumentMetadata = xDMA;
4548
4549}
4550
4551void SAL_CALL
4553 Reference< embed::XStorage > const & i_xStorage)
4554{
4555 SfxModelGuard aGuard( *this );
4556
4557 const Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4558 if (!xDMA.is()) {
4559 throw RuntimeException( "model has no document metadata", *this );
4560 }
4561
4562 return xDMA->storeMetadataToStorage(i_xStorage);
4563}
4564
4565void SAL_CALL
4567 const Sequence< beans::PropertyValue > & i_rMedium)
4568{
4569 SfxModelGuard aGuard( *this );
4570
4571 const Reference<rdf::XDocumentMetadataAccess> xDMA(
4572 m_pData->CreateDMAUninitialized());
4573 if (!xDMA.is()) {
4574 throw RuntimeException( "model has no document metadata", *this );
4575 }
4576
4577 try {
4578 xDMA->loadMetadataFromMedium(i_rMedium);
4579 } catch (lang::IllegalArgumentException &) {
4580 throw; // not initialized
4581 } catch (Exception &) {
4582 // UGLY: if it's a RuntimeException, we can't be sure DMA is initialized
4583 m_pData->m_xDocumentMetadata = xDMA;
4584 throw;
4585 }
4586 m_pData->m_xDocumentMetadata = xDMA;
4587}
4588
4589void SAL_CALL
4591 const Sequence< beans::PropertyValue > & i_rMedium)
4592{
4593 SfxModelGuard aGuard( *this );
4594
4595 const Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4596 if (!xDMA.is()) {
4597 throw RuntimeException( "model has no document metadata", *this );
4598 }
4599
4600 return xDMA->storeMetadataToMedium(i_rMedium);
4601}
4602
4603
4604// = SfxModelSubComponent
4605
4606
4608{
4609}
4610
4611/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
PropertiesInfo aProperties
Reference< XInputStream > xStream
SfxApplication * SfxGetpApp()
Definition: app.hxx:231
void TransformItems(sal_uInt16 nSlotId, const SfxItemSet &rSet, uno::Sequence< beans::PropertyValue > &rArgs, const SfxSlot *pSlot)
Definition: appuno.cxx:908
void TransformParameters(sal_uInt16 nSlotId, const uno::Sequence< beans::PropertyValue > &rArgs, SfxAllItemSet &rSet, const SfxSlot *pSlot)
Definition: appuno.cxx:170
AnyEventRef aEvent
uno::Reference< script::XStarBasicAccess > getStarBasicAccess(BasicManager *pMgr)
const sal_uInt16 nVersion
Definition: childwin.cxx:43
static comphelper::SolarMutex & GetSolarMutex()
const OUString & GetValue() const
COMPHELPER_DLLPUBLIC OUString toString() const
bool IsWarning() const
static OUString GetEventName(GlobalEventId nID)
OUString getName(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
css::uno::Reference< css::task::XInteractionRequest > GetRequest() const
Definition: appuno.cxx:1837
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
bool isApproved() const
Definition: appuno.cxx:1787
css::uno::Reference< css::task::XInteractionRequest > GetRequest() const
Definition: appuno.cxx:1792
SfxFilterMatcher & GetFilterMatcher()
Definition: appmain.cxx:27
static SfxApplication * Get()
Definition: app.cxx:70
void NotifyEvent(const SfxEventHint &rEvent, bool bSynchron=true)
Definition: appcfg.cxx:338
SAL_DLLPRIVATE void SetCreationArguments_Impl(const css::uno::Sequence< css::beans::PropertyValue > &i_rCreationArgs)
virtual void SAL_CALL print(const css::uno::Sequence< css::beans::PropertyValue > &seqOptions) override
virtual css::uno::Sequence< css::datatransfer::DataFlavor > SAL_CALL getTransferDataFlavors() override
virtual sal_Bool SAL_CALL canCheckOut() override
virtual void SAL_CALL storeMetadataToStorage(const css::uno::Reference< css::embed::XStorage > &i_xStorage) override
virtual void SAL_CALL removePrintJobListener(const css::uno::Reference< css::view::XPrintJobListener > &xListener) override
virtual css::uno::Sequence< css::document::CmisVersion > SAL_CALL getAllVersions() override
virtual OUString SAL_CALL getUntitledPrefix() override
virtual css::uno::Sequence< OUString > SAL_CALL getDocumentSubStoragesNames() override
virtual void SAL_CALL storeToStorage(const css::uno::Reference< css::embed::XStorage > &xStorage, const css::uno::Sequence< css::beans::PropertyValue > &aMediaDescriptor) override
SAL_DLLPRIVATE OUString GetMediumFilterName_Impl() const
virtual css::uno::Reference< css::embed::XStorage > SAL_CALL getDocumentStorage() override
virtual void SAL_CALL storeAsURL(const OUString &sURL, const css::uno::Sequence< css::beans::PropertyValue > &seqArguments) override
virtual void SAL_CALL addCloseListener(const css::uno::Reference< css::util::XCloseListener > &xListener) override
css::uno::Reference< css::ui::XUIConfigurationManager2 > getUIConfigurationManager2()
virtual void SAL_CALL addShapeEventListener(const css::uno::Reference< css::drawing::XShape > &xShape, const css::uno::Reference< css::document::XShapeEventListener > &xListener) override
virtual sal_Bool SAL_CALL attachResource(const OUString &sURL, const css::uno::Sequence< css::beans::PropertyValue > &aArgs) override
virtual css::uno::Reference< css::document::XDocumentProperties > SAL_CALL getDocumentProperties() override
virtual void SAL_CALL recoverFromFile(const OUString &i_SourceLocation, const OUString &i_SalvagedFile, const css::uno::Sequence< css::beans::PropertyValue > &i_MediaDescriptor) override
virtual void SAL_CALL addDialog(const OUString &LibraryName, const OUString &DialogName, const css::uno::Sequence< sal_Int8 > &Data) override
virtual void SAL_CALL addContentOrStylesFile(const OUString &i_rFileName) override
virtual void SAL_CALL setCmisProperties(const css::uno::Sequence< css::document::CmisProperty > &_cmisproperties) override
SfxBaseModel(SfxObjectShell *pObjectShell)
virtual void SAL_CALL loadMetadataFromMedium(const css::uno::Sequence< css::beans::PropertyValue > &i_rMedium) override
virtual void SAL_CALL close(sal_Bool bDeliverOwnership) override
virtual sal_Int64 SAL_CALL getModifiedStateDuration() override
virtual sal_Bool SAL_CALL canCheckIn() override
virtual void SAL_CALL removeContentOrStylesFile(const OUString &i_rFileName) override
virtual css::uno::Reference< css::rdf::XURI > SAL_CALL importMetadataFile(::sal_Int16 i_Format, const css::uno::Reference< css::io::XInputStream > &i_xInStream, const OUString &i_rFileName, const css::uno::Reference< css::rdf::XURI > &i_xBaseURI, const css::uno::Sequence< css::uno::Reference< css::rdf::XURI > > &i_rTypes) override
virtual void SAL_CALL store() override
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getCurrentSelection() override
virtual css::uno::Reference< css::frame::XController2 > SAL_CALL createDefaultViewController(const css::uno::Reference< css::frame::XFrame > &Frame) override
void Notify(SfxBroadcaster &aBC, const SfxHint &aHint) override
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent() override
virtual void SAL_CALL storeToURL(const OUString &sURL, const css::uno::Sequence< css::beans::PropertyValue > &seqArguments) override
virtual css::uno::Reference< css::script::XStorageBasedLibraryContainer > SAL_CALL getDialogLibraries() override
virtual void SAL_CALL updateCmisProperties(const css::uno::Sequence< css::document::CmisProperty > &_cmisproperties) override
virtual OUString SAL_CALL getIdentifier() override
virtual css::uno::Reference< css::script::XStorageBasedLibraryContainer > SAL_CALL getBasicLibraries() override
virtual void SAL_CALL addTitleChangeListener(const css::uno::Reference< css::frame::XTitleChangeListener > &xListener) override
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
get information about supported interfaces @seealso XTypeProvider
void impl_getPrintHelper()
virtual void SAL_CALL connectController(const css::uno::Reference< css::frame::XController > &xController) override
bool IsInitialized() const
void notifyEvent(const css::document::EventObject &aEvent) const
calls all XEventListeners
virtual OUString SAL_CALL getLocalName() override
virtual OUString SAL_CALL getLocation() override
virtual sal_Bool SAL_CALL isReadonly() override
virtual void SAL_CALL setTitle(const OUString &sTitle) override
virtual css::uno::Reference< css::ui::XUIConfigurationManager > SAL_CALL getUIConfigurationManager() override
SAL_DLLPRIVATE css::uno::Reference< css::frame::XTitle > impl_getTitleHelper()
virtual ::sal_Int32 SAL_CALL leaseNumber(const css::uno::Reference< css::uno::XInterface > &xComponent) override
virtual void SAL_CALL cancelCheckOut() override
virtual void SAL_CALL disposing(const css::lang::EventObject &aEvent) override
virtual sal_Bool SAL_CALL canCancelCheckOut() override
void getGrabBagItem(css::uno::Any &rVal) const
bool hasValidSignatures() const
SAL_DLLPRIVATE SfxViewFrame * FindOrCreateViewFrame_Impl(const css::uno::Reference< css::frame::XFrame > &i_rFrame, ::sfx::intern::ViewCreationGuard &i_rGuard) const
virtual void SAL_CALL unlockControllers() override
virtual css::uno::Reference< css::container::XNameContainer > SAL_CALL getLibraryContainer() override
SAL_DLLPRIVATE void impl_store(const OUString &sURL, const css::uno::Sequence< css::beans::PropertyValue > &seqArguments, bool bSaveTo)
virtual css::uno::Sequence< OUString > SAL_CALL getAvailableViewControllerNames() override
virtual css::uno::Sequence< css::uno::Reference< css::rdf::XURI > > SAL_CALL getMetadataGraphsWithType(const css::uno::Reference< css::rdf::XURI > &i_xType) override
virtual OUString SAL_CALL getNamespace() override
virtual void SAL_CALL storeSelf(const css::uno::Sequence< css::beans::PropertyValue > &seqArguments) override
SAL_DLLPRIVATE void postEvent_Impl(const OUString &aName, const css::uno::Reference< css::frame::XController2 > &xController=css::uno::Reference< css::frame::XController2 >(), const css::uno::Any &aSupplement=css::uno::Any())
virtual css::embed::VisualRepresentation SAL_CALL getPreferredVisualRepresentation(::sal_Int64 nAspect) override
virtual void SAL_CALL releaseNumberForComponent(const css::uno::Reference< css::uno::XInterface > &xComponent) override
virtual sal_Bool SAL_CALL getAllowMacroExecution() override
virtual void SAL_CALL removeMetadataFile(const css::uno::Reference< css::rdf::XURI > &i_xGraphName) override
virtual void SAL_CALL setCurrentController(const css::uno::Reference< css::frame::XController > &xController) override
virtual sal_Bool SAL_CALL isSetModifiedEnabled() override
virtual void SAL_CALL notifyDocumentEvent(const OUString &EventName, const css::uno::Reference< css::frame::XController2 > &ViewController, const css::uno::Any &Supplement) override
virtual OUString SAL_CALL getTitle() override
virtual css::uno::Reference< css::script::provider::XScriptProvider > SAL_CALL getScriptProvider() override
virtual void SAL_CALL removeModifyListener(const css::uno::Reference< css::util::XModifyListener > &xListener) override
virtual void SAL_CALL addModifyListener(const css::uno::Reference< css::util::XModifyListener > &xListener) override
virtual void SAL_CALL setModified(sal_Bool bModified) override
virtual sal_Bool SAL_CALL hasLocation() override
virtual sal_Bool SAL_CALL enableSetModified() override
virtual void SAL_CALL addModule(const OUString &LibraryName, const OUString &ModuleName, const OUString &Language, const OUString &Source) override
virtual css::uno::Reference< css::rdf::XMetadatable > SAL_CALL getElementByURI(const css::uno::Reference< css::rdf::XURI > &i_xURI) override
SAL_DLLPRIVATE SfxMedium * handleLoadError(ErrCode nError, SfxMedium *pMedium)
virtual css::uno::Reference< css::frame::XController > SAL_CALL getCurrentController() override
virtual css::uno::Reference< css::embed::XStorage > SAL_CALL getDocumentSubStorage(const OUString &aStorageName, sal_Int32 nMode) override
SAL_DLLPRIVATE css::uno::Reference< css::frame::XUntitledNumbers > impl_getUntitledHelper()
virtual css::awt::Size SAL_CALL getVisualAreaSize(sal_Int64 nAspect) override
SAL_DLLPRIVATE void ListenForStorage_Impl(const css::uno::Reference< css::embed::XStorage > &xStorage)
virtual void SAL_CALL setVisualAreaSize(sal_Int64 nAspect, const css::awt::Size &aSize) override
virtual css::uno::Reference< css::rdf::XMetadatable > SAL_CALL getElementByMetadataReference(const css::beans::StringPair &i_rReference) override
std::shared_ptr< IMPL_SfxBaseModel_DataContainer > m_pData
virtual css::uno::Reference< css::document::XUndoManager > SAL_CALL getUndoManager() override
virtual void SAL_CALL loadFromStorage(const css::uno::Reference< css::embed::XStorage > &xStorage, const css::uno::Sequence< css::beans::PropertyValue > &aMediaDescriptor) override
SAL_DLLPRIVATE void NotifyModifyListeners_Impl() const
virtual void SAL_CALL load(const css::uno::Sequence< css::beans::PropertyValue > &seqArguments) override
virtual OUString SAL_CALL getURL() override
virtual void SAL_CALL checkIn(sal_Bool bIsMajor, const OUString &rMessage) override
virtual sal_Bool SAL_CALL isVersionable() override
virtual void SAL_CALL addDocumentEventListener(const css::uno::Reference< css::document::XDocumentEventListener > &Listener) override
virtual sal_Bool SAL_CALL isDataFlavorSupported(const css::datatransfer::DataFlavor &aFlavor) override
virtual sal_Bool SAL_CALL disableSetModified() override
virtual void SAL_CALL releaseNumber(::sal_Int32 nNumber) override
virtual ~SfxBaseModel() override
virtual void SAL_CALL addStorageChangeListener(const css::uno::Reference< css::document::XStorageChangeListener > &xListener) override
virtual void SAL_CALL loadMetadataFromStorage(const css::uno::Reference< css::embed::XStorage > &i_xStorage, const css::uno::Reference< css::rdf::XURI > &i_xBaseURI, const css::uno::Reference< css::task::XInteractionHandler > &i_xHandler) override
void MethodEntryCheck(const bool i_mustBeInitialized) const
const bool m_bSupportEmbeddedScripts
virtual void SAL_CALL disconnectController(const css::uno::Reference< css::frame::XController > &xController) override
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &aListener) override
virtual OUString SAL_CALL getStringValue() override
virtual void SAL_CALL removeDocumentEventListener(const css::uno::Reference< css::document::XDocumentEventListener > &Listener) override
virtual void SAL_CALL createLibrary(const OUString &LibName, const OUString &Password, const OUString &ExternalSourceURL, const OUString &LinkTargetURL) override
virtual css::uno::Sequence< css::document::CmisProperty > SAL_CALL getCmisProperties() override
virtual void SAL_CALL setIdentifier(const OUString &sIdentifier) override
bool getBoolPropertyValue(const OUString &rName)
virtual void SAL_CALL setParent(const css::uno::Reference< css::uno::XInterface > &xParent) override
void SAL_CALL setViewData(const css::uno::Reference< css::container::XIndexAccess > &aData) override
virtual sal_Bool SAL_CALL hasControllersLocked() override
SfxObjectShell * GetObjectShell() const
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getArgs2(const css::uno::Sequence< OUString > &requestedArgs) override
virtual void SAL_CALL addPrintJobListener(const css::uno::Reference< css::view::XPrintJobListener > &xListener) override
virtual css::uno::Reference< css::rdf::XRepository > SAL_CALL getRDFRepository() override
virtual void SAL_CALL switchToStorage(const css::uno::Reference< css::embed::XStorage > &xStorage) override
virtual css::uno::Reference< css::rdf::XURI > SAL_CALL addMetadataFile(const OUString &i_rFileName, const css::uno::Sequence< css::uno::Reference< css::rdf::XURI > > &i_rTypes) override
virtual void SAL_CALL storeMetadataToMedium(const css::uno::Sequence< css::beans::PropertyValue > &i_rMedium) override
virtual css::uno::Reference< css::frame::XController2 > SAL_CALL createViewController(const OUString &ViewName, const css::uno::Sequence< css::beans::PropertyValue > &Arguments, const css::uno::Reference< css::frame::XFrame > &Frame) override
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getPrinter() override
OUString const & getRuntimeUID() const
SAL_DLLPRIVATE void loadCmisProperties()
virtual void SAL_CALL storeToRecoveryFile(const OUString &i_TargetLocation, const css::uno::Sequence< css::beans::PropertyValue > &i_MediaDescriptor) override
virtual void SAL_CALL dispose() override
virtual sal_Int64 SAL_CALL getSomething(const css::uno::Sequence< sal_Int8 > &aIdentifier) override
virtual void SAL_CALL removeShapeEventListener(const css::uno::Reference< css::drawing::XShape > &xShape, const css::uno::Reference< css::document::XShapeEventListener > &xListener) override
virtual void SAL_CALL checkOut() override
virtual void SAL_CALL lockControllers() override
virtual void SAL_CALL setPrinter(const css::uno::Sequence< css::beans::PropertyValue > &seqPrinter) override
virtual sal_Bool SAL_CALL isModified() override
virtual css::uno::Reference< css::container::XNameReplace > SAL_CALL getEvents() override
virtual void SAL_CALL setArgs(const css::uno::Sequence< css::beans::PropertyValue > &aArgs) override
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL getControllers() override
void setGrabBagItem(const css::uno::Any &rVal)
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
give answer, if interface is supported @descr The interfaces are searched by type.
virtual sal_Bool SAL_CALL wasModifiedSinceLastSave() override
virtual void SAL_CALL removeCloseListener(const css::uno::Reference< css::util::XCloseListener > &xListener) override
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
get implementation id @descr This ID is necessary for UNO-caching.
virtual css::uno::Any SAL_CALL getTransferData(const css::datatransfer::DataFlavor &aFlavor) override
SAL_DLLPRIVATE bool impl_isDisposed() const
virtual void SAL_CALL removeStorageChangeListener(const css::uno::Reference< css::document::XStorageChangeListener > &xListener) override
virtual css::uno::Reference< css::document::XEmbeddedScripts > SAL_CALL getScriptContainer() override
const bool m_bSupportDocRecovery
bool hasEventListeners() const
returns true if someone added a XEventListener to this XEventBroadcaster
css::uno::Reference< css::container::XIndexAccess > SAL_CALL getViewData() override
virtual sal_Int32 SAL_CALL getMapUnit(sal_Int64 nAspect) override
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getArgs() override
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &aListener) override
virtual void SAL_CALL initNew() override
virtual void SAL_CALL removeTitleChangeListener(const css::uno::Reference< css::frame::XTitleChangeListener > &xListener) override
void HidePopups(bool bHide=true)
Definition: bindings.cxx:230
bool GetValue() const
void Broadcast(const SfxHint &rHint)
void SetDisableFlags(SfxDisableFlags nFlags)
Definition: dispatch.cxx:2078
const OUString & GetEventName() const
Definition: event.hxx:208
SfxEventHintId GetEventId() const
Definition: event.hxx:205
std::shared_ptr< const SfxFilter > GetFilter4FilterName(const OUString &rName, SfxFilterFlags nMust=SfxFilterFlags::NONE, SfxFilterFlags nDont=SFX_FILTER_NOTINSTALLED) const
Definition: fltfnc.cxx:112
std::shared_ptr< const SfxFilter > GetFilter4FilterName(const OUString &rName, SfxFilterFlags nMust=SfxFilterFlags::NONE, SfxFilterFlags nDont=SFX_FILTER_NOTINSTALLED) const
Definition: fltfnc.cxx:728
static SfxFrame * Create(const css::uno::Reference< css::frame::XFrame > &xFrame)
Definition: frame2.cxx:281
const css::uno::Reference< css::frame::XFrame > & GetFrameInterface() const
Definition: frame.cxx:515
SAL_DLLPRIVATE void PrepareForDoc_Impl(const SfxObjectShell &i_rDoc)
Definition: frame2.cxx:384
SAL_DLLPRIVATE void SetMenuBarOn_Impl(bool bOn)
Definition: frame2.cxx:355
SAL_DLLPRIVATE SfxWorkWindow * GetWorkWindow_Impl() const
Definition: frame.cxx:588
static SAL_WARN_UNUSED_RESULT SfxFrame * GetNext(SfxFrame &)
Definition: frame.cxx:711
bool IsInPlace() const
Definition: frame.cxx:657
static SAL_WARN_UNUSED_RESULT SfxFrame * GetFirst()
Definition: frame.cxx:706
vcl::Window & GetWindow() const
Definition: frame.hxx:85
SfxHintId GetId() const
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
void CloseStorage()
Definition: docfile.cxx:1923
const std::shared_ptr< const SfxFilter > & GetFilter() const
Definition: docfile.cxx:3111
void ResetError()
Definition: docfile.cxx:483
const INetURLObject & GetURLObject() const
Definition: docfile.cxx:3597
void UseInteractionHandler(bool)
Definition: docfile.cxx:3069
SfxItemSet & GetItemSet() const
Definition: docfile.cxx:3647
SAL_DLLPRIVATE void SetUpdatePickList(bool)
Definition: docfile.cxx:2919
SAL_DLLPRIVATE void CanDisposeStorage_Impl(bool bDisposeStorage)
Definition: docfile.cxx:1947
ErrCode GetError() const
Definition: docfile.hxx:147
const OUString & GetName() const
Definition: docfile.cxx:3592
void SetWarningError(ErrCode nWarningError)
Definition: docfile.cxx:507
static bool CallApproveHandler(const css::uno::Reference< css::task::XInteractionHandler > &xHandler, const css::uno::Any &rRequest, bool bAllowAbort)
Definition: docfile.cxx:4376
void SetFilter(const std::shared_ptr< const SfxFilter > &pFilter)
Does not take ownership of pFlt but pFlt needs to be around as long as the SfxMedium instance.
Definition: docfile.cxx:3106
bool IsReadOnly() const
Definition: docfile.cxx:3799
css::uno::Reference< css::task::XInteractionHandler > GetInteractionHandler(bool bGetAlways=false)
Definition: docfile.cxx:3076
virtual ~SfxModelSubComponent()
SfxSlotPool * GetSlotPool() const
Definition: module.cxx:102
SfxModule * GetModule() const
Definition: docfac.cxx:123
SfxFilterContainer * GetFilterContainer() const
Definition: docfac.cxx:66
SfxViewFactory * GetViewFactoryByViewName(std::u16string_view i_rViewName) const
returns the view factory whose GetAPIViewName or GetLegacyViewName delivers the requested logical nam...
Definition: docfac.cxx:339
SfxViewFactory & GetViewFactory(sal_uInt16 i=0) const
Definition: docfac.cxx:117
sal_uInt16 GetViewFactoryCount() const
Definition: docfac.cxx:111
SAL_DLLPRIVATE void BreakMacroSign_Impl(bool bBreakMacroSing)
Definition: objmisc.cxx:938
MapUnit GetMapUnit() const
Definition: objembed.cxx:109
BasicManager * GetBasicManager() const
Definition: objxtor.cxx:644
virtual void SetVisArea(const tools::Rectangle &rVisArea)
Definition: objembed.cxx:81
virtual SfxObjectFactory & GetFactory() const =0
SfxMedium * GetMedium() const
Definition: objsh.hxx:261
static SAL_DLLPRIVATE bool UseInteractionToHandleError(const css::uno::Reference< css::task::XInteractionHandler > &xHandler, ErrCode nError)
Definition: objmisc.cxx:1694
void SetMacroCallsSeenWhileLoading()
Definition: objstor.cxx:3780
SfxItemPool & GetPool() const
Each Subclass of SfxShell must reference a pool.
Definition: shell.hxx:511
SfxViewShell * GetViewShell() const
Returns the SfxViewShell in which they are located in the subshells.
Definition: shell.cxx:129
const SfxSlot * GetSlot(sal_uInt16 nId) const
Definition: msgpool.cxx:155
Definition: msg.hxx:184
SFX2_DLLPUBLIC OUString GetCommand() const
Definition: msg.cxx:46
const css::uno::Any & GetValue() const
Definition: frame.hxx:175
const css::uno::Reference< css::frame::XController2 > & GetController() const
Definition: event.hxx:231
SfxViewShell * CreateInstance(SfxViewFrame &rViewFrame, SfxViewShell *pOldSh)
Definition: viewfac.cxx:24
OUString GetAPIViewName() const
returns an API-compatible view name.
Definition: viewfac.cxx:34
SfxInterfaceId GetOrdinal() const
Definition: viewfac.hxx:40
SAL_DLLPRIVATE const SvBorder & GetBorderPixelImpl() const
Definition: viewfrm.cxx:1259
SAL_DLLPRIVATE void UpdateDocument_Impl()
Definition: viewfrm.cxx:3573
static SAL_WARN_UNUSED_RESULT SfxViewFrame * Current()
Definition: viewfrm.cxx:1975
vcl::Window & GetWindow() const
Definition: viewfrm.cxx:2792
SAL_DLLPRIVATE void SetViewShell_Impl(SfxViewShell *pVSh)
Definition: viewfrm.cxx:2074
SfxBindings & GetBindings()
Definition: viewfrm.hxx:110
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetNext(const SfxViewFrame &rPrev, const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
Definition: viewfrm.cxx:2006
SfxDispatcher * GetDispatcher()
Definition: viewfrm.hxx:109
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetFirst(const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
Definition: viewfrm.cxx:1983
SfxFrame & GetFrame() const
Definition: viewfrm.cxx:2782
virtual SfxObjectShell * GetObjectShell() override
Definition: viewfrm.cxx:2218
static SAL_WARN_UNUSED_RESULT SfxViewFrame * Get(const css::uno::Reference< css::frame::XController > &i_rController, const SfxObjectShell *i_pDoc)
Definition: viewfrm.cxx:2356
SAL_DLLPRIVATE void ForceOuterResize_Impl()
Definition: viewfrm.cxx:2088
void UpdateTitle()
Definition: viewfrm2.cxx:76
SAL_DLLPRIVATE void SetCurViewId_Impl(const SfxInterfaceId i_nID)
Definition: viewfrm.cxx:2542
One SfxViewShell more or less represents one edit window for a document, there can be multiple ones f...
Definition: viewsh.hxx:165
css::uno::Reference< css::frame::XController > GetController() const
Definition: viewsh.cxx:2662
virtual void libreOfficeKitViewCallback(int nType, const OString &pPayload) const override
Invokes the registered callback, if there are any.
Definition: viewsh.cxx:2244
static SAL_WARN_UNUSED_RESULT SfxViewShell * Get(const css::uno::Reference< css::frame::XController > &i_rController)
Definition: viewsh.cxx:1855
SAL_DLLPRIVATE SfxBaseController * GetBaseController_Impl() const
Definition: viewsh.cxx:2667
void SetController(SfxBaseController *pController)
Definition: viewsh.cxx:2651
static SAL_WARN_UNUSED_RESULT SfxViewShell * Current()
Definition: viewsh.cxx:1848
vcl::Window * GetWindow() const
Definition: viewsh.hxx:272
void MakeVisible_Impl(bool)
Definition: workwin.cxx:1482
void Lock_Impl(bool)
Definition: workwin.cxx:533
constexpr tools::Long Height() const
tools::Long AdjustHeight(tools::Long n)
tools::Long AdjustWidth(tools::Long n)
constexpr tools::Long Width() const
tools::Long & Left()
tools::Long & Top()
tools::Long & Right()
tools::Long & Bottom()
const void * GetData()
virtual sal_uInt64 TellEnd() override
sal_uInt64 Tell() const
void SetVersion(sal_Int32 n)
SvStream & Write(const GDIMetaFile &rMetaFile)
static sal_Int32 VCL2UnoEmbedMapUnit(MapUnit nVCLMapUnit)
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
bool has(const OUString &_rValueName) const
bool put(const OUString &_rValueName, const VALUE_TYPE &_rValue)
css::uno::Sequence< css::beans::PropertyValue > getPropertyValues() const
VALUE_TYPE getOrDefault(const OUString &_rValueName, const VALUE_TYPE &_rDefault) const
void notifyEach(void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event)
css::uno::XInterface * next()
static css::uno::Sequence< css::beans::NamedValue > CreatePackageEncryptionData(std::u16string_view aPassword)
iterator erase(iterator it)
TValueType getUnpackedValueOrDefault(const OUString &sKey, const TValueType &aDefault) const
css::uno::Sequence< css::beans::PropertyValue > getAsConstPropertyValueList() const
css::uno::Type const & get()
callback for the DocumentStorageModifyListener class
a class which, in its dtor, cleans up various objects (well, at the moment only the frame) collected ...
void takeFrameOwnership(SfxFrame *i_pFrame)
constexpr tools::Long GetWidth() const
constexpr tools::Long Top() const
void SetSize(const Size &)
constexpr tools::Long Right() const
constexpr bool IsWidthEmpty() const
constexpr tools::Long GetHeight() const
constexpr bool IsHeightEmpty() const
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
bool is() const
css::uno::Any getPropertyValue(const OUString &rPropertyName)
css::uno::Reference< css::beans::XPropertySetInfo > getProperties()
css::uno::Any executeCommand(const OUString &rCommandName, const css::uno::Any &rCommandArgument)
void EnableKillingFile(bool bEnable=true)
SvStream * GetStream(StreamMode eMode)
OUString const & GetURL() const
Point LogicToPixel(const Point &rLogicPt) const
void Disable(bool bChild=true)
void Enable(bool bEnable=true, bool bChild=true)
void SetBorderStyle(WindowBorderStyle nBorderStyle)
bool IsEnabled() const
int nCount
#define DBG_ASSERT(sCon, aError)
const ContainerEvent & m_rEvent
ContainerApprovalMethod m_pMethod
#define ENSURE_OR_THROW(c, m)
#define DBG_UNHANDLED_EXCEPTION(...)
Reference< frame::XModel > m_xModel
float u
float x
#define ERRCODE_IO_ABORT
#define ERRCODE_IO_CANTREAD
#define ERRCODE_IO_CANTCREATE
#define ERRCODE_IO_GENERAL
#define ERRCODE_IO_BROKENPACKAGE
#define ERRCODE_IO_CANTWRITE
#define ERRCODE_ABORT
#define ERRCODE_NONE
#define SOFFICE_FILEFORMAT_CURRENT
FmFilterData * m_pData
OUString sName
std::mutex m_aMutex
sal_Int32 nIndex
OUString aName
uno_Any a
Sequence< sal_Int8 > aSeq
Definition: lnkbase2.cxx:83
DdeData aData
Definition: lnkbase2.cxx:82
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
MapUnit
std::unique_ptr< sal_Int32[]> pData
@ Exception
sal_Int64 getSomething_cast(void *p)
Reference< XComponentContext > getProcessComponentContext()
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
Any SAL_CALL getCaughtException()
std::u16string_view getTitle(std::u16string_view aPath)
Value
Reference
int i
std::shared_ptr< T > make_shared(Args &&... args)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
enumrange< T >::Iterator begin(enumrange< T >)
end
ErrCode SetPassword(const std::shared_ptr< const SfxFilter > &pCurrentFilter, SfxItemSet *pSet, const OUString &rPasswordToOpen, std::u16string_view rPasswordToModify, bool bAllowPasswordReset)
UNOTOOLS_DLLPUBLIC css::uno::Reference< css::ucb::XCommandEnvironment > getDefaultCommandEnvironment()
auto syncExecute(FuncT const &func) -> decltype(func())
#define ASPECT_CONTENT
Definition: objsh.hxx:83
#define SFX_GLOBAL_CLASSID
Definition: objsh.hxx:808
bool GetEncryptionData_Impl(const SfxItemSet *pSet, uno::Sequence< beans::NamedValue > &o_rEncryptionData)
Definition: objstor.cxx:170
static void GetCommandFromSequence(OUString &rCommand, sal_Int32 &nIndex, const Sequence< beans::PropertyValue > &rSeqPropValue)
static void addTitle_Impl(Sequence< beans::PropertyValue > &rSeq, const OUString &rTitle)
static void ConvertSlotsToCommands(SfxObjectShell const *pDoc, Reference< container::XIndexContainer > const &rToolbarDefinition)
#define ERRCTX_SFX_SAVEASDOC
#define ERRCODE_SFX_SHARED_NOPASSWORDCHANGE
OUString SfxResId(TranslateId aId)
Definition: sfxresid.cxx:22
std::vector< Reference< frame::XController > > m_seqControllers
Reference< ui::XUIConfigurationManager2 > m_xUIConfigurationManager
Reference< container::XIndexAccess > m_contViewData
::rtl::Reference< ::sfx2::DocumentUndoManager > m_pDocumentUndoManager
Reference< rdf::XDocumentMetadataAccess > CreateDMAUninitialized()
Reference< container::XNameReplace > m_xEvents
Reference< rdf::XDocumentMetadataAccess > m_xDocumentMetadata
Reference< frame::XController > m_xCurrent
Reference< XInterface > m_xParent
std::optional< std::chrono::steady_clock::time_point > m_oDirtyTimestamp
Reference< view::XPrintable > m_xPrintable
Sequence< beans::PropertyValue > m_seqArguments
Reference< frame::XTitle > m_xTitleHelper
::rtl::Reference< ::sfx2::DocumentStorageModifyListener > m_pStorageModifyListen
IMPL_SfxBaseModel_DataContainer(::osl::Mutex &rMutex, SfxObjectShell *pObjectShell)
Reference< document::XDocumentProperties > m_xDocumentProperties
Reference< script::XStarBasicAccess > m_xStarBasicAccess
Reference< frame::XUntitledNumbers > m_xNumberedControllers
Sequence< document::CmisProperty > m_cmisProperties
comphelper::OMultiTypeInterfaceContainerHelper2 m_aInterfaceContainer
std::unordered_map< css::uno::Reference< css::drawing::XShape >, std::vector< css::uno::Reference< css::document::XShapeEventListener > > > maShapeListeners
virtual void storageIsModified() override
indicates the root or a sub storage of the document has been modified
void impl_setDocumentProperties(const Reference< document::XDocumentProperties > &)
std::shared_ptr< SfxGrabBagItem > m_xGrabBagItem
Reference< rdf::XDocumentMetadataAccess > GetDMA()
Reference< XController > xController
Reference< XFrame > xFrame
Reference< XModel > xModel
OUString aCommand
SvStream & WriteTransferableObjectDescriptor(SvStream &rOStm, const TransferableObjectDescriptor &rObjDesc)
unsigned char sal_Bool
signed char sal_Int8
OUString sId
const SvXMLTokenMapEntry aTypes[]
sal_Int32 nLength