summaryrefslogtreecommitdiff
path: root/embeddedobj
diff options
context:
space:
mode:
Diffstat (limited to 'embeddedobj')
-rw-r--r--embeddedobj/CppunitTest_embeddedobj_general.mk4
-rw-r--r--embeddedobj/CppunitTest_embeddedobj_msole.mk53
-rw-r--r--embeddedobj/Library_embobj.mk6
-rw-r--r--embeddedobj/Library_emboleobj.mk7
-rw-r--r--embeddedobj/Module_embeddedobj.mk6
-rw-r--r--embeddedobj/README1
-rw-r--r--embeddedobj/README.md3
-rw-r--r--embeddedobj/qa/cppunit/data/ole2.ole19
-rw-r--r--embeddedobj/qa/cppunit/data/ole2.pngbin0 -> 766 bytes
-rw-r--r--embeddedobj/qa/cppunit/data/reqif-ole2.xhtml5
-rw-r--r--embeddedobj/qa/cppunit/general.cxx58
-rw-r--r--embeddedobj/qa/cppunit/msole.cxx134
-rw-r--r--embeddedobj/source/commonembedding/embedobj.cxx163
-rw-r--r--embeddedobj/source/commonembedding/miscobj.cxx361
-rw-r--r--embeddedobj/source/commonembedding/persistence.cxx273
-rw-r--r--embeddedobj/source/commonembedding/specialobject.cxx32
-rw-r--r--embeddedobj/source/commonembedding/visobj.cxx8
-rw-r--r--embeddedobj/source/commonembedding/xfactory.cxx24
-rw-r--r--embeddedobj/source/general/docholder.cxx207
-rw-r--r--embeddedobj/source/general/dummyobject.cxx39
-rw-r--r--embeddedobj/source/general/intercept.cxx58
-rw-r--r--embeddedobj/source/general/xcreator.cxx36
-rw-r--r--embeddedobj/source/inc/commonembobj.hxx73
-rw-r--r--embeddedobj/source/inc/docholder.hxx7
-rw-r--r--embeddedobj/source/inc/dummyobject.hxx16
-rw-r--r--embeddedobj/source/inc/intercept.hxx11
-rw-r--r--embeddedobj/source/inc/oleembobj.hxx37
-rw-r--r--embeddedobj/source/inc/specialobject.hxx11
-rw-r--r--embeddedobj/source/inc/strings.hrc19
-rw-r--r--embeddedobj/source/msole/graphconvert.cxx17
-rw-r--r--embeddedobj/source/msole/olecomponent.cxx887
-rw-r--r--embeddedobj/source/msole/olecomponent.hxx20
-rw-r--r--embeddedobj/source/msole/oleembed.cxx121
-rw-r--r--embeddedobj/source/msole/olemisc.cxx71
-rw-r--r--embeddedobj/source/msole/olepersist.cxx128
-rw-r--r--embeddedobj/source/msole/olevisual.cxx14
-rw-r--r--embeddedobj/source/msole/ownview.cxx86
-rw-r--r--embeddedobj/source/msole/xdialogcreator.cxx68
-rw-r--r--embeddedobj/source/msole/xolefactory.cxx15
-rw-r--r--embeddedobj/test/mtexecutor/bitmapcreator.cxx9
-rw-r--r--embeddedobj/test/mtexecutor/mainthreadexecutor.cxx9
41 files changed, 1967 insertions, 1149 deletions
diff --git a/embeddedobj/CppunitTest_embeddedobj_general.mk b/embeddedobj/CppunitTest_embeddedobj_general.mk
index 32fea16fb2b2..6c4014e2fc89 100644
--- a/embeddedobj/CppunitTest_embeddedobj_general.mk
+++ b/embeddedobj/CppunitTest_embeddedobj_general.mk
@@ -22,10 +22,14 @@ $(eval $(call gb_CppunitTest_add_exception_objects,embeddedobj_general, \
$(eval $(call gb_CppunitTest_use_libraries,embeddedobj_general, \
comphelper \
cppu \
+ cppuhelper \
embobj \
sal \
+ subsequenttest \
test \
+ tl \
unotest \
+ utl \
))
$(eval $(call gb_CppunitTest_use_sdk_api,embeddedobj_general))
diff --git a/embeddedobj/CppunitTest_embeddedobj_msole.mk b/embeddedobj/CppunitTest_embeddedobj_msole.mk
new file mode 100644
index 000000000000..bdeda1ef98dd
--- /dev/null
+++ b/embeddedobj/CppunitTest_embeddedobj_msole.mk
@@ -0,0 +1,53 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,embeddedobj_msole))
+
+$(eval $(call gb_CppunitTest_use_externals,embeddedobj_msole,\
+ boost_headers \
+ libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,embeddedobj_msole, \
+ embeddedobj/qa/cppunit/msole \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,embeddedobj_msole, \
+ comphelper \
+ cppu \
+ embobj \
+ sal \
+ subsequenttest \
+ test \
+ unotest \
+ utl \
+ vcl \
+ tl \
+))
+
+$(eval $(call gb_CppunitTest_use_system_win32_libs,embeddedobj_msole,\
+ ole32 \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,embeddedobj_msole))
+
+$(eval $(call gb_CppunitTest_use_ure,embeddedobj_msole))
+$(eval $(call gb_CppunitTest_use_vcl,embeddedobj_msole))
+
+$(eval $(call gb_CppunitTest_use_rdb,embeddedobj_msole,services))
+
+$(eval $(call gb_CppunitTest_use_custom_headers,embeddedobj_msole,\
+ officecfg/registry \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,embeddedobj_msole))
+
+# vim: set noet sw=4 ts=4:
diff --git a/embeddedobj/Library_embobj.mk b/embeddedobj/Library_embobj.mk
index 000a710ac0f4..18cf55518d44 100644
--- a/embeddedobj/Library_embobj.mk
+++ b/embeddedobj/Library_embobj.mk
@@ -14,13 +14,17 @@ $(eval $(call gb_Library_use_custom_headers,embobj,\
officecfg/registry \
))
-$(eval $(call gb_Library_set_componentfile,embobj,embeddedobj/util/embobj))
+$(eval $(call gb_Library_set_componentfile,embobj,embeddedobj/util/embobj,services))
$(eval $(call gb_Library_set_include,embobj,\
-I$(SRCDIR)/embeddedobj/source/inc \
$$(INCLUDE) \
))
+$(eval $(call gb_Library_add_defs,embobj,\
+ -DEMBOBJ_DLLIMPLEMENTATION \
+))
+
$(eval $(call gb_Library_use_external,embobj,boost_headers))
$(eval $(call gb_Library_use_sdk_api,embobj))
diff --git a/embeddedobj/Library_emboleobj.mk b/embeddedobj/Library_emboleobj.mk
index 38472c5cbf89..661bd655358b 100644
--- a/embeddedobj/Library_emboleobj.mk
+++ b/embeddedobj/Library_emboleobj.mk
@@ -10,7 +10,11 @@
$(eval $(call gb_Library_Library,emboleobj))
-$(eval $(call gb_Library_set_componentfile,emboleobj,embeddedobj/source/msole/emboleobj$(if $(filter WNT,$(OS)),.windows)))
+$(eval $(call gb_Library_use_custom_headers,emboleobj,\
+ officecfg/registry \
+))
+
+$(eval $(call gb_Library_set_componentfile,emboleobj,embeddedobj/source/msole/emboleobj$(if $(filter WNT,$(OS)),.windows),services))
$(eval $(call gb_Library_set_include,emboleobj,\
-I$(SRCDIR)/embeddedobj/source/inc \
@@ -51,6 +55,7 @@ $(eval $(call gb_Library_use_system_win32_libs,emboleobj,\
gdi32 \
ole32 \
oleaut32 \
+ oledlg \
uuid \
))
diff --git a/embeddedobj/Module_embeddedobj.mk b/embeddedobj/Module_embeddedobj.mk
index 394112a13b7d..659b406b9ea9 100644
--- a/embeddedobj/Module_embeddedobj.mk
+++ b/embeddedobj/Module_embeddedobj.mk
@@ -21,4 +21,10 @@ $(eval $(call gb_Module_add_slowcheck_targets,embeddedobj,\
))
endif
+ifeq ($(OS),WNT)
+$(eval $(call gb_Module_add_slowcheck_targets,embeddedobj,\
+ CppunitTest_embeddedobj_msole \
+))
+endif
+
# vim: set noet sw=4 ts=4:
diff --git a/embeddedobj/README b/embeddedobj/README
deleted file mode 100644
index 3fe564abd6b3..000000000000
--- a/embeddedobj/README
+++ /dev/null
@@ -1 +0,0 @@
-Code for embedding objects into LibreOffice (reverse of embedserv module).
diff --git a/embeddedobj/README.md b/embeddedobj/README.md
new file mode 100644
index 000000000000..247ef1fda083
--- /dev/null
+++ b/embeddedobj/README.md
@@ -0,0 +1,3 @@
+# Embedding Objects Into LibreOffice
+
+Code for embedding objects into LibreOffice (reverse of `embedserv` module).
diff --git a/embeddedobj/qa/cppunit/data/ole2.ole b/embeddedobj/qa/cppunit/data/ole2.ole
new file mode 100644
index 000000000000..c0013db40113
--- /dev/null
+++ b/embeddedobj/qa/cppunit/data/ole2.ole
@@ -0,0 +1,19 @@
+{\object\objemb\objw240\objh240{\*\objclass PBrush}{\*\objdata 01050000020000000700000050427275736800000000000000000040030000
+424d36030000000000003600000028000000100000001000000001001800000000000003000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000001050000050000000d0000004d45544146494c455049435400a701000059feffffe40000000800a701a7010000
+0100090000036e00000000004500000000000400000003010800050000000b0200000000050000000c0211001100030000001e000400000007010400040000000701040045000000410b2000cc00100010000000000010001000000000002800000010000000100000000100010000000000000000000000000000000000
+000000000000000000000000ffffff00ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101040000002701ffff030000000000}{\result {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid793696
+{\*\shppict{\pict{\*\picprop\shplid1027{\sp{\sn shapeType}{\sv 75}}{\sp{\sn fFlipH}{\sv 0}}{\sp{\sn fFlipV}{\sv 0}}{\sp{\sn fLockAspectRatio}{\sv 1}}{\sp{\sn pictureGray}{\sv 0}}
+{\sp{\sn pictureBiLevel}{\sv 0}}{\sp{\sn pictureActive}{\sv 0}}{\sp{\sn fRecolorFillAsPicture}{\sv 0}}{\sp{\sn fUseShapeAnchor}{\sv 0}}{\sp{\sn fFilled}{\sv 0}}{\sp{\sn fHitTestFill}{\sv 1}}
+{\sp{\sn fillShape}{\sv 1}}{\sp{\sn fillUseRect}{\sv 0}}{\sp{\sn fNoFillHitTest}{\sv 0}}{\sp{\sn fLine}{\sv 0}}{\sp{\sn fPreferRelativeResize}{\sv 1}}{\sp{\sn fReallyHidden}{\sv 0}}
+{\sp{\sn fScriptAnchor}{\sv 0}}{\sp{\sn fFakeMaster}{\sv 0}}{\sp{\sn fCameFromImgDummy}{\sv 0}}{\sp{\sn fLayoutInCell}{\sv 1}}}\picscalex100\picscaley100\piccropl0\piccropr0\piccropt0\piccropb0
+\picw423\pich423\picwgoal240\pichgoal240\pngblip\bliptag602933164{\*\blipuid 23f007ac3ac2aed53753eaea27c13e03}89504e470d0a1a0a0000000d494844520000001000000010080200000090916836000000017352474200aece1ce9000000097048597300000ec700000ec70138
+922f760000001f49444154384f63fcffff3f0329808914c520b5a31a8809b1d1501a1ca10400556d031d6ec895ac0000000049454e44ae426082}}{\nonshppict{\pict\picscalex100\picscaley100\piccropl0\piccropr0\piccropt0\piccropb0
+\picw423\pich423\picwgoal240\pichgoal240\wmetafile8\bliptag602933164\blipupi96{\*\blipuid 23f007ac3ac2aed53753eaea27c13e03}0100090000036e00000000004500000000000400000003010800050000000b0200000000050000000c0211001100030000001e00040000000701040004000000
+0701040045000000410b2000cc001000100000000000100010000000000028000000100000001000000001000100000000000000000000000000000000000000
+00000000000000000000ffffff00ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101ffff0101040000002701ffff030000000000}}}}}
diff --git a/embeddedobj/qa/cppunit/data/ole2.png b/embeddedobj/qa/cppunit/data/ole2.png
new file mode 100644
index 000000000000..fdad35484e7c
--- /dev/null
+++ b/embeddedobj/qa/cppunit/data/ole2.png
Binary files differ
diff --git a/embeddedobj/qa/cppunit/data/reqif-ole2.xhtml b/embeddedobj/qa/cppunit/data/reqif-ole2.xhtml
new file mode 100644
index 000000000000..716ecd1bda63
--- /dev/null
+++ b/embeddedobj/qa/cppunit/data/reqif-ole2.xhtml
@@ -0,0 +1,5 @@
+<reqif-xhtml:div>
+ <reqif-xhtml:object data="ole2.ole" type="text/rtf">
+ <reqif-xhtml:object data="ole2.png" type="image/png">OLE Object</reqif-xhtml:object>
+ </reqif-xhtml:object>
+</reqif-xhtml:div>
diff --git a/embeddedobj/qa/cppunit/general.cxx b/embeddedobj/qa/cppunit/general.cxx
index 815656519c83..02ff289342a6 100644
--- a/embeddedobj/qa/cppunit/general.cxx
+++ b/embeddedobj/qa/cppunit/general.cxx
@@ -7,10 +7,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-#include <test/bootstrapfixture.hxx>
-#include <unotest/macros_test.hxx>
+#include <test/unoapi_test.hxx>
-#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <comphelper/embeddedobjectcontainer.hxx>
@@ -21,34 +19,20 @@
using namespace ::com::sun::star;
-/// embeddedobj general tests.
-class EmbeddedobjGeneralTest : public test::BootstrapFixture, public unotest::MacrosTest
+namespace
+{
+/// Covers embeddedobj/source/general/ fixes.
+class Test : public UnoApiTest
{
-private:
- uno::Reference<lang::XComponent> mxComponent;
-
public:
- void setUp() override;
- void tearDown() override;
- uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
+ Test()
+ : UnoApiTest("/embeddedobj/qa/cppunit/data/")
+ {
+ }
};
-
-void EmbeddedobjGeneralTest::setUp()
-{
- test::BootstrapFixture::setUp();
-
- mxDesktop.set(frame::Desktop::create(mxComponentContext));
-}
-
-void EmbeddedobjGeneralTest::tearDown()
-{
- if (mxComponent.is())
- mxComponent->dispose();
-
- test::BootstrapFixture::tearDown();
}
-CPPUNIT_TEST_FIXTURE(EmbeddedobjGeneralTest, testInsertFileConfig)
+CPPUNIT_TEST_FIXTURE(Test, testInsertFileConfig)
{
// Explicitly disable Word->Writer mapping for this test.
std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
@@ -62,14 +46,12 @@ CPPUNIT_TEST_FIXTURE(EmbeddedobjGeneralTest, testInsertFileConfig)
pBatchReset);
pBatchReset->commit();
});
- getComponent().set(
- loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument"));
+ mxComponent.set(loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument"));
// Insert a file as an embedded object.
uno::Reference<embed::XStorage> xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
comphelper::EmbeddedObjectContainer aContainer(xStorage);
- OUString aFileName
- = m_directories.getURLFromSrc(u"embeddedobj/qa/cppunit/data/insert-file-config.doc");
+ OUString aFileName = createFileURL(u"insert-file-config.doc");
uno::Sequence<beans::PropertyValue> aMedium{ comphelper::makePropertyValue("URL", aFileName) };
OUString aName("Object 1");
uno::Reference<embed::XEmbeddedObject> xObject
@@ -82,7 +64,7 @@ CPPUNIT_TEST_FIXTURE(EmbeddedobjGeneralTest, testInsertFileConfig)
CPPUNIT_ASSERT(!xObject.is());
}
-CPPUNIT_TEST_FIXTURE(EmbeddedobjGeneralTest, testInsertFileConfigVsdx)
+CPPUNIT_TEST_FIXTURE(Test, testInsertFileConfigVsdx)
{
// Explicitly disable Word->Writer mapping for this test.
std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
@@ -95,14 +77,12 @@ CPPUNIT_TEST_FIXTURE(EmbeddedobjGeneralTest, testInsertFileConfigVsdx)
officecfg::Office::Common::Filter::Microsoft::Import::VisioToDraw::set(true, pBatchReset);
pBatchReset->commit();
});
- getComponent().set(
- loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument"));
+ mxComponent.set(loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument"));
// Insert a file as an embedded object.
uno::Reference<embed::XStorage> xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
comphelper::EmbeddedObjectContainer aContainer(xStorage);
- OUString aFileName
- = m_directories.getURLFromSrc(u"embeddedobj/qa/cppunit/data/insert-file-config.vsdx");
+ OUString aFileName = createFileURL(u"insert-file-config.vsdx");
uno::Sequence<beans::PropertyValue> aMedium{ comphelper::makePropertyValue("URL", aFileName) };
OUString aName("Object 1");
uno::Reference<embed::XEmbeddedObject> xObject
@@ -115,7 +95,7 @@ CPPUNIT_TEST_FIXTURE(EmbeddedobjGeneralTest, testInsertFileConfigVsdx)
CPPUNIT_ASSERT(!xObject.is());
}
-CPPUNIT_TEST_FIXTURE(EmbeddedobjGeneralTest, testInsertFileConfigPdf)
+CPPUNIT_TEST_FIXTURE(Test, testInsertFileConfigPdf)
{
// Explicitly disable Word->Writer mapping for this test.
std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
@@ -128,14 +108,12 @@ CPPUNIT_TEST_FIXTURE(EmbeddedobjGeneralTest, testInsertFileConfigPdf)
officecfg::Office::Common::Filter::Adobe::Import::PDFToDraw::set(true, pBatchReset);
pBatchReset->commit();
});
- getComponent().set(
- loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument"));
+ mxComponent.set(loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument"));
// Insert a PDF file as an embedded object.
uno::Reference<embed::XStorage> xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
comphelper::EmbeddedObjectContainer aContainer(xStorage);
- OUString aFileName
- = m_directories.getURLFromSrc(u"embeddedobj/qa/cppunit/data/insert-file-config.pdf");
+ OUString aFileName = createFileURL(u"insert-file-config.pdf");
uno::Sequence<beans::PropertyValue> aMedium{ comphelper::makePropertyValue("URL", aFileName) };
OUString aName("Object 1");
uno::Reference<embed::XEmbeddedObject> xObject
diff --git a/embeddedobj/qa/cppunit/msole.cxx b/embeddedobj/qa/cppunit/msole.cxx
new file mode 100644
index 000000000000..6bd849584a4a
--- /dev/null
+++ b/embeddedobj/qa/cppunit/msole.cxx
@@ -0,0 +1,134 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/unoapixml_test.hxx>
+
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+
+#include <comphelper/embeddedobjectcontainer.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/scopeguard.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <unotools/tempfile.hxx>
+#include <osl/thread.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/debug.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <vcl/outdev.hxx>
+
+#ifdef _WIN32
+#include <systools/win32/comtools.hxx>
+#endif
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Covers embeddedobj/source/msole/ fixes.
+class Test : public UnoApiXmlTest
+{
+public:
+ Test()
+ : UnoApiXmlTest("/embeddedobj/qa/cppunit/data/")
+ {
+ }
+};
+
+bool IsPaintClassNotRegistered()
+{
+#ifdef _WIN32
+ sal::systools::CoInitializeGuard g(0);
+ // Check if MS Paint's {0003000A-0000-0000-C000-000000000046} is registered
+ CLSID clsidPaint{ 0x0003000A, 0000, 0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
+ LPOLESTR pProgId = nullptr;
+ if (ProgIDFromCLSID(clsidPaint, &pProgId) == REGDB_E_CLASSNOTREG)
+ return true;
+ CoTaskMemFree(pProgId);
+#endif
+ return false;
+}
+}
+
+namespace
+{
+class OdtExportThread : public osl::Thread
+{
+ uno::Reference<lang::XComponent> mxComponent;
+ OUString maURL;
+
+public:
+ OdtExportThread(const uno::Reference<lang::XComponent>& xComponent, const OUString& rURL);
+ virtual void SAL_CALL run() override;
+};
+
+OdtExportThread::OdtExportThread(const uno::Reference<lang::XComponent>& xComponent,
+ const OUString& rURL)
+ : mxComponent(xComponent)
+ , maURL(rURL)
+{
+}
+
+void OdtExportThread::run()
+{
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ uno::Sequence<beans::PropertyValue> aStoreProperties = {
+ comphelper::makePropertyValue("FilterName", OUString("writer8")),
+ };
+ xStorable->storeToURL(maURL, aStoreProperties);
+}
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testSaveOnThread)
+{
+ // Given an embedded object which hosts mspaint data:
+ if (Application::GetDefaultDevice()->GetDPIX() != 96)
+ {
+ return;
+ }
+
+ if (IsPaintClassNotRegistered())
+ return;
+
+ DBG_TESTSOLARMUTEX();
+ OUString aURL = createFileURL(u"reqif-ole2.xhtml");
+ uno::Sequence<beans::PropertyValue> aLoadProperties = {
+ comphelper::makePropertyValue("FilterName", OUString("HTML (StarWriter)")),
+ comphelper::makePropertyValue("FilterOptions", OUString("xhtmlns=reqif-xhtml")),
+ };
+ mxComponent = loadFromDesktop(aURL, "com.sun.star.text.TextDocument", aLoadProperties);
+
+ // When saving that document on a thread:
+ OdtExportThread aThread(mxComponent, maTempFile.GetURL());
+ aThread.create();
+ {
+ SolarMutexReleaser r;
+ while (aThread.isRunning())
+ {
+ SolarMutexGuard g;
+ Application::Reschedule(/*bHandleAllCurrentEvents=*/true);
+ }
+ }
+
+ // Then make sure its visible area's width is correct.
+ xmlDocUniquePtr pXmlDoc = parseExport("content.xml");
+ // 16 pixels, assuming 96 DPI.
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 0.1665in
+ // - Actual : 1.9685in
+ // i.e. we wrote a hardcoded 5cm width, not the real one.
+ assertXPath(pXmlDoc, "//style:graphic-properties", "visible-area-width", "0.1665in");
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/commonembedding/embedobj.cxx b/embeddedobj/source/commonembedding/embedobj.cxx
index dcba248ca4f7..61e5d1f39ef4 100644
--- a/embeddedobj/source/commonembedding/embedobj.cxx
+++ b/embeddedobj/source/commonembedding/embedobj.cxx
@@ -37,9 +37,10 @@
#include <com/sun/star/embed/EmbedMisc.hpp>
#include <cppuhelper/exc_hlp.hxx>
-#include <cppuhelper/interfacecontainer.hxx>
+#include <comphelper/multicontainer2.hxx>
#include <comphelper/lok.hxx>
#include <sal/log.hxx>
+#include <officecfg/Office/Common.hxx>
#include <vcl/svapp.hxx>
@@ -48,6 +49,7 @@
#include <commonembobj.hxx>
#include "embedobj.hxx"
#include <specialobject.hxx>
+#include <array>
using namespace ::com::sun::star;
@@ -71,6 +73,60 @@ awt::Rectangle GetRectangleInterception( const awt::Rectangle& aRect1, const awt
return aResult;
}
+namespace
+{
+ using IntermediateStatesMap = std::array<std::array<uno::Sequence< sal_Int32 >, NUM_SUPPORTED_STATES>, NUM_SUPPORTED_STATES>;
+ const IntermediateStatesMap & getIntermediateStatesMap()
+ {
+ static const IntermediateStatesMap map = [] () {
+ IntermediateStatesMap tmp;
+
+ // intermediate states
+ // In the following table the first index points to starting state,
+ // the second one to the target state, and the sequence referenced by
+ // first two indexes contains intermediate states, that should be
+ // passed by object to reach the target state.
+ // If the sequence is empty that means that indirect switch from start
+ // state to the target state is forbidden, only if direct switch is possible
+ // the state can be reached.
+
+ tmp[0][2] = { embed::EmbedStates::RUNNING };
+
+ tmp[0][3] = { embed::EmbedStates::RUNNING,
+ embed::EmbedStates::INPLACE_ACTIVE };
+
+ tmp[0][4] = {embed::EmbedStates::RUNNING};
+
+ tmp[1][3] = { embed::EmbedStates::INPLACE_ACTIVE };
+
+ tmp[2][0] = { embed::EmbedStates::RUNNING };
+
+ tmp[3][0] = { embed::EmbedStates::INPLACE_ACTIVE,
+ embed::EmbedStates::RUNNING };
+
+ tmp[3][1] = { embed::EmbedStates::INPLACE_ACTIVE };
+
+ tmp[4][0] = { embed::EmbedStates::RUNNING };
+
+ return tmp;
+ }();
+ return map;
+ }
+
+ // accepted states
+ const css::uno::Sequence< sal_Int32 > & getAcceptedStates()
+ {
+ static const css::uno::Sequence< sal_Int32 > states {
+ /* [0] */ embed::EmbedStates::LOADED,
+ /* [1] */ embed::EmbedStates::RUNNING,
+ /* [2] */ embed::EmbedStates::INPLACE_ACTIVE,
+ /* [3] */ embed::EmbedStates::UI_ACTIVE,
+ /* [4] */ embed::EmbedStates::ACTIVE };
+ assert(states.getLength() == NUM_SUPPORTED_STATES);
+ return states;
+ }
+
+}
sal_Int32 OCommonEmbeddedObject::ConvertVerbToState_Impl( sal_Int32 nVerb )
{
@@ -100,6 +156,12 @@ void OCommonEmbeddedObject::Deactivate()
{
try {
xClientSite->saveObject();
+
+ // tdf#141529 take note that an eventually used linked file
+ // got changed/saved/written and that we need to copy it back if the
+ // hosting file/document gets saved
+ if(m_aLinkTempFile.is())
+ m_bLinkTempFileChanged = true;
}
catch( const embed::ObjectSaveVetoException& )
{
@@ -123,13 +185,13 @@ void OCommonEmbeddedObject::StateChangeNotification_Impl( bool bBeforeChange, sa
if ( !m_pInterfaceContainer )
return;
- ::cppu::OInterfaceContainerHelper* pContainer = m_pInterfaceContainer->getContainer(
+ comphelper::OInterfaceContainerHelper2* pContainer = m_pInterfaceContainer->getContainer(
cppu::UnoType<embed::XStateChangeListener>::get());
if ( pContainer == nullptr )
return;
lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
- ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer);
// should be locked after the method is finished successfully
rGuard.clear();
@@ -155,6 +217,37 @@ void OCommonEmbeddedObject::StateChangeNotification_Impl( bool bBeforeChange, sa
rGuard.reset();
}
+void OCommonEmbeddedObject::SetInplaceActiveState()
+{
+ if ( !m_xClientSite.is() )
+ throw embed::WrongStateException( "client site not set, yet", *this );
+
+ uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY );
+ if ( !xInplaceClient.is() || !xInplaceClient->canInplaceActivate() )
+ throw embed::WrongStateException(); //TODO: can't activate inplace
+ xInplaceClient->activatingInplace();
+
+ uno::Reference< embed::XWindowSupplier > xClientWindowSupplier( xInplaceClient, uno::UNO_QUERY_THROW );
+
+ m_xClientWindow = xClientWindowSupplier->getWindow();
+ m_aOwnRectangle = xInplaceClient->getPlacement();
+ m_aClipRectangle = xInplaceClient->getClipRectangle();
+ awt::Rectangle aRectangleToShow = GetRectangleInterception( m_aOwnRectangle, m_aClipRectangle );
+
+ // create own window based on the client window
+ // place and resize the window according to the rectangles
+ uno::Reference< awt::XWindowPeer > xClientWindowPeer( m_xClientWindow, uno::UNO_QUERY_THROW );
+
+ // dispatch provider may not be provided
+ uno::Reference< frame::XDispatchProvider > xContainerDP = xInplaceClient->getInplaceDispatchProvider();
+ bool bOk = m_xDocHolder->ShowInplace( xClientWindowPeer, aRectangleToShow, xContainerDP );
+ m_nObjectState = embed::EmbedStates::INPLACE_ACTIVE;
+ if ( !bOk )
+ {
+ SwitchStateTo_Impl( embed::EmbedStates::RUNNING );
+ throw embed::WrongStateException(); //TODO: can't activate inplace
+ }
+}
void OCommonEmbeddedObject::SwitchStateTo_Impl( sal_Int32 nNextState )
{
@@ -168,7 +261,7 @@ void OCommonEmbeddedObject::SwitchStateTo_Impl( sal_Int32 nNextState )
// after the object reaches the running state the cloned size is not necessary any more
m_bHasClonedSize = false;
- if ( m_bIsLink )
+ if ( m_bIsLinkURL )
{
m_xDocHolder->SetComponent( LoadLink_Impl(), m_bReadOnly );
}
@@ -187,8 +280,8 @@ void OCommonEmbeddedObject::SwitchStateTo_Impl( sal_Int32 nNextState )
else
{
// objects without persistence will be initialized internally
- uno::Sequence < uno::Any > aArgs(1);
- aArgs[0] <<= uno::Reference < embed::XEmbeddedObject >( this );
+ uno::Sequence < uno::Any > aArgs{ uno::Any(
+ uno::Reference < embed::XEmbeddedObject >( this )) };
uno::Reference< util::XCloseable > xDocument(
m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( GetDocumentServiceName(), aArgs, m_xContext),
uno::UNO_QUERY );
@@ -228,34 +321,7 @@ void OCommonEmbeddedObject::SwitchStateTo_Impl( sal_Int32 nNextState )
{
if ( nNextState == embed::EmbedStates::INPLACE_ACTIVE )
{
- if ( !m_xClientSite.is() )
- throw embed::WrongStateException( "client site not set, yet", *this );
-
- uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY );
- if ( !xInplaceClient.is() || !xInplaceClient->canInplaceActivate() )
- throw embed::WrongStateException(); //TODO: can't activate inplace
- xInplaceClient->activatingInplace();
-
- uno::Reference< embed::XWindowSupplier > xClientWindowSupplier( xInplaceClient, uno::UNO_QUERY_THROW );
-
- m_xClientWindow = xClientWindowSupplier->getWindow();
- m_aOwnRectangle = xInplaceClient->getPlacement();
- m_aClipRectangle = xInplaceClient->getClipRectangle();
- awt::Rectangle aRectangleToShow = GetRectangleInterception( m_aOwnRectangle, m_aClipRectangle );
-
- // create own window based on the client window
- // place and resize the window according to the rectangles
- uno::Reference< awt::XWindowPeer > xClientWindowPeer( m_xClientWindow, uno::UNO_QUERY_THROW );
-
- // dispatch provider may not be provided
- uno::Reference< frame::XDispatchProvider > xContainerDP = xInplaceClient->getInplaceDispatchProvider();
- bool bOk = m_xDocHolder->ShowInplace( xClientWindowPeer, aRectangleToShow, xContainerDP );
- m_nObjectState = nNextState;
- if ( !bOk )
- {
- SwitchStateTo_Impl( embed::EmbedStates::RUNNING );
- throw embed::WrongStateException(); //TODO: can't activate inplace
- }
+ SetInplaceActiveState();
}
else if ( nNextState == embed::EmbedStates::ACTIVE )
{
@@ -383,32 +449,36 @@ void OCommonEmbeddedObject::SwitchStateTo_Impl( sal_Int32 nNextState )
uno::Sequence< sal_Int32 > const & OCommonEmbeddedObject::GetIntermediateStatesSequence_Impl( sal_Int32 nNewState )
{
sal_Int32 nCurInd = 0;
- for ( nCurInd = 0; nCurInd < m_aAcceptedStates.getLength(); nCurInd++ )
- if ( m_aAcceptedStates[nCurInd] == m_nObjectState )
+ auto & rAcceptedStates = getAcceptedStates();
+ for ( nCurInd = 0; nCurInd < rAcceptedStates.getLength(); nCurInd++ )
+ if ( rAcceptedStates[nCurInd] == m_nObjectState )
break;
- if ( nCurInd == m_aAcceptedStates.getLength() )
+ if ( nCurInd == rAcceptedStates.getLength() )
throw embed::WrongStateException( "The object is in unacceptable state!",
static_cast< ::cppu::OWeakObject* >(this) );
sal_Int32 nDestInd = 0;
- for ( nDestInd = 0; nDestInd < m_aAcceptedStates.getLength(); nDestInd++ )
- if ( m_aAcceptedStates[nDestInd] == nNewState )
+ for ( nDestInd = 0; nDestInd < rAcceptedStates.getLength(); nDestInd++ )
+ if ( rAcceptedStates[nDestInd] == nNewState )
break;
- if ( nDestInd == m_aAcceptedStates.getLength() )
+ if ( nDestInd == rAcceptedStates.getLength() )
throw embed::UnreachableStateException(
"The state either not reachable, or the object allows the state only as an intermediate one!",
static_cast< ::cppu::OWeakObject* >(this),
m_nObjectState,
nNewState );
- return m_pIntermediateStatesSeqs[nCurInd][nDestInd];
+ return getIntermediateStatesMap()[nCurInd][nDestInd];
}
void SAL_CALL OCommonEmbeddedObject::changeState( sal_Int32 nNewState )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get()
+ && nNewState != embed::EmbedStates::LOADED )
+ throw embed::UnreachableStateException();
::osl::ResettableMutexGuard aGuard( m_aMutex );
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
@@ -447,7 +517,7 @@ void SAL_CALL OCommonEmbeddedObject::changeState( sal_Int32 nNewState )
StateChangeNotification_Impl( true, nOldState, nNewState,aGuard );
try {
- for ( sal_Int32 state : aIntermediateStates )
+ for (sal_Int32 state : aIntermediateStates)
SwitchStateTo_Impl( state );
SwitchStateTo_Impl( nNewState );
@@ -480,7 +550,7 @@ uno::Sequence< sal_Int32 > SAL_CALL OCommonEmbeddedObject::getReachableStates()
throw embed::WrongStateException( "The object has no persistence!",
static_cast< ::cppu::OWeakObject* >(this) );
- return m_aAcceptedStates;
+ return getAcceptedStates();
}
@@ -633,6 +703,13 @@ void SAL_CALL OCommonEmbeddedObject::setContainerName( const OUString& sName )
m_aContainerName = sName;
}
+void OCommonEmbeddedObject::SetOleState(bool bIsOleUpdate)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ m_bOleUpdate = bIsOleUpdate;
+}
+
css::uno::Reference< css::uno::XInterface > SAL_CALL OCommonEmbeddedObject::getParent()
{
return m_xParent;
diff --git a/embeddedobj/source/commonembedding/miscobj.cxx b/embeddedobj/source/commonembedding/miscobj.cxx
index c62527f84398..f34a35a2c1ac 100644
--- a/embeddedobj/source/commonembedding/miscobj.cxx
+++ b/embeddedobj/source/commonembedding/miscobj.cxx
@@ -27,34 +27,53 @@
#include <com/sun/star/lang/NoSupportException.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
+#include <com/sun/star/io/TempFile.hpp>
+#include <comphelper/multicontainer2.hxx>
+#include <comphelper/storagehelper.hxx>
+
#include <cppuhelper/queryinterface.hxx>
-#include <cppuhelper/interfacecontainer.h>
#include <comphelper/mimeconfighelper.hxx>
+#include <utility>
+#include <vcl/weld.hxx>
+#include <vcl/stdtext.hxx>
+#include <strings.hrc>
+#include <osl/file.hxx>
+#include <comphelper/DirectoryHelper.hxx>
+
#include <vcl/svapp.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <comphelper/sequenceashashmap.hxx>
#include "persistence.hxx"
+#include <cassert>
+
using namespace ::com::sun::star;
-OCommonEmbeddedObject::OCommonEmbeddedObject( const uno::Reference< uno::XComponentContext >& rxContext,
+OCommonEmbeddedObject::OCommonEmbeddedObject( uno::Reference< uno::XComponentContext > xContext,
const uno::Sequence< beans::NamedValue >& aObjProps )
-: m_pInterfaceContainer( nullptr )
-, m_bReadOnly( false )
+: m_bReadOnly( false )
, m_bDisposed( false )
, m_bClosed( false )
, m_nObjectState( -1 )
, m_nTargetState( -1 )
, m_nUpdateMode ( embed::EmbedUpdateModes::ALWAYS_UPDATE )
-, m_xContext( rxContext )
+, m_xContext(std::move( xContext ))
, m_nMiscStatus( 0 )
, m_bEmbeddedScriptSupport( true )
, m_bDocumentRecoverySupport( true )
, m_bWaitSaveCompleted( false )
-, m_bIsLink( false )
+, m_bIsLinkURL( false )
+, m_bLinkTempFileChanged( false )
+, m_pLinkFile( )
+, m_bOleUpdate( false )
+, m_bInHndFunc( false )
, m_bLinkHasPassword( false )
+, m_aLinkTempFile( )
, m_bHasClonedSize( false )
, m_nClonedMapUnit( 0 )
{
@@ -63,24 +82,28 @@ OCommonEmbeddedObject::OCommonEmbeddedObject( const uno::Reference< uno::XCompon
OCommonEmbeddedObject::OCommonEmbeddedObject(
- const uno::Reference< uno::XComponentContext >& rxContext,
+ uno::Reference< uno::XComponentContext > xContext,
const uno::Sequence< beans::NamedValue >& aObjProps,
const uno::Sequence< beans::PropertyValue >& aMediaDescr,
const uno::Sequence< beans::PropertyValue >& aObjectDescr )
-: m_pInterfaceContainer( nullptr )
-, m_bReadOnly( false )
+: m_bReadOnly( false )
, m_bDisposed( false )
, m_bClosed( false )
, m_nObjectState( embed::EmbedStates::LOADED )
, m_nTargetState( -1 )
, m_nUpdateMode ( embed::EmbedUpdateModes::ALWAYS_UPDATE )
-, m_xContext( rxContext )
+, m_xContext(std::move( xContext ))
, m_nMiscStatus( 0 )
, m_bEmbeddedScriptSupport( true )
, m_bDocumentRecoverySupport( true )
, m_bWaitSaveCompleted( false )
-, m_bIsLink( true )
+, m_bIsLinkURL( true )
+, m_bLinkTempFileChanged( false )
+, m_pLinkFile( )
+, m_bOleUpdate( false )
+, m_bInHndFunc( false )
, m_bLinkHasPassword( false )
+, m_aLinkTempFile( )
, m_bHasClonedSize( false )
, m_nClonedMapUnit( 0 )
{
@@ -95,7 +118,7 @@ void OCommonEmbeddedObject::CommonInit_Impl( const uno::Sequence< beans::NamedVa
if ( !m_xContext.is() )
throw uno::RuntimeException();
- m_xDocHolder = new DocumentHolder( m_xContext, this );
+ m_xDocHolder = new embeddedobj::DocumentHolder( m_xContext, this );
// parse configuration entries
// TODO/LATER: in future UI names can be also provided here
@@ -116,53 +139,8 @@ void OCommonEmbeddedObject::CommonInit_Impl( const uno::Sequence< beans::NamedVa
if ( m_aClassID.getLength() != 16 /*|| !m_aDocServiceName.getLength()*/ )
throw uno::RuntimeException(); // something goes really wrong
- // accepted states
- m_aAcceptedStates.realloc( NUM_SUPPORTED_STATES );
-
- m_aAcceptedStates[0] = embed::EmbedStates::LOADED;
- m_aAcceptedStates[1] = embed::EmbedStates::RUNNING;
- m_aAcceptedStates[2] = embed::EmbedStates::INPLACE_ACTIVE;
- m_aAcceptedStates[3] = embed::EmbedStates::UI_ACTIVE;
- m_aAcceptedStates[4] = embed::EmbedStates::ACTIVE;
-
-
- // intermediate states
- // In the following table the first index points to starting state,
- // the second one to the target state, and the sequence referenced by
- // first two indexes contains intermediate states, that should be
- // passed by object to reach the target state.
- // If the sequence is empty that means that indirect switch from start
- // state to the target state is forbidden, only if direct switch is possible
- // the state can be reached.
-
- m_pIntermediateStatesSeqs[0][2].realloc( 1 );
- m_pIntermediateStatesSeqs[0][2][0] = embed::EmbedStates::RUNNING;
-
- m_pIntermediateStatesSeqs[0][3].realloc( 2 );
- m_pIntermediateStatesSeqs[0][3][0] = embed::EmbedStates::RUNNING;
- m_pIntermediateStatesSeqs[0][3][1] = embed::EmbedStates::INPLACE_ACTIVE;
-
- m_pIntermediateStatesSeqs[0][4].realloc( 1 );
- m_pIntermediateStatesSeqs[0][4][0] = embed::EmbedStates::RUNNING;
-
- m_pIntermediateStatesSeqs[1][3].realloc( 1 );
- m_pIntermediateStatesSeqs[1][3][0] = embed::EmbedStates::INPLACE_ACTIVE;
-
- m_pIntermediateStatesSeqs[2][0].realloc( 1 );
- m_pIntermediateStatesSeqs[2][0][0] = embed::EmbedStates::RUNNING;
-
- m_pIntermediateStatesSeqs[3][0].realloc( 2 );
- m_pIntermediateStatesSeqs[3][0][0] = embed::EmbedStates::INPLACE_ACTIVE;
- m_pIntermediateStatesSeqs[3][0][1] = embed::EmbedStates::RUNNING;
-
- m_pIntermediateStatesSeqs[3][1].realloc( 1 );
- m_pIntermediateStatesSeqs[3][1][0] = embed::EmbedStates::INPLACE_ACTIVE;
-
- m_pIntermediateStatesSeqs[4][0].realloc( 1 );
- m_pIntermediateStatesSeqs[4][0][0] = embed::EmbedStates::RUNNING;
-
// verbs table
- for ( auto const & verb : std::as_const(m_aObjectVerbs) )
+ for (auto const& verb : m_aObjectVerbs)
{
if ( verb.VerbID == embed::EmbedVerbs::MS_OLEVERB_PRIMARY )
{
@@ -215,7 +193,49 @@ void OCommonEmbeddedObject::LinkInit_Impl(
m_bReadOnly = aExportFilterName != m_aLinkFilterName;
}
- m_aDocMediaDescriptor = GetValuableArgs_Impl( aMediaDescr, false );
+ if(m_bIsLinkURL && !m_bReadOnly)
+ {
+ // tdf#141529 we have a linked OLE object. To prevent the original OLE
+ // data to be changed each time the OLE gets changed (at deactivate), copy it to
+ // a temporary file. That file will be changed on activated OLE changes then.
+ // The moment the original gets changed itself will now be associated with the
+ // file/document embedding the OLE being changed (see other additions to the
+ // task-ID above)
+ //
+ // open OLE original data as read input file
+ if ( comphelper::DirectoryHelper::fileExists( m_aLinkURL ) )
+ {
+ // create temporary file
+ m_aLinkTempFile = io::TempFile::create( m_xContext );
+
+ m_pLinkFile.reset( new FileChangedChecker( m_aLinkURL ) );
+ handleLinkedOLE( CopyBackToOLELink::CopyLinkToTempInit );
+ }
+ }
+
+ if(m_aLinkTempFile.is())
+ {
+ uno::Sequence< beans::PropertyValue > aAlternativeMediaDescr(aMediaDescr.getLength());
+ auto aAlternativeMediaDescrRange = asNonConstRange(aAlternativeMediaDescr);
+
+ for ( sal_Int32 a(0); a < aMediaDescr.getLength(); a++ )
+ {
+ const beans::PropertyValue& rSource(aMediaDescr[a]);
+ beans::PropertyValue& rDestination(aAlternativeMediaDescrRange[a]);
+
+ rDestination.Name = rSource.Name;
+ if(rSource.Name == "URL")
+ rDestination.Value <<= m_aLinkTempFile->getUri();
+ else
+ rDestination.Value = rSource.Value;
+ }
+
+ m_aDocMediaDescriptor = GetValuableArgs_Impl( aAlternativeMediaDescr, false );
+ }
+ else
+ {
+ m_aDocMediaDescriptor = GetValuableArgs_Impl( aMediaDescr, false );
+ }
uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor;
for ( beans::PropertyValue const & prop : aObjectDescr )
@@ -242,17 +262,14 @@ OCommonEmbeddedObject::~OCommonEmbeddedObject()
return;
osl_atomic_increment(&m_refCount);
- try {
- lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
-
- if ( m_pInterfaceContainer )
- {
+ if ( m_pInterfaceContainer )
+ {
+ try {
+ lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
m_pInterfaceContainer->disposeAndClear( aSource );
-
- delete m_pInterfaceContainer;
- m_pInterfaceContainer = nullptr;
- }
- } catch( const uno::Exception& ) {}
+ } catch( const uno::Exception& ) {}
+ m_pInterfaceContainer.reset();
+ }
try {
if ( m_xDocHolder.is() )
@@ -298,7 +315,7 @@ void OCommonEmbeddedObject::PostEvent_Impl( const OUString& aEventName )
if ( !m_pInterfaceContainer )
return;
- ::cppu::OInterfaceContainerHelper* pIC = m_pInterfaceContainer->getContainer(
+ comphelper::OInterfaceContainerHelper2* pIC = m_pInterfaceContainer->getContainer(
cppu::UnoType<document::XEventListener>::get());
if( !pIC )
return;
@@ -309,7 +326,7 @@ void OCommonEmbeddedObject::PostEvent_Impl( const OUString& aEventName )
// For now all the events are sent as object events
// aEvent.Source = ( xSource.is() ? xSource
// : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ) );
- ::cppu::OInterfaceIteratorHelper aIt( *pIC );
+ comphelper::OInterfaceIteratorHelper2 aIt( *pIC );
while( aIt.hasMoreElements() )
{
try
@@ -328,6 +345,123 @@ void OCommonEmbeddedObject::PostEvent_Impl( const OUString& aEventName )
}
+int OCommonEmbeddedObject::ShowMsgDialog(TranslateId Msg, const OUString& sFileName)
+{
+ std::locale aResLocale = Translate::Create( "emo" );
+ OUString aMsg = Translate::get( Msg, aResLocale );
+ OUString aBtn = Translate::get( BTN_OVERWRITE_TEXT, aResLocale );
+ OUString aTemp = sFileName;
+
+ osl::FileBase::getSystemPathFromFileURL( sFileName, aTemp );
+
+ aMsg = aMsg.replaceFirst( "%{filename}", aTemp );
+ weld::Window* pParent = Application::GetFrameWeld(m_xClientWindow);
+
+ std::unique_ptr<weld::MessageDialog> xQueryBox (Application::CreateMessageDialog( pParent,
+ VclMessageType::Warning, VclButtonsType::NONE, aMsg ) );
+ xQueryBox->add_button( aBtn, RET_YES );
+ xQueryBox->add_button( GetStandardText( StandardButtonType::Cancel ), RET_CANCEL );
+ xQueryBox->set_default_response( RET_CANCEL );
+
+ return xQueryBox->run();
+}
+
+
+void OCommonEmbeddedObject::handleLinkedOLE( CopyBackToOLELink eState )
+{
+ // do not refresh and autosave at the same time
+ // when refresh all, then get both Link and Ole Update, in this case ignore OLE-refresh
+ if ( m_bInHndFunc || m_bOleUpdate || !m_aLinkTempFile.is() )
+ return;
+
+ m_bInHndFunc = true;
+
+ bool bLnkFileChg = m_pLinkFile->hasFileChanged( false );
+ bool bTmpFileChg = m_bLinkTempFileChanged;
+
+
+ if ( eState != CopyBackToOLELink::CopyLinkToTempInit && !bLnkFileChg && !bTmpFileChg )
+ {
+ // no changes
+ eState = CopyBackToOLELink::NoCopy;
+ }
+ else if ( ( eState == CopyBackToOLELink::CopyTempToLink ) && bLnkFileChg && !bTmpFileChg )
+ {
+ // Save pressed, but the Link-file is changed, but not the temp-file
+ // in this case update the object with new link data
+ eState = CopyBackToOLELink::CopyLinkToTempRefresh;
+ }
+ else if ( ( eState == CopyBackToOLELink::CopyTempToLink ) && bLnkFileChg && bTmpFileChg )
+ {
+ // Save pressed, but the Link-file is changed, question to user for overwrite
+ if ( ShowMsgDialog(STR_OVERWRITE_LINK, m_aLinkURL) == RET_CANCEL )
+ eState = CopyBackToOLELink::NoCopy;
+ }
+ else if ( ( eState == CopyBackToOLELink::CopyLinkToTemp ) && bTmpFileChg )
+ {
+ // Refresh pressed, but the Temp-file is changed, question to user for overwrite
+ // it is not important it has bLnkFileChg, always overwrite the temp-file
+ if ( ShowMsgDialog( STR_OVERWRITE_TEMP, m_aLinkURL ) == RET_CANCEL )
+ eState = CopyBackToOLELink::NoCopy;
+ }
+
+ auto writeFile = [ this ]( const OUString& SrcName, const OUString& DesName )
+ {
+ uno::Reference < ucb::XSimpleFileAccess2 > xWriteAccess( ucb::SimpleFileAccess::create( m_xContext ) );
+ uno::Reference < ucb::XSimpleFileAccess > xReadAccess( ucb::SimpleFileAccess::create( m_xContext ) );
+
+ try
+ {
+ uno::Reference < io::XInputStream > xInStream( xReadAccess->openFileRead (SrcName ) );
+
+ // This is *needed* since OTempFileService calls OTempFileService::readBytes which
+ // ensures the SvStream mpStream gets/is opened, *but* also sets the mnCachedPos from
+ // OTempFileService which still points to the end-of-file (from write-cc'ing).
+ uno::Reference < io::XSeekable > xSeek( xInStream, uno::UNO_QUERY_THROW );
+ xSeek->seek( 0 );
+
+ xWriteAccess->writeFile( DesName, xInStream );
+ m_bLinkTempFileChanged = false;
+ // store the new timestamp
+ m_pLinkFile->hasFileChanged();
+ }
+ catch ( const uno::Exception& ex )
+ {
+ OUString aMsg;
+ osl::FileBase::getSystemPathFromFileURL( SrcName, aMsg );
+ aMsg = ex.Message + "\n\n" + aMsg;
+ weld::Window* pParent = Application::GetFrameWeld(m_xClientWindow);
+ std::unique_ptr<weld::MessageDialog> xQueryBox( Application::CreateMessageDialog( pParent,
+ VclMessageType::Error, VclButtonsType::Ok, aMsg ) );
+
+ xQueryBox->run();
+ }
+ };
+
+ switch ( eState )
+ {
+ case CopyBackToOLELink::NoCopy:
+ break;
+ case CopyBackToOLELink::CopyLinkToTemp: // copy Link-File to Temp-File (Refresh)
+ case CopyBackToOLELink::CopyLinkToTempInit: //create temp file
+ writeFile( m_aLinkURL, m_aLinkTempFile->getUri() );
+ break;
+ case CopyBackToOLELink::CopyTempToLink: // copy Temp-File to Link-File (Save)
+ // tdf#141529 if we have a changed copy of the original OLE data we now
+ // need to write it back 'over' the original OLE data
+ writeFile( m_aLinkTempFile->getUri(), m_aLinkURL );
+ break;
+ case CopyBackToOLELink::CopyLinkToTempRefresh: // need a Refresh not save
+ // do nothing
+ break;
+ default:
+ break;
+ }
+
+ m_bInHndFunc = false;
+}
+
+
uno::Any SAL_CALL OCommonEmbeddedObject::queryInterface( const uno::Type& rType )
{
uno::Any aReturn;
@@ -342,6 +476,21 @@ uno::Any SAL_CALL OCommonEmbeddedObject::queryInterface( const uno::Type& rType
void* p = static_cast<embed::XEmbedPersist2*>(this);
return uno::Any(&p, rType);
}
+ else if (rType == cppu::UnoType<lang::XServiceInfo>::get())
+ {
+ void* p = static_cast<lang::XServiceInfo*>(this);
+ return uno::Any(&p, rType);
+ }
+ else if (rType == cppu::UnoType<lang::XInitialization>::get())
+ {
+ void* p = static_cast<lang::XInitialization*>(this);
+ return uno::Any(&p, rType);
+ }
+ else if (rType == cppu::UnoType<lang::XTypeProvider>::get())
+ {
+ void* p = static_cast<lang::XTypeProvider*>(this);
+ return uno::Any(&p, rType);
+ }
else
aReturn = ::cppu::queryInterface(
rType,
@@ -367,14 +516,14 @@ uno::Any SAL_CALL OCommonEmbeddedObject::queryInterface( const uno::Type& rType
void SAL_CALL OCommonEmbeddedObject::acquire()
- throw()
+ noexcept
{
::cppu::OWeakObject::acquire() ;
}
void SAL_CALL OCommonEmbeddedObject::release()
- throw()
+ noexcept
{
::cppu::OWeakObject::release() ;
}
@@ -429,7 +578,7 @@ void SAL_CALL OCommonEmbeddedObject::addStateChangeListener( const uno::Referenc
throw lang::DisposedException(); // TODO
if ( !m_pInterfaceContainer )
- m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
+ m_pInterfaceContainer.reset(new comphelper::OMultiTypeInterfaceContainerHelper2( m_aMutex ));
m_pInterfaceContainer->addInterface( cppu::UnoType<embed::XStateChangeListener>::get(),
xListener );
@@ -457,11 +606,11 @@ void SAL_CALL OCommonEmbeddedObject::close( sal_Bool bDeliverOwnership )
if ( m_pInterfaceContainer )
{
- ::cppu::OInterfaceContainerHelper* pContainer =
+ comphelper::OInterfaceContainerHelper2* pContainer =
m_pInterfaceContainer->getContainer( cppu::UnoType<util::XCloseListener>::get());
if ( pContainer != nullptr )
{
- ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer);
while (pIterator.hasMoreElements())
{
try
@@ -479,7 +628,7 @@ void SAL_CALL OCommonEmbeddedObject::close( sal_Bool bDeliverOwnership )
cppu::UnoType<util::XCloseListener>::get());
if ( pContainer != nullptr )
{
- ::cppu::OInterfaceIteratorHelper pCloseIterator(*pContainer);
+ comphelper::OInterfaceIteratorHelper2 pCloseIterator(*pContainer);
while (pCloseIterator.hasMoreElements())
{
try
@@ -494,6 +643,7 @@ void SAL_CALL OCommonEmbeddedObject::close( sal_Bool bDeliverOwnership )
}
m_pInterfaceContainer->disposeAndClear( aSource );
+ m_pInterfaceContainer.reset();
}
m_bDisposed = true; // the object is disposed now for outside
@@ -548,7 +698,7 @@ void SAL_CALL OCommonEmbeddedObject::addCloseListener( const uno::Reference< uti
throw lang::DisposedException(); // TODO
if ( !m_pInterfaceContainer )
- m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper(m_aMutex);
+ m_pInterfaceContainer.reset(new comphelper::OMultiTypeInterfaceContainerHelper2(m_aMutex));
m_pInterfaceContainer->addInterface( cppu::UnoType<util::XCloseListener>::get(), xListener );
}
@@ -570,7 +720,7 @@ void SAL_CALL OCommonEmbeddedObject::addEventListener( const uno::Reference< doc
throw lang::DisposedException(); // TODO
if ( !m_pInterfaceContainer )
- m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper(m_aMutex);
+ m_pInterfaceContainer.reset(new comphelper::OMultiTypeInterfaceContainerHelper2(m_aMutex));
m_pInterfaceContainer->addInterface( cppu::UnoType<document::XEventListener>::get(), xListener );
}
@@ -584,4 +734,55 @@ void SAL_CALL OCommonEmbeddedObject::removeEventListener( const uno::Reference<
xListener );
}
+OUString SAL_CALL OCommonEmbeddedObject::getImplementationName()
+{
+ return "com.sun.star.comp.embed.OCommonEmbeddedObject";
+}
+
+sal_Bool SAL_CALL OCommonEmbeddedObject::supportsService(const OUString& ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+uno::Sequence<OUString> SAL_CALL OCommonEmbeddedObject::getSupportedServiceNames()
+{
+ return { "com.sun.star.comp.embed.OCommonEmbeddedObject" };
+}
+
+uno::Sequence<uno::Type> SAL_CALL OCommonEmbeddedObject::getTypes()
+{
+ static const uno::Sequence<uno::Type> aTypes{
+ cppu::UnoType<embed::XEmbeddedObject>::get(),
+ cppu::UnoType<embed::XEmbedPersist2>::get(),
+ cppu::UnoType<embed::XLinkageSupport>::get(),
+ cppu::UnoType<embed::XInplaceObject>::get(),
+ cppu::UnoType<container::XChild>::get(),
+ cppu::UnoType<chart2::XDefaultSizeTransmitter>::get(),
+ cppu::UnoType<lang::XServiceInfo>::get(),
+ cppu::UnoType<lang::XInitialization>::get(),
+ cppu::UnoType<lang::XTypeProvider>::get(),
+ };
+ return aTypes;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL OCommonEmbeddedObject::getImplementationId()
+{
+ return uno::Sequence<sal_Int8>();
+}
+
+void SAL_CALL OCommonEmbeddedObject::initialize(const uno::Sequence<uno::Any>& rArguments)
+{
+ if (!rArguments.hasElements())
+ {
+ return;
+ }
+
+ comphelper::SequenceAsHashMap aMap(rArguments[0]);
+ auto it = aMap.find("ReadOnly");
+ if (it != aMap.end())
+ {
+ it->second >>= m_bReadOnly;
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/commonembedding/persistence.cxx b/embeddedobj/source/commonembedding/persistence.cxx
index 6dda3c67830b..80fc047b1016 100644
--- a/embeddedobj/source/commonembedding/persistence.cxx
+++ b/embeddedobj/source/commonembedding/persistence.cxx
@@ -47,14 +47,19 @@
#include <com/sun/star/beans/IllegalTypeException.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
+
#include <comphelper/fileformat.h>
#include <comphelper/storagehelper.hxx>
#include <comphelper/mimeconfighelper.hxx>
#include <comphelper/namedvaluecollection.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/configuration.hxx>
+#include <unotools/mediadescriptor.hxx>
+#include <unotools/securityoptions.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <sal/log.hxx>
-#include <unotools/configmgr.hxx>
#include "persistence.hxx"
using namespace ::com::sun::star;
@@ -75,11 +80,11 @@ uno::Sequence< beans::PropertyValue > GetValuableArgs_Impl( const uno::Sequence<
|| prop.Name == "StartPresentation" || prop.Name == "RepairPackage"
|| prop.Name == "StatusIndicator" || prop.Name == "ViewData"
|| prop.Name == "ViewId" || prop.Name == "MacroExecutionMode"
- || prop.Name == "UpdateDocMode"
+ || prop.Name == "UpdateDocMode" || prop.Name == "Referer"
|| (prop.Name == "DocumentBaseURL" && bCanUseDocumentBaseURL) )
{
aResult.realloc( ++nResLen );
- aResult[nResLen-1] = prop;
+ aResult.getArray()[nResLen-1] = prop;
}
}
@@ -91,25 +96,23 @@ static uno::Sequence< beans::PropertyValue > addAsTemplate( const uno::Sequence<
{
bool bAsTemplateSet = false;
sal_Int32 nLength = aOrig.getLength();
- uno::Sequence< beans::PropertyValue > aResult( nLength );
+ uno::Sequence< beans::PropertyValue > aResult( aOrig );
for ( sal_Int32 nInd = 0; nInd < nLength; nInd++ )
{
- aResult[nInd].Name = aOrig[nInd].Name;
if ( aResult[nInd].Name == "AsTemplate" )
{
- aResult[nInd].Value <<= true;
+ aResult.getArray()[nInd].Value <<= true;
bAsTemplateSet = true;
}
- else
- aResult[nInd].Value = aOrig[nInd].Value;
}
if ( !bAsTemplateSet )
{
aResult.realloc( nLength + 1 );
- aResult[nLength].Name = "AsTemplate";
- aResult[nLength].Value <<= true;
+ auto pResult = aResult.getArray();
+ pResult[nLength].Name = "AsTemplate";
+ pResult[nLength].Value <<= true;
}
return aResult;
@@ -128,9 +131,8 @@ static uno::Reference< io::XInputStream > createTempInpStreamFromStor(
uno::Reference < lang::XSingleServiceFactory > xStorageFactory( embed::StorageFactory::create(xContext) );
- uno::Sequence< uno::Any > aArgs( 2 );
- aArgs[0] <<= xTempStream;
- aArgs[1] <<= embed::ElementModes::READWRITE;
+ uno::Sequence< uno::Any > aArgs{ uno::Any(xTempStream),
+ uno::Any(embed::ElementModes::READWRITE) };
uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArgs ),
uno::UNO_QUERY_THROW );
@@ -176,7 +178,7 @@ static void TransferMediaType( const uno::Reference< embed::XStorage >& i_rSourc
{
const uno::Reference< beans::XPropertySet > xSourceProps( i_rSource, uno::UNO_QUERY_THROW );
const uno::Reference< beans::XPropertySet > xTargetProps( i_rTarget, uno::UNO_QUERY_THROW );
- const OUString sMediaTypePropName( "MediaType" );
+ static constexpr OUString sMediaTypePropName( u"MediaType"_ustr );
xTargetProps->setPropertyValue( sMediaTypePropName, xSourceProps->getPropertyValue( sMediaTypePropName ) );
}
catch( const uno::Exception& )
@@ -189,10 +191,13 @@ static void TransferMediaType( const uno::Reference< embed::XStorage >& i_rSourc
static uno::Reference< util::XCloseable > CreateDocument( const uno::Reference< uno::XComponentContext >& _rxContext,
const OUString& _rDocumentServiceName, bool _bEmbeddedScriptSupport, const bool i_bDocumentRecoverySupport )
{
+ static constexpr OUStringLiteral sEmbeddedObject = u"EmbeddedObject";
+ static constexpr OUStringLiteral sEmbeddedScriptSupport = u"EmbeddedScriptSupport";
+ static constexpr OUStringLiteral sDocumentRecoverySupport = u"DocumentRecoverySupport";
::comphelper::NamedValueCollection aArguments;
- aArguments.put( "EmbeddedObject", true );
- aArguments.put( "EmbeddedScriptSupport", _bEmbeddedScriptSupport );
- aArguments.put( "DocumentRecoverySupport", i_bDocumentRecoverySupport );
+ aArguments.put( sEmbeddedObject, true );
+ aArguments.put( sEmbeddedScriptSupport, _bEmbeddedScriptSupport );
+ aArguments.put( sDocumentRecoverySupport, i_bDocumentRecoverySupport );
uno::Reference< uno::XInterface > xDocument;
try
@@ -220,9 +225,7 @@ static void SetDocToEmbedded( const uno::Reference< frame::XModel >& rDocument,
if (!rDocument.is())
return;
- uno::Sequence< beans::PropertyValue > aSeq( 1 );
- aSeq[0].Name = "SetEmbedded";
- aSeq[0].Value <<= true;
+ uno::Sequence< beans::PropertyValue > aSeq{ comphelper::makePropertyValue("SetEmbedded", true) };
rDocument->attachResource( OUString(), aSeq );
if ( !aModuleName.isEmpty() )
@@ -254,7 +257,7 @@ void OCommonEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::X
m_aEntryName = aNewName;
// the linked document should not be switched
- if ( !m_bIsLink )
+ if ( !m_bIsLinkURL )
{
uno::Reference< document::XStorageBasedDocument > xDoc( m_xDocHolder->GetComponent(), uno::UNO_QUERY );
if ( xDoc.is() )
@@ -359,36 +362,84 @@ uno::Reference< util::XCloseable > OCommonEmbeddedObject::InitNewDocument_Impl()
return xDocument;
}
+bool OCommonEmbeddedObject::getAllowLinkUpdate() const
+{
+ // assume we can update if we can't determine a parent
+ bool bAllowLinkUpdate(true);
+
+ try
+ {
+ uno::Reference<container::XChild> xParent(m_xParent, uno::UNO_QUERY);
+ while (xParent)
+ {
+ uno::Reference<container::XChild> xGrandParent(xParent->getParent(), uno::UNO_QUERY);
+ if (!xGrandParent)
+ break;
+ xParent = xGrandParent;
+ }
+
+ uno::Reference<beans::XPropertySet> xPropSet(xParent, uno::UNO_QUERY);
+ if (xPropSet.is())
+ {
+ uno::Any aAny = xPropSet->getPropertyValue("AllowLinkUpdate");
+ aAny >>= bAllowLinkUpdate;
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ }
+
+ SAL_WARN_IF(!bAllowLinkUpdate, "embeddedobj.common", "getAllowLinkUpdate is false");
+
+ return bAllowLinkUpdate;
+}
uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadLink_Impl()
{
- uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xContext, GetDocumentServiceName(),
- m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );
+ if (!getAllowLinkUpdate())
+ return nullptr;
- uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY_THROW );
+ sal_Int32 nLen = m_bLinkHasPassword ? 3 : 2;
+ uno::Sequence< beans::PropertyValue > aArgs( m_aDocMediaDescriptor.getLength() + nLen );
+ auto pArgs = aArgs.getArray();
+
+ pArgs[0].Name = "URL";
+ if(m_aLinkTempFile.is())
+ pArgs[0].Value <<= m_aLinkTempFile->getUri();
+ else
+ pArgs[0].Value <<= m_aLinkURL;
+
+ pArgs[1].Name = "FilterName";
+ pArgs[1].Value <<= m_aLinkFilterName;
- sal_Int32 nLen = 2;
- uno::Sequence< beans::PropertyValue > aArgs( nLen );
- aArgs[0].Name = "URL";
- aArgs[0].Value <<= m_aLinkURL;
- aArgs[1].Name = "FilterName";
- aArgs[1].Value <<= m_aLinkFilterName;
if ( m_bLinkHasPassword )
{
- aArgs.realloc( ++nLen );
- aArgs[nLen-1].Name = "Password";
- aArgs[nLen-1].Value <<= m_aLinkPassword;
+ pArgs[2].Name = "Password";
+ pArgs[2].Value <<= m_aLinkPassword;
}
- aArgs.realloc( m_aDocMediaDescriptor.getLength() + nLen );
for ( sal_Int32 nInd = 0; nInd < m_aDocMediaDescriptor.getLength(); nInd++ )
{
- aArgs[nInd+nLen].Name = m_aDocMediaDescriptor[nInd].Name;
- aArgs[nInd+nLen].Value = m_aDocMediaDescriptor[nInd].Value;
+ // return early if this document is not trusted to open links
+ if (m_aDocMediaDescriptor[nInd].Name == utl::MediaDescriptor::PROP_REFERRER)
+ {
+ OUString referer;
+ m_aDocMediaDescriptor[nInd].Value >>= referer;
+ if (SvtSecurityOptions::isUntrustedReferer(referer))
+ return nullptr;
+ }
+ pArgs[nInd+nLen].Name = m_aDocMediaDescriptor[nInd].Name;
+ pArgs[nInd+nLen].Value = m_aDocMediaDescriptor[nInd].Value;
}
+ uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xContext, GetDocumentServiceName(),
+ m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );
+ uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY_THROW );
+
try
{
+ handleLinkedOLE(CopyBackToOLELink::CopyLinkToTemp);
+
// the document is not really an embedded one, it is a link
EmbedAndReparentDoc_Impl( xDocument );
@@ -428,14 +479,13 @@ uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadLink_Impl()
}
-
OUString OCommonEmbeddedObject::GetFilterName( sal_Int32 nVersion ) const
{
OUString aFilterName = GetPresetFilterName();
if ( aFilterName.isEmpty() )
{
OUString sDocumentServiceName = GetDocumentServiceName();
- if (utl::ConfigManager::IsFuzzing() && nVersion == SOFFICE_FILEFORMAT_CURRENT &&
+ if (comphelper::IsFuzzing() && nVersion == SOFFICE_FILEFORMAT_CURRENT &&
sDocumentServiceName == "com.sun.star.chart2.ChartDocument")
{
return "chart8";
@@ -530,6 +580,11 @@ uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadDocumentFromStorag
// set the document mode to embedded as the first step!!!
EmbedAndReparentDoc_Impl( xDocument );
+ if (m_bReadOnly)
+ {
+ aLoadArgs.put("ReadOnly", true);
+ }
+
if ( xDoc.is() )
{
xDoc->loadFromStorage( xSourceStorage, aLoadArgs.getPropertyValues() );
@@ -578,23 +633,20 @@ uno::Reference< io::XInputStream > OCommonEmbeddedObject::StoreDocumentToTempStr
}
if( !xStorable.is() )
- throw uno::RuntimeException(); // TODO:
+ throw uno::RuntimeException("No storage is provided for storing!"); // TODO:
OUString aFilterName = GetFilterName( nStorageFormat );
SAL_WARN_IF( aFilterName.isEmpty(), "embeddedobj.common", "Wrong document service name!" );
if ( aFilterName.isEmpty() )
- throw io::IOException(); // TODO:
-
- uno::Sequence< beans::PropertyValue > aArgs( 4 );
- aArgs[0].Name = "FilterName";
- aArgs[0].Value <<= aFilterName;
- aArgs[1].Name = "OutputStream";
- aArgs[1].Value <<= xTempOut;
- aArgs[2].Name = "DocumentBaseURL";
- aArgs[2].Value <<= aBaseURL;
- aArgs[3].Name = "HierarchicalDocumentName";
- aArgs[3].Value <<= aHierarchName;
+ throw io::IOException("No filter name provided / Wrong document service name"); // TODO:
+
+ uno::Sequence< beans::PropertyValue > aArgs{
+ comphelper::makePropertyValue("FilterName", aFilterName),
+ comphelper::makePropertyValue("OutputStream", xTempOut),
+ comphelper::makePropertyValue("DocumentBaseURL", aBaseURL),
+ comphelper::makePropertyValue("HierarchicalDocumentName", aHierarchName)
+ };
xStorable->storeToURL( "private:stream", aArgs );
try
@@ -715,7 +767,8 @@ void OCommonEmbeddedObject::SwitchDocToStorage_Impl( const uno::Reference< docum
namespace {
-OUString getStringPropertyValue( const uno::Sequence<beans::PropertyValue>& rProps, std::u16string_view rName )
+beans::PropertyValue getStringPropertyValue(const uno::Sequence<beans::PropertyValue>& rProps,
+ const OUString& rName)
{
OUString aStr;
@@ -728,7 +781,7 @@ OUString getStringPropertyValue( const uno::Sequence<beans::PropertyValue>& rPro
}
}
- return aStr;
+ return comphelper::makePropertyValue(rName, aStr);
}
}
@@ -767,17 +820,13 @@ void OCommonEmbeddedObject::StoreDocToStorage_Impl(
if ( aFilterName.isEmpty() )
throw io::IOException(); // TODO:
- uno::Sequence<beans::PropertyValue> aArgs(5);
- aArgs[0].Name = "FilterName";
- aArgs[0].Value <<= aFilterName;
- aArgs[1].Name = "HierarchicalDocumentName";
- aArgs[1].Value <<= aHierarchName;
- aArgs[2].Name = "DocumentBaseURL";
- aArgs[2].Value <<= aBaseURL;
- aArgs[3].Name = "SourceShellID";
- aArgs[3].Value <<= getStringPropertyValue(rObjArgs, u"SourceShellID");
- aArgs[4].Name = "DestinationShellID";
- aArgs[4].Value <<= getStringPropertyValue(rObjArgs, u"DestinationShellID");
+ uno::Sequence<beans::PropertyValue> aArgs{
+ comphelper::makePropertyValue(u"FilterName"_ustr, aFilterName),
+ comphelper::makePropertyValue(u"HierarchicalDocumentName"_ustr, aHierarchName),
+ comphelper::makePropertyValue(u"DocumentBaseURL"_ustr, aBaseURL),
+ getStringPropertyValue(rObjArgs, u"SourceShellID"_ustr),
+ getStringPropertyValue(rObjArgs, u"DestinationShellID"_ustr),
+ };
xDoc->storeToStorage( xStorage, aArgs );
if ( bAttachToTheStorage )
@@ -793,8 +842,7 @@ void OCommonEmbeddedObject::StoreDocToStorage_Impl(
// open storage based on document temporary file for reading
uno::Reference < lang::XSingleServiceFactory > xStorageFactory = embed::StorageFactory::create(m_xContext);
- uno::Sequence< uno::Any > aArgs(1);
- aArgs[0] <<= xTempIn;
+ uno::Sequence< uno::Any > aArgs{ uno::Any(xTempIn) };
uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArgs ),
uno::UNO_QUERY_THROW );
@@ -843,7 +891,7 @@ uno::Reference< util::XCloseable > OCommonEmbeddedObject::CreateTempDocFromLink_
{
uno::Reference< util::XCloseable > xResult;
- SAL_WARN_IF( !m_bIsLink, "embeddedobj.common", "The object is not a linked one!" );
+ SAL_WARN_IF( !m_bIsLinkURL, "embeddedobj.common", "The object is not a linked one!" );
uno::Sequence< beans::PropertyValue > aTempMediaDescr;
@@ -882,22 +930,19 @@ uno::Reference< util::XCloseable > OCommonEmbeddedObject::CreateTempDocFromLink_
SAL_WARN_IF( aTempFileURL.isEmpty(), "embeddedobj.common", "Couldn't retrieve temporary file URL!" );
- aTempMediaDescr[0].Name = "URL";
- aTempMediaDescr[0].Value <<= aTempFileURL;
- aTempMediaDescr[1].Name = "InputStream";
- aTempMediaDescr[1].Value <<= xTempStream;
- aTempMediaDescr[2].Name = "FilterName";
- aTempMediaDescr[2].Value <<= GetFilterName( nStorageFormat );
- aTempMediaDescr[3].Name = "AsTemplate";
- aTempMediaDescr[3].Value <<= true;
+ aTempMediaDescr
+ = { comphelper::makePropertyValue("URL", aTempFileURL),
+ comphelper::makePropertyValue("InputStream", xTempStream),
+ comphelper::makePropertyValue("FilterName", GetFilterName( nStorageFormat )),
+ comphelper::makePropertyValue("AsTemplate", true) };
}
else
{
- aTempMediaDescr.realloc( 2 );
- aTempMediaDescr[0].Name = "URL";
- aTempMediaDescr[0].Value <<= m_aLinkURL;
- aTempMediaDescr[1].Name = "FilterName";
- aTempMediaDescr[1].Value <<= m_aLinkFilterName;
+ aTempMediaDescr = { comphelper::makePropertyValue(
+ "URL",
+ // tdf#141529 use URL of the linked TempFile if it exists
+ m_aLinkTempFile.is() ? m_aLinkTempFile->getUri() : m_aLinkURL),
+ comphelper::makePropertyValue("FilterName", m_aLinkFilterName) };
}
xResult = CreateDocFromMediaDescr_Impl( aTempMediaDescr );
@@ -968,8 +1013,8 @@ void SAL_CALL OCommonEmbeddedObject::setPersistentEntry(
// for now support of this interface is required to allow breaking of links and converting them to normal embedded
// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
- // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!" );
- if ( m_bIsLink )
+ // OSL_ENSURE( !m_bIsLinkURL, "This method implementation must not be used for links!" );
+ if ( m_bIsLinkURL )
{
m_aEntryName = sEntName;
return;
@@ -1147,8 +1192,8 @@ void SAL_CALL OCommonEmbeddedObject::storeToEntry( const uno::Reference< embed::
// for now support of this interface is required to allow breaking of links and converting them to normal embedded
// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
- // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!" );
- if ( m_bIsLink )
+ // OSL_ENSURE( !m_bIsLinkURL, "This method implementation must not be used for links!" );
+ if ( m_bIsLinkURL )
return;
OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!" );
@@ -1255,12 +1300,14 @@ void SAL_CALL OCommonEmbeddedObject::storeAsEntry( const uno::Reference< embed::
const uno::Sequence< beans::PropertyValue >& lArguments,
const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
- // TODO: use lObjArgs
-
::osl::ResettableMutexGuard aGuard( m_aMutex );
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
+ bool AutoSaveEvent = false;
+ utl::MediaDescriptor lArgs(lObjArgs);
+ lArgs[utl::MediaDescriptor::PROP_AUTOSAVEEVENT] >>= AutoSaveEvent;
+
if ( m_nObjectState == -1 )
{
// the object is still not loaded
@@ -1275,10 +1322,14 @@ void SAL_CALL OCommonEmbeddedObject::storeAsEntry( const uno::Reference< embed::
// for now support of this interface is required to allow breaking of links and converting them to normal embedded
// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
- // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!" );
- if ( m_bIsLink )
+ // OSL_ENSURE( !m_bIsLinkURL, "This method implementation must not be used for links!" );
+ if ( m_bIsLinkURL )
{
m_aNewEntryName = sEntName;
+
+ if ( !AutoSaveEvent )
+ handleLinkedOLE(CopyBackToOLELink::CopyTempToLink);
+
return;
}
@@ -1407,8 +1458,8 @@ void SAL_CALL OCommonEmbeddedObject::saveCompleted( sal_Bool bUseNew )
// for now support of this interface is required to allow breaking of links and converting them to normal embedded
// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
- // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!" );
- if ( m_bIsLink )
+ // OSL_ENSURE( !m_bIsLinkURL, "This method implementation must not be used for links!" );
+ if ( m_bIsLinkURL )
{
if ( bUseNew )
m_aEntryName = m_aNewEntryName;
@@ -1542,7 +1593,7 @@ void SAL_CALL OCommonEmbeddedObject::storeOwn()
if ( !m_xDocHolder->GetComponent().is() )
throw uno::RuntimeException();
- if ( m_bIsLink )
+ if ( m_bIsLinkURL )
{
// TODO: just store the document to its location
uno::Reference< frame::XStorable > xStorable( m_xDocHolder->GetComponent(), uno::UNO_QUERY_THROW );
@@ -1582,9 +1633,8 @@ void SAL_CALL OCommonEmbeddedObject::storeOwn()
aGuard.clear();
uno::Sequence<beans::PropertyValue> aEmpty;
- uno::Sequence<beans::PropertyValue> aMediaArgs(1);
- aMediaArgs[0].Name = "DocumentBaseURL";
- aMediaArgs[0].Value <<= GetBaseURL_Impl();
+ uno::Sequence<beans::PropertyValue> aMediaArgs{ comphelper::makePropertyValue(
+ "DocumentBaseURL", GetBaseURL_Impl()) };
StoreDocToStorage_Impl( m_xObjectStorage, aMediaArgs, aEmpty, nStorageFormat, m_aEntryName, true );
aGuard.reset();
}
@@ -1650,7 +1700,7 @@ void SAL_CALL OCommonEmbeddedObject::reload(
"The object waits for saveCompleted() call!",
static_cast< ::cppu::OWeakObject* >(this) );
- if ( m_bIsLink )
+ if ( m_bIsLinkURL )
{
// reload of the link
OUString aOldLinkFilter = m_aLinkFilterName;
@@ -1678,9 +1728,8 @@ void SAL_CALL OCommonEmbeddedObject::reload(
m_aLinkFilterName = aNewLinkFilter;
else
{
- uno::Sequence< beans::PropertyValue > aArgs( 1 );
- aArgs[0].Name = "URL";
- aArgs[0].Value <<= m_aLinkURL;
+ uno::Sequence< beans::PropertyValue > aArgs{ comphelper::makePropertyValue(
+ "URL", m_aLinkURL) };
m_aLinkFilterName = aHelper.UpdateMediaDescriptorWithFilterName( aArgs, false );
}
}
@@ -1719,7 +1768,7 @@ void SAL_CALL OCommonEmbeddedObject::reload(
if ( prop.Name == "ReadOnly" )
prop.Value >>= m_bReadOnly;
- if ( bOldReadOnlyValue == m_bReadOnly || m_bIsLink )
+ if ( bOldReadOnlyValue == m_bReadOnly || m_bIsLinkURL )
return;
// close own storage
@@ -1751,7 +1800,7 @@ void SAL_CALL OCommonEmbeddedObject::breakLink( const uno::Reference< embed::XSt
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
- if (!m_bIsLink || m_nObjectState == -1)
+ if (!m_bIsLinkURL || m_nObjectState == -1)
{
// it must be a linked initialized object
throw embed::WrongStateException(
@@ -1789,10 +1838,21 @@ void SAL_CALL OCommonEmbeddedObject::breakLink( const uno::Reference< embed::XSt
// TODO/LATER: handle the case when temp doc can not be created
// the document is a new embedded object so it must be marked as modified
uno::Reference< util::XCloseable > xDocument = CreateTempDocFromLink_Impl();
- uno::Reference< util::XModifiable > xModif( m_xDocHolder->GetComponent(), uno::UNO_QUERY_THROW );
try
{
- xModif->setModified( true );
+ if(m_xDocHolder.is() && m_xDocHolder->GetComponent().is())
+ {
+ // tdf#141528 m_xDocHolder->GetComponent() may be not set, so add it
+ // to the try path to not get thrown out of the local context to the next
+ // higher try...catch on the stack. To make breakLink work it is
+ // *necessary* to execute the code below that resets the linked state,
+ // esp. the *.clear stuff and resetting m_bIsLink.
+ uno::Reference< util::XModifiable > xModif( m_xDocHolder->GetComponent(), uno::UNO_QUERY_THROW );
+
+ // all other locations in this file check for xModif.is(), so do it here, too
+ if ( xModif.is() )
+ xModif->setModified( true );
+ }
}
catch( const uno::Exception& )
{}
@@ -1809,7 +1869,10 @@ void SAL_CALL OCommonEmbeddedObject::breakLink( const uno::Reference< embed::XSt
else if ( m_nObjectState == embed::EmbedStates::ACTIVE )
m_xDocHolder->Show();
- m_bIsLink = false;
+ // tdf#141529 reset all stuff involved in linked state, including
+ // the OLE content copied to the temp file
+ m_bIsLinkURL = false;
+ m_aLinkTempFile.clear();
m_aLinkFilterName.clear();
m_aLinkURL.clear();
}
@@ -1821,7 +1884,7 @@ sal_Bool SAL_CALL OCommonEmbeddedObject::isLink()
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
- return m_bIsLink;
+ return m_bIsLinkURL;
}
@@ -1831,7 +1894,7 @@ OUString SAL_CALL OCommonEmbeddedObject::getLinkURL()
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
- if ( !m_bIsLink )
+ if ( !m_bIsLinkURL )
throw embed::WrongStateException(
"The object is not a link object!",
static_cast< ::cppu::OWeakObject* >(this) );
diff --git a/embeddedobj/source/commonembedding/specialobject.cxx b/embeddedobj/source/commonembedding/specialobject.cxx
index 683fe0aab3f2..a2f282ed1aae 100644
--- a/embeddedobj/source/commonembedding/specialobject.cxx
+++ b/embeddedobj/source/commonembedding/specialobject.cxx
@@ -28,6 +28,8 @@
#include <cppuhelper/queryinterface.hxx>
#include <osl/diagnose.h>
+#include <cppuhelper/supportsservice.hxx>
+#include <officecfg/Office/Common.hxx>
#include <specialobject.hxx>
@@ -47,10 +49,13 @@ uno::Any SAL_CALL OSpecialEmbeddedObject::queryInterface( const uno::Type& rType
uno::Any aReturn = ::cppu::queryInterface( rType,
static_cast< embed::XEmbeddedObject* >( this ),
static_cast< embed::XInplaceObject* >( this ),
+ static_cast< embed::XCommonEmbedPersist* >( static_cast< embed::XEmbedPersist* >( this ) ),
static_cast< embed::XVisualObject* >( this ),
static_cast< embed::XClassifiedObject* >( this ),
static_cast< embed::XComponentSupplier* >( this ),
static_cast< util::XCloseable* >( this ),
+ static_cast< lang::XServiceInfo* >( this ),
+ static_cast< lang::XTypeProvider* >( this ),
static_cast< document::XEventBroadcaster* >( this ) );
if ( aReturn.hasValue() )
return aReturn;
@@ -133,6 +138,10 @@ sal_Int32 SAL_CALL OSpecialEmbeddedObject::getMapUnit( sal_Int64 nAspect )
void SAL_CALL OSpecialEmbeddedObject::changeState( sal_Int32 nNewState )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get()
+ && nNewState != embed::EmbedStates::LOADED )
+ throw embed::UnreachableStateException();
+
if ( nNewState == embed::EmbedStates::UI_ACTIVE )
nNewState = embed::EmbedStates::INPLACE_ACTIVE;
OCommonEmbeddedObject::changeState( nNewState );
@@ -160,4 +169,27 @@ void SAL_CALL OSpecialEmbeddedObject::doVerb( sal_Int32 nVerbID )
OCommonEmbeddedObject::doVerb( nVerbID );
}
+void SAL_CALL OSpecialEmbeddedObject::reload(
+ const uno::Sequence< beans::PropertyValue >&,
+ const uno::Sequence< beans::PropertyValue >&)
+{
+ // Allow IFrames to reload their content
+ SetInplaceActiveState();
+}
+
+OUString SAL_CALL OSpecialEmbeddedObject::getImplementationName()
+{
+ return "com.sun.star.comp.embed.OSpecialEmbeddedObject";
+}
+
+sal_Bool SAL_CALL OSpecialEmbeddedObject::supportsService(const OUString& ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+uno::Sequence<OUString> SAL_CALL OSpecialEmbeddedObject::getSupportedServiceNames()
+{
+ return { "com.sun.star.comp.embed.OSpecialEmbeddedObject" };
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/commonembedding/visobj.cxx b/embeddedobj/source/commonembedding/visobj.cxx
index 6306ecfad0cf..851457609e7d 100644
--- a/embeddedobj/source/commonembedding/visobj.cxx
+++ b/embeddedobj/source/commonembedding/visobj.cxx
@@ -55,7 +55,7 @@ void SAL_CALL OCommonEmbeddedObject::setVisualAreaSize( sal_Int64 nAspect, const
changeState( embed::EmbedStates::RUNNING );
// the links should be switched back to loaded state for now to avoid locking problems
- bBackToLoaded = m_bIsLink;
+ bBackToLoaded = m_bIsLinkURL;
}
bool bSuccess = m_xDocHolder->SetExtent( nAspect, aSize );
@@ -88,7 +88,7 @@ awt::Size SAL_CALL OCommonEmbeddedObject::getVisualAreaSize( sal_Int64 nAspect )
changeState( embed::EmbedStates::RUNNING );
// the links should be switched back to loaded state for now to avoid locking problems
- bBackToLoaded = m_bIsLink;
+ bBackToLoaded = m_bIsLinkURL;
}
awt::Size aResult;
@@ -128,7 +128,7 @@ sal_Int32 SAL_CALL OCommonEmbeddedObject::getMapUnit( sal_Int64 nAspect )
changeState( embed::EmbedStates::RUNNING );
// the links should be switched back to loaded state for now to avoid locking problems
- bBackToLoaded = m_bIsLink;
+ bBackToLoaded = m_bIsLinkURL;
}
sal_Int32 nResult = m_xDocHolder->GetMapUnit( nAspect );
@@ -172,7 +172,7 @@ embed::VisualRepresentation SAL_CALL OCommonEmbeddedObject::getPreferredVisualRe
setVisualAreaSize(nAspect, aOrigSize);
// the links should be switched back to loaded state for now to avoid locking problems
- bBackToLoaded = m_bIsLink;
+ bBackToLoaded = m_bIsLinkURL;
}
SAL_WARN_IF( !m_xDocHolder->GetComponent().is(), "embeddedobj.common", "Running or Active object has no component!" );
diff --git a/embeddedobj/source/commonembedding/xfactory.cxx b/embeddedobj/source/commonembedding/xfactory.cxx
index 3f7cb8fde98f..cdc6d94b351b 100644
--- a/embeddedobj/source/commonembedding/xfactory.cxx
+++ b/embeddedobj/source/commonembedding/xfactory.cxx
@@ -23,9 +23,11 @@
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/lang/NoSupportException.hpp>
#include <cppuhelper/supportsservice.hxx>
#include <cppuhelper/weak.hxx>
#include <comphelper/documentconstants.hxx>
+#include <officecfg/Office/Common.hxx>
#include "xfactory.hxx"
#include <commonembobj.hxx>
@@ -41,6 +43,8 @@ uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInsta
const uno::Sequence< beans::PropertyValue >& aMediaDescr,
const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
+ throw lang::NoSupportException("Active embedded content is disabled!");
if ( !xStorage.is() )
throw lang::IllegalArgumentException( "No parent storage is provided!",
static_cast< ::cppu::OWeakObject* >(this),
@@ -118,6 +122,8 @@ uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInsta
const uno::Sequence< beans::PropertyValue >& aMediaDescr,
const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
+ throw lang::NoSupportException("Active embedded content is disabled!");
if ( !xStorage.is() )
throw lang::IllegalArgumentException( "No parent storage is provided!",
static_cast< ::cppu::OWeakObject* >(this),
@@ -169,6 +175,8 @@ uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInsta
const OUString& sEntName,
const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
+ throw lang::NoSupportException("Active embedded content is disabled!");
uno::Reference< uno::XInterface > xResult;
if ( !xStorage.is() )
@@ -212,6 +220,8 @@ uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInsta
const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
// the initialization is completely controlled by user
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
+ throw lang::NoSupportException("Active embedded content is disabled!");
if ( !xStorage.is() )
throw lang::IllegalArgumentException( "No parent storage is provided!",
uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
@@ -257,13 +267,15 @@ uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInsta
const uno::Sequence< beans::PropertyValue >& aMediaDescr,
const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
+ throw lang::NoSupportException("Active embedded content is disabled!");
uno::Reference< uno::XInterface > xResult;
uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr );
// check if there is URL, URL must exist
OUString aURL;
- for ( beans::PropertyValue const & prop : std::as_const(aTempMedDescr) )
+ for (beans::PropertyValue const& prop : aTempMedDescr)
if ( prop.Name == "URL" )
prop.Value >>= aURL;
@@ -302,6 +314,8 @@ uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInsta
const uno::Sequence< beans::PropertyValue >& lArguments,
const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
+ throw lang::NoSupportException("Active embedded content is disabled!");
uno::Reference< uno::XInterface > xResult;
// the initialization is completely controlled by user
@@ -318,7 +332,7 @@ uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInsta
uno::Sequence< beans::PropertyValue > aTempMedDescr( lArguments );
OUString aURL;
- for ( beans::PropertyValue const & prop : std::as_const(aTempMedDescr) )
+ for (beans::PropertyValue const& prop : aTempMedDescr)
if ( prop.Name == "URL" )
prop.Value >>= aURL;
@@ -368,7 +382,7 @@ extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
embeddedobj_OOoEmbeddedObjectFactory_get_implementation(
css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
{
- return cppu::acquire(static_cast<cppu::OWeakObject*>(new OOoEmbeddedObjectFactory(context)));
+ return cppu::acquire(new OOoEmbeddedObjectFactory(context));
}
@@ -381,6 +395,8 @@ uno::Reference< uno::XInterface > SAL_CALL OOoSpecialEmbeddedObjectFactory::crea
const uno::Sequence< beans::PropertyValue >& /*lArguments*/,
const uno::Sequence< beans::PropertyValue >& /*lObjArgs*/ )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
+ throw lang::NoSupportException("Active embedded content is disabled!");
uno::Sequence< beans::NamedValue > aObject = m_aConfigHelper.GetObjectPropsByClassID( aClassID );
if ( !aObject.hasElements() )
throw io::IOException(); // unexpected mimetype of the storage
@@ -412,6 +428,6 @@ extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
embeddedobj_OOoSpecialEmbeddedObjectFactory_get_implementation(
css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
{
- return cppu::acquire(static_cast<cppu::OWeakObject*>(new OOoSpecialEmbeddedObjectFactory(context)));
+ return cppu::acquire(new OOoSpecialEmbeddedObjectFactory(context));
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/general/docholder.cxx b/embeddedobj/source/general/docholder.cxx
index 66a2290ab639..4fcb563bc424 100644
--- a/embeddedobj/source/general/docholder.cxx
+++ b/embeddedobj/source/general/docholder.cxx
@@ -57,6 +57,7 @@
#include <com/sun/star/embed/EmbedMisc.hpp>
#include <com/sun/star/embed/EmbedStates.hpp>
#include <osl/diagnose.h>
+#include <utility>
#include <vcl/svapp.hxx>
#include <unotools/resmgr.hxx>
#include <sfx2/strings.hrc>
@@ -110,45 +111,50 @@ static void InsertMenu_Impl( const uno::Reference< container::XIndexContainer >&
uno::Sequence< beans::PropertyValue > aSourceProps;
xSourceMenu->getByIndex( nSourceIndex ) >>= aSourceProps;
uno::Sequence< beans::PropertyValue > aTargetProps( aSourceProps.getLength() );
+ auto aTargetPropsRange = asNonConstRange(aTargetProps);
for ( nInd = 0; nInd < aSourceProps.getLength(); nInd++ )
{
- aTargetProps[nInd].Name = aSourceProps[nInd].Name;
+ aTargetPropsRange[nInd].Name = aSourceProps[nInd].Name;
if ( !aContModuleName.isEmpty() && aTargetProps[nInd].Name == aModuleIdentPropName )
{
- aTargetProps[nInd].Value <<= aContModuleName;
+ aTargetPropsRange[nInd].Value <<= aContModuleName;
bModuleNameSet = true;
}
else if ( aTargetProps[nInd].Name == aDispProvPropName )
{
- aTargetProps[nInd].Value <<= xSourceDisp;
+ aTargetPropsRange[nInd].Value <<= xSourceDisp;
bDispProvSet = true;
}
else
- aTargetProps[nInd].Value = aSourceProps[nInd].Value;
+ aTargetPropsRange[nInd].Value = aSourceProps[nInd].Value;
}
if ( !bModuleNameSet && !aContModuleName.isEmpty() )
{
aTargetProps.realloc( ++nInd );
- aTargetProps[nInd-1].Name = aModuleIdentPropName;
- aTargetProps[nInd-1].Value <<= aContModuleName;
+ auto pTargetProps = aTargetProps.getArray();
+ pTargetProps[nInd-1].Name = aModuleIdentPropName;
+ pTargetProps[nInd-1].Value <<= aContModuleName;
}
if ( !bDispProvSet && xSourceDisp.is() )
{
aTargetProps.realloc( ++nInd );
- aTargetProps[nInd-1].Name = aDispProvPropName;
- aTargetProps[nInd-1].Value <<= xSourceDisp;
+ auto pTargetProps = aTargetProps.getArray();
+ pTargetProps[nInd-1].Name = aDispProvPropName;
+ pTargetProps[nInd-1].Value <<= xSourceDisp;
}
- xTargetMenu->insertByIndex( nTargetIndex, uno::makeAny( aTargetProps ) );
+ xTargetMenu->insertByIndex( nTargetIndex, uno::Any( aTargetProps ) );
}
+namespace embeddedobj
+{
-DocumentHolder::DocumentHolder( const uno::Reference< uno::XComponentContext >& xContext,
+DocumentHolder::DocumentHolder( uno::Reference< uno::XComponentContext > xContext,
OCommonEmbeddedObject* pEmbObj )
: m_pEmbedObj( pEmbObj ),
- m_xContext( xContext ),
+ m_xContext(std::move( xContext )),
m_bReadOnly( false ),
m_bWaitForClose( false ),
m_bAllowClosing( false ),
@@ -156,17 +162,6 @@ DocumentHolder::DocumentHolder( const uno::Reference< uno::XComponentContext >&
m_nNoBorderResizeReact( 0 ),
m_nNoResizeReact( 0 )
{
- m_aOutplaceFrameProps.realloc( 3 );
- beans::NamedValue aArg;
-
- aArg.Name = "TopWindow";
- aArg.Value <<= true;
- m_aOutplaceFrameProps[0] <<= aArg;
-
- aArg.Name = "MakeVisible";
- aArg.Value <<= false;
- m_aOutplaceFrameProps[1] <<= aArg;
-
uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( m_xContext );
osl_atomic_increment(&m_refCount);
try
@@ -178,9 +173,10 @@ DocumentHolder::DocumentHolder( const uno::Reference< uno::XComponentContext >&
}
osl_atomic_decrement(&m_refCount);
- aArg.Name = "ParentFrame";
- aArg.Value <<= xDesktop; //TODO/LATER: should use parent document frame
- m_aOutplaceFrameProps[2] <<= aArg;
+ m_aOutplaceFrameProps = { uno::Any(beans::NamedValue{ "TopWindow", uno::Any(true) }),
+ uno::Any(beans::NamedValue{ "MakeVisible", uno::Any(false) }),
+ //TODO/LATER: should use parent document frame
+ uno::Any(beans::NamedValue{ "ParentFrame", uno::Any(xDesktop) }) };
}
@@ -239,8 +235,12 @@ void DocumentHolder::CloseFrame()
void DocumentHolder::FreeOffice()
{
- uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( m_xContext );
- xDesktop->removeTerminateListener( this );
+ try {
+ uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( m_xContext );
+ xDesktop->removeTerminateListener( this );
+ } catch (const css::uno::DeploymentException&) {
+ // if this happens, the desktop is already gone
+ }
// the following code is commented out since for now there is still no completely correct way to detect
// whether the office can be terminated, so it is better to have unnecessary process running than
@@ -430,26 +430,25 @@ bool DocumentHolder::ShowInplace( const uno::Reference< awt::XWindowPeer >& xPar
uno::Reference< awt::XWindowPeer > xNewWinPeer = xToolkit->createWindow( aOwnWinDescriptor );
uno::Reference< awt::XWindow > xOwnWindow( xNewWinPeer, uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XFrame > xContFrame( xContDisp, uno::UNO_QUERY );
// create a frame based on the specified window
uno::Reference< lang::XSingleServiceFactory > xFrameFact = frame::TaskCreator::create(m_xContext);
- uno::Sequence< uno::Any > aArgs( 2 );
+ uno::Sequence< uno::Any > aArgs( xContFrame.is() ? 2 : 1 );
+ auto pArgs = aArgs.getArray();
beans::NamedValue aArg;
aArg.Name = "ContainerWindow";
aArg.Value <<= xOwnWindow;
- aArgs[0] <<= aArg;
+ pArgs[0] <<= aArg;
- uno::Reference< frame::XFrame > xContFrame( xContDisp, uno::UNO_QUERY );
if ( xContFrame.is() )
{
aArg.Name = "ParentFrame";
aArg.Value <<= xContFrame;
- aArgs[1] <<= aArg;
+ pArgs[1] <<= aArg;
}
- else
- aArgs.realloc( 1 );
// the call will create, initialize the frame, and register it in the parent
m_xFrame.set( xFrameFact->createInstanceWithArguments( aArgs ), uno::UNO_QUERY_THROW );
@@ -472,30 +471,28 @@ bool DocumentHolder::ShowInplace( const uno::Reference< awt::XWindowPeer >& xPar
// TODO: some listeners to the frame and the window ( resize for example )
}
- if ( m_xComponent.is() )
- {
- if ( !LoadDocToFrame( true ) )
- {
- CloseFrame();
- return false;
- }
+ if ( !m_xComponent )
+ return false;
- uno::Reference< frame::XControllerBorder > xControllerBorder( m_xFrame->getController(), uno::UNO_QUERY );
- if ( xControllerBorder.is() )
- {
- m_aBorderWidths = xControllerBorder->getBorder();
- xControllerBorder->addBorderResizeListener( static_cast<frame::XBorderResizeListener*>(this) );
- }
+ if ( !LoadDocToFrame( true ) )
+ {
+ CloseFrame();
+ return false;
+ }
- PlaceFrame( aRectangleToShow );
+ uno::Reference< frame::XControllerBorder > xControllerBorder( m_xFrame->getController(), uno::UNO_QUERY );
+ if ( xControllerBorder.is() )
+ {
+ m_aBorderWidths = xControllerBorder->getBorder();
+ xControllerBorder->addBorderResizeListener( static_cast<frame::XBorderResizeListener*>(this) );
+ }
- if ( m_xHatchWindow.is() )
- m_xHatchWindow->setVisible( true );
+ PlaceFrame( aRectangleToShow );
- return true;
- }
+ if ( m_xHatchWindow.is() )
+ m_xHatchWindow->setVisible( true );
- return false;
+ return true;
}
@@ -547,7 +544,7 @@ uno::Reference< container::XIndexAccess > DocumentHolder::RetrieveOwnMenu_Impl()
}
if ( !xResult.is() )
- throw uno::RuntimeException();
+ throw uno::RuntimeException("Unable to retrieve the UI configuration menu.", getXWeak());
return xResult;
}
@@ -564,7 +561,7 @@ void DocumentHolder::FindConnectPoints(
uno::Sequence< beans::PropertyValue > aProps;
xMenu->getByIndex( nInd ) >>= aProps;
OUString aCommand;
- for ( beans::PropertyValue const & prop : std::as_const(aProps) )
+ for (beans::PropertyValue const& prop : aProps)
if ( prop.Name == "CommandURL" )
{
prop.Value >>= aCommand;
@@ -572,7 +569,7 @@ void DocumentHolder::FindConnectPoints(
}
if ( aCommand.isEmpty() )
- throw uno::RuntimeException();
+ throw uno::RuntimeException("CommandURL is empty at index: " + OUString::number(nInd), xMenu);
if ( aCommand == ".uno:PickList" )
nConnectPoints[0] = nInd;
@@ -641,7 +638,7 @@ bool DocumentHolder::MergeMenus_Impl( const uno::Reference< css::frame::XLayoutM
uno::UNO_QUERY_THROW );
uno::Reference< container::XIndexAccess > xContMenu = xUISettings->getSettings( true );
if ( !xContMenu.is() )
- throw uno::RuntimeException();
+ throw uno::RuntimeException("Unable to merge the menu", getXWeak());
uno::Reference< container::XIndexAccess > xOwnMenu = RetrieveOwnMenu_Impl();
uno::Reference< frame::XDispatchProvider > xOwnDisp( m_xFrame, uno::UNO_QUERY_THROW );
@@ -879,7 +876,7 @@ uno::Reference< frame::XFrame > const & DocumentHolder::GetDocFrame()
{
sal_Int32 nDisplay = Application::GetDisplayBuiltInScreen();
- tools::Rectangle aWorkRect = Application::GetScreenPosSizePixel( nDisplay );
+ AbsoluteScreenPixelRectangle aWorkRect = Application::GetScreenPosSizePixel( nDisplay );
awt::Rectangle aWindowRect = xHWindow->getPosSize();
if (( aWindowRect.Width < aWorkRect.GetWidth()) && ( aWindowRect.Height < aWorkRect.GetHeight() ))
@@ -942,60 +939,60 @@ void DocumentHolder::SetComponent( const uno::Reference< util::XCloseable >& xDo
bool DocumentHolder::LoadDocToFrame( bool bInPlace )
{
- if ( m_xFrame.is() && m_xComponent.is() )
+ if ( !m_xFrame || !m_xComponent )
+ return true;
+
+ uno::Reference < frame::XModel > xDoc( m_xComponent, uno::UNO_QUERY );
+ if ( xDoc.is() )
{
- uno::Reference < frame::XModel > xDoc( m_xComponent, uno::UNO_QUERY );
- if ( xDoc.is() )
- {
- // load new document into the frame
- uno::Reference< frame::XComponentLoader > xComponentLoader( m_xFrame, uno::UNO_QUERY_THROW );
+ // load new document into the frame
+ uno::Reference< frame::XComponentLoader > xComponentLoader( m_xFrame, uno::UNO_QUERY_THROW );
- ::comphelper::NamedValueCollection aArgs;
- aArgs.put( "Model", m_xComponent );
- aArgs.put( "ReadOnly", m_bReadOnly );
+ ::comphelper::NamedValueCollection aArgs;
+ aArgs.put( "Model", m_xComponent );
+ aArgs.put( "ReadOnly", m_bReadOnly );
- // set document title to show in the title bar
- css::uno::Reference< css::frame::XTitle > xModelTitle( xDoc, css::uno::UNO_QUERY );
- if( xModelTitle.is() && m_pEmbedObj && !m_pEmbedObj->getContainerName().isEmpty() )
- {
- std::locale aResLoc = Translate::Create("sfx");
- OUString sEmbedded = Translate::get(STR_EMBEDDED_TITLE, aResLoc);
- xModelTitle->setTitle( m_pEmbedObj->getContainerName() + sEmbedded );
- m_aContainerName = m_pEmbedObj->getContainerName();
- // TODO: get real m_aDocumentNamePart
- m_aDocumentNamePart = sEmbedded;
- }
+ // set document title to show in the title bar
+ css::uno::Reference< css::frame::XTitle > xModelTitle( xDoc, css::uno::UNO_QUERY );
+ if( xModelTitle.is() && m_pEmbedObj && !m_pEmbedObj->getContainerName().isEmpty() )
+ {
+ std::locale aResLoc = Translate::Create("sfx");
+ OUString sEmbedded = Translate::get(STR_EMBEDDED_TITLE, aResLoc);
+ xModelTitle->setTitle( m_pEmbedObj->getContainerName() + sEmbedded );
+ m_aContainerName = m_pEmbedObj->getContainerName();
+ // TODO: get real m_aDocumentNamePart
+ m_aDocumentNamePart = sEmbedded;
+ }
- if ( bInPlace )
- aArgs.put( "PluginMode", sal_Int16(1) );
- OUString sUrl;
- uno::Reference< lang::XServiceInfo> xServiceInfo(xDoc,uno::UNO_QUERY);
- if ( xServiceInfo.is()
- && xServiceInfo->supportsService("com.sun.star.report.ReportDefinition") )
- {
- sUrl = ".component:DB/ReportDesign";
- }
- else if( xServiceInfo.is()
- && xServiceInfo->supportsService("com.sun.star.chart2.ChartDocument"))
- sUrl = "private:factory/schart";
- else
- sUrl = "private:object";
+ if ( bInPlace )
+ aArgs.put( "PluginMode", sal_Int16(1) );
+ OUString sUrl;
+ uno::Reference< lang::XServiceInfo> xServiceInfo(xDoc,uno::UNO_QUERY);
+ if ( xServiceInfo.is()
+ && xServiceInfo->supportsService("com.sun.star.report.ReportDefinition") )
+ {
+ sUrl = ".component:DB/ReportDesign";
+ }
+ else if( xServiceInfo.is()
+ && xServiceInfo->supportsService("com.sun.star.chart2.ChartDocument"))
+ sUrl = "private:factory/schart";
+ else
+ sUrl = "private:object";
- xComponentLoader->loadComponentFromURL( sUrl,
- "_self",
- 0,
- aArgs.getPropertyValues() );
+ xComponentLoader->loadComponentFromURL( sUrl,
+ "_self",
+ 0,
+ aArgs.getPropertyValues() );
- return true;
- }
+ return true;
+ }
+ else
+ {
+ uno::Reference < frame::XSynchronousFrameLoader > xLoader( m_xComponent, uno::UNO_QUERY );
+ if ( xLoader.is() )
+ return xLoader->load( uno::Sequence < beans::PropertyValue >(), m_xFrame );
else
- {
- uno::Reference < frame::XSynchronousFrameLoader > xLoader( m_xComponent, uno::UNO_QUERY );
- if ( xLoader.is() )
- return xLoader->load( uno::Sequence < beans::PropertyValue >(), m_xFrame );
- else
- return false;
- }
+ return false;
}
return true;
@@ -1285,4 +1282,6 @@ void SAL_CALL DocumentHolder::deactivated( )
// so UIDeactivation is actively triggered by the container
}
+} // namespace embeddedobj
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/general/dummyobject.cxx b/embeddedobj/source/general/dummyobject.cxx
index e37aca939b9b..4d2af144a479 100644
--- a/embeddedobj/source/general/dummyobject.cxx
+++ b/embeddedobj/source/general/dummyobject.cxx
@@ -30,6 +30,9 @@
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/lang/NoSupportException.hpp>
+#include <comphelper/multicontainer2.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <osl/diagnose.h>
#include <dummyobject.hxx>
@@ -60,7 +63,7 @@ void ODummyEmbeddedObject::PostEvent_Impl( const OUString& aEventName )
if ( !m_pInterfaceContainer )
return;
- ::cppu::OInterfaceContainerHelper* pIC = m_pInterfaceContainer->getContainer(
+ comphelper::OInterfaceContainerHelper2* pIC = m_pInterfaceContainer->getContainer(
cppu::UnoType<document::XEventListener>::get());
if( !pIC )
return;
@@ -71,7 +74,7 @@ void ODummyEmbeddedObject::PostEvent_Impl( const OUString& aEventName )
// For now all the events are sent as object events
// aEvent.Source = ( xSource.is() ? xSource
// : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ) );
- ::cppu::OInterfaceIteratorHelper aIt( *pIC );
+ comphelper::OInterfaceIteratorHelper2 aIt( *pIC );
while( aIt.hasMoreElements() )
{
try
@@ -112,10 +115,7 @@ uno::Sequence< sal_Int32 > SAL_CALL ODummyEmbeddedObject::getReachableStates()
::osl::MutexGuard aGuard( m_aMutex );
CheckInit_WrongState();
- uno::Sequence< sal_Int32 > aResult( 1 );
- aResult[0] = embed::EmbedStates::LOADED;
-
- return aResult;
+ return { embed::EmbedStates::LOADED };
}
@@ -506,7 +506,7 @@ void SAL_CALL ODummyEmbeddedObject::addStateChangeListener( const uno::Reference
return;
if ( !m_pInterfaceContainer )
- m_pInterfaceContainer.reset(new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ));
+ m_pInterfaceContainer.reset(new comphelper::OMultiTypeInterfaceContainerHelper2( m_aMutex ));
m_pInterfaceContainer->addInterface( cppu::UnoType<embed::XStateChangeListener>::get(),
xListener );
@@ -534,11 +534,11 @@ void SAL_CALL ODummyEmbeddedObject::close( sal_Bool bDeliverOwnership )
if ( m_pInterfaceContainer )
{
- ::cppu::OInterfaceContainerHelper* pContainer =
+ comphelper::OInterfaceContainerHelper2* pContainer =
m_pInterfaceContainer->getContainer( cppu::UnoType<util::XCloseListener>::get());
if ( pContainer != nullptr )
{
- ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer);
while (pIterator.hasMoreElements())
{
try
@@ -556,7 +556,7 @@ void SAL_CALL ODummyEmbeddedObject::close( sal_Bool bDeliverOwnership )
cppu::UnoType<util::XCloseListener>::get());
if ( pContainer != nullptr )
{
- ::cppu::OInterfaceIteratorHelper pCloseIterator(*pContainer);
+ comphelper::OInterfaceIteratorHelper2 pCloseIterator(*pContainer);
while (pCloseIterator.hasMoreElements())
{
try
@@ -584,7 +584,7 @@ void SAL_CALL ODummyEmbeddedObject::addCloseListener( const uno::Reference< util
return;
if ( !m_pInterfaceContainer )
- m_pInterfaceContainer.reset(new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ));
+ m_pInterfaceContainer.reset(new comphelper::OMultiTypeInterfaceContainerHelper2( m_aMutex ));
m_pInterfaceContainer->addInterface( cppu::UnoType<util::XCloseListener>::get(), xListener );
}
@@ -606,7 +606,7 @@ void SAL_CALL ODummyEmbeddedObject::addEventListener( const uno::Reference< docu
return;
if ( !m_pInterfaceContainer )
- m_pInterfaceContainer.reset(new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ));
+ m_pInterfaceContainer.reset(new comphelper::OMultiTypeInterfaceContainerHelper2( m_aMutex ));
m_pInterfaceContainer->addInterface( cppu::UnoType<document::XEventListener>::get(), xListener );
}
@@ -620,4 +620,19 @@ void SAL_CALL ODummyEmbeddedObject::removeEventListener( const uno::Reference< d
xListener );
}
+OUString SAL_CALL ODummyEmbeddedObject::getImplementationName()
+{
+ return "com.sun.star.comp.embed.ODummyEmbeddedObject";
+}
+
+sal_Bool SAL_CALL ODummyEmbeddedObject::supportsService(const OUString& ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+uno::Sequence<OUString> SAL_CALL ODummyEmbeddedObject::getSupportedServiceNames()
+{
+ return { "com.sun.star.comp.embed.ODummyEmbeddedObject" };
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/general/intercept.cxx b/embeddedobj/source/general/intercept.cxx
index 9b1449cd9518..2ee2949bcf9f 100644
--- a/embeddedobj/source/general/intercept.cxx
+++ b/embeddedobj/source/general/intercept.cxx
@@ -18,7 +18,7 @@
*/
#include <com/sun/star/embed/EmbedStates.hpp>
-#include <cppuhelper/interfacecontainer.hxx>
+#include <comphelper/multiinterfacecontainer3.hxx>
#include <intercept.hxx>
#include <docholder.hxx>
@@ -26,35 +26,36 @@
using namespace ::com::sun::star;
-#define IUL 6
-
-uno::Sequence< OUString > Interceptor::m_aInterceptedURL(IUL);
+constexpr OUString IU0 = u".uno:Save"_ustr;
+constexpr OUString IU1 = u".uno:SaveAll"_ustr;
+constexpr OUString IU2 = u".uno:CloseDoc"_ustr;
+constexpr OUString IU3 = u".uno:CloseWin"_ustr;
+constexpr OUString IU4 = u".uno:CloseFrame"_ustr;
+constexpr OUString IU5 = u".uno:SaveAs"_ustr;
class StatusChangeListenerContainer
- : public cppu::OMultiTypeInterfaceContainerHelperVar<OUString>
+ : public comphelper::OMultiTypeInterfaceContainerHelperVar3<frame::XStatusListener, OUString>
{
public:
explicit StatusChangeListenerContainer(osl::Mutex& aMutex)
- : cppu::OMultiTypeInterfaceContainerHelperVar<OUString>(aMutex)
+ : comphelper::OMultiTypeInterfaceContainerHelperVar3<frame::XStatusListener, OUString>(aMutex)
{
}
};
+namespace embeddedobj
+{
+const uno::Sequence< OUString > Interceptor::m_aInterceptedURL{ IU0, IU1, IU2, IU3, IU4, IU5 };
+
void Interceptor::DisconnectDocHolder()
{
osl::MutexGuard aGuard( m_aMutex );
m_pDocHolder = nullptr;
}
-Interceptor::Interceptor( DocumentHolder* pDocHolder )
+Interceptor::Interceptor( embeddedobj::DocumentHolder* pDocHolder )
: m_pDocHolder( pDocHolder )
{
- m_aInterceptedURL[0] = ".uno:Save";
- m_aInterceptedURL[1] = ".uno:SaveAll";
- m_aInterceptedURL[2] = ".uno:CloseDoc";
- m_aInterceptedURL[3] = ".uno:CloseWin";
- m_aInterceptedURL[4] = ".uno:CloseFrame";
- m_aInterceptedURL[5] = ".uno:SaveAs";
}
Interceptor::~Interceptor()
@@ -94,7 +95,7 @@ Interceptor::dispatch(
{
if ( aNewArgs[nInd].Name == "SaveTo" )
{
- aNewArgs[nInd].Value <<= true;
+ aNewArgs.getArray()[nInd].Value <<= true;
break;
}
nInd++;
@@ -103,8 +104,9 @@ Interceptor::dispatch(
if ( nInd == aNewArgs.getLength() )
{
aNewArgs.realloc( nInd + 1 );
- aNewArgs[nInd].Name = "SaveTo";
- aNewArgs[nInd].Value <<= true;
+ auto pNewArgs = aNewArgs.getArray();
+ pNewArgs[nInd].Name = "SaveTo";
+ pNewArgs[nInd].Value <<= true;
}
uno::Reference< frame::XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch(
@@ -251,26 +253,26 @@ uno::Sequence< uno::Reference< frame::XDispatch > > SAL_CALL
Interceptor::queryDispatches(
const uno::Sequence<frame::DispatchDescriptor >& Requests )
{
- uno::Sequence< uno::Reference< frame::XDispatch > > aRet;
osl::MutexGuard aGuard(m_aMutex);
- if(m_xSlaveDispatchProvider.is())
- aRet = m_xSlaveDispatchProvider->queryDispatches(Requests);
- else
- aRet.realloc(Requests.getLength());
+ typedef uno::Sequence<uno::Reference<frame::XDispatch>> DispatchSeq;
+ DispatchSeq aRet = m_xSlaveDispatchProvider.is()
+ ? m_xSlaveDispatchProvider->queryDispatches(Requests)
+ : DispatchSeq(Requests.getLength());
+ auto aRetRange = asNonConstRange(aRet);
for(sal_Int32 i = 0; i < Requests.getLength(); ++i)
if(m_aInterceptedURL[0] == Requests[i].FeatureURL.Complete)
- aRet[i] = static_cast<frame::XDispatch*>(this);
+ aRetRange[i] = static_cast<frame::XDispatch*>(this);
else if(m_aInterceptedURL[1] == Requests[i].FeatureURL.Complete)
- aRet[i] = nullptr;
+ aRetRange[i] = nullptr;
else if(m_aInterceptedURL[2] == Requests[i].FeatureURL.Complete)
- aRet[i] = static_cast<frame::XDispatch*>(this);
+ aRetRange[i] = static_cast<frame::XDispatch*>(this);
else if(m_aInterceptedURL[3] == Requests[i].FeatureURL.Complete)
- aRet[i] = static_cast<frame::XDispatch*>(this);
+ aRetRange[i] = static_cast<frame::XDispatch*>(this);
else if(m_aInterceptedURL[4] == Requests[i].FeatureURL.Complete)
- aRet[i] = static_cast<frame::XDispatch*>(this);
+ aRetRange[i] = static_cast<frame::XDispatch*>(this);
else if(m_aInterceptedURL[5] == Requests[i].FeatureURL.Complete)
- aRet[i] = static_cast<frame::XDispatch*>(this);
+ aRetRange[i] = static_cast<frame::XDispatch*>(this);
return aRet;
}
@@ -310,4 +312,6 @@ Interceptor::setMasterDispatchProvider(
m_xMasterDispatchProvider = NewSupplier;
}
+} // namespace embeddedobj
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/general/xcreator.cxx b/embeddedobj/source/general/xcreator.cxx
index a54295895190..bceaab63c752 100644
--- a/embeddedobj/source/general/xcreator.cxx
+++ b/embeddedobj/source/general/xcreator.cxx
@@ -25,6 +25,7 @@
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/lang/NoSupportException.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <cppuhelper/supportsservice.hxx>
@@ -45,6 +46,8 @@ uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInsta
const OUString& sEntName,
const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
+ throw lang::NoSupportException("Active OLE content is disabled!");
if ( !xStorage.is() )
throw lang::IllegalArgumentException( "No parent storage is provided!",
static_cast< ::cppu::OWeakObject* >(this),
@@ -164,7 +167,10 @@ uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInsta
aEmbedFactory = m_aConfigHelper.GetFactoryNameByMediaType(MIMETYPE_VND_SUN_XML_BASE_ASCII);
}
- if ( !aEmbedFactory.isEmpty() )
+ if ( !aEmbedFactory.isEmpty()
+ // when active OLE content is disabled, ignore aEmbedFactory and force
+ // the embedded object to be an ODummyEmbeddedObject
+ && !officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
{
uno::Reference< uno::XInterface > xFact = m_xContext->getServiceManager()->createInstanceWithContext(aEmbedFactory, m_xContext);
@@ -188,13 +194,11 @@ uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInsta
* Decides if rFilter should be used to load data into a doc model or real OLE embedding should
* happen. Empty return value means the later.
*/
-static OUString HandleFilter(const uno::Reference<uno::XComponentContext>& xComponentContext,
- const OUString& rFilter)
+static OUString HandleFilter(const OUString& rFilter)
{
OUString aRet = rFilter;
- if (!officecfg::Office::Common::Filter::Microsoft::Import::WinWordToWriter::get(
- xComponentContext))
+ if (!officecfg::Office::Common::Filter::Microsoft::Import::WinWordToWriter::get())
{
if (rFilter == "MS Word 97" || rFilter == "MS Word 2007 XML")
{
@@ -202,29 +206,28 @@ static OUString HandleFilter(const uno::Reference<uno::XComponentContext>& xComp
}
}
- if (!officecfg::Office::Common::Filter::Microsoft::Import::ExcelToCalc::get(xComponentContext))
+ if (!officecfg::Office::Common::Filter::Microsoft::Import::ExcelToCalc::get())
{
if (rFilter == "MS Excel 97" || rFilter == "Calc MS Excel 2007 XML")
{
aRet.clear();
}
}
- if (!officecfg::Office::Common::Filter::Microsoft::Import::PowerPointToImpress::get(
- xComponentContext))
+ if (!officecfg::Office::Common::Filter::Microsoft::Import::PowerPointToImpress::get())
{
if (rFilter == "MS PowerPoint 97" || rFilter == "Impress MS PowerPoint 2007 XML")
{
aRet.clear();
}
}
- if (!officecfg::Office::Common::Filter::Microsoft::Import::VisioToDraw::get(xComponentContext))
+ if (!officecfg::Office::Common::Filter::Microsoft::Import::VisioToDraw::get())
{
if (rFilter == "Visio Document")
{
aRet.clear();
}
}
- if (!officecfg::Office::Common::Filter::Adobe::Import::PDFToDraw::get(xComponentContext))
+ if (!officecfg::Office::Common::Filter::Adobe::Import::PDFToDraw::get())
{
if (rFilter == "draw_pdf_import")
{
@@ -241,6 +244,8 @@ uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInsta
const uno::Sequence< beans::PropertyValue >& aMediaDescr,
const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
+ throw lang::NoSupportException("Active OLE content is disabled!");
// TODO: use lObjArgs
if ( !xStorage.is() )
@@ -259,7 +264,7 @@ uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInsta
// check if there is FilterName
OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, false );
- aFilterName = HandleFilter(m_xContext, aFilterName);
+ aFilterName = HandleFilter(aFilterName);
if ( !aFilterName.isEmpty() )
{
@@ -302,6 +307,8 @@ uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInsta
const uno::Sequence< beans::PropertyValue >& aArgs,
const uno::Sequence< beans::PropertyValue >& aObjectArgs )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
+ throw lang::NoSupportException("Active OLE content is disabled!");
if ( !xStorage.is() )
throw lang::IllegalArgumentException( "No parent storage is provided!",
static_cast< ::cppu::OWeakObject* >(this),
@@ -333,13 +340,16 @@ uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInsta
const uno::Sequence< beans::PropertyValue >& aMediaDescr,
const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
+ throw lang::NoSupportException("Active OLE content is disabled!");
+
uno::Reference< uno::XInterface > xResult;
uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr );
// check if there is URL, URL must exist
OUString aURL;
- for ( beans::PropertyValue const & prop : std::as_const(aTempMedDescr) )
+ for (beans::PropertyValue const& prop : aTempMedDescr)
if ( prop.Name == "URL" )
prop.Value >>= aURL;
@@ -410,7 +420,7 @@ extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
embeddedobj_UNOEmbeddedObjectCreator_get_implementation(
css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
{
- return cppu::acquire(static_cast<cppu::OWeakObject*>(new UNOEmbeddedObjectCreator(context)));
+ return cppu::acquire(new UNOEmbeddedObjectCreator(context));
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/inc/commonembobj.hxx b/embeddedobj/source/inc/commonembobj.hxx
index 2294b0d7e915..2e2cfc38d326 100644
--- a/embeddedobj/source/inc/commonembobj.hxx
+++ b/embeddedobj/source/inc/commonembobj.hxx
@@ -32,9 +32,16 @@
#include <com/sun/star/awt/Rectangle.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/chart2/XDefaultSizeTransmitter.hpp>
+#include <com/sun/star/io/XTempFile.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
#include <cppuhelper/weak.hxx>
+#include <embeddedobj/embeddedupdate.hxx>
#include <rtl/ref.hxx>
#include <map>
+#include <memory>
+#include <svtools/filechangedchecker.hxx>
+#include <unotools/resmgr.hxx>
namespace com::sun::star {
namespace embed {
@@ -52,8 +59,8 @@ namespace com::sun::star {
}
}
-namespace cppu {
- class OMultiTypeInterfaceContainerHelper;
+namespace comphelper {
+ class OMultiTypeInterfaceContainerHelper2;
}
namespace comphelper {
@@ -65,26 +72,30 @@ namespace comphelper {
#include "docholder.hxx"
-class Interceptor;
+namespace embeddedobj { class Interceptor; }
/**
* Represents an OLE object that has native data and we loaded that data into a
* document model successfully.
*/
class OCommonEmbeddedObject : public css::embed::XEmbeddedObject
+ , public css::embed::EmbeddedUpdate
, public css::embed::XEmbedPersist2
, public css::embed::XLinkageSupport
, public css::embed::XInplaceObject
, public css::container::XChild
, public css::chart2::XDefaultSizeTransmitter
+ , public css::lang::XServiceInfo
+ , public css::lang::XInitialization
+ , public css::lang::XTypeProvider
, public ::cppu::OWeakObject
{
protected:
::osl::Mutex m_aMutex;
- rtl::Reference<DocumentHolder> m_xDocHolder;
+ rtl::Reference<embeddedobj::DocumentHolder> m_xDocHolder;
- ::cppu::OMultiTypeInterfaceContainerHelper* m_pInterfaceContainer;
+ std::unique_ptr<::comphelper::OMultiTypeInterfaceContainerHelper2> m_pInterfaceContainer;
bool m_bReadOnly;
@@ -109,8 +120,6 @@ protected:
css::uno::Sequence< css::embed::VerbDescriptor > m_aObjectVerbs;
- css::uno::Sequence< sal_Int32 > m_aAcceptedStates;
- css::uno::Sequence< sal_Int32 > m_pIntermediateStatesSeqs[NUM_SUPPORTED_STATES][NUM_SUPPORTED_STATES];
std::map< sal_Int32, sal_Int32 > m_aVerbTable;
css::uno::Reference< css::embed::XEmbeddedClient > m_xClientSite;
@@ -132,7 +141,11 @@ protected:
css::awt::Rectangle m_aOwnRectangle;
css::awt::Rectangle m_aClipRectangle;
- bool m_bIsLink;
+ bool m_bIsLinkURL;
+ bool m_bLinkTempFileChanged;
+ ::std::unique_ptr< FileChangedChecker > m_pLinkFile;
+ bool m_bOleUpdate;
+ bool m_bInHndFunc;
// embedded object related stuff
OUString m_aEntryName;
@@ -146,6 +159,9 @@ protected:
bool m_bLinkHasPassword;
OUString m_aLinkPassword;
+ // tdf#141529 hold a cc of a linked OLE
+ css::uno::Reference < css::io::XTempFile > m_aLinkTempFile;
+
css::uno::Reference< css::uno::XInterface > m_xParent;
bool m_bHasClonedSize; // the object has cached size
@@ -182,6 +198,16 @@ private:
void Deactivate();
+ // when State = CopyTempToLink -> the user pressed the save button
+ // when change in embedded part then copy to the linked-file
+ // CopyLinkToTemp -> the user pressed the refresh button
+ // when change in linked-file then copy to the embedded part (temp-file)
+ // CopyLinkToTempInit -> create the temp file
+ // CopyLinkToTempRefresh -> when save and Link change but not temp then update temp
+ enum class CopyBackToOLELink {NoCopy, CopyTempToLink, CopyLinkToTemp, CopyLinkToTempInit, CopyLinkToTempRefresh};
+
+ void handleLinkedOLE( CopyBackToOLELink eState );
+
void StateChangeNotification_Impl( bool bBeforeChange, sal_Int32 nOldState, sal_Int32 nNewState,::osl::ResettableMutexGuard& _rGuard );
void SwitchStateTo_Impl( sal_Int32 nNextState );
@@ -226,14 +252,21 @@ private:
const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
const css::uno::Sequence< css::beans::PropertyValue >& lObjArgs );
+ int ShowMsgDialog(TranslateId Msg, const OUString& sFileName);
+
+ bool getAllowLinkUpdate() const;
+
+protected:
+ void SetInplaceActiveState();
+
public:
OCommonEmbeddedObject(
- const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ css::uno::Reference< css::uno::XComponentContext > xContext,
const css::uno::Sequence< css::beans::NamedValue >& aObjectProps );
// no persistence for linked objects, so the descriptors are provided in constructor
OCommonEmbeddedObject(
- const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ css::uno::Reference< css::uno::XComponentContext > xContext,
const css::uno::Sequence< css::beans::NamedValue >& aObjectProps,
const css::uno::Sequence< css::beans::PropertyValue >& aMediaDescr,
const css::uno::Sequence< css::beans::PropertyValue >& aObjectDescr );
@@ -253,10 +286,10 @@ public:
virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& rType ) override ;
virtual void SAL_CALL acquire()
- throw() override;
+ noexcept override;
virtual void SAL_CALL release()
- throw() override;
+ noexcept override;
// XEmbeddedObject
@@ -283,6 +316,10 @@ public:
virtual void SAL_CALL setContainerName( const OUString& sName ) override;
+// EmbeddedUpdate
+
+ virtual void SetOleState(bool bIsOleUpdate) override;
+
// XVisualObject
@@ -393,6 +430,18 @@ public:
// XDefaultSizeTransmitter
//#i103460# charts do not necessarily have an own size within ODF files, in this case they need to use the size settings from the surrounding frame, which is made available with this method
virtual void SAL_CALL setDefaultSize( const css::awt::Size& rSize_100TH_MM ) override;
+
+ // XServiceInfo
+ OUString SAL_CALL getImplementationName() override;
+ sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+ // XInitialization
+ void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& rArguments) override;
+
+ // XTypeProvider
+ css::uno::Sequence<css::uno::Type> SAL_CALL getTypes() override;
+ css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() override;
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/inc/docholder.hxx b/embeddedobj/source/inc/docholder.hxx
index 303fb4c97d10..d4aa54d3b10c 100644
--- a/embeddedobj/source/inc/docholder.hxx
+++ b/embeddedobj/source/inc/docholder.hxx
@@ -38,6 +38,9 @@
#include <rtl/ref.hxx>
class OCommonEmbeddedObject;
+
+namespace embeddedobj
+{
class Interceptor;
class DocumentHolder :
@@ -112,7 +115,7 @@ public:
const css::uno::Reference< css::frame::XDispatchProvider >& xOwnDisp );
- DocumentHolder( const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ DocumentHolder( css::uno::Reference< css::uno::XComponentContext > xContext,
OCommonEmbeddedObject* pEmbObj );
virtual ~DocumentHolder() override;
@@ -197,4 +200,6 @@ public:
virtual void SAL_CALL deactivated( ) override;
};
+} // namespace embeddedobj
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/inc/dummyobject.hxx b/embeddedobj/source/inc/dummyobject.hxx
index 17d113cb7153..64ee7deeb5e8 100644
--- a/embeddedobj/source/inc/dummyobject.hxx
+++ b/embeddedobj/source/inc/dummyobject.hxx
@@ -27,8 +27,9 @@
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/embed/XEmbeddedObject.hpp>
#include <com/sun/star/embed/XEmbedPersist.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
#include <cppuhelper/implbase.hxx>
-#include <cppuhelper/interfacecontainer.hxx>
+#include <comphelper/multicontainer2.hxx>
namespace com::sun::star {
namespace embed {
@@ -43,20 +44,17 @@ namespace com::sun::star {
}
}
-namespace cppu {
- class OMultiTypeInterfaceContainerHelper;
-}
-
/**
* Represents an OLE object that has native data (next to the replacement
* image), but we don't understand that data.
*/
class ODummyEmbeddedObject : public ::cppu::WeakImplHelper
< css::embed::XEmbeddedObject
- , css::embed::XEmbedPersist >
+ , css::embed::XEmbedPersist
+ , css::lang::XServiceInfo >
{
::osl::Mutex m_aMutex;
- std::unique_ptr<cppu::OMultiTypeInterfaceContainerHelper>
+ std::unique_ptr<comphelper::OMultiTypeInterfaceContainerHelper2>
m_pInterfaceContainer;
bool m_bDisposed;
@@ -198,6 +196,10 @@ public:
virtual void SAL_CALL removeEventListener(
const css::uno::Reference< css::document::XEventListener >& Listener ) override;
+ // XServiceInfo
+ OUString SAL_CALL getImplementationName() override;
+ sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/inc/intercept.hxx b/embeddedobj/source/inc/intercept.hxx
index 8dc0f843959a..83228c837ddc 100644
--- a/embeddedobj/source/inc/intercept.hxx
+++ b/embeddedobj/source/inc/intercept.hxx
@@ -28,6 +28,9 @@
class StatusChangeListenerContainer;
+
+namespace embeddedobj
+{
class DocumentHolder;
class Interceptor : public ::cppu::WeakImplHelper< css::frame::XDispatchProviderInterceptor,
@@ -36,7 +39,7 @@ class Interceptor : public ::cppu::WeakImplHelper< css::frame::XDispatchProvider
{
public:
- Interceptor( DocumentHolder* pDocHolder );
+ Interceptor( embeddedobj::DocumentHolder* pDocHolder );
virtual ~Interceptor() override;
void DisconnectDocHolder();
@@ -104,14 +107,16 @@ private:
osl::Mutex m_aMutex;
- DocumentHolder* m_pDocHolder;
+ embeddedobj::DocumentHolder* m_pDocHolder;
css::uno::Reference< css::frame::XDispatchProvider > m_xSlaveDispatchProvider;
css::uno::Reference< css::frame::XDispatchProvider > m_xMasterDispatchProvider;
- static css::uno::Sequence< OUString > m_aInterceptedURL;
+ static const css::uno::Sequence< OUString > m_aInterceptedURL;
std::unique_ptr<StatusChangeListenerContainer> m_pStatCL;
};
+} // namespace embeddedobj
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/inc/oleembobj.hxx b/embeddedobj/source/inc/oleembobj.hxx
index bc75a5af9c4c..087a3c829527 100644
--- a/embeddedobj/source/inc/oleembobj.hxx
+++ b/embeddedobj/source/inc/oleembobj.hxx
@@ -32,6 +32,7 @@
#include <com/sun/star/util/XCloseListener.hpp>
#include <com/sun/star/io/XActiveDataStreamer.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <cppuhelper/implbase.hxx>
#include <rtl/ref.hxx>
@@ -39,8 +40,8 @@
#include <osl/thread.h>
#include <memory>
-namespace cppu {
- class OMultiTypeInterfaceContainerHelper;
+namespace comphelper {
+ class OMultiTypeInterfaceContainerHelper2;
}
class VerbExecutionController
@@ -114,7 +115,8 @@ class OleEmbeddedObject : public ::cppu::WeakImplHelper
, css::embed::XInplaceObject
, css::container::XChild
, css::io::XActiveDataStreamer
- , css::lang::XInitialization >
+ , css::lang::XInitialization
+ , css::lang::XServiceInfo >
{
friend class OleComponent;
@@ -122,7 +124,7 @@ class OleEmbeddedObject : public ::cppu::WeakImplHelper
rtl::Reference<OleComponent> m_pOleComponent;
- std::unique_ptr<::cppu::OMultiTypeInterfaceContainerHelper> m_pInterfaceContainer;
+ std::unique_ptr<::comphelper::OMultiTypeInterfaceContainerHelper2> m_pInterfaceContainer;
bool m_bReadOnly;
@@ -247,7 +249,8 @@ protected:
const css::uno::Reference< css::embed::XStorage >& xStorage,
const OUString& sEntName,
const css::uno::Sequence< css::beans::PropertyValue >& lObjArgs,
- bool bSaveAs );
+ bool bSaveAs,
+ osl::ResettableMutexGuard& rGuard);
#ifdef _WIN32
/// @throws css::uno::Exception
void StoreObjectToStream( css::uno::Reference< css::io::XOutputStream > const & xOutStream );
@@ -270,7 +273,7 @@ protected:
css::uno::Reference< css::io::XStream > TryToRetrieveCachedVisualRepresentation_Impl(
const css::uno::Reference< css::io::XStream >& xStream,
bool bAllowRepair50 = false )
- throw ();
+ noexcept;
#ifdef _WIN32
bool SaveObject_Impl();
bool OnShowWindow_Impl( bool bShow );
@@ -290,13 +293,13 @@ protected:
public:
// in case a new object must be created the class ID must be specified
- OleEmbeddedObject( const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ OleEmbeddedObject( css::uno::Reference< css::uno::XComponentContext > xContext,
const css::uno::Sequence< sal_Int8 >& aClassID,
- const OUString& aClassName );
+ OUString aClassName );
// in case object will be loaded from a persistent entry or from a file the class ID will be detected on loading
// factory can do it for OOo objects, but for OLE objects OS dependent code is required
- OleEmbeddedObject( const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ OleEmbeddedObject( css::uno::Reference< css::uno::XComponentContext > xContext,
bool bLink );
#ifdef _WIN32
// this constructor let object be initialized from clipboard
@@ -444,6 +447,22 @@ public:
// XInitialization
void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& rArguments) override;
+
+ // XServiceInfo
+ OUString SAL_CALL getImplementationName() override;
+ sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
};
+namespace
+{
+#if defined(_WIN32)
+template <class Proc> auto ExecUnlocked(Proc proc, osl::ResettableMutexGuard& guard)
+{
+ osl::ResettableMutexGuardScopedReleaser area(guard);
+ return proc();
+}
+#endif
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/inc/specialobject.hxx b/embeddedobj/source/inc/specialobject.hxx
index 5c467b97a379..9ec0d7d86465 100644
--- a/embeddedobj/source/inc/specialobject.hxx
+++ b/embeddedobj/source/inc/specialobject.hxx
@@ -47,6 +47,17 @@ public:
virtual void SAL_CALL changeState( sal_Int32 nNewState ) override;
virtual void SAL_CALL doVerb( sal_Int32 nVerbID ) override;
+
+// XCommonEmbedPersist
+
+ virtual void SAL_CALL reload(
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
+ const css::uno::Sequence< css::beans::PropertyValue >& lObjArgs ) override;
+
+ // XServiceInfo
+ OUString SAL_CALL getImplementationName() override;
+ sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/inc/strings.hrc b/embeddedobj/source/inc/strings.hrc
new file mode 100644
index 000000000000..420d2d05d091
--- /dev/null
+++ b/embeddedobj/source/inc/strings.hrc
@@ -0,0 +1,19 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#define NC_(Context, String) TranslateId(Context, u8##String)
+
+#define BTN_OVERWRITE_TEXT NC_("BTN_OVERWRITE_TEXT", "Overwrite")
+#define STR_OVERWRITE_LINK NC_("STR_OVERWRITE_LINK", "You have made changes to the %{filename}, saving will overwrite the data from the inserted object.\n\nDo you still want to overwrite this data?")
+#define STR_OVERWRITE_TEMP NC_("STR_OVERWRITE_TEMP", "You have changed the data in the inserted object which will be overwritten by updating the %{filename}.\n\nDo you still want to overwrite this data?")
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/embeddedobj/source/msole/graphconvert.cxx b/embeddedobj/source/msole/graphconvert.cxx
index f5de2b35824d..f853f03dc19b 100644
--- a/embeddedobj/source/msole/graphconvert.cxx
+++ b/embeddedobj/source/msole/graphconvert.cxx
@@ -29,6 +29,7 @@
#include <com/sun/star/beans/PropertyValue.hpp>
#include <unotools/streamwrap.hxx>
#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
#include <comphelper/seqstream.hxx>
#include <tools/stream.hxx>
#include <vcl/graphicfilter.hxx>
@@ -53,7 +54,7 @@ bool ConvertBufferToFormat( void* pBuf,
SvMemoryStream aMemoryStream(pBuf, nBufSize, StreamMode::READ);
GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
sal_uInt16 nRetFormat = 0;
- if (rFilter.CanImportGraphic(OUString(), aMemoryStream, GRFILTER_FORMAT_DONTKNOW, &nRetFormat) == ERRCODE_NONE &&
+ if (rFilter.CanImportGraphic(u"", aMemoryStream, GRFILTER_FORMAT_DONTKNOW, &nRetFormat) == ERRCODE_NONE &&
rFilter.GetImportFormatMediaType(nRetFormat) == aMimeType)
{
aResult <<= uno::Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemoryStream.GetData() ), aMemoryStream.TellEnd() );
@@ -65,19 +66,17 @@ bool ConvertBufferToFormat( void* pBuf,
try
{
uno::Reference < graphic::XGraphicProvider > xGraphicProvider( graphic::GraphicProvider::create(comphelper::getProcessComponentContext()));
- uno::Sequence< beans::PropertyValue > aMediaProperties( 1 );
- aMediaProperties[0].Name = "InputStream";
- aMediaProperties[0].Value <<= xIn;
+ uno::Sequence< beans::PropertyValue > aMediaProperties{ comphelper::makePropertyValue(
+ "InputStream", xIn) };
uno::Reference< graphic::XGraphic > xGraphic( xGraphicProvider->queryGraphic( aMediaProperties ) );
if( xGraphic.is() )
{
SvMemoryStream aNewStream( 65535, 65535 );
uno::Reference < io::XStream > xOut = new utl::OStreamWrapper( aNewStream );
- uno::Sequence< beans::PropertyValue > aOutMediaProperties( 2 );
- aOutMediaProperties[0].Name = "OutputStream";
- aOutMediaProperties[0].Value <<= xOut;
- aOutMediaProperties[1].Name = "MimeType";
- aOutMediaProperties[1].Value <<= aMimeType;
+ uno::Sequence< beans::PropertyValue > aOutMediaProperties{
+ comphelper::makePropertyValue("OutputStream", xOut),
+ comphelper::makePropertyValue("MimeType", aMimeType)
+ };
xGraphicProvider->storeGraphic( xGraphic, aOutMediaProperties );
aResult <<= uno::Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aNewStream.GetData() ), aNewStream.TellEnd() );
diff --git a/embeddedobj/source/msole/olecomponent.cxx b/embeddedobj/source/msole/olecomponent.cxx
index 9fe827bb00d9..b9c1c27827bb 100644
--- a/embeddedobj/source/msole/olecomponent.cxx
+++ b/embeddedobj/source/msole/olecomponent.cxx
@@ -24,6 +24,7 @@
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/embed/WrongStateException.hpp>
#include <com/sun/star/embed/UnreachableStateException.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/io/TempFile.hpp>
@@ -32,12 +33,18 @@
#include <com/sun/star/awt/XRequestCallback.hpp>
#include "platform.h"
-#include <cppuhelper/interfacecontainer.h>
+#include <comphelper/multicontainer2.hxx>
#include <comphelper/mimeconfighelper.hxx>
#include <comphelper/processfactory.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <comphelper/windowserrorstring.hxx>
#include <osl/file.hxx>
#include <rtl/ref.hxx>
#include <o3tl/char16_t2wchar_t.hxx>
+#include <o3tl/unit_conversion.hxx>
+#include <systools/win32/comtools.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/threadex.hxx>
#include "graphconvert.hxx"
#include "olecomponent.hxx"
@@ -54,168 +61,118 @@ using namespace ::comphelper;
#define MAX_ENUM_ELE 20
#define FORMATS_NUM 3
-// ============ class ComSmart =====================
-namespace {
-
-template< class T > class ComSmart
-{
- T* m_pInterface;
-
- void OwnRelease()
- {
- if ( m_pInterface )
- {
- T* pInterface = m_pInterface;
- m_pInterface = nullptr;
- pInterface->Release();
- }
- }
-
-public:
- ComSmart()
- : m_pInterface( nullptr )
- {}
-
- ComSmart( const ComSmart<T>& rObj )
- : m_pInterface( rObj.m_pInterface )
- {
- if ( m_pInterface != NULL )
- m_pInterface->AddRef();
- }
-
- ComSmart( T* pInterface )
- : m_pInterface( pInterface )
- {
- if ( m_pInterface != NULL )
- m_pInterface->AddRef();
- }
-
- ~ComSmart()
- {
- OwnRelease();
- }
-
- ComSmart& operator=( const ComSmart<T>& rObj )
- {
- if(this == &rObj)
- return *this;
-
- OwnRelease();
-
- m_pInterface = rObj.m_pInterface;
-
- if ( m_pInterface != NULL )
- m_pInterface->AddRef();
-
- return *this;
- }
-
- ComSmart<T>& operator=( T* pInterface )
- {
- OwnRelease();
-
- m_pInterface = pInterface;
-
- if ( m_pInterface != NULL )
- m_pInterface->AddRef();
-
- return *this;
- }
-
- operator T*() const
- {
- return m_pInterface;
- }
-
- T& operator*() const
- {
- return *m_pInterface;
- }
-
- T** operator&()
- {
- OwnRelease();
-
- m_pInterface = nullptr;
-
- return &m_pInterface;
- }
-
- T* operator->() const
- {
- return m_pInterface;
- }
-
- bool operator==( const ComSmart<T>& rObj ) const
- {
- return ( m_pInterface == rObj.m_pInterface );
- }
-
- bool operator!=( const ComSmart<T>& rObj ) const
- {
- return ( m_pInterface != rObj.m_pInterface );
- }
-
- bool operator==( const T* pInterface ) const
- {
- return ( m_pInterface == pInterface );
- }
-
- bool operator!=( const T* pInterface ) const
- {
- return ( m_pInterface != pInterface );
- }
-};
-
-}
-
-// ============ class ComSmart =====================
-
-typedef std::vector< FORMATETC* > FormatEtcList;
-
FORMATETC const pFormatTemplates[FORMATS_NUM] = {
{ CF_ENHMETAFILE, nullptr, 0, -1, TYMED_ENHMF },
{ CF_METAFILEPICT, nullptr, 0, -1, TYMED_MFPICT },
{ CF_BITMAP, nullptr, 0, -1, TYMED_GDI } };
-struct OleComponentNative_Impl {
- ComSmart< IUnknown > m_pObj;
- ComSmart< IOleObject > m_pOleObject;
- ComSmart< IViewObject2 > m_pViewObject2;
- ComSmart< IStorage > m_pIStorage;
- FormatEtcList m_aFormatsList;
+// We have at least one single-threaded apartment (STA) in the process (the VCL Main thread, which
+// is the GUI thread), and a multithreaded apartment (MTA) for most of other threads. OLE objects
+// may be created in either: in interactive mode, this typically happens in the STA; when serving
+// external requests, this may be either in STA (when explicit "OnMainThread" argument is passed to
+// loadComponentFromURL, and the instantiation of the object happens during the load), or in MTA
+// (the thread actually serving the incoming calls).
+//
+// The objects typically can only be used in the apartment where they were instantiated. This means
+// that e.g. a call to IOleObject::Close will fail, if it is performed in a different thread, when
+// it was started in the main thread. And vice versa, opening a document in a handler thread, then
+// trying to interact with the OLE object in GUI would fail.
+//
+// To handle this, several workarounds were implemented in the past; the mentioned "OnMainThread"
+// argument is one of these, allowing open document requests be processed not in the handler threads
+// that received the request, but in the main thread which will then be used for interaction. Also
+// OleComponent::GetExtent was changed to check if the first call to IDataObject::GetData failed
+// with RPC_E_WRONG_THREAD, and then retry in the main thread.
+//
+// But ultimately every call to the OLE object needs such checks. E.g., failing to close the object
+// keeps the server running, effectively leaking resources, until it crashes/freezes after multiple
+// iterations.
+//
+// Currently, OleComponentNative_Impl is implemented using IGlobalInterfaceTable, which allows to
+// register an object in process-global instance of the table from the thread that instantiated the
+// object, and obtain a "cookie" (a number); and then use that cookie from any thread to access that
+// object. The global table will do its magic to provide either the original object (when it is
+// requested from the same apartment as used for its registration), or a "proxy", which will marshal
+// all calls to the proper thread, transparently for the caller. This implementation should obsolete
+// the previous workarounds (in theory).
+//
+// m_pGlobalTable is the reference to the global table.
+// The storage object gets registered in the global table immediately when it's created.
+// But the OLE object itself can't be registered immediately, before it is run: an attempt to call
+// RegisterInterfaceInGlobal with such a newly created OLE object fails with CO_E_OBJNOTCONNECTED.
+// Thus, the initial reference to the OLE object (which at this stage seems to be apartment-neutral)
+// is stored to m_pObj. Only when it is run, it is registered in the global table.
+//
+// Indeed, the implicit change of the thread is a blocking operation, which opens a wonderful new
+// opportunities for shiny deadlocks. Thus, precautions are needed to avoid them.
+//
+// When the OLE object is accessed by m_pObj (should be only in initialization code!), no measures
+// are taken to change locking. But when it is accessed by getObj() - which may return the proxy -
+// the calls are guarded by a SolarMutexReleaser, to allow the other thread do its job.
+//
+// There are at least two other mutexes in play here. One is in OleEmbeddedObject, that holds the
+// OleComponent. The calls to OleComponent's methods are also wrapped there into unlock/lock pairs
+// (see OleEmbeddedObject::changeState). The other is in OleComponent itself. For now, I see no
+// deadlocks caused by that mutex, so no unlock/lock is introduced for that. It may turn out to be
+// required eventually.
+class OleComponentNative_Impl
+{
+public:
+ sal::systools::COMReference< IUnknown > m_pObj;
uno::Sequence< datatransfer::DataFlavor > m_aSupportedGraphFormats;
+ // The getters may return a proxy, that redirects the calls to another thread.
+ // Thus, calls to methods of returned objects must be inside solar mutex releaser.
+ auto getStorage() const { return getInterface<IStorage>(m_nStorage); }
+ auto getObj() const { return m_nOleObject ? getInterface<IUnknown>(m_nOleObject) : m_pObj; }
+ template <typename T>
+ auto get() const { return getObj().QueryInterface<T>(sal::systools::COM_QUERY); }
+
+ void registerStorage(IStorage* pStorage) { registerInterface(pStorage, m_nStorage); }
+ void registerObj() { registerInterface(m_pObj.get(), m_nOleObject); }
+
+ bool IsStorageRegistered() const { return m_nStorage != 0; }
+
OleComponentNative_Impl()
+ : m_pGlobalTable(CLSID_StdGlobalInterfaceTable, nullptr, CLSCTX_INPROC_SERVER)
{
// TODO: Extend format list
- m_aSupportedGraphFormats.realloc( 5 );
+ m_aSupportedGraphFormats = {
- m_aSupportedGraphFormats[0] = datatransfer::DataFlavor(
+ datatransfer::DataFlavor(
"application/x-openoffice-emf;windows_formatname=\"Image EMF\"",
"Windows Enhanced Metafile",
- cppu::UnoType<uno::Sequence< sal_Int8 >>::get() );
+ cppu::UnoType<uno::Sequence< sal_Int8 >>::get() ),
- m_aSupportedGraphFormats[1] = datatransfer::DataFlavor(
+ datatransfer::DataFlavor(
"application/x-openoffice-wmf;windows_formatname=\"Image WMF\"",
"Windows Metafile",
- cppu::UnoType<uno::Sequence< sal_Int8 >>::get() );
+ cppu::UnoType<uno::Sequence< sal_Int8 >>::get() ),
- m_aSupportedGraphFormats[2] = datatransfer::DataFlavor(
+ datatransfer::DataFlavor(
"application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"",
"Bitmap",
- cppu::UnoType<uno::Sequence< sal_Int8 >>::get() );
+ cppu::UnoType<uno::Sequence< sal_Int8 >>::get() ),
- m_aSupportedGraphFormats[3] = datatransfer::DataFlavor(
+ datatransfer::DataFlavor(
"image/png",
"PNG",
- cppu::UnoType<uno::Sequence< sal_Int8 >>::get() );
+ cppu::UnoType<uno::Sequence< sal_Int8 >>::get() ),
- m_aSupportedGraphFormats[0] = datatransfer::DataFlavor(
+ datatransfer::DataFlavor(
"application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"",
"GDIMetafile",
- cppu::UnoType<uno::Sequence< sal_Int8 >>::get() );
+ cppu::UnoType<uno::Sequence< sal_Int8 >>::get() )
+ };
+ }
+
+ ~OleComponentNative_Impl()
+ {
+ if (m_nOleObject)
+ m_pGlobalTable->RevokeInterfaceFromGlobal(m_nOleObject);
+ if (m_nStorage)
+ m_pGlobalTable->RevokeInterfaceFromGlobal(m_nStorage);
}
bool ConvertDataForFlavor( const STGMEDIUM& aMedium,
@@ -225,8 +182,31 @@ struct OleComponentNative_Impl {
bool GraphicalFlavor( const datatransfer::DataFlavor& aFlavor );
uno::Sequence< datatransfer::DataFlavor > GetFlavorsForAspects( sal_uInt32 nSupportedAspects );
-};
+ sal::systools::COMReference<IStorage> CreateNewStorage(const OUString& url);
+
+private:
+ sal::systools::COMReference<IGlobalInterfaceTable> m_pGlobalTable;
+ DWORD m_nStorage = 0;
+ DWORD m_nOleObject = 0;
+
+ template <typename T> sal::systools::COMReference<T> getInterface(DWORD cookie) const
+ {
+ sal::systools::COMReference<T> result;
+ HRESULT hr = m_pGlobalTable->GetInterfaceFromGlobal(cookie, IID_PPV_ARGS(&result));
+ SAL_WARN_IF(FAILED(hr), "embeddedobj.ole",
+ "GetInterfaceFromGlobal failed: is cookie " << cookie << " not registered?");
+ return result;
+ }
+
+ template <typename T> void registerInterface(T* pInterface, DWORD& cookie)
+ {
+ if (cookie != 0) // E.g., on subsequent RunObject calls
+ return;
+ HRESULT hr = m_pGlobalTable->RegisterInterfaceInGlobal(pInterface, __uuidof(T), &cookie);
+ SAL_WARN_IF(FAILED(hr), "embeddedobj.ole", "RegisterInterfaceInGlobal failed");
+ }
+};
static DWORD GetAspectFromFlavor( const datatransfer::DataFlavor& aFlavor )
{
@@ -258,23 +238,6 @@ static OUString GetFlavorSuffixFromAspect( DWORD nAsp )
}
-static HRESULT OpenIStorageFromURL_Impl( const OUString& aURL, IStorage** ppIStorage )
-{
- OSL_ENSURE( ppIStorage, "The pointer must not be empty!" );
-
- OUString aFilePath;
- if ( !ppIStorage || ::osl::FileBase::getSystemPathFromFileURL( aURL, aFilePath ) != ::osl::FileBase::E_None )
- throw uno::RuntimeException(); // TODO: something dangerous happened
-
- return StgOpenStorage( o3tl::toW(aFilePath.getStr()),
- nullptr,
- STGM_READWRITE | STGM_TRANSACTED, // | STGM_DELETEONRELEASE,
- nullptr,
- 0,
- ppIStorage );
-}
-
-
bool OleComponentNative_Impl::ConvertDataForFlavor( const STGMEDIUM& aMedium,
const datatransfer::DataFlavor& aFlavor,
uno::Any& aResult )
@@ -311,7 +274,7 @@ bool OleComponentNative_Impl::ConvertDataForFlavor( const STGMEDIUM& aMedium,
if ( nBufSize && nBufSize == GetMetaFileBitsEx( pMF->hMF, nBufSize - 22, pBuf.get() + 22 ) )
{
- if ( aFlavor.MimeType.matchAsciiL( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"", 57 ) )
+ if ( aFlavor.MimeType.match( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) )
{
aResult <<= uno::Sequence< sal_Int8 >( pBuf.get(), nBufSize );
bAnyIsReady = true;
@@ -328,7 +291,7 @@ bool OleComponentNative_Impl::ConvertDataForFlavor( const STGMEDIUM& aMedium,
pBuf.reset(new sal_Int8[nBufSize]);
if ( nBufSize && nBufSize == GetEnhMetaFileBits( aMedium.hEnhMetaFile, nBufSize, reinterpret_cast<LPBYTE>(pBuf.get()) ) )
{
- if ( aFlavor.MimeType.matchAsciiL( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"", 57 ) )
+ if ( aFlavor.MimeType.match( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) )
{
aResult <<= uno::Sequence< sal_Int8 >( pBuf.get(), nBufSize );
bAnyIsReady = true;
@@ -348,7 +311,7 @@ bool OleComponentNative_Impl::ConvertDataForFlavor( const STGMEDIUM& aMedium,
pBuf.reset(new sal_Int8[nBufSize]);
if ( nBufSize && nBufSize == sal::static_int_cast< ULONG >( GetBitmapBits( aMedium.hBitmap, nBufSize, pBuf.get() ) ) )
{
- if ( aFlavor.MimeType.matchAsciiL( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", 54 ) )
+ if ( aFlavor.MimeType.match( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ) )
{
aResult <<= uno::Sequence< sal_Int8 >( pBuf.get(), nBufSize );
bAnyIsReady = true;
@@ -358,14 +321,14 @@ bool OleComponentNative_Impl::ConvertDataForFlavor( const STGMEDIUM& aMedium,
if ( pBuf && !bAnyIsReady )
{
- for ( auto const & supportedFormat : std::as_const(m_aSupportedGraphFormats) )
- if ( aFlavor.MimeType.match( supportedFormat.MimeType )
+ for (auto const& supportedFormat : m_aSupportedGraphFormats)
+ if ( aFlavor.MimeType.match( supportedFormat.MimeType )
&& aFlavor.DataType == supportedFormat.DataType
&& aFlavor.DataType == cppu::UnoType<uno::Sequence< sal_Int8 >>::get() )
- {
- bAnyIsReady = ConvertBufferToFormat( pBuf.get(), nBufSize, aFormat, aResult );
- break;
- }
+ {
+ bAnyIsReady = ConvertBufferToFormat( pBuf.get(), nBufSize, aFormat, aResult );
+ break;
+ }
}
}
@@ -376,7 +339,7 @@ bool OleComponentNative_Impl::ConvertDataForFlavor( const STGMEDIUM& aMedium,
bool OleComponentNative_Impl::GraphicalFlavor( const datatransfer::DataFlavor& aFlavor )
{
// Actually all the required graphical formats must be supported
- for ( auto const & supportedFormat : std::as_const(m_aSupportedGraphFormats) )
+ for (auto const& supportedFormat : m_aSupportedGraphFormats)
if ( aFlavor.MimeType.match( supportedFormat.MimeType )
&& aFlavor.DataType == supportedFormat.DataType )
return true;
@@ -417,7 +380,7 @@ static OUString WinAccToVcl_Impl( const sal_Unicode* pStr )
}
else
{
- aResult += OUString( pStr, 1 );
+ aResult += OUStringChar( *pStr );
pStr++;
}
}
@@ -431,12 +394,10 @@ OleComponent::OleComponent( const uno::Reference< uno::XComponentContext >& xCon
: m_pInterfaceContainer( nullptr )
, m_bDisposed( false )
, m_bModified( false )
-, m_pNativeImpl( new OleComponentNative_Impl() )
+, m_pNativeImpl( std::make_unique<OleComponentNative_Impl>() )
, m_pUnoOleObject( pUnoOleObject )
, m_pOleWrapClientSite( nullptr )
, m_pImplAdviseSink( nullptr )
-, m_nOLEMiscFlags( 0 )
-, m_nAdvConn( 0 )
, m_xContext( xContext )
, m_bOleInitialized( false )
, m_bWorkaroundActive( false )
@@ -444,9 +405,14 @@ OleComponent::OleComponent( const uno::Reference< uno::XComponentContext >& xCon
OSL_ENSURE( m_pUnoOleObject, "No owner object is provided!" );
HRESULT hr = OleInitialize( nullptr );
- OSL_ENSURE( hr == S_OK || hr == S_FALSE, "The ole can not be successfully initialized" );
if ( hr == S_OK || hr == S_FALSE )
m_bOleInitialized = true;
+ else
+ {
+ SAL_WARN("embeddedobj.ole", "OleComponent ctor: OleInitialize() failed with 0x"
+ << OUString::number(static_cast<sal_uInt32>(hr), 16) << ": "
+ << WindowsErrorStringFromHRESULT(hr));
+ }
m_pOleWrapClientSite = new OleWrapperClientSite( this );
m_pOleWrapClientSite->AddRef();
@@ -469,14 +435,6 @@ OleComponent::~OleComponent()
Dispose();
} catch( const uno::Exception& ) {}
}
-
- for (auto const& format : m_pNativeImpl->m_aFormatsList)
- {
- delete format;
- }
- m_pNativeImpl->m_aFormatsList.clear();
-
- delete m_pNativeImpl;
}
void OleComponent::Dispose()
@@ -534,30 +492,37 @@ void OleComponent::disconnectEmbeddedObject()
}
-void OleComponent::CreateNewIStorage_Impl()
+OUString OleComponent::getTempURL() const
{
- // TODO: in future a global memory could be used instead of file.
-
- // write the stream to the temporary file
- OUString aTempURL;
-
OSL_ENSURE( m_pUnoOleObject, "Unexpected object absence!" );
if ( m_pUnoOleObject )
- aTempURL = m_pUnoOleObject->CreateTempURLEmpty_Impl();
+ return m_pUnoOleObject->CreateTempURLEmpty_Impl();
else
- aTempURL = GetNewTempFileURL_Impl( m_xContext );
+ return GetNewTempFileURL_Impl(m_xContext);
+}
- if ( !aTempURL.getLength() )
+
+sal::systools::COMReference<IStorage> OleComponentNative_Impl::CreateNewStorage(const OUString& url)
+{
+ if (IsStorageRegistered())
+ throw io::IOException(); // TODO:the object is already initialized
+ // TODO: in future a global memory could be used instead of file.
+
+ // write the stream to the temporary file
+ if (url.isEmpty())
throw uno::RuntimeException(); // TODO
// open an IStorage based on the temporary file
OUString aTempFilePath;
- if ( ::osl::FileBase::getSystemPathFromFileURL( aTempURL, aTempFilePath ) != ::osl::FileBase::E_None )
+ if (osl::FileBase::getSystemPathFromFileURL(url, aTempFilePath) != osl::FileBase::E_None)
throw uno::RuntimeException(); // TODO: something dangerous happened
- HRESULT hr = StgCreateDocfile( o3tl::toW(aTempFilePath.getStr()), STGM_CREATE | STGM_READWRITE | STGM_TRANSACTED | STGM_DELETEONRELEASE, 0, &m_pNativeImpl->m_pIStorage );
- if ( FAILED( hr ) || !m_pNativeImpl->m_pIStorage )
+ sal::systools::COMReference<IStorage> pStorage;
+ HRESULT hr = StgCreateDocfile( o3tl::toW(aTempFilePath.getStr()), STGM_CREATE | STGM_READWRITE | STGM_TRANSACTED | STGM_DELETEONRELEASE, 0, &pStorage );
+ if (FAILED(hr) || !pStorage)
throw io::IOException(); // TODO: transport error code?
+ registerStorage(pStorage);
+ return pStorage;
}
@@ -571,12 +536,13 @@ uno::Sequence< datatransfer::DataFlavor > OleComponentNative_Impl::GetFlavorsFor
sal_Int32 nLength = aResult.getLength();
aResult.realloc( nLength + m_aSupportedGraphFormats.getLength() );
+ auto pResult = aResult.getArray();
for ( sal_Int32 nInd = 0; nInd < m_aSupportedGraphFormats.getLength(); nInd++ )
{
- aResult[nLength + nInd].MimeType = m_aSupportedGraphFormats[nInd].MimeType + aAspectSuffix;
- aResult[nLength + nInd].HumanPresentableName = m_aSupportedGraphFormats[nInd].HumanPresentableName;
- aResult[nLength + nInd].DataType = m_aSupportedGraphFormats[nInd].DataType;
+ pResult[nLength + nInd].MimeType = m_aSupportedGraphFormats[nInd].MimeType + aAspectSuffix;
+ pResult[nLength + nInd].HumanPresentableName = m_aSupportedGraphFormats[nInd].HumanPresentableName;
+ pResult[nLength + nInd].DataType = m_aSupportedGraphFormats[nInd].DataType;
}
}
@@ -586,17 +552,19 @@ uno::Sequence< datatransfer::DataFlavor > OleComponentNative_Impl::GetFlavorsFor
void OleComponent::RetrieveObjectDataFlavors_Impl()
{
- if ( !m_pNativeImpl->m_pOleObject )
+ if (!m_pNativeImpl->m_pObj)
throw embed::WrongStateException(); // TODO: the object is in wrong state
if ( !m_aDataFlavors.getLength() )
{
- ComSmart< IDataObject > pDataObject;
- HRESULT hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pDataObject) );
- if ( SUCCEEDED( hr ) && pDataObject )
+ if (auto pDataObject = m_pNativeImpl->get<IDataObject>())
{
- ComSmart< IEnumFORMATETC > pFormatEnum;
- hr = pDataObject->EnumFormatEtc( DATADIR_GET, &pFormatEnum );
+ HRESULT hr;
+ sal::systools::COMReference< IEnumFORMATETC > pFormatEnum;
+ {
+ SolarMutexReleaser releaser;
+ hr = pDataObject->EnumFormatEtc(DATADIR_GET, &pFormatEnum);
+ }
if ( SUCCEEDED( hr ) && pFormatEnum )
{
FORMATETC pElem[ MAX_ENUM_ELE ];
@@ -611,7 +579,7 @@ void OleComponent::RetrieveObjectDataFlavors_Impl()
if( hr2 == S_OK || hr2 == S_FALSE )
{
for( sal_uInt32 nInd = 0; nInd < FORMATS_NUM; nInd++ )
- {
+ {
if ( pElem[nInd].cfFormat == pFormatTemplates[nInd].cfFormat
&& pElem[nInd].tymed == pFormatTemplates[nInd].tymed )
nSupportedAspects |= pElem[nInd].dwAspect;
@@ -636,27 +604,23 @@ void OleComponent::RetrieveObjectDataFlavors_Impl()
}
-bool OleComponent::InitializeObject_Impl()
+void OleComponent::InitializeObject_Impl()
// There will be no static objects!
{
if ( !m_pNativeImpl->m_pObj )
- return false;
+ throw embed::WrongStateException();
// the linked object will be detected here
- ComSmart< IOleLink > pOleLink;
- HRESULT hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IOleLink, reinterpret_cast<void**>(&pOleLink) );
OSL_ENSURE( m_pUnoOleObject, "Unexpected object absence!" );
if ( m_pUnoOleObject )
- m_pUnoOleObject->SetObjectIsLink_Impl( pOleLink != nullptr );
-
+ m_pUnoOleObject->SetObjectIsLink_Impl( m_pNativeImpl->m_pObj.QueryInterface<IOleLink>(sal::systools::COM_QUERY).is() );
- hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IViewObject2, reinterpret_cast<void**>(&m_pNativeImpl->m_pViewObject2) );
- if ( FAILED( hr ) || !m_pNativeImpl->m_pViewObject2 )
- return false;
+ auto pViewObject2(m_pNativeImpl->m_pObj.QueryInterface<IViewObject2>(sal::systools::COM_QUERY));
+ if (!pViewObject2)
+ throw uno::RuntimeException(); // TODO
// remove all the caches
- IOleCache* pIOleCache = nullptr;
- if ( SUCCEEDED( m_pNativeImpl->m_pObj->QueryInterface( IID_IOleCache, reinterpret_cast<void**>(&pIOleCache) ) ) && pIOleCache )
+ if ( sal::systools::COMReference< IOleCache > pIOleCache{ m_pNativeImpl->m_pObj, sal::systools::COM_QUERY } )
{
IEnumSTATDATA* pEnumSD = nullptr;
HRESULT hr2 = pIOleCache->EnumCache( &pEnumSD );
@@ -674,41 +638,51 @@ bool OleComponent::InitializeObject_Impl()
DWORD nConn;
FORMATETC aFormat = { 0, nullptr, DVASPECT_CONTENT, -1, TYMED_MFPICT };
hr2 = pIOleCache->Cache( &aFormat, ADVFCACHE_ONSAVE, &nConn );
-
- pIOleCache->Release();
- pIOleCache = nullptr;
}
- hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&m_pNativeImpl->m_pOleObject) );
- if ( FAILED( hr ) || !m_pNativeImpl->m_pOleObject )
- return false; // Static objects are not supported, they should be inserted as graphics
+ auto pOleObject(m_pNativeImpl->m_pObj.QueryInterface<IOleObject>(sal::systools::COM_QUERY));
+ if (!pOleObject)
+ throw uno::RuntimeException(); // Static objects are not supported, they should be inserted as graphics
- m_pNativeImpl->m_pOleObject->GetMiscStatus( DVASPECT_CONTENT, reinterpret_cast<DWORD*>(&m_nOLEMiscFlags) );
+ DWORD nOLEMiscFlags(0);
+ pOleObject->GetMiscStatus(DVASPECT_CONTENT, reinterpret_cast<DWORD*>(&nOLEMiscFlags));
// TODO: use other misc flags also
// the object should have drawable aspect even in case it supports only iconic representation
- // if ( m_nOLEMiscFlags & OLEMISC_ONLYICONIC )
+ // if ( nOLEMiscFlags & OLEMISC_ONLYICONIC )
- m_pNativeImpl->m_pOleObject->SetClientSite( m_pOleWrapClientSite );
+ pOleObject->SetClientSite(m_pOleWrapClientSite);
// the only need in this registration is workaround for close notification
- m_pNativeImpl->m_pOleObject->Advise( m_pImplAdviseSink, reinterpret_cast<DWORD*>(&m_nAdvConn) );
- m_pNativeImpl->m_pViewObject2->SetAdvise( DVASPECT_CONTENT, 0, m_pImplAdviseSink );
+ DWORD nAdvConn(0);
+ pOleObject->Advise(m_pImplAdviseSink, reinterpret_cast<DWORD*>(&nAdvConn));
+ pViewObject2->SetAdvise(DVASPECT_CONTENT, 0, m_pImplAdviseSink);
- OleSetContainedObject( m_pNativeImpl->m_pOleObject, TRUE );
-
- return true;
+ OleSetContainedObject(pOleObject, TRUE);
}
namespace
{
- HRESULT OleLoadSeh(LPSTORAGE pIStorage, LPVOID* ppObj)
+ HRESULT OleLoadSeh(LPSTORAGE pIStorage, IUnknown** ppObj)
{
HRESULT hr = E_FAIL;
+ // tdf#119039: there is a nasty bug in OleLoad, that may call an unpaired
+ // IUnknown::Release on pIStorage on STG_E_FILENOTFOUND: see
+ // https://developercommunity.visualstudio.com/t/10144795
+ // Workaround it here to avoid crash in smart COM pointer destructor that
+ // would try to release already released object. Since we don't know if
+ // the bug appears each time STG_E_FILENOTFOUND is returned, this might
+ // potentially leak the storage object.
+ if (pIStorage)
+ pIStorage->AddRef();
+
__try {
- hr = OleLoad(pIStorage, IID_IUnknown, nullptr, ppObj);
+ hr = OleLoad(pIStorage, IID_IUnknown, nullptr, IID_PPV_ARGS_Helper(ppObj));
} __except( EXCEPTION_EXECUTE_HANDLER ) {
- return E_FAIL;
+ hr = E_FAIL;
}
+ if (pIStorage && hr != STG_E_FILENOTFOUND)
+ pIStorage->Release();
+
return hr;
}
}
@@ -718,62 +692,62 @@ void OleComponent::LoadEmbeddedObject( const OUString& aTempURL )
if ( !aTempURL.getLength() )
throw lang::IllegalArgumentException(); // TODO
- if ( m_pNativeImpl->m_pIStorage )
+ if (m_pNativeImpl->IsStorageRegistered())
throw io::IOException(); // TODO the object is already initialized or wrong initialization is done
// open an IStorage based on the temporary file
- HRESULT hr = OpenIStorageFromURL_Impl( aTempURL, &m_pNativeImpl->m_pIStorage );
+ OUString aFilePath;
+ if (osl::FileBase::getSystemPathFromFileURL(aTempURL, aFilePath) != ::osl::FileBase::E_None)
+ throw uno::RuntimeException(); // TODO: something dangerous happened
- if ( FAILED( hr ) || !m_pNativeImpl->m_pIStorage )
+ sal::systools::COMReference<IStorage> pStorage;
+ HRESULT hr = StgOpenStorage(o3tl::toW(aFilePath.getStr()), nullptr,
+ STGM_READWRITE | STGM_TRANSACTED, // | STGM_DELETEONRELEASE,
+ nullptr, 0, &pStorage);
+ if (FAILED(hr) || !pStorage)
throw io::IOException(); // TODO: transport error code?
- hr = OleLoadSeh(m_pNativeImpl->m_pIStorage, reinterpret_cast<void**>(&m_pNativeImpl->m_pObj));
- if ( FAILED( hr ) || !m_pNativeImpl->m_pObj )
- {
+ m_pNativeImpl->registerStorage(pStorage);
+
+ hr = OleLoadSeh(pStorage, &m_pNativeImpl->m_pObj);
+ if (FAILED(hr))
throw uno::RuntimeException();
- }
- if ( !InitializeObject_Impl() )
- throw uno::RuntimeException(); // TODO
+ InitializeObject_Impl();
}
void OleComponent::CreateObjectFromClipboard()
{
- if ( m_pNativeImpl->m_pIStorage )
- throw io::IOException(); // TODO:the object is already initialized
-
- CreateNewIStorage_Impl();
- if ( !m_pNativeImpl->m_pIStorage )
+ auto pStorage(m_pNativeImpl->CreateNewStorage(getTempURL()));
+ if (!pStorage)
throw uno::RuntimeException(); // TODO
IDataObject * pDO = nullptr;
HRESULT hr = OleGetClipboard( &pDO );
- if( SUCCEEDED( hr ) && pDO )
+ if (FAILED(hr))
+ throw uno::RuntimeException();
+
+ hr = OleQueryCreateFromData(pDO);
+ if (S_OK == hr)
{
- hr = OleQueryCreateFromData( pDO );
- if( S_OK == GetScode( hr ) )
- {
- hr = OleCreateFromData( pDO,
- IID_IUnknown,
- OLERENDER_DRAW, // OLERENDER_FORMAT
- nullptr, // &aFormat,
- nullptr,
- m_pNativeImpl->m_pIStorage,
- reinterpret_cast<void**>(&m_pNativeImpl->m_pObj) );
- }
- else
- {
- // Static objects are not supported
- pDO->Release();
- }
+ hr = OleCreateFromData( pDO,
+ IID_IUnknown,
+ OLERENDER_DRAW, // OLERENDER_FORMAT
+ nullptr, // &aFormat,
+ nullptr,
+ pStorage,
+ IID_PPV_ARGS_Helper(&m_pNativeImpl->m_pObj) );
+ if (FAILED(hr))
+ throw uno::RuntimeException();
+ }
+ else
+ {
+ // Static objects are not supported
+ pDO->Release();
}
- if ( FAILED( hr ) || !m_pNativeImpl->m_pObj )
- throw uno::RuntimeException();
-
- if ( !InitializeObject_Impl() )
- throw uno::RuntimeException(); // TODO
+ InitializeObject_Impl();
}
@@ -784,11 +758,8 @@ void OleComponent::CreateNewEmbeddedObject( const uno::Sequence< sal_Int8 >& aSe
if ( !GetClassIDFromSequence_Impl( aSeqCLSID, aClsID ) )
throw lang::IllegalArgumentException(); // TODO
- if ( m_pNativeImpl->m_pIStorage )
- throw io::IOException(); // TODO:the object is already initialized
-
- CreateNewIStorage_Impl();
- if ( !m_pNativeImpl->m_pIStorage )
+ auto pStorage(m_pNativeImpl->CreateNewStorage(getTempURL()));
+ if (!pStorage)
throw uno::RuntimeException(); // TODO
// FORMATETC aFormat = { CF_METAFILEPICT, NULL, nAspect, -1, TYMED_MFPICT }; // for OLE..._DRAW should be NULL
@@ -798,14 +769,12 @@ void OleComponent::CreateNewEmbeddedObject( const uno::Sequence< sal_Int8 >& aSe
OLERENDER_DRAW, // OLERENDER_FORMAT
nullptr, // &aFormat,
nullptr,
- m_pNativeImpl->m_pIStorage,
- reinterpret_cast<void**>(&m_pNativeImpl->m_pObj) );
-
- if ( FAILED( hr ) || !m_pNativeImpl->m_pObj )
+ pStorage,
+ IID_PPV_ARGS_Helper(&m_pNativeImpl->m_pObj) );
+ if (FAILED(hr))
throw uno::RuntimeException(); // TODO
- if ( !InitializeObject_Impl() )
- throw uno::RuntimeException(); // TODO
+ InitializeObject_Impl();
// TODO: getExtent???
}
@@ -824,11 +793,8 @@ void OleComponent::CreateObjectFromData( const uno::Reference< datatransfer::XTr
void OleComponent::CreateObjectFromFile( const OUString& aFileURL )
{
- if ( m_pNativeImpl->m_pIStorage )
- throw io::IOException(); // TODO:the object is already initialized
-
- CreateNewIStorage_Impl();
- if ( !m_pNativeImpl->m_pIStorage )
+ auto pStorage(m_pNativeImpl->CreateNewStorage(getTempURL()));
+ if (!pStorage)
throw uno::RuntimeException(); // TODO:
OUString aFilePath;
@@ -841,24 +807,19 @@ void OleComponent::CreateObjectFromFile( const OUString& aFileURL )
OLERENDER_DRAW, // OLERENDER_FORMAT
nullptr,
nullptr,
- m_pNativeImpl->m_pIStorage,
- reinterpret_cast<void**>(&m_pNativeImpl->m_pObj) );
-
- if ( FAILED( hr ) || !m_pNativeImpl->m_pObj )
+ pStorage,
+ IID_PPV_ARGS_Helper(&m_pNativeImpl->m_pObj) );
+ if (FAILED(hr))
throw uno::RuntimeException(); // TODO
- if ( !InitializeObject_Impl() )
- throw uno::RuntimeException(); // TODO
+ InitializeObject_Impl();
}
void OleComponent::CreateLinkFromFile( const OUString& aFileURL )
{
- if ( m_pNativeImpl->m_pIStorage )
- throw io::IOException(); // TODO:the object is already initialized
-
- CreateNewIStorage_Impl();
- if ( !m_pNativeImpl->m_pIStorage )
+ auto pStorage(m_pNativeImpl->CreateNewStorage(getTempURL()));
+ if (!pStorage)
throw uno::RuntimeException(); // TODO:
OUString aFilePath;
@@ -870,52 +831,52 @@ void OleComponent::CreateLinkFromFile( const OUString& aFileURL )
OLERENDER_DRAW, // OLERENDER_FORMAT
nullptr,
nullptr,
- m_pNativeImpl->m_pIStorage,
- reinterpret_cast<void**>(&m_pNativeImpl->m_pObj) );
-
- if ( FAILED( hr ) || !m_pNativeImpl->m_pObj )
+ pStorage,
+ IID_PPV_ARGS_Helper(&m_pNativeImpl->m_pObj) );
+ if (FAILED(hr))
throw uno::RuntimeException(); // TODO
- if ( !InitializeObject_Impl() )
- throw uno::RuntimeException(); // TODO
+ InitializeObject_Impl();
}
void OleComponent::InitEmbeddedCopyOfLink( rtl::Reference<OleComponent> const & pOleLinkComponent )
{
- if ( !pOleLinkComponent || !pOleLinkComponent->m_pNativeImpl->m_pObj )
+ if (!pOleLinkComponent)
throw lang::IllegalArgumentException(); // TODO
- if ( m_pNativeImpl->m_pIStorage )
- throw io::IOException(); // TODO:the object is already initialized
+ auto pOleLinkComponentObj(pOleLinkComponent->m_pNativeImpl->getObj());
+ if (!pOleLinkComponentObj)
+ throw lang::IllegalArgumentException();
+
+ // the object must be already disconnected from the temporary URL
+ auto pStorage(m_pNativeImpl->CreateNewStorage(getTempURL()));
+
+ SolarMutexReleaser releaser;
- ComSmart< IDataObject > pDataObject;
- HRESULT hr = pOleLinkComponent->m_pNativeImpl->m_pObj->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pDataObject) );
- if ( SUCCEEDED( hr ) && pDataObject && SUCCEEDED( OleQueryCreateFromData( pDataObject ) ) )
+ auto pDataObject(pOleLinkComponentObj.QueryInterface<IDataObject>(sal::systools::COM_QUERY));
+ if ( pDataObject && SUCCEEDED( OleQueryCreateFromData( pDataObject ) ) )
{
- // the object must be already disconnected from the temporary URL
- CreateNewIStorage_Impl();
- if ( !m_pNativeImpl->m_pIStorage )
+ if (!pStorage)
throw uno::RuntimeException(); // TODO:
- hr = OleCreateFromData( pDataObject,
+ OleCreateFromData( pDataObject,
IID_IUnknown,
OLERENDER_DRAW,
nullptr,
nullptr,
- m_pNativeImpl->m_pIStorage,
- reinterpret_cast<void**>(&m_pNativeImpl->m_pObj) );
+ pStorage,
+ IID_PPV_ARGS_Helper(&m_pNativeImpl->m_pObj) );
}
if ( !m_pNativeImpl->m_pObj )
{
- ComSmart< IOleLink > pOleLink;
- hr = pOleLinkComponent->m_pNativeImpl->m_pObj->QueryInterface( IID_IOleLink, reinterpret_cast<void**>(&pOleLink) );
- if ( FAILED( hr ) || !pOleLink )
+ auto pOleLink(pOleLinkComponentObj.QueryInterface<IOleLink>(sal::systools::COM_QUERY));
+ if ( !pOleLink )
throw io::IOException(); // TODO: the object doesn't support IOleLink
- ComSmart< IMoniker > pMoniker;
- hr = pOleLink->GetSourceMoniker( &pMoniker );
+ sal::systools::COMReference< IMoniker > pMoniker;
+ HRESULT hr = pOleLink->GetSourceMoniker( &pMoniker );
if ( FAILED( hr ) || !pMoniker )
throw io::IOException(); // TODO: can not retrieve moniker
@@ -924,7 +885,7 @@ void OleComponent::InitEmbeddedCopyOfLink( rtl::Reference<OleComponent> const &
hr = pMoniker->IsSystemMoniker( &aMonType );
if ( SUCCEEDED( hr ) && aMonType == MKSYS_FILEMONIKER )
{
- ComSmart< IMalloc > pMalloc;
+ sal::systools::COMReference< IMalloc > pMalloc;
hr = CoGetMalloc( 1, &pMalloc ); // if fails there will be a memory leak
OSL_ENSURE(SUCCEEDED(hr) && pMalloc, "CoGetMalloc() failed!");
@@ -942,56 +903,74 @@ void OleComponent::InitEmbeddedCopyOfLink( rtl::Reference<OleComponent> const &
OLERENDER_DRAW, // OLERENDER_FORMAT
nullptr,
nullptr,
- m_pNativeImpl->m_pIStorage,
- reinterpret_cast<void**>(&m_pNativeImpl->m_pObj) );
+ pStorage,
+ IID_PPV_ARGS_Helper(&m_pNativeImpl->m_pObj) );
}
}
// in case of other moniker types the only way is to get storage
if ( !m_pNativeImpl->m_pObj )
{
- ComSmart< IBindCtx > pBindCtx;
+ sal::systools::COMReference< IBindCtx > pBindCtx;
hr = CreateBindCtx( 0, &pBindCtx );
if ( SUCCEEDED( hr ) && pBindCtx )
{
- ComSmart< IStorage > pObjectStorage;
- hr = pMoniker->BindToStorage( pBindCtx, nullptr, IID_IStorage, reinterpret_cast<void**>(&pObjectStorage) );
+ sal::systools::COMReference< IStorage > pObjectStorage;
+ hr = pMoniker->BindToStorage(pBindCtx, nullptr, IID_PPV_ARGS(&pObjectStorage));
if ( SUCCEEDED( hr ) && pObjectStorage )
{
- hr = pObjectStorage->CopyTo( 0, nullptr, nullptr, m_pNativeImpl->m_pIStorage );
+ hr = pObjectStorage->CopyTo(0, nullptr, nullptr, pStorage);
if ( SUCCEEDED( hr ) )
- hr = OleLoadSeh(m_pNativeImpl->m_pIStorage, reinterpret_cast<void**>(&m_pNativeImpl->m_pObj));
+ hr = OleLoadSeh(pStorage, &m_pNativeImpl->m_pObj);
}
}
}
}
- // If object could not be created the only way is to use graphical representation
- if ( FAILED( hr ) || !m_pNativeImpl->m_pObj )
- throw uno::RuntimeException(); // TODO
-
- if ( !InitializeObject_Impl() )
- throw uno::RuntimeException(); // TODO
+ InitializeObject_Impl();
}
void OleComponent::RunObject()
{
- OSL_ENSURE( m_pNativeImpl->m_pOleObject, "The pointer can not be set to NULL here!" );
- if ( !m_pNativeImpl->m_pOleObject )
+ auto pOleObject(m_pNativeImpl->get<IOleObject>());
+ OSL_ENSURE(pOleObject, "The pointer can not be set to NULL here!");
+ if (!pOleObject)
throw embed::WrongStateException(); // TODO: the object is in wrong state
- if ( !OleIsRunning( m_pNativeImpl->m_pOleObject ) )
+ if (!OleIsRunning(pOleObject))
{
HRESULT hr = OleRun( m_pNativeImpl->m_pObj );
if ( FAILED( hr ) )
{
+ OUString error = WindowsErrorStringFromHRESULT(hr);
if ( hr == REGDB_E_CLASSNOTREG )
- throw embed::UnreachableStateException(); // the object server is not installed
+ {
+ if (auto pOleObj
+ = m_pNativeImpl->m_pObj.QueryInterface<IOleObject>(sal::systools::COM_QUERY))
+ {
+ LPOLESTR lpUserType = nullptr;
+ if (SUCCEEDED(pOleObj->GetUserType(USERCLASSTYPE_FULL, &lpUserType)))
+ {
+ error += OUString::Concat("\n") + o3tl::toU(lpUserType);
+ sal::systools::COMReference<IMalloc> pMalloc;
+ hr = CoGetMalloc(1, &pMalloc); // if fails there will be a memory leak
+ SAL_WARN_IF(FAILED(hr) || !pMalloc, "embeddedobj.ole", "CoGetMalloc() failed");
+ if (pMalloc)
+ pMalloc->Free(lpUserType);
+ }
+ }
+ throw embed::UnreachableStateException(
+ error, getXWeak(), -1,
+ css::embed::EmbedStates::RUNNING); // the object server is not installed
+ }
else
- throw io::IOException();
+ throw io::IOException(error, getXWeak());
}
+ // Only now, when the object is activated, it can be registered in the global table;
+ // before this point, RegisterInterfaceInGlobal would return CO_E_OBJNOTCONNECTED
+ m_pNativeImpl->registerObj();
}
}
@@ -1017,20 +996,31 @@ awt::Size OleComponent::CalculateWithFactor( const awt::Size& aSize,
void OleComponent::CloseObject()
{
- if ( m_pNativeImpl->m_pOleObject && OleIsRunning( m_pNativeImpl->m_pOleObject ) )
- m_pNativeImpl->m_pOleObject->Close( OLECLOSE_NOSAVE ); // must be saved before
+ auto pOleObject(m_pNativeImpl->get<IOleObject>());
+ if (pOleObject && OleIsRunning(pOleObject))
+ {
+ SolarMutexReleaser releaser;
+ HRESULT hr = pOleObject->Close(OLECLOSE_NOSAVE); // must be saved before
+ SAL_WARN_IF(FAILED(hr), "embeddedobj.ole", "IOleObject::Close failed");
+ }
}
uno::Sequence< embed::VerbDescriptor > OleComponent::GetVerbList()
{
- if ( !m_pNativeImpl->m_pOleObject )
+ auto pOleObject(m_pNativeImpl->get<IOleObject>());
+ if (!pOleObject)
throw embed::WrongStateException(); // TODO: the object is in wrong state
if( !m_aVerbList.getLength() )
{
- ComSmart< IEnumOLEVERB > pEnum;
- if( SUCCEEDED( m_pNativeImpl->m_pOleObject->EnumVerbs( &pEnum ) ) )
+ sal::systools::COMReference< IEnumOLEVERB > pEnum;
+ HRESULT hr;
+ {
+ SolarMutexReleaser releaser;
+ hr = pOleObject->EnumVerbs(&pEnum);
+ }
+ if (SUCCEEDED(hr))
{
OLEVERB szEle[ MAX_ENUM_ELE ];
ULONG nNum = 0;
@@ -1038,16 +1028,17 @@ uno::Sequence< embed::VerbDescriptor > OleComponent::GetVerbList()
do
{
- HRESULT hr = pEnum->Next( MAX_ENUM_ELE, szEle, &nNum );
+ hr = pEnum->Next(MAX_ENUM_ELE, szEle, &nNum);
if( hr == S_OK || hr == S_FALSE )
{
m_aVerbList.realloc( nSeqSize += nNum );
+ auto pVerbList = m_aVerbList.getArray();
for( sal_uInt32 nInd = 0; nInd < nNum; nInd++ )
{
- m_aVerbList[nSeqSize-nNum+nInd].VerbID = szEle[ nInd ].lVerb;
- m_aVerbList[nSeqSize-nNum+nInd].VerbName = WinAccToVcl_Impl( o3tl::toU(szEle[ nInd ].lpszVerbName) );
- m_aVerbList[nSeqSize-nNum+nInd].VerbFlags = szEle[ nInd ].fuFlags;
- m_aVerbList[nSeqSize-nNum+nInd].VerbAttributes = szEle[ nInd ].grfAttribs;
+ pVerbList[nSeqSize-nNum+nInd].VerbID = szEle[ nInd ].lVerb;
+ pVerbList[nSeqSize-nNum+nInd].VerbName = WinAccToVcl_Impl( o3tl::toU(szEle[ nInd ].lpszVerbName) );
+ pVerbList[nSeqSize-nNum+nInd].VerbFlags = szEle[ nInd ].fuFlags;
+ pVerbList[nSeqSize-nNum+nInd].VerbAttributes = szEle[ nInd ].grfAttribs;
}
}
else
@@ -1063,16 +1054,17 @@ uno::Sequence< embed::VerbDescriptor > OleComponent::GetVerbList()
void OleComponent::ExecuteVerb( sal_Int32 nVerbID )
{
- if ( !m_pNativeImpl->m_pOleObject )
+ RunObject();
+
+ auto pOleObject(m_pNativeImpl->get<IOleObject>());
+ if (!pOleObject)
throw embed::WrongStateException(); // TODO
- HRESULT hr = OleRun( m_pNativeImpl->m_pOleObject );
- if ( FAILED( hr ) )
- throw io::IOException(); // TODO: a specific exception that transport error code can be thrown here
+ SolarMutexReleaser releaser;
// TODO: probably extents should be set here and stored in aRect
// TODO: probably the parent window also should be set
- hr = m_pNativeImpl->m_pOleObject->DoVerb( nVerbID, nullptr, m_pOleWrapClientSite, 0, nullptr, nullptr );
+ HRESULT hr = pOleObject->DoVerb(nVerbID, nullptr, m_pOleWrapClientSite, 0, nullptr, nullptr);
if ( FAILED( hr ) )
throw io::IOException(); // TODO
@@ -1081,22 +1073,29 @@ void OleComponent::ExecuteVerb( sal_Int32 nVerbID )
void OleComponent::SetHostName( const OUString& aEmbDocName )
{
- if ( !m_pNativeImpl->m_pOleObject )
+ auto pOleObject(m_pNativeImpl->get<IOleObject>());
+ if (!pOleObject)
throw embed::WrongStateException(); // TODO: the object is in wrong state
- m_pNativeImpl->m_pOleObject->SetHostNames( L"app name", o3tl::toW( aEmbDocName.getStr() ) );
+ SolarMutexReleaser releaser;
+ pOleObject->SetHostNames(L"app name", o3tl::toW(aEmbDocName.getStr()));
}
void OleComponent::SetExtent( const awt::Size& aVisAreaSize, sal_Int64 nAspect )
{
- if ( !m_pNativeImpl->m_pOleObject )
+ auto pOleObject(m_pNativeImpl->get<IOleObject>());
+ if (!pOleObject)
throw embed::WrongStateException(); // TODO: the object is in wrong state
DWORD nMSAspect = static_cast<DWORD>(nAspect); // first 32 bits are for MS aspects
SIZEL aSize = { aVisAreaSize.Width, aVisAreaSize.Height };
- HRESULT hr = m_pNativeImpl->m_pOleObject->SetExtent( nMSAspect, &aSize );
+ HRESULT hr;
+ {
+ SolarMutexReleaser releaser;
+ hr = pOleObject->SetExtent(nMSAspect, &aSize);
+ }
if ( FAILED( hr ) )
{
@@ -1112,7 +1111,7 @@ void OleComponent::SetExtent( const awt::Size& aVisAreaSize, sal_Int64 nAspect )
awt::Size OleComponent::GetExtent( sal_Int64 nAspect )
{
- if ( !m_pNativeImpl->m_pOleObject )
+ if (!m_pNativeImpl->m_pObj)
throw embed::WrongStateException(); // TODO: the object is in wrong state
DWORD nMSAspect = static_cast<DWORD>(nAspect); // first 32 bits are for MS aspects
@@ -1122,42 +1121,52 @@ awt::Size OleComponent::GetExtent( sal_Int64 nAspect )
if ( nMSAspect == DVASPECT_CONTENT )
{
// Try to get the size from the replacement image first
- ComSmart< IDataObject > pDataObject;
- HRESULT hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pDataObject) );
- if ( SUCCEEDED( hr ) || pDataObject )
+ if (auto pDataObject = m_pNativeImpl->get<IDataObject>())
{
STGMEDIUM aMedium;
FORMATETC aFormat = pFormatTemplates[1]; // use windows metafile format
aFormat.dwAspect = nMSAspect;
- hr = pDataObject->GetData( &aFormat, &aMedium );
+ HRESULT hr;
+ {
+ SolarMutexReleaser releaser;
+ hr = pDataObject->GetData(&aFormat, &aMedium);
+ }
+
+ if (hr == RPC_E_WRONG_THREAD)
+ {
+ // Assume that the OLE object was loaded on the main thread.
+ vcl::solarthread::syncExecute([this, &hr, &pDataObject, &aFormat, &aMedium]() {
+ // Make sure that the current state is embed::EmbedStates::RUNNING.
+ RunObject();
+ // Now try again on the correct thread.
+ hr = pDataObject->GetData(&aFormat, &aMedium);
+ });
+ }
+
if ( SUCCEEDED( hr ) && aMedium.tymed == TYMED_MFPICT ) // Win Metafile
{
METAFILEPICT* pMF = static_cast<METAFILEPICT*>(GlobalLock( aMedium.hMetaFilePict ));
if ( pMF )
{
// the object uses 0.01 mm as unit, so the metafile size should be converted to object unit
- sal_Int64 nMult = 1;
- sal_Int64 nDiv = 1;
+ o3tl::Length eFrom = o3tl::Length::mm100;
switch( pMF->mm )
{
case MM_HIENGLISH:
- nMult = 254;
- nDiv = 100;
+ eFrom = o3tl::Length::in1000;
break;
case MM_LOENGLISH:
- nMult = 254;
- nDiv = 10;
+ eFrom = o3tl::Length::in100;
break;
case MM_LOMETRIC:
- nMult = 10;
+ eFrom = o3tl::Length::mm10;
break;
case MM_TWIPS:
- nMult = 254;
- nDiv = 144;
+ eFrom = o3tl::Length::twip;
break;
case MM_ISOTROPIC:
@@ -1167,8 +1176,8 @@ awt::Size OleComponent::GetExtent( sal_Int64 nAspect )
break;
}
- sal_Int64 nX = static_cast<sal_Int64>(abs( pMF->xExt )) * nMult / nDiv;
- sal_Int64 nY = static_cast<sal_Int64>(abs( pMF->yExt )) * nMult / nDiv;
+ sal_Int64 nX = o3tl::convert(abs( pMF->xExt ), eFrom, o3tl::Length::mm100);
+ sal_Int64 nY = o3tl::convert(abs( pMF->yExt ), eFrom, o3tl::Length::mm100);
if ( nX < SAL_MAX_INT32 && nY < SAL_MAX_INT32 )
{
aSize.Width = static_cast<sal_Int32>(nX);
@@ -1179,6 +1188,10 @@ awt::Size OleComponent::GetExtent( sal_Int64 nAspect )
OSL_FAIL( "Unexpected size is provided!" );
}
}
+ else if (!SUCCEEDED(hr))
+ {
+ SAL_WARN("embeddedobj.ole", " OleComponent::GetExtent: GetData() failed");
+ }
// i113605, to release storage medium
if ( SUCCEEDED( hr ) )
::ReleaseStgMedium(&aMedium);
@@ -1194,13 +1207,18 @@ awt::Size OleComponent::GetExtent( sal_Int64 nAspect )
awt::Size OleComponent::GetCachedExtent( sal_Int64 nAspect )
{
- if ( !m_pNativeImpl->m_pOleObject )
+ auto pViewObject2(m_pNativeImpl->get<IViewObject2>());
+ if (!pViewObject2)
throw embed::WrongStateException(); // TODO: the object is in wrong state
DWORD nMSAspect = static_cast<DWORD>(nAspect); // first 32 bits are for MS aspects
SIZEL aSize;
- HRESULT hr = m_pNativeImpl->m_pViewObject2->GetExtent( nMSAspect, -1, nullptr, &aSize );
+ HRESULT hr;
+ {
+ SolarMutexReleaser releaser;
+ hr = pViewObject2->GetExtent(nMSAspect, -1, nullptr, &aSize);
+ }
if ( FAILED( hr ) )
{
@@ -1211,6 +1229,7 @@ awt::Size OleComponent::GetCachedExtent( sal_Int64 nAspect )
//else
// throw io::IOException(); // TODO
+ SAL_WARN("embeddedobj.ole", " OleComponent::GetCachedExtent: GetExtent() failed");
throw lang::IllegalArgumentException();
}
@@ -1220,14 +1239,22 @@ awt::Size OleComponent::GetCachedExtent( sal_Int64 nAspect )
awt::Size OleComponent::GetRecommendedExtent( sal_Int64 nAspect )
{
- if ( !m_pNativeImpl->m_pOleObject )
+ auto pOleObject(m_pNativeImpl->get<IOleObject>());
+ if (!pOleObject)
throw embed::WrongStateException(); // TODO: the object is in wrong state
DWORD nMSAspect = static_cast<DWORD>(nAspect); // first 32 bits are for MS aspects
SIZEL aSize;
- HRESULT hr = m_pNativeImpl->m_pOleObject->GetExtent( nMSAspect, &aSize );
+ HRESULT hr;
+ {
+ SolarMutexReleaser releaser;
+ hr = pOleObject->GetExtent(nMSAspect, &aSize);
+ }
if ( FAILED( hr ) )
+ {
+ SAL_WARN("embeddedobj.ole", " OleComponent::GetRecommendedExtent: GetExtent() failed");
throw lang::IllegalArgumentException();
+ }
return awt::Size( aSize.cx, aSize.cy );
}
@@ -1235,22 +1262,31 @@ awt::Size OleComponent::GetRecommendedExtent( sal_Int64 nAspect )
sal_Int64 OleComponent::GetMiscStatus( sal_Int64 nAspect )
{
- if ( !m_pNativeImpl->m_pOleObject )
+ auto pOleObject(m_pNativeImpl->get<IOleObject>());
+ if (!pOleObject)
throw embed::WrongStateException(); // TODO: the object is in wrong state
- DWORD nResult;
- m_pNativeImpl->m_pOleObject->GetMiscStatus( static_cast<DWORD>(nAspect), &nResult );
+ DWORD nResult = 0;
+ {
+ SolarMutexReleaser releaser;
+ pOleObject->GetMiscStatus(static_cast<DWORD>(nAspect), &nResult);
+ }
return static_cast<sal_Int64>(nResult); // first 32 bits are for MS flags
}
uno::Sequence< sal_Int8 > OleComponent::GetCLSID()
{
- if ( !m_pNativeImpl->m_pOleObject )
+ auto pOleObject(m_pNativeImpl->get<IOleObject>());
+ if (!pOleObject)
throw embed::WrongStateException(); // TODO: the object is in wrong state
GUID aCLSID;
- HRESULT hr = m_pNativeImpl->m_pOleObject->GetUserClassID( &aCLSID );
+ HRESULT hr;
+ {
+ SolarMutexReleaser releaser;
+ hr = pOleObject->GetUserClassID(&aCLSID);
+ }
if ( FAILED( hr ) )
throw io::IOException(); // TODO:
@@ -1264,57 +1300,60 @@ uno::Sequence< sal_Int8 > OleComponent::GetCLSID()
bool OleComponent::IsDirty()
{
- if ( !m_pNativeImpl->m_pOleObject )
- throw embed::WrongStateException(); // TODO: the object is in wrong state
-
if ( IsWorkaroundActive() )
return true;
- ComSmart< IPersistStorage > pPersistStorage;
- HRESULT hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersistStorage) );
- if ( FAILED( hr ) || !pPersistStorage )
+ auto pPersistStorage(m_pNativeImpl->get<IPersistStorage>());
+ if ( !pPersistStorage )
throw io::IOException(); // TODO
- hr = pPersistStorage->IsDirty();
+ SolarMutexReleaser releaser;
+ HRESULT hr = pPersistStorage->IsDirty();
return ( hr != S_FALSE );
}
void OleComponent::StoreOwnTmpIfNecessary()
{
- if ( !m_pNativeImpl->m_pOleObject )
+ auto pOleObject(m_pNativeImpl->get<IOleObject>());
+ if (!pOleObject)
throw embed::WrongStateException(); // TODO: the object is in wrong state
- ComSmart< IPersistStorage > pPersistStorage;
- HRESULT hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersistStorage) );
- if ( FAILED( hr ) || !pPersistStorage )
+ auto pPersistStorage(m_pNativeImpl->get<IPersistStorage>());
+ if ( !pPersistStorage )
throw io::IOException(); // TODO
+ SolarMutexReleaser releaser;
+
if ( m_bWorkaroundActive || pPersistStorage->IsDirty() != S_FALSE )
{
- hr = OleSave( pPersistStorage, m_pNativeImpl->m_pIStorage, TRUE );
+ auto pStorage(m_pNativeImpl->getStorage());
+ HRESULT hr = OleSave(pPersistStorage, pStorage, TRUE);
if ( FAILED( hr ) )
{
// Till now was required only for AcrobatReader7.0.8
GUID aCLSID;
- hr = m_pNativeImpl->m_pOleObject->GetUserClassID( &aCLSID );
+ hr = pOleObject->GetUserClassID(&aCLSID);
if ( FAILED( hr ) )
+ {
+ SAL_WARN("embeddedobj.ole", "OleComponent::StoreOwnTmpIfNecessary: GetUserClassID() failed");
throw io::IOException(); // TODO
+ }
- hr = WriteClassStg( m_pNativeImpl->m_pIStorage, aCLSID );
+ hr = WriteClassStg(pStorage, aCLSID);
if ( FAILED( hr ) )
throw io::IOException(); // TODO
// the result of the following call is not checked because some objects, for example AcrobatReader7.0.8
// return error even in case the saving was done correctly
- hr = pPersistStorage->Save( m_pNativeImpl->m_pIStorage, TRUE );
+ hr = pPersistStorage->Save(pStorage, TRUE);
// another workaround for AcrobatReader7.0.8 object, this object might think that it is not changed
// when it has been created from file, although it must be saved
m_bWorkaroundActive = true;
}
- hr = m_pNativeImpl->m_pIStorage->Commit( STGC_DEFAULT );
+ hr = pStorage->Commit(STGC_DEFAULT);
if ( FAILED( hr ) )
throw io::IOException(); // TODO
@@ -1430,11 +1469,11 @@ void SAL_CALL OleComponent::close( sal_Bool bDeliverOwnership )
if (m_pInterfaceContainer)
{
- ::cppu::OInterfaceContainerHelper* pContainer
+ comphelper::OInterfaceContainerHelper2* pContainer
= m_pInterfaceContainer->getContainer(cppu::UnoType<util::XCloseListener>::get());
if (pContainer != nullptr)
{
- ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer);
while (pIterator.hasMoreElements())
{
try
@@ -1453,7 +1492,7 @@ void SAL_CALL OleComponent::close( sal_Bool bDeliverOwnership )
= m_pInterfaceContainer->getContainer(cppu::UnoType<util::XCloseListener>::get());
if (pContainer != nullptr)
{
- ::cppu::OInterfaceIteratorHelper pCloseIterator(*pContainer);
+ comphelper::OInterfaceIteratorHelper2 pCloseIterator(*pContainer);
while (pCloseIterator.hasMoreElements())
{
try
@@ -1481,7 +1520,7 @@ void SAL_CALL OleComponent::addCloseListener( const uno::Reference< util::XClose
throw lang::DisposedException(); // TODO
if ( !m_pInterfaceContainer )
- m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
+ m_pInterfaceContainer = new comphelper::OMultiTypeInterfaceContainerHelper2( m_aMutex );
m_pInterfaceContainer->addInterface( cppu::UnoType<util::XCloseListener>::get(), xListener );
}
@@ -1506,7 +1545,7 @@ uno::Any SAL_CALL OleComponent::getTransferData( const datatransfer::DataFlavor&
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
- if ( !m_pNativeImpl->m_pOleObject )
+ if (!m_pNativeImpl->m_pObj)
throw embed::WrongStateException(); // TODO: the object is in wrong state
uno::Any aResult;
@@ -1517,9 +1556,8 @@ uno::Any SAL_CALL OleComponent::getTransferData( const datatransfer::DataFlavor&
DWORD nRequestedAspect = GetAspectFromFlavor( aFlavor );
// if own icon is set and icon aspect is requested the own icon can be returned directly
- ComSmart< IDataObject > pDataObject;
- HRESULT hr = m_pNativeImpl->m_pObj->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pDataObject) );
- if ( FAILED( hr ) || !pDataObject )
+ auto pDataObject(m_pNativeImpl->get<IDataObject>());
+ if ( !pDataObject )
throw io::IOException(); // TODO: transport error code
// The following optimization does not make much sense currently just because
@@ -1545,7 +1583,11 @@ uno::Any SAL_CALL OleComponent::getTransferData( const datatransfer::DataFlavor&
FORMATETC aFormat = pFormatTemplates[nInd];
aFormat.dwAspect = nRequestedAspect;
- hr = pDataObject->GetData( &aFormat, &aMedium );
+ HRESULT hr;
+ {
+ SolarMutexReleaser releaser;
+ hr = pDataObject->GetData(&aFormat, &aMedium);
+ }
if ( SUCCEEDED( hr ) )
{
bSupportedFlavor = m_pNativeImpl->ConvertDataForFlavor( aMedium, aFlavor, aResult );
@@ -1604,9 +1646,6 @@ uno::Sequence< datatransfer::DataFlavor > SAL_CALL OleComponent::getTransferData
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
- if ( !m_pNativeImpl->m_pOleObject )
- throw embed::WrongStateException(); // TODO: the object is in wrong state
-
RetrieveObjectDataFlavors_Impl();
return m_aDataFlavors;
@@ -1619,15 +1658,9 @@ sal_Bool SAL_CALL OleComponent::isDataFlavorSupported( const datatransfer::DataF
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
- if ( !m_pNativeImpl->m_pOleObject )
- throw embed::WrongStateException(); // TODO: the object is in wrong state
-
- if ( !m_aDataFlavors.getLength() )
- {
- RetrieveObjectDataFlavors_Impl();
- }
+ RetrieveObjectDataFlavors_Impl();
- for ( auto const & supportedFormat : std::as_const(m_aDataFlavors) )
+ for (auto const& supportedFormat : m_aDataFlavors)
if ( supportedFormat.MimeType.equals( aFlavor.MimeType ) && supportedFormat.DataType == aFlavor.DataType )
return true;
@@ -1652,7 +1685,7 @@ void SAL_CALL OleComponent::addEventListener( const uno::Reference< lang::XEvent
throw lang::DisposedException(); // TODO
if ( !m_pInterfaceContainer )
- m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
+ m_pInterfaceContainer = new comphelper::OMultiTypeInterfaceContainerHelper2( m_aMutex );
m_pInterfaceContainer->addInterface( cppu::UnoType<lang::XEventListener>::get(), xListener );
}
@@ -1675,25 +1708,7 @@ sal_Int64 SAL_CALL OleComponent::getSomething( const css::uno::Sequence< sal_Int
{
uno::Sequence < sal_Int8 > aCLSID = GetCLSID();
if ( MimeConfigurationHelper::ClassIDsEqual( aIdentifier, aCLSID ) )
- return reinterpret_cast<sal_Int64>(static_cast<IUnknown*>(m_pNativeImpl->m_pObj));
-
- // compatibility hack for old versions: CLSID was used in wrong order (SvGlobalName order)
- sal_Int32 nLength = aIdentifier.getLength();
- if ( nLength == 16 )
- {
- for ( sal_Int32 n=8; n<16; n++ )
- if ( aIdentifier[n] != aCLSID[n] )
- return 0;
- if ( aIdentifier[7] == aCLSID[6] &&
- aIdentifier[6] == aCLSID[7] &&
- aIdentifier[5] == aCLSID[4] &&
- aIdentifier[4] == aCLSID[5] &&
- aIdentifier[3] == aCLSID[0] &&
- aIdentifier[2] == aCLSID[1] &&
- aIdentifier[1] == aCLSID[2] &&
- aIdentifier[0] == aCLSID[3] )
- return reinterpret_cast<sal_Int64>(static_cast<IUnknown*>(m_pNativeImpl->m_pObj));
- }
+ return comphelper::getSomething_cast(m_pNativeImpl->m_pObj.get());
}
catch ( const uno::Exception& )
{
@@ -1713,11 +1728,11 @@ void SAL_CALL OleComponent::setModified( sal_Bool bModified )
if ( bModified && m_pInterfaceContainer )
{
- ::cppu::OInterfaceContainerHelper* pContainer =
+ comphelper::OInterfaceContainerHelper2* pContainer =
m_pInterfaceContainer->getContainer( cppu::UnoType<util::XModifyListener>::get());
if ( pContainer != nullptr )
{
- ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
+ comphelper::OInterfaceIteratorHelper2 pIterator( *pContainer );
while ( pIterator.hasMoreElements() )
{
try
@@ -1741,7 +1756,7 @@ void SAL_CALL OleComponent::addModifyListener( const css::uno::Reference < css::
throw lang::DisposedException(); // TODO
if ( !m_pInterfaceContainer )
- m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );
+ m_pInterfaceContainer = new comphelper::OMultiTypeInterfaceContainerHelper2( m_aMutex );
m_pInterfaceContainer->addInterface( cppu::UnoType<util::XModifyListener>::get(), xListener );
}
diff --git a/embeddedobj/source/msole/olecomponent.hxx b/embeddedobj/source/msole/olecomponent.hxx
index 63547c321adc..e08d5a69b2f4 100644
--- a/embeddedobj/source/msole/olecomponent.hxx
+++ b/embeddedobj/source/msole/olecomponent.hxx
@@ -34,33 +34,30 @@
#include <com/sun/star/uno/XComponentContext.hpp>
#include <rtl/ref.hxx>
-namespace cppu {
- class OMultiTypeInterfaceContainerHelper;
+namespace comphelper {
+ class OMultiTypeInterfaceContainerHelper2;
}
class OleWrapperClientSite;
class OleWrapperAdviseSink;
class OleEmbeddedObject;
-struct OleComponentNative_Impl;
+class OleComponentNative_Impl;
class OleComponent : public ::cppu::WeakImplHelper< css::util::XCloseable, css::lang::XComponent,
css::lang::XUnoTunnel, css::util::XModifiable,
css::datatransfer::XTransferable >
{
::osl::Mutex m_aMutex;
- ::cppu::OMultiTypeInterfaceContainerHelper* m_pInterfaceContainer;
+ comphelper::OMultiTypeInterfaceContainerHelper2* m_pInterfaceContainer;
bool m_bDisposed;
bool m_bModified;
- OleComponentNative_Impl* m_pNativeImpl;
+ std::unique_ptr<OleComponentNative_Impl> m_pNativeImpl;
OleEmbeddedObject* m_pUnoOleObject;
OleWrapperClientSite* m_pOleWrapClientSite;
OleWrapperAdviseSink* m_pImplAdviseSink;
- sal_Int32 m_nOLEMiscFlags;
- sal_Int32 m_nAdvConn;
-
css::uno::Sequence< css::embed::VerbDescriptor > m_aVerbList;
css::uno::Sequence< css::datatransfer::DataFlavor > m_aDataFlavors;
@@ -72,9 +69,10 @@ class OleComponent : public ::cppu::WeakImplHelper< css::util::XCloseable, css::
// such objects report the dirty state wrongly sometimes and do not allow to store them any time
bool m_bWorkaroundActive;
- bool InitializeObject_Impl();
+ void InitializeObject_Impl();
+
+ OUString getTempURL() const;
- void CreateNewIStorage_Impl();
void RetrieveObjectDataFlavors_Impl();
void Dispose();
@@ -123,7 +121,7 @@ public:
css::uno::Sequence< sal_Int8 > GetCLSID();
- bool IsWorkaroundActive() { return m_bWorkaroundActive; }
+ bool IsWorkaroundActive() const { return m_bWorkaroundActive; }
bool IsDirty();
void StoreOwnTmpIfNecessary();
diff --git a/embeddedobj/source/msole/oleembed.cxx b/embeddedobj/source/msole/oleembed.cxx
index 926f5b9e9393..a055ceae2249 100644
--- a/embeddedobj/source/msole/oleembed.cxx
+++ b/embeddedobj/source/msole/oleembed.cxx
@@ -47,11 +47,12 @@
#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
#include <cppuhelper/exc_hlp.hxx>
-#include <cppuhelper/interfacecontainer.h>
+#include <comphelper/multicontainer2.hxx>
#include <comphelper/mimeconfighelper.hxx>
+#include <comphelper/propertyvalue.hxx>
#include <sal/log.hxx>
-#include <tools/diagnose_ex.h>
-
+#include <comphelper/diagnose_ex.hxx>
+#include <officecfg/Office/Common.hxx>
#include <targetstatecontrol.hxx>
@@ -91,14 +92,13 @@ void OleEmbeddedObject::SwitchComponentToRunningState_Impl()
uno::Sequence< sal_Int32 > OleEmbeddedObject::GetReachableStatesList_Impl(
const uno::Sequence< embed::VerbDescriptor >& aVerbList )
{
- uno::Sequence< sal_Int32 > aStates(2);
- aStates[0] = embed::EmbedStates::LOADED;
- aStates[1] = embed::EmbedStates::RUNNING;
+ uno::Sequence< sal_Int32 > aStates { embed::EmbedStates::LOADED, embed::EmbedStates::RUNNING };
for ( embed::VerbDescriptor const & vd : aVerbList )
if ( vd.VerbID == embed::EmbedVerbs::MS_OLEVERB_OPEN )
{
aStates.realloc(3);
- aStates[2] = embed::EmbedStates::ACTIVE;
+ aStates.getArray()[2] = embed::EmbedStates::ACTIVE;
+ break;
}
return aStates;
@@ -112,8 +112,7 @@ uno::Sequence< sal_Int32 > OleEmbeddedObject::GetIntermediateVerbsSequence_Impl(
// actually there will be only one verb
if ( m_nObjectState == embed::EmbedStates::RUNNING && nNewState == embed::EmbedStates::ACTIVE )
{
- uno::Sequence< sal_Int32 > aVerbs( 1 );
- aVerbs[0] = embed::EmbedVerbs::MS_OLEVERB_OPEN;
+ return { embed::EmbedVerbs::MS_OLEVERB_OPEN };
}
return uno::Sequence< sal_Int32 >();
@@ -127,13 +126,13 @@ void OleEmbeddedObject::MoveListeners()
// move state change listeners
{
- ::cppu::OInterfaceContainerHelper* pStateChangeContainer =
+ comphelper::OInterfaceContainerHelper2* pStateChangeContainer =
m_pInterfaceContainer->getContainer( cppu::UnoType<embed::XStateChangeListener>::get());
if ( pStateChangeContainer != nullptr )
{
if ( m_xWrappedObject.is() )
{
- ::cppu::OInterfaceIteratorHelper pIterator( *pStateChangeContainer );
+ comphelper::OInterfaceIteratorHelper2 pIterator( *pStateChangeContainer );
while ( pIterator.hasMoreElements() )
{
try
@@ -151,13 +150,13 @@ void OleEmbeddedObject::MoveListeners()
// move event listeners
{
- ::cppu::OInterfaceContainerHelper* pEventContainer =
+ comphelper::OInterfaceContainerHelper2* pEventContainer =
m_pInterfaceContainer->getContainer( cppu::UnoType<document::XEventListener>::get());
if ( pEventContainer != nullptr )
{
if ( m_xWrappedObject.is() )
{
- ::cppu::OInterfaceIteratorHelper pIterator( *pEventContainer );
+ comphelper::OInterfaceIteratorHelper2 pIterator( *pEventContainer );
while ( pIterator.hasMoreElements() )
{
try
@@ -175,13 +174,13 @@ void OleEmbeddedObject::MoveListeners()
// move close listeners
{
- ::cppu::OInterfaceContainerHelper* pCloseContainer =
+ comphelper::OInterfaceContainerHelper2* pCloseContainer =
m_pInterfaceContainer->getContainer( cppu::UnoType<util::XCloseListener>::get());
if ( pCloseContainer != nullptr )
{
if ( m_xWrappedObject.is() )
{
- ::cppu::OInterfaceIteratorHelper pIterator( *pCloseContainer );
+ comphelper::OInterfaceIteratorHelper2 pIterator( *pCloseContainer );
while ( pIterator.hasMoreElements() )
{
try
@@ -218,7 +217,7 @@ uno::Reference< embed::XStorage > OleEmbeddedObject::CreateTemporarySubstorage(
if ( !xResult.is() )
{
o_aStorageName.clear();
- throw uno::RuntimeException();
+ throw uno::RuntimeException("Failed to create temporary storage for OLE embed object");
}
return xResult;
@@ -239,7 +238,7 @@ OUString OleEmbeddedObject::MoveToTemporarySubstream()
}
if ( aResult.isEmpty() )
- throw uno::RuntimeException();
+ throw uno::RuntimeException("Failed to rename temporary storage for OLE embed object");
return aResult;
}
@@ -278,7 +277,7 @@ bool OleEmbeddedObject::TryToConvertToOOo( const uno::Reference< io::XStream >&
uno::Sequence< beans::PropertyValue > aFilterData;
if ( aFilterAnyData >>= aFilterData )
{
- for ( beans::PropertyValue const & prop : std::as_const(aFilterData) )
+ for (beans::PropertyValue const& prop : aFilterData)
if ( prop.Name == "DocumentService" )
prop.Value >>= aDocServiceName;
}
@@ -286,8 +285,8 @@ bool OleEmbeddedObject::TryToConvertToOOo( const uno::Reference< io::XStream >&
if ( !aDocServiceName.isEmpty() )
{
// create the model
- uno::Sequence< uno::Any > aArguments(1);
- aArguments[0] <<= beans::NamedValue( "EmbeddedObject", uno::makeAny( true ));
+ uno::Sequence< uno::Any > aArguments{ uno::Any(
+ beans::NamedValue( "EmbeddedObject", uno::Any( true ))) };
uno::Reference< util::XCloseable > xDocument( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( aDocServiceName, aArguments, m_xContext ), uno::UNO_QUERY_THROW );
uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY_THROW );
@@ -295,23 +294,18 @@ bool OleEmbeddedObject::TryToConvertToOOo( const uno::Reference< io::XStream >&
// let the model behave as embedded one
uno::Reference< frame::XModel > xModel( xDocument, uno::UNO_QUERY_THROW );
- uno::Sequence< beans::PropertyValue > aSeq( 1 );
- aSeq[0].Name = "SetEmbedded";
- aSeq[0].Value <<= true;
+ uno::Sequence< beans::PropertyValue > aSeq{ comphelper::makePropertyValue(
+ "SetEmbedded", true) };
xModel->attachResource( OUString(), aSeq );
// load the model from the stream
- uno::Sequence< beans::PropertyValue > aArgs( 5 );
- aArgs[0].Name = "HierarchicalDocumentName";
- aArgs[0].Value <<= m_aEntryName;
- aArgs[1].Name = "ReadOnly";
- aArgs[1].Value <<= true;
- aArgs[2].Name = "FilterName";
- aArgs[2].Value <<= m_aFilterName;
- aArgs[3].Name = "URL";
- aArgs[3].Value <<= OUString( "private:stream" );
- aArgs[4].Name = "InputStream";
- aArgs[4].Value <<= xStream->getInputStream();
+ uno::Sequence< beans::PropertyValue > aArgs{
+ comphelper::makePropertyValue("HierarchicalDocumentName", m_aEntryName),
+ comphelper::makePropertyValue("ReadOnly", true),
+ comphelper::makePropertyValue("FilterName", m_aFilterName),
+ comphelper::makePropertyValue("URL", OUString( "private:stream" )),
+ comphelper::makePropertyValue("InputStream", xStream->getInputStream())
+ };
xSeekable->seek( 0 );
xLoadable->load( aArgs );
@@ -332,7 +326,7 @@ bool OleEmbeddedObject::TryToConvertToOOo( const uno::Reference< io::XStream >&
aEmbedFactory = aConfigHelper.GetFactoryNameByMediaType( aMediaType );
if ( aEmbedFactory.isEmpty() )
- throw uno::RuntimeException();
+ throw uno::RuntimeException("Failed to get OLE embedded object factory");
uno::Reference< uno::XInterface > xFact = m_xContext->getServiceManager()->createInstanceWithContext( aEmbedFactory, m_xContext );
@@ -444,6 +438,9 @@ bool OleEmbeddedObject::TryToConvertToOOo( const uno::Reference< io::XStream >&
void SAL_CALL OleEmbeddedObject::changeState( sal_Int32 nNewState )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get()
+ && nNewState != embed::EmbedStates::LOADED )
+ throw embed::UnreachableStateException();
// begin wrapping related part ====================
uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
if ( xWrappedObject.is() )
@@ -501,12 +498,12 @@ void SAL_CALL OleEmbeddedObject::changeState( sal_Int32 nNewState )
// the loaded state must be set before, because of notifications!
m_nObjectState = nNewState;
+ aGuard.clear();
{
VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController );
m_pOleComponent->CloseObject();
}
- aGuard.clear();
StateChangeNotification_Impl( false, nOldState, m_nObjectState );
aGuard.reset();
}
@@ -607,7 +604,7 @@ uno::Sequence< sal_Int32 > SAL_CALL OleEmbeddedObject::getReachableStates()
}
// end wrapping related part ====================
- ::osl::MutexGuard aGuard( m_aMutex );
+ ::osl::ResettableMutexGuard aGuard( m_aMutex );
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
@@ -626,7 +623,10 @@ uno::Sequence< sal_Int32 > SAL_CALL OleEmbeddedObject::getReachableStates()
// the list of states can only be guessed based on standard verbs,
// since there is no way to detect what additional verbs do
- return GetReachableStatesList_Impl( m_pOleComponent->GetVerbList() );
+ // Pass m_pOleComponent to the lambda by copy, to make sure it doesn't depend on possible
+ // destruction of 'this', while the lock is unset
+ return GetReachableStatesList_Impl(
+ ExecUnlocked([p = m_pOleComponent] { return p->GetVerbList(); }, aGuard));
}
else
#endif
@@ -687,14 +687,13 @@ namespace
const css::uno::Reference< css::uno::XComponentContext >& xContext,
const css::uno::Reference< css::io::XStream >& xObjectStream )
{
- uno::Reference <beans::XPropertySet> xNativeTempFile(
+ uno::Reference <io::XTempFile> xNativeTempFile(
io::TempFile::create(xContext),
- uno::UNO_QUERY_THROW);
- uno::Reference < io::XStream > xStream(xNativeTempFile, uno::UNO_QUERY_THROW);
+ uno::UNO_SET_THROW);
+ uno::Reference < io::XStream > xStream(xNativeTempFile);
- uno::Sequence< uno::Any > aArgs( 2 );
- aArgs[0] <<= xObjectStream;
- aArgs[1] <<= true; // do not create copy
+ uno::Sequence< uno::Any > aArgs{ uno::Any(xObjectStream),
+ uno::Any(true) }; // do not create copy
uno::Reference< container::XNameContainer > xNameContainer(
xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
"com.sun.star.embed.OLESimpleStorage",
@@ -713,7 +712,7 @@ namespace
};
bool bCopied = false;
- for (size_t i = 0; i < SAL_N_ELEMENTS(aStreamNames) && !bCopied; ++i)
+ for (size_t i = 0; i < std::size(aStreamNames) && !bCopied; ++i)
{
uno::Reference<io::XStream> xEmbeddedFile;
try
@@ -782,10 +781,8 @@ namespace
if (bCopied)
{
- xNativeTempFile->setPropertyValue("RemoveFile",
- uno::makeAny(false));
- uno::Any aUrl = xNativeTempFile->getPropertyValue("Uri");
- aUrl >>= rUrl;
+ xNativeTempFile->setRemoveFile(false);
+ rUrl = xNativeTempFile->getUri();
xNativeTempFile.clear();
@@ -796,8 +793,7 @@ namespace
}
else
{
- xNativeTempFile->setPropertyValue("RemoveFile",
- uno::makeAny(true));
+ xNativeTempFile->setRemoveFile(true);
}
return xStream;
@@ -868,14 +864,16 @@ void SAL_CALL OleEmbeddedObject::doVerb( sal_Int32 nVerbID )
try {
if ( !m_pOleComponent )
- throw uno::RuntimeException();
+ throw uno::RuntimeException("Null reference to OLE component");
// ==== the STAMPIT related solution =============================
m_aVerbExecutionController.StartControlExecution();
-
- m_pOleComponent->ExecuteVerb( nVerbID );
- m_pOleComponent->SetHostName( m_aContainerName );
+ {
+ osl::ResettableMutexGuardScopedReleaser clearedMutex(aGuard);
+ m_pOleComponent->ExecuteVerb(nVerbID);
+ m_pOleComponent->SetHostName(m_aContainerName);
+ }
// ==== the STAMPIT related solution =============================
bool bModifiedOnExecution = m_aVerbExecutionController.EndControlExecution_WasModified();
@@ -982,7 +980,7 @@ uno::Sequence< embed::VerbDescriptor > SAL_CALL OleEmbeddedObject::getSupportedV
}
// end wrapping related part ====================
- ::osl::MutexGuard aGuard( m_aMutex );
+ osl::ClearableMutexGuard aGuard(m_aMutex);
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
@@ -999,6 +997,7 @@ uno::Sequence< embed::VerbDescriptor > SAL_CALL OleEmbeddedObject::getSupportedV
// throw embed::NeedsRunningStateException(); // TODO:
// }
+ aGuard.clear();
return m_pOleComponent->GetVerbList();
}
else
@@ -1008,7 +1007,7 @@ uno::Sequence< embed::VerbDescriptor > SAL_CALL OleEmbeddedObject::getSupportedV
// So in SfxViewFrame::GetState_Impl in case SID_OBJECT hasVerbs is not
// empty, so that the doVerb attempt with -9 fallback is attempted
uno::Sequence<embed::VerbDescriptor> aRet(1);
- aRet[0].VerbID = -9;
+ aRet.getArray()[0].VerbID = -9;
return aRet;
}
}
@@ -1138,7 +1137,7 @@ sal_Int64 SAL_CALL OleEmbeddedObject::getStatus( sal_Int64
}
// end wrapping related part ====================
- ::osl::MutexGuard aGuard( m_aMutex );
+ osl::ResettableMutexGuard aGuard(m_aMutex);
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
@@ -1153,8 +1152,10 @@ sal_Int64 SAL_CALL OleEmbeddedObject::getStatus( sal_Int64
nResult = m_nStatus;
else if ( m_pOleComponent )
{
-
- m_nStatus = m_pOleComponent->GetMiscStatus( nAspect );
+ {
+ osl::ResettableMutexGuardScopedReleaser clearedMutex(aGuard);
+ m_nStatus = m_pOleComponent->GetMiscStatus(nAspect);
+ }
m_nStatusAspect = nAspect;
m_bGotStatus = true;
nResult = m_nStatus;
diff --git a/embeddedobj/source/msole/olemisc.cxx b/embeddedobj/source/msole/olemisc.cxx
index f85c845e31a8..4f50aedeba5f 100644
--- a/embeddedobj/source/msole/olemisc.cxx
+++ b/embeddedobj/source/msole/olemisc.cxx
@@ -28,10 +28,13 @@
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
-#include <cppuhelper/interfacecontainer.h>
+#include <comphelper/multicontainer2.hxx>
#include <comphelper/sequenceashashmap.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <osl/diagnose.h>
#include <oleembobj.hxx>
+#include <utility>
#include "olepersist.hxx"
#include "ownview.hxx"
@@ -41,17 +44,17 @@
using namespace ::com::sun::star;
-OleEmbeddedObject::OleEmbeddedObject( const uno::Reference< uno::XComponentContext >& xContext,
+OleEmbeddedObject::OleEmbeddedObject( uno::Reference< uno::XComponentContext > xContext,
const uno::Sequence< sal_Int8 >& aClassID,
- const OUString& aClassName )
+ OUString aClassName )
: m_bReadOnly( false )
, m_bDisposed( false )
, m_nObjectState( -1 )
, m_nTargetState( -1 )
, m_nUpdateMode ( embed::EmbedUpdateModes::ALWAYS_UPDATE )
-, m_xContext( xContext )
+, m_xContext(std::move( xContext ))
, m_aClassID( aClassID )
-, m_aClassName( aClassName )
+, m_aClassName(std::move( aClassName ))
, m_bWaitSaveCompleted( false )
, m_bNewVisReplInStream( true )
, m_bStoreLoaded( false )
@@ -74,13 +77,13 @@ OleEmbeddedObject::OleEmbeddedObject( const uno::Reference< uno::XComponentConte
// In case of loading from persistent entry the classID of the object
// will be retrieved from the entry, during construction it is unknown
-OleEmbeddedObject::OleEmbeddedObject( const uno::Reference< uno::XComponentContext >& xContext, bool bLink )
+OleEmbeddedObject::OleEmbeddedObject( uno::Reference< uno::XComponentContext > xContext, bool bLink )
: m_bReadOnly( false )
, m_bDisposed( false )
, m_nObjectState( -1 )
, m_nTargetState( -1 )
, m_nUpdateMode( embed::EmbedUpdateModes::ALWAYS_UPDATE )
-, m_xContext( xContext )
+, m_xContext(std::move( xContext ))
, m_bWaitSaveCompleted( false )
, m_bNewVisReplInStream( true )
, m_bStoreLoaded( false )
@@ -156,14 +159,14 @@ void OleEmbeddedObject::MakeEventListenerNotification_Impl( const OUString& aEve
if ( !m_pInterfaceContainer )
return;
- ::cppu::OInterfaceContainerHelper* pContainer =
- m_pInterfaceContainer->getContainer(
+ comphelper::OInterfaceContainerHelper2* pContainer =
+ m_pInterfaceContainer->getContainer(
cppu::UnoType<document::XEventListener>::get());
if ( pContainer == nullptr )
return;
document::EventObject aEvent( static_cast< ::cppu::OWeakObject* >( this ), aEventName );
- ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer);
while (pIterator.hasMoreElements())
{
try
@@ -181,12 +184,12 @@ void OleEmbeddedObject::StateChangeNotification_Impl( bool bBeforeChange, sal_In
{
if ( m_pInterfaceContainer )
{
- ::cppu::OInterfaceContainerHelper* pContainer = m_pInterfaceContainer->getContainer(
+ comphelper::OInterfaceContainerHelper2* pContainer = m_pInterfaceContainer->getContainer(
cppu::UnoType<embed::XStateChangeListener>::get());
if ( pContainer != nullptr )
{
lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
- ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer);
while (pIterator.hasMoreElements())
{
@@ -286,6 +289,15 @@ void OleEmbeddedObject::Dispose()
}
m_xParentStorage.clear();
+ m_xClientSite.clear();
+ m_xClosePreventer.clear();
+ m_xNewCachedVisRepl.clear();
+ m_xNewParentStorage.clear();
+ m_xNewObjectStream.clear();
+ m_xCachedVisualRepresentation.clear();
+ m_xWrappedObject.clear();
+ m_xParent.clear();
+ m_pOleComponent.clear();
m_bDisposed = true;
}
@@ -399,7 +411,7 @@ void SAL_CALL OleEmbeddedObject::addStateChangeListener( const uno::Reference< e
throw lang::DisposedException(); // TODO
if ( !m_pInterfaceContainer )
- m_pInterfaceContainer.reset(new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ));
+ m_pInterfaceContainer.reset(new comphelper::OMultiTypeInterfaceContainerHelper2( m_aMutex ));
m_pInterfaceContainer->addInterface( cppu::UnoType<embed::XStateChangeListener>::get(),
xListener );
@@ -446,11 +458,11 @@ void SAL_CALL OleEmbeddedObject::close( sal_Bool bDeliverOwnership )
if ( m_pInterfaceContainer )
{
- ::cppu::OInterfaceContainerHelper* pContainer =
+ comphelper::OInterfaceContainerHelper2* pContainer =
m_pInterfaceContainer->getContainer( cppu::UnoType<util::XCloseListener>::get());
if ( pContainer != nullptr )
{
- ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer);
while (pIterator.hasMoreElements())
{
try
@@ -468,7 +480,7 @@ void SAL_CALL OleEmbeddedObject::close( sal_Bool bDeliverOwnership )
cppu::UnoType<util::XCloseListener>::get());
if ( pContainer != nullptr )
{
- ::cppu::OInterfaceIteratorHelper pCloseIterator(*pContainer);
+ comphelper::OInterfaceIteratorHelper2 pCloseIterator(*pContainer);
while (pCloseIterator.hasMoreElements())
{
try
@@ -504,7 +516,7 @@ void SAL_CALL OleEmbeddedObject::addCloseListener( const uno::Reference< util::X
throw lang::DisposedException(); // TODO
if ( !m_pInterfaceContainer )
- m_pInterfaceContainer.reset(new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ));
+ m_pInterfaceContainer.reset(new comphelper::OMultiTypeInterfaceContainerHelper2( m_aMutex ));
m_pInterfaceContainer->addInterface( cppu::UnoType<util::XCloseListener>::get(), xListener );
}
@@ -549,7 +561,7 @@ void SAL_CALL OleEmbeddedObject::addEventListener( const uno::Reference< documen
throw lang::DisposedException(); // TODO
if ( !m_pInterfaceContainer )
- m_pInterfaceContainer.reset(new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ));
+ m_pInterfaceContainer.reset(new comphelper::OMultiTypeInterfaceContainerHelper2( m_aMutex ));
m_pInterfaceContainer->addInterface( cppu::UnoType<document::XEventListener>::get(), xListener );
}
@@ -675,11 +687,24 @@ void OleEmbeddedObject::initialize(const uno::Sequence<uno::Any>& rArguments)
return;
comphelper::SequenceAsHashMap aValues(rArguments[0]);
- for (const auto& rValue : aValues)
- {
- if (rValue.first == "StreamReadOnly")
- rValue.second >>= m_bStreamReadOnly;
- }
+ auto it = aValues.find("StreamReadOnly");
+ if (it != aValues.end())
+ it->second >>= m_bStreamReadOnly;
+}
+
+OUString SAL_CALL OleEmbeddedObject::getImplementationName()
+{
+ return "com.sun.star.comp.embed.OleEmbeddedObject";
+}
+
+sal_Bool SAL_CALL OleEmbeddedObject::supportsService(const OUString& ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+uno::Sequence<OUString> SAL_CALL OleEmbeddedObject::getSupportedServiceNames()
+{
+ return { "com.sun.star.comp.embed.OleEmbeddedObject" };
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/msole/olepersist.cxx b/embeddedobj/source/msole/olepersist.cxx
index 7f5002ec2772..e6af72fedccf 100644
--- a/embeddedobj/source/msole/olepersist.cxx
+++ b/embeddedobj/source/msole/olepersist.cxx
@@ -41,7 +41,6 @@
#include <com/sun/star/ucb/SimpleFileAccess.hpp>
#include <com/sun/star/io/IOException.hpp>
-#include <comphelper/processfactory.hxx>
#include <comphelper/storagehelper.hxx>
#include <comphelper/mimeconfighelper.hxx>
#include <comphelper/classids.hxx>
@@ -89,14 +88,13 @@ OUString GetNewTempFileURL_Impl( const uno::Reference< uno::XComponentContext >&
OUString aResult;
- uno::Reference < beans::XPropertySet > xTempFile(
+ uno::Reference < io::XTempFile > xTempFile(
io::TempFile::create(xContext),
- uno::UNO_QUERY_THROW );
+ uno::UNO_SET_THROW );
try {
- xTempFile->setPropertyValue("RemoveFile", uno::makeAny( false ) );
- uno::Any aUrl = xTempFile->getPropertyValue("Uri");
- aUrl >>= aResult;
+ xTempFile->setRemoveFile( false );
+ aResult = xTempFile->getUri();
}
catch ( const uno::Exception& )
{
@@ -163,16 +161,14 @@ static OUString GetNewFilledTempFile_Impl( const uno::Reference< embed::XOptimiz
try
{
- uno::Reference < beans::XPropertySet > xTempFile(
+ uno::Reference < io::XTempFile > xTempFile(
io::TempFile::create(xContext),
- uno::UNO_QUERY );
- uno::Reference < io::XStream > xTempStream( xTempFile, uno::UNO_QUERY_THROW );
+ uno::UNO_SET_THROW );
- xParentStorage->copyStreamElementData( aEntryName, xTempStream );
+ xParentStorage->copyStreamElementData( aEntryName, xTempFile );
- xTempFile->setPropertyValue("RemoveFile", uno::makeAny( false ) );
- uno::Any aUrl = xTempFile->getPropertyValue("Uri");
- aUrl >>= aResult;
+ xTempFile->setRemoveFile( false );
+ aResult = xTempFile->getUri();
}
catch( const uno::RuntimeException& )
{
@@ -192,7 +188,7 @@ static OUString GetNewFilledTempFile_Impl( const uno::Reference< embed::XOptimiz
static void SetStreamMediaType_Impl( const uno::Reference< io::XStream >& xStream, const OUString& aMediaType )
{
uno::Reference< beans::XPropertySet > xPropSet( xStream, uno::UNO_QUERY_THROW );
- xPropSet->setPropertyValue("MediaType", uno::makeAny( aMediaType ) );
+ xPropSet->setPropertyValue("MediaType", uno::Any( aMediaType ) );
}
#endif
@@ -200,7 +196,7 @@ static void LetCommonStoragePassBeUsed_Impl( const uno::Reference< io::XStream >
{
uno::Reference< beans::XPropertySet > xPropSet( xStream, uno::UNO_QUERY_THROW );
xPropSet->setPropertyValue("UseCommonStoragePasswordEncryption",
- uno::makeAny( true ) );
+ uno::Any( true ) );
}
#ifdef _WIN32
@@ -364,9 +360,8 @@ void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStrea
if ( !xTargetStream.is() || !xCachedVisualRepresentation.is() )
throw uno::RuntimeException();
- uno::Sequence< uno::Any > aArgs( 2 );
- aArgs[0] <<= xTargetStream;
- aArgs[1] <<= true; // do not create copy
+ uno::Sequence< uno::Any > aArgs{ uno::Any(xTargetStream),
+ uno::Any(true) }; // do not create copy
uno::Reference< container::XNameContainer > xNameContainer(
m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
@@ -394,7 +389,8 @@ void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStrea
// write 0xFFFFFFFF at the beginning
uno::Sequence< sal_Int8 > aData( 4 );
- * reinterpret_cast<sal_uInt32*>(aData.getArray()) = 0xFFFFFFFF;
+ auto pData = aData.getArray();
+ * reinterpret_cast<sal_uInt32*>(pData) = 0xFFFFFFFF;
xTempOutStream->writeBytes( aData );
@@ -407,33 +403,33 @@ void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStrea
if ( aSigData[0] == 'B' && aSigData[1] == 'M' )
{
// it's a bitmap
- aData[0] = 0x02; aData[1] = 0; aData[2] = 0; aData[3] = 0;
+ pData[0] = 0x02; pData[1] = 0; pData[2] = 0; pData[3] = 0;
}
else
{
// treat it as a metafile
- aData[0] = 0x03; aData[1] = 0; aData[2] = 0; aData[3] = 0;
+ pData[0] = 0x03; pData[1] = 0; pData[2] = 0; pData[3] = 0;
}
xTempOutStream->writeBytes( aData );
// write job related information
- aData[0] = 0x04; aData[1] = 0; aData[2] = 0; aData[3] = 0;
+ pData[0] = 0x04; pData[1] = 0; pData[2] = 0; pData[3] = 0;
xTempOutStream->writeBytes( aData );
// write aspect
- aData[0] = 0x01; aData[1] = 0; aData[2] = 0; aData[3] = 0;
+ pData[0] = 0x01; pData[1] = 0; pData[2] = 0; pData[3] = 0;
xTempOutStream->writeBytes( aData );
// write l-index
- * reinterpret_cast<sal_uInt32*>(aData.getArray()) = 0xFFFFFFFF;
+ * reinterpret_cast<sal_uInt32*>(pData) = 0xFFFFFFFF;
xTempOutStream->writeBytes( aData );
// write adv. flags
- aData[0] = 0x02; aData[1] = 0; aData[2] = 0; aData[3] = 0;
+ pData[0] = 0x02; pData[1] = 0; pData[2] = 0; pData[3] = 0;
xTempOutStream->writeBytes( aData );
// write compression
- * reinterpret_cast<sal_uInt32*>(aData.getArray()) = 0x0;
+ * reinterpret_cast<sal_uInt32*>(pData) = 0x0;
xTempOutStream->writeBytes( aData );
// get the size
@@ -443,7 +439,7 @@ void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStrea
// write width
for ( nIndex = 0; nIndex < 4; nIndex++ )
{
- aData[nIndex] = static_cast<sal_Int8>( aSize.Width % 0x100 );
+ pData[nIndex] = static_cast<sal_Int8>( aSize.Width % 0x100 );
aSize.Width /= 0x100;
}
xTempOutStream->writeBytes( aData );
@@ -451,7 +447,7 @@ void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStrea
// write height
for ( nIndex = 0; nIndex < 4; nIndex++ )
{
- aData[nIndex] = static_cast<sal_Int8>( aSize.Height % 0x100 );
+ pData[nIndex] = static_cast<sal_Int8>( aSize.Height % 0x100 );
aSize.Height /= 0x100;
}
xTempOutStream->writeBytes( aData );
@@ -474,7 +470,7 @@ void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStrea
}
for ( sal_Int32 nInd = 0; nInd < 4; nInd++ )
{
- aData[nInd] = static_cast<sal_Int8>( static_cast<sal_uInt64>(nLength) % 0x100 );
+ pData[nInd] = static_cast<sal_Int8>( static_cast<sal_uInt64>(nLength) % 0x100 );
nLength /= 0x100;
}
xTempSeek->seek( 36 );
@@ -489,9 +485,9 @@ void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStrea
// insert the result file as replacement image
OUString aCacheName = "\002OlePres000";
if ( xNameContainer->hasByName( aCacheName ) )
- xNameContainer->replaceByName( aCacheName, uno::makeAny( xTempFile ) );
+ xNameContainer->replaceByName( aCacheName, uno::Any( xTempFile ) );
else
- xNameContainer->insertByName( aCacheName, uno::makeAny( xTempFile ) );
+ xNameContainer->insertByName( aCacheName, uno::Any( xTempFile ) );
uno::Reference< embed::XTransactedObject > xTransacted( xNameContainer, uno::UNO_QUERY_THROW );
xTransacted->commit();
@@ -504,9 +500,8 @@ void OleEmbeddedObject::RemoveVisualCache_Impl( const uno::Reference< io::XStrea
if ( !xTargetStream.is() )
throw uno::RuntimeException();
- uno::Sequence< uno::Any > aArgs( 2 );
- aArgs[0] <<= xTargetStream;
- aArgs[1] <<= true; // do not create copy
+ uno::Sequence< uno::Any > aArgs{ uno::Any(xTargetStream),
+ uno::Any(true) }; // do not create copy
uno::Reference< container::XNameContainer > xNameContainer(
m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
"com.sun.star.embed.OLESimpleStorage",
@@ -566,9 +561,8 @@ bool OleEmbeddedObject::HasVisReplInStream()
{
bool bExists = false;
- uno::Sequence< uno::Any > aArgs( 2 );
- aArgs[0] <<= xStream;
- aArgs[1] <<= true; // do not create copy
+ uno::Sequence< uno::Any > aArgs{ uno::Any(xStream),
+ uno::Any(true) }; // do not create copy
uno::Reference< container::XNameContainer > xNameContainer(
m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
"com.sun.star.embed.OLESimpleStorage",
@@ -601,7 +595,7 @@ bool OleEmbeddedObject::HasVisReplInStream()
uno::Reference< io::XStream > OleEmbeddedObject::TryToRetrieveCachedVisualRepresentation_Impl(
const uno::Reference< io::XStream >& xStream,
bool bAllowToRepair50 )
- throw ()
+ noexcept
{
uno::Reference< io::XStream > xResult;
@@ -610,9 +604,8 @@ uno::Reference< io::XStream > OleEmbeddedObject::TryToRetrieveCachedVisualRepres
SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::TryToRetrieveCachedVisualRepresentation, retrieving" );
uno::Reference< container::XNameContainer > xNameContainer;
- uno::Sequence< uno::Any > aArgs( 2 );
- aArgs[0] <<= xStream;
- aArgs[1] <<= true; // do not create copy
+ uno::Sequence< uno::Any > aArgs{ uno::Any(xStream),
+ uno::Any(true) }; // do not create copy
try
{
xNameContainer.set(
@@ -743,6 +736,22 @@ void OleEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStor
return;
}
+ uno::Reference<io::XSeekable> xNewSeekable(xNewObjectStream, uno::UNO_QUERY);
+ if (xNewSeekable.is() && xNewSeekable->getLength() == 0)
+ {
+ uno::Reference<io::XSeekable> xOldSeekable(m_xObjectStream, uno::UNO_QUERY);
+ if (xOldSeekable.is() && xOldSeekable->getLength() > 0)
+ {
+ SAL_WARN("embeddedobj.ole", "OleEmbeddedObject::SwitchOwnPersistence(stream version): "
+ "empty new stream, reusing old one");
+ uno::Reference<io::XInputStream> xInput = m_xObjectStream->getInputStream();
+ uno::Reference<io::XOutputStream> xOutput = xNewObjectStream->getOutputStream();
+ xOldSeekable->seek(0);
+ comphelper::OStorageHelper::CopyInputToOutput(xInput, xOutput);
+ xNewSeekable->seek(0);
+ }
+ }
+
try {
uno::Reference< lang::XComponent > xComponent( m_xObjectStream, uno::UNO_QUERY );
OSL_ENSURE( !m_xObjectStream.is() || xComponent.is(), "Wrong stream implementation!" );
@@ -768,6 +777,21 @@ void OleEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStor
sal_Int32 nStreamMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
uno::Reference< io::XStream > xNewOwnStream = xNewParentStorage->openStreamElement( aNewName, nStreamMode );
+
+ uno::Reference<io::XSeekable> xNewSeekable (xNewOwnStream, uno::UNO_QUERY);
+ if (xNewSeekable.is() && xNewSeekable->getLength() == 0)
+ {
+ uno::Reference<io::XSeekable> xOldSeekable(m_xObjectStream, uno::UNO_QUERY);
+ if (xOldSeekable.is() && xOldSeekable->getLength() > 0)
+ {
+ SAL_WARN("embeddedobj.ole", "OleEmbeddedObject::SwitchOwnPersistence: empty new stream, reusing old one");
+ uno::Reference<io::XInputStream> xInput = m_xObjectStream->getInputStream();
+ uno::Reference<io::XOutputStream> xOutput = xNewOwnStream->getOutputStream();
+ comphelper::OStorageHelper::CopyInputToOutput(xInput, xOutput);
+ xNewSeekable->seek(0);
+ }
+ }
+
SAL_WARN_IF( !xNewOwnStream.is(), "embeddedobj.ole", "The method can not return empty reference!" );
SwitchOwnPersistence( xNewParentStorage, xNewOwnStream, aNewName );
@@ -935,8 +959,7 @@ void OleEmbeddedObject::CreateOleComponent_Impl(
m_pOleComponent = pOleComponent ? pOleComponent : new OleComponent( m_xContext, this );
if ( !m_xClosePreventer.is() )
- m_xClosePreventer.set( static_cast< ::cppu::OWeakObject* >( new OClosePreventer ),
- uno::UNO_QUERY );
+ m_xClosePreventer = new OClosePreventer;
m_pOleComponent->addCloseListener( m_xClosePreventer );
}
@@ -1036,8 +1059,11 @@ void OleEmbeddedObject::StoreToLocation_Impl(
const uno::Reference< embed::XStorage >& xStorage,
const OUString& sEntName,
const uno::Sequence< beans::PropertyValue >& lObjArgs,
- bool bSaveAs )
+ bool bSaveAs, osl::ResettableMutexGuard& rGuard)
{
+#ifndef _WIN32
+ (void)rGuard;
+#endif
// TODO: use lObjArgs
// TODO: exchange StoreVisualReplacement by SO file format version?
@@ -1087,7 +1113,7 @@ void OleEmbeddedObject::StoreToLocation_Impl(
#ifdef _WIN32
// if the object was NOT modified after storing it can be just copied
// as if it was in loaded state
- || ( m_pOleComponent && !m_pOleComponent->IsDirty() )
+ || (m_pOleComponent && !ExecUnlocked([this] { return m_pOleComponent->IsDirty(); }, rGuard))
#endif
)
{
@@ -1459,13 +1485,13 @@ void SAL_CALL OleEmbeddedObject::storeToEntry( const uno::Reference< embed::XSto
}
// end wrapping related part ====================
- ::osl::MutexGuard aGuard( m_aMutex );
+ ::osl::ResettableMutexGuard aGuard( m_aMutex );
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController );
- StoreToLocation_Impl( xStorage, sEntName, lObjArgs, false );
+ StoreToLocation_Impl( xStorage, sEntName, lObjArgs, false, aGuard );
// TODO: should the listener notification be done?
}
@@ -1486,13 +1512,13 @@ void SAL_CALL OleEmbeddedObject::storeAsEntry( const uno::Reference< embed::XSto
}
// end wrapping related part ====================
- ::osl::MutexGuard aGuard( m_aMutex );
+ ::osl::ResettableMutexGuard aGuard( m_aMutex );
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController );
- StoreToLocation_Impl( xStorage, sEntName, lObjArgs, true );
+ StoreToLocation_Impl( xStorage, sEntName, lObjArgs, true, aGuard );
// TODO: should the listener notification be done here or in saveCompleted?
}
@@ -1668,7 +1694,7 @@ void SAL_CALL OleEmbeddedObject::storeOwn()
// ask container to store the object, the container has to make decision
// to do so or not
- osl::ClearableMutexGuard aGuard(m_aMutex);
+ osl::ResettableMutexGuard aGuard(m_aMutex);
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
@@ -1694,7 +1720,7 @@ void SAL_CALL OleEmbeddedObject::storeOwn()
bool bStoreLoaded = true;
#ifdef _WIN32
- if ( m_nObjectState != embed::EmbedStates::LOADED && m_pOleComponent && m_pOleComponent->IsDirty() )
+ if ( m_nObjectState != embed::EmbedStates::LOADED && m_pOleComponent && ExecUnlocked([this] { return m_pOleComponent->IsDirty(); }, aGuard) )
{
bStoreLoaded = false;
diff --git a/embeddedobj/source/msole/olevisual.cxx b/embeddedobj/source/msole/olevisual.cxx
index 19084209e7d3..7b3e12e7339a 100644
--- a/embeddedobj/source/msole/olevisual.cxx
+++ b/embeddedobj/source/msole/olevisual.cxx
@@ -27,14 +27,16 @@
#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
#include <oleembobj.hxx>
+#if defined (_WIN32)
#include <comphelper/mimeconfighelper.hxx>
+#endif
#include <comphelper/seqstream.hxx>
#include <filter/msfilter/classids.hxx>
#include <sal/log.hxx>
#if defined(_WIN32)
#include "olecomponent.hxx"
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#endif
using namespace ::com::sun::star;
@@ -227,6 +229,7 @@ awt::Size SAL_CALL OleEmbeddedObject::getVisualAreaSize( sal_Int64 nAspect )
}
catch( const uno::Exception& )
{
+ TOOLS_WARN_EXCEPTION("embeddedobj.ole", "OleEmbeddedObject::getVisualAreaSize: GetExtent() failed:");
}
if (bBackToLoaded)
@@ -251,6 +254,7 @@ awt::Size SAL_CALL OleEmbeddedObject::getVisualAreaSize( sal_Int64 nAspect )
}
catch( const uno::Exception& )
{
+ TOOLS_WARN_EXCEPTION("embeddedobj.ole", "OleEmbeddedObject::getVisualAreaSize: GetCachedExtent() failed:");
}
}
@@ -264,6 +268,7 @@ awt::Size SAL_CALL OleEmbeddedObject::getVisualAreaSize( sal_Int64 nAspect )
}
catch( const uno::Exception& )
{
+ TOOLS_WARN_EXCEPTION("embeddedobj.ole", "OleEmbeddedObject::getVisualAreaSize: GetRecommendedExtent() failed:");
}
}
@@ -320,7 +325,7 @@ embed::VisualRepresentation SAL_CALL OleEmbeddedObject::getPreferredVisualRepres
}
// end wrapping related part ====================
- ::osl::MutexGuard aGuard( m_aMutex );
+ osl::ResettableMutexGuard aGuard(m_aMutex);
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
@@ -359,7 +364,10 @@ embed::VisualRepresentation SAL_CALL OleEmbeddedObject::getPreferredVisualRepres
cppu::UnoType<uno::Sequence< sal_Int8 >>::get() );
embed::VisualRepresentation aVisualRepr;
- aVisualRepr.Data = m_pOleComponent->getTransferData( aDataFlavor );
+ {
+ osl::ResettableMutexGuardScopedReleaser clearedMutex(aGuard);
+ aVisualRepr.Data = m_pOleComponent->getTransferData(aDataFlavor);
+ }
aVisualRepr.Flavor = aDataFlavor;
uno::Sequence< sal_Int8 > aVisReplSeq;
diff --git a/embeddedobj/source/msole/ownview.cxx b/embeddedobj/source/msole/ownview.cxx
index 75a41d0a1ac9..66dcab3b45fd 100644
--- a/embeddedobj/source/msole/ownview.cxx
+++ b/embeddedobj/source/msole/ownview.cxx
@@ -29,7 +29,6 @@
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/ucb/SimpleFileAccess.hpp>
#include <com/sun/star/util/XCloseable.hpp>
-#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/document/XEventBroadcaster.hpp>
#include <com/sun/star/document/XEventListener.hpp>
@@ -39,7 +38,7 @@
#include <comphelper/processfactory.hxx>
#include <comphelper/storagehelper.hxx>
#include <comphelper/mimeconfighelper.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include "olepersist.hxx"
#include "ownview.hxx"
@@ -104,24 +103,24 @@ bool OwnView_Impl::CreateModelFromURL( const OUString& aFileURL )
uno::Reference < frame::XDesktop2 > xDocumentLoader = frame::Desktop::create(m_xContext);
uno::Sequence< beans::PropertyValue > aArgs( m_aFilterName.isEmpty() ? 4 : 5 );
+ auto pArgs = aArgs.getArray();
- aArgs[0].Name = "URL";
- aArgs[0].Value <<= aFileURL;
+ pArgs[0].Name = "URL";
+ pArgs[0].Value <<= aFileURL;
- aArgs[1].Name = "ReadOnly";
- aArgs[1].Value <<= true;
+ pArgs[1].Name = "ReadOnly";
+ pArgs[1].Value <<= true;
- aArgs[2].Name = "InteractionHandler";
- aArgs[2].Value <<= uno::Reference< task::XInteractionHandler >(
- static_cast< ::cppu::OWeakObject* >( new DummyHandler_Impl() ), uno::UNO_QUERY );
+ pArgs[2].Name = "InteractionHandler";
+ pArgs[2].Value <<= uno::Reference< task::XInteractionHandler >( new DummyHandler_Impl() );
- aArgs[3].Name = "DontEdit";
- aArgs[3].Value <<= true;
+ pArgs[3].Name = "DontEdit";
+ pArgs[3].Value <<= true;
if ( !m_aFilterName.isEmpty() )
{
- aArgs[4].Name = "FilterName";
- aArgs[4].Value <<= m_aFilterName;
+ pArgs[4].Name = "FilterName";
+ pArgs[4].Value <<= m_aFilterName;
}
uno::Reference< frame::XModel > xModel( xDocumentLoader->loadComponentFromURL(
@@ -135,16 +134,12 @@ bool OwnView_Impl::CreateModelFromURL( const OUString& aFileURL )
{
uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
if ( xBroadCaster.is() )
- xBroadCaster->addEventListener( uno::Reference< document::XEventListener >(
- static_cast< ::cppu::OWeakObject* >( this ),
- uno::UNO_QUERY ) );
+ xBroadCaster->addEventListener( uno::Reference< document::XEventListener >(this) );
uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
if ( xCloseable.is() )
{
- xCloseable->addCloseListener( uno::Reference< util::XCloseListener >(
- static_cast< ::cppu::OWeakObject* >( this ),
- uno::UNO_QUERY ) );
+ xCloseable->addCloseListener( uno::Reference< util::XCloseListener >(this) );
::osl::MutexGuard aGuard( m_aMutex );
m_xModel = xModel;
@@ -198,20 +193,21 @@ OUString OwnView_Impl::GetFilterNameFromExtentionAndInStream(
}
uno::Sequence< beans::PropertyValue > aArgs( aTypeName.isEmpty() ? 2 : 3 );
- aArgs[0].Name = "URL";
- aArgs[0].Value <<= OUString( "private:stream" );
- aArgs[1].Name = "InputStream";
- aArgs[1].Value <<= xInputStream;
+ auto pArgs = aArgs.getArray();
+ pArgs[0].Name = "URL";
+ pArgs[0].Value <<= OUString( "private:stream" );
+ pArgs[1].Name = "InputStream";
+ pArgs[1].Value <<= xInputStream;
if ( !aTypeName.isEmpty() )
{
- aArgs[2].Name = "TypeName";
- aArgs[2].Value <<= aTypeName;
+ pArgs[2].Name = "TypeName";
+ pArgs[2].Value <<= aTypeName;
}
aTypeName = xTypeDetection->queryTypeByDescriptor( aArgs, true );
OUString aFilterName;
- for ( beans::PropertyValue const & prop : std::as_const(aArgs) )
+ for (beans::PropertyValue const& prop : aArgs)
if ( prop.Name == "FilterName" )
prop.Value >>= aFilterName;
@@ -223,7 +219,7 @@ OUString OwnView_Impl::GetFilterNameFromExtentionAndInStream(
if ( xNameAccess.is() && ( xNameAccess->getByName( aTypeName ) >>= aTypes ) )
{
- for ( beans::PropertyValue const & prop : std::as_const(aTypes) )
+ for (beans::PropertyValue const& prop : aTypes)
{
if ( prop.Name == "PreferredFilter" && ( prop.Value >>= aFilterName ) )
{
@@ -246,19 +242,17 @@ bool OwnView_Impl::ReadContentsAndGenerateTempFile( const uno::Reference< io::XI
// create m_aNativeTempURL
OUString aNativeTempURL;
- uno::Reference < beans::XPropertySet > xNativeTempFile(
+ uno::Reference < io::XTempFile > xNativeTempFile(
io::TempFile::create(m_xContext),
- uno::UNO_QUERY_THROW );
- uno::Reference < io::XStream > xNativeTempStream( xNativeTempFile, uno::UNO_QUERY_THROW );
- uno::Reference < io::XOutputStream > xNativeOutTemp = xNativeTempStream->getOutputStream();
- uno::Reference < io::XInputStream > xNativeInTemp = xNativeTempStream->getInputStream();
+ uno::UNO_SET_THROW );
+ uno::Reference < io::XOutputStream > xNativeOutTemp = xNativeTempFile->getOutputStream();
+ uno::Reference < io::XInputStream > xNativeInTemp = xNativeTempFile->getInputStream();
if ( !xNativeOutTemp.is() || !xNativeInTemp.is() )
throw uno::RuntimeException();
try {
- xNativeTempFile->setPropertyValue("RemoveFile", uno::makeAny( false ) );
- uno::Any aUrl = xNativeTempFile->getPropertyValue("Uri");
- aUrl >>= aNativeTempURL;
+ xNativeTempFile->setRemoveFile( false );
+ aNativeTempURL = xNativeTempFile->getUri();
}
catch ( uno::Exception& )
{
@@ -400,15 +394,14 @@ void OwnView_Impl::CreateNative()
if ( !xInStream.is() )
throw uno::RuntimeException();
- uno::Sequence< uno::Any > aArgs( 1 );
- aArgs[0] <<= xInStream;
+ uno::Sequence< uno::Any > aArgs{ uno::Any(xInStream) };
uno::Reference< container::XNameAccess > xNameAccess(
m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
"com.sun.star.embed.OLESimpleStorage",
aArgs, m_xContext ),
uno::UNO_QUERY_THROW );
- OUString aSubStreamName = "\1Ole10Native";
+ static constexpr OUString aSubStreamName(u"\1Ole10Native"_ustr);
uno::Reference< embed::XClassifiedObject > xStor( xNameAccess, uno::UNO_QUERY_THROW );
uno::Sequence< sal_Int8 > aStorClassID = xStor->getClassID();
@@ -416,6 +409,7 @@ void OwnView_Impl::CreateNative()
{
sal_uInt8 const aClassID[] =
{ 0x00, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
+ // coverity[overrun-buffer-arg : FALSE] - coverity has difficulty with css::uno::Sequence
uno::Sequence< sal_Int8 > aPackageClassID( reinterpret_cast<sal_Int8 const *>(aClassID), 16 );
uno::Reference< io::XStream > xSubStream;
@@ -544,16 +538,12 @@ void OwnView_Impl::Close()
try {
uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
if ( xBroadCaster.is() )
- xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
- static_cast< ::cppu::OWeakObject* >( this ),
- uno::UNO_QUERY ) );
+ xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >( this ) );
uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
if ( xCloseable.is() )
{
- xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
- static_cast< ::cppu::OWeakObject* >( this ),
- uno::UNO_QUERY ) );
+ xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >( this ) );
xCloseable->close( true );
}
}
@@ -585,15 +575,11 @@ void SAL_CALL OwnView_Impl::notifyEvent( const document::EventObject& aEvent )
try {
uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
if ( xBroadCaster.is() )
- xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
- static_cast< ::cppu::OWeakObject* >( this ),
- uno::UNO_QUERY ) );
+ xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >( this ) );
uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
if ( xCloseable.is() )
- xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
- static_cast< ::cppu::OWeakObject* >( this ),
- uno::UNO_QUERY ) );
+ xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >( this ) );
}
catch( uno::Exception& )
{}
diff --git a/embeddedobj/source/msole/xdialogcreator.cxx b/embeddedobj/source/msole/xdialogcreator.cxx
index 2d162cf9608e..74b267eca22f 100644
--- a/embeddedobj/source/msole/xdialogcreator.cxx
+++ b/embeddedobj/source/msole/xdialogcreator.cxx
@@ -29,6 +29,7 @@
#include <com/sun/star/datatransfer/DataFlavor.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
#include <osl/thread.h>
#include <osl/file.hxx>
@@ -38,8 +39,10 @@
#include "platform.h"
#include <comphelper/mimeconfighelper.hxx>
#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <cppuhelper/weak.hxx>
+#include <comphelper/sequenceashashmap.hxx>
#include "xdialogcreator.hxx"
#include <oleembobj.hxx>
@@ -48,6 +51,7 @@
#ifdef _WIN32
#include <oledlg.h>
+#include <o3tl/char16_t2wchar_t.hxx>
#include <vcl/winscheduler.hxx>
namespace {
@@ -137,34 +141,21 @@ embed::InsertedObjectInfo SAL_CALL MSOLEDialogObjectCreator::createInstanceByDia
InitializedOleGuard aGuard;
- OLEUIINSERTOBJECT io = {};
- char szFile[MAX_PATH];
- UINT uTemp;
-
- io.cbStruct = sizeof(io);
+ OLEUIINSERTOBJECTW io{ sizeof(io) };
io.hWndOwner = GetActiveWindow();
+ wchar_t szFile[MAX_PATH];
szFile[0] = 0;
io.lpszFile = szFile;
- io.cchFile = MAX_PATH;
+ io.cchFile = std::size(szFile);
io.dwFlags = IOF_SELECTCREATENEW | IOF_DISABLELINK;
-
- ::osl::Module aOleDlgLib;
- if( !aOleDlgLib.load( "oledlg" ))
- throw uno::RuntimeException();
-
- OleUIInsertObjectA_Type * pInsertFct = reinterpret_cast<OleUIInsertObjectA_Type *>(
- aOleDlgLib.getSymbol( "OleUIInsertObjectA" ));
- if( !pInsertFct )
- throw uno::RuntimeException();
-
// Disable any event loop shortcuts by enabling a real timer.
// This way the native windows dialog won't block our own processing.
WinScheduler::SetForceRealTimer();
- uTemp=pInsertFct(&io);
+ UINT uTemp = OleUIInsertObjectW(&io);
if ( OLEUI_OK != uTemp )
throw ucb::CommandAbortedException();
@@ -193,15 +184,13 @@ embed::InsertedObjectInfo SAL_CALL MSOLEDialogObjectCreator::createInstanceByDia
}
else
{
- OUString aFileName
- = OStringToOUString( std::string_view( szFile ), osl_getThreadTextEncoding() );
+ OUString aFileName(o3tl::toU(szFile));
OUString aFileURL;
if ( osl::FileBase::getFileURLFromSystemPath( aFileName, aFileURL ) != osl::FileBase::E_None )
throw uno::RuntimeException();
- uno::Sequence< beans::PropertyValue > aMediaDescr( 1 );
- aMediaDescr[0].Name = "URL";
- aMediaDescr[0].Value <<= aFileURL;
+ uno::Sequence< beans::PropertyValue > aMediaDescr{ comphelper::makePropertyValue("URL",
+ aFileURL) };
// TODO: use config helper for type detection
uno::Reference< embed::XEmbeddedObjectCreator > xEmbCreator;
@@ -215,8 +204,31 @@ embed::InsertedObjectInfo SAL_CALL MSOLEDialogObjectCreator::createInstanceByDia
if ( !xEmbCreator.is() )
throw uno::RuntimeException();
+ uno::Reference<task::XStatusIndicator> xProgress;
+ OUString aProgressText;
+ comphelper::SequenceAsHashMap aMap(aInObjArgs);
+ auto it = aMap.find("StatusIndicator");
+ if (it != aMap.end())
+ {
+ it->second >>= xProgress;
+ }
+ it = aMap.find("StatusIndicatorText");
+ if (it != aMap.end())
+ {
+ it->second >>= aProgressText;
+ }
+ if (xProgress.is())
+ {
+ xProgress->start(aProgressText, 100);
+ }
+
aObjectInfo.Object.set( xEmbCreator->createInstanceInitFromMediaDescriptor( xStorage, sEntName, aMediaDescr, aObjArgs ),
uno::UNO_QUERY );
+
+ if (xProgress.is())
+ {
+ xProgress->end();
+ }
}
if ( ( io.dwFlags & IOF_CHECKDISPLAYASICON) && io.hMetaPict != nullptr )
@@ -241,11 +253,8 @@ embed::InsertedObjectInfo SAL_CALL MSOLEDialogObjectCreator::createInstanceByDia
"Image WMF",
cppu::UnoType<uno::Sequence< sal_Int8 >>::get() );
- aObjectInfo.Options.realloc( 2 );
- aObjectInfo.Options[0].Name = "Icon";
- aObjectInfo.Options[0].Value <<= aMetafile;
- aObjectInfo.Options[1].Name = "IconFormat";
- aObjectInfo.Options[1].Value <<= aFlavor;
+ aObjectInfo.Options = { { "Icon", css::uno::Any(aMetafile) },
+ { "IconFormat", css::uno::Any(aFlavor) } };
}
GlobalUnlock( io.hMetaPict );
@@ -282,8 +291,7 @@ embed::InsertedObjectInfo SAL_CALL MSOLEDialogObjectCreator::createInstanceInitF
2 );
uno::Reference< embed::XEmbeddedObject > xResult(
- static_cast< ::cppu::OWeakObject* > ( new OleEmbeddedObject( m_xContext ) ),
- uno::UNO_QUERY );
+ new OleEmbeddedObject( m_xContext ) );
uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY_THROW );
xPersist->setPersistentEntry( xStorage,
@@ -329,7 +337,7 @@ extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
embeddedobj_MSOLEDialogObjectCreator_get_implementation(
css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
{
- return cppu::acquire(static_cast<cppu::OWeakObject*>(new MSOLEDialogObjectCreator(context)));
+ return cppu::acquire(new MSOLEDialogObjectCreator(context));
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/msole/xolefactory.cxx b/embeddedobj/source/msole/xolefactory.cxx
index b18ba1153498..735e1438c5f8 100644
--- a/embeddedobj/source/msole/xolefactory.cxx
+++ b/embeddedobj/source/msole/xolefactory.cxx
@@ -22,6 +22,7 @@
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/embed/Aspects.hpp>
#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/lang/NoSupportException.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include "xolefactory.hxx"
@@ -30,6 +31,8 @@
#include <cppuhelper/supportsservice.hxx>
#include <cppuhelper/weak.hxx>
+#include <officecfg/Office/Common.hxx>
+
using namespace ::com::sun::star;
// TODO: do not create OLE objects that represent OOo documents
@@ -41,6 +44,8 @@ uno::Reference< uno::XInterface > SAL_CALL OleEmbeddedObjectFactory::createInsta
const uno::Sequence< beans::PropertyValue >& aMedDescr,
const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
+ throw lang::NoSupportException("Active OLE content is disabled!");
if ( !xStorage.is() )
throw lang::IllegalArgumentException( "No parent storage is provided!",
static_cast< ::cppu::OWeakObject* >(this),
@@ -101,6 +106,8 @@ uno::Reference< uno::XInterface > SAL_CALL OleEmbeddedObjectFactory::createInsta
const uno::Sequence< beans::PropertyValue >& aMediaDescr,
const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
+ throw lang::NoSupportException("Active OLE content is disabled!");
if ( !xStorage.is() )
throw lang::IllegalArgumentException( "No parent storage is provided!",
static_cast< ::cppu::OWeakObject* >(this),
@@ -133,6 +140,8 @@ uno::Reference< uno::XInterface > SAL_CALL OleEmbeddedObjectFactory::createInsta
const OUString& sEntName,
const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
+ throw lang::NoSupportException("Active OLE content is disabled!");
if ( !xStorage.is() )
throw lang::IllegalArgumentException( "No parent storage is provided!",
static_cast< ::cppu::OWeakObject* >(this),
@@ -164,6 +173,8 @@ uno::Reference< uno::XInterface > SAL_CALL OleEmbeddedObjectFactory::createInsta
const uno::Sequence< beans::PropertyValue >& aMediaDescr,
const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
+ throw lang::NoSupportException("Active OLE content is disabled!");
if ( !xStorage.is() )
throw lang::IllegalArgumentException( "No parent storage is provided!",
static_cast< ::cppu::OWeakObject* >(this),
@@ -198,6 +209,8 @@ uno::Reference< uno::XInterface > SAL_CALL OleEmbeddedObjectFactory::createInsta
const uno::Sequence< beans::PropertyValue >& /*lArguments*/,
const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
+ if (officecfg::Office::Common::Security::Scripting::DisableActiveContent::get())
+ throw lang::NoSupportException("Active OLE content is disabled!");
// the initialization is completely controlled by user
if ( !xStorage.is() )
throw lang::IllegalArgumentException( "No parent storage is provided!",
@@ -245,7 +258,7 @@ extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
embeddedobj_OleEmbeddedObjectFactory_get_implementation(
css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
{
- return cppu::acquire(static_cast<cppu::OWeakObject*>(new OleEmbeddedObjectFactory(context)));
+ return cppu::acquire(new OleEmbeddedObjectFactory(context));
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/test/mtexecutor/bitmapcreator.cxx b/embeddedobj/test/mtexecutor/bitmapcreator.cxx
index 458c085ae111..60a89f8cd078 100644
--- a/embeddedobj/test/mtexecutor/bitmapcreator.cxx
+++ b/embeddedobj/test/mtexecutor/bitmapcreator.cxx
@@ -29,10 +29,11 @@ using namespace ::com::sun::star;
uno::Sequence< OUString > SAL_CALL VCLBitmapCreator::impl_staticGetSupportedServiceNames()
{
- uno::Sequence< OUString > aRet(2);
- aRet[0] = "com.sun.star.embed.BitmapCreator";
- aRet[1] = "com.sun.star.comp.embed.BitmapCreator";
- return aRet;
+ return
+ {
+ "com.sun.star.embed.BitmapCreator",
+ "com.sun.star.comp.embed.BitmapCreator"
+ };
}
diff --git a/embeddedobj/test/mtexecutor/mainthreadexecutor.cxx b/embeddedobj/test/mtexecutor/mainthreadexecutor.cxx
index 1fc7d2e3cc31..82a124a2c969 100644
--- a/embeddedobj/test/mtexecutor/mainthreadexecutor.cxx
+++ b/embeddedobj/test/mtexecutor/mainthreadexecutor.cxx
@@ -27,10 +27,11 @@ using namespace ::com::sun::star;
uno::Sequence< OUString > SAL_CALL MainThreadExecutor::impl_staticGetSupportedServiceNames()
{
- uno::Sequence< OUString > aRet(2);
- aRet[0] = "com.sun.star.thread.MainThreadExecutor";
- aRet[1] = "com.sun.star.comp.thread.MainThreadExecutor";
- return aRet;
+ return
+ {
+ "com.sun.star.thread.MainThreadExecutor",
+ "com.sun.star.comp.thread.MainThreadExecutor"
+ }
}