comphelper/source/misc/lok.cxx | 12 + configure.ac | 4 cui/source/options/optbasic.cxx | 25 +- desktop/CppunitTest_desktop_app.mk | 2 desktop/Library_sofficeapp.mk | 2 desktop/Module_desktop.mk | 5 desktop/source/lib/init.cxx | 41 +++ desktop/source/lib/lokinteractionhandler.cxx | 42 ++- include/LibreOfficeKit/LibreOfficeKitEnums.h | 31 ++ include/comphelper/lok.hxx | 4 include/test/testinteractionhandler.hxx | 160 +++++++++++++++ include/vcl/ITiledRenderable.hxx | 7 include/vcl/opengl/OpenGLWrapper.hxx | 8 libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 29 +- libreofficekit/source/gtk/lokdocview.cxx | 9 sax/source/fastparser/fastparser.cxx | 4 sc/source/ui/app/inputhdl.cxx | 8 sc/source/ui/docshell/docfunc.cxx | 2 sc/source/ui/drawfunc/futext3.cxx | 2 sc/source/ui/inc/tabview.hxx | 1 sc/source/ui/view/gridwin4.cxx | 14 + sc/source/ui/view/tabview5.cxx | 45 ++++ sc/source/ui/view/viewfun6.cxx | 2 scripting/Module_scripting.mk | 4 sfx2/source/control/unoctitm.cxx | 26 +- svtools/source/control/ruler.cxx | 9 svx/Executable_gengal.mk | 2 sw/CppunitTest_sw_ooxmlencryption.mk | 49 ++++ sw/Module_sw.mk | 1 sw/inc/AnnotationWin.hxx | 2 sw/inc/PostItMgr.hxx | 2 sw/inc/SidebarWin.hxx | 4 sw/inc/docufld.hxx | 15 + sw/inc/editsh.hxx | 1 sw/inc/swundo.hxx | 3 sw/inc/unotxdoc.hxx | 3 sw/ooxmlexport_setup.mk | 1 sw/qa/extras/docbookexport/docbookexport.cxx | 2 sw/qa/extras/htmlexport/htmlexport.cxx | 4 sw/qa/extras/htmlimport/htmlimport.cxx | 2 sw/qa/extras/inc/swmodeltestbase.hxx | 99 ++++++--- sw/qa/extras/ooxmlexport/data/Encrypted_MSO2007_abc.docx |binary sw/qa/extras/ooxmlexport/data/Encrypted_MSO2010_abc.docx |binary sw/qa/extras/ooxmlexport/data/Encrypted_MSO2013_abc.docx |binary sw/qa/extras/ooxmlexport/ooxmlencryption.cxx | 47 ++++ sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 7 sw/qa/extras/tiledrendering/tiledrendering.cxx | 99 +++++++++ sw/qa/extras/ww8import/ww8import.cxx | 2 sw/source/core/edit/edws.cxx | 3 sw/source/core/fields/docufld.cxx | 27 +- sw/source/core/undo/docundo.cxx | 12 + sw/source/core/view/viewsh.cxx | 3 sw/source/uibase/docvw/PostItMgr.cxx | 158 +++++++++++--- sw/source/uibase/docvw/SidebarWin.cxx | 93 ++++---- sw/source/uibase/shells/annotsh.cxx | 30 ++ sw/source/uibase/shells/basesh.cxx | 50 +++- sw/source/uibase/shells/textfld.cxx | 6 sw/source/uibase/uno/unotxdoc.cxx | 52 ++++ sw/source/uibase/wrtsh/wrtundo.cxx | 2 vcl/source/filter/graphicfilter.cxx | 2 writerfilter/source/ooxml/OOXMLDocumentImpl.cxx | 8 61 files changed, 1073 insertions(+), 216 deletions(-)
New commits: commit 97eaa05c40a926a9e16a109028ca8c829d34cb34 Author: Mike Kaganski <mike.kagan...@collabora.com> Date: Wed Jan 18 10:16:14 2017 +0300 Also consider saved exceptions when mbEnableThreads is true Previously, saved exceptions are only checked in FastSaxParserImpl::parse(), which is used in case mbEnableThreads is false (when data in input stream is no more than 10000). This patch also enables the same check for the other case. Change-Id: Ie718556b7c01322e30698515ecd331b7ebad4105 Reviewed-on: https://gerrit.libreoffice.org/33249 Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Tested-by: Mike Kaganski <mike.kagan...@collabora.com> (cherry picked from commit 18ae77a065cb8ae6940d4067f6ab7e99a3f74047) diff --git a/sax/source/fastparser/fastparser.cxx b/sax/source/fastparser/fastparser.cxx index 03ea471..420f8c7 100644 --- a/sax/source/fastparser/fastparser.cxx +++ b/sax/source/fastparser/fastparser.cxx @@ -811,6 +811,10 @@ void FastSaxParserImpl::parseStream(const InputSource& maStructSource) } while (!done); xParser->join(); deleteUsedEvents(); + + // callbacks used inside XML_Parse may have caught an exception + if( rEntity.maSavedException.hasValue() ) + rEntity.throwException( mxDocumentLocator, true ); } else { commit 1e996e3ae1f39b23efe846831d0498aa748a4f70 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Tue Jan 17 17:55:44 2017 +0100 sw: roundtrip test of OOXML decryption/encryption Change-Id: Idea2a46a692aed666eb8dbc6185ae001d30757c2 Reviewed-on: https://gerrit.libreoffice.org/33228 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> (cherry picked from commit 106c642b7542d587e961774cac515611982c6f0d) diff --git a/include/test/testinteractionhandler.hxx b/include/test/testinteractionhandler.hxx new file mode 100644 index 0000000..4e627b7 --- /dev/null +++ b/include/test/testinteractionhandler.hxx @@ -0,0 +1,160 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_TEST_TESTINTERACTIONHANDLER_HXX +#define INCLUDED_TEST_TESTINTERACTIONHANDLER_HXX + +#include <sal/config.h> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/task/InteractionHandler.hpp> +#include <com/sun/star/task/XInteractionAbort.hpp> +#include <com/sun/star/task/XInteractionApprove.hpp> +#include <com/sun/star/task/XInteractionPassword2.hpp> +#include <com/sun/star/task/DocumentPasswordRequest2.hpp> +#include <com/sun/star/task/DocumentMSPasswordRequest2.hpp> + +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <comphelper/sequence.hxx> + +class TestInteractionHandler : public cppu::WeakImplHelper<css::lang::XServiceInfo, + css::lang::XInitialization, + css::task::XInteractionHandler2> +{ + OUString msPassword; + bool mbPasswordRequested; + + TestInteractionHandler(const TestInteractionHandler&) = delete; + TestInteractionHandler& operator=(const TestInteractionHandler&) = delete; + +public: + TestInteractionHandler(const OUString& sPassword) + : msPassword(sPassword) + {} + + virtual ~TestInteractionHandler() override + {} + + bool wasPasswordRequested() + { + return mbPasswordRequested; + } + + virtual OUString SAL_CALL getImplementationName() + throw (css::uno::RuntimeException, std::exception) override + { + return OUString("com.sun.star.comp.uui.TestInteractionHandler"); + } + + virtual sal_Bool SAL_CALL supportsService(OUString const & rServiceName) + throw (css::uno::RuntimeException, std::exception) override + { + return cppu::supportsService(this, rServiceName); + } + + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() + throw (css::uno::RuntimeException, std::exception) override + { + css::uno::Sequence<OUString> aNames(3); + aNames[0] = "com.sun.star.task.InteractionHandler"; + // added to indicate support for configuration.backend.MergeRecoveryRequest + aNames[1] = "com.sun.star.configuration.backend.InteractionHandler"; + aNames[2] = "com.sun.star.uui.InteractionHandler"; + // for backwards compatibility + return aNames; + } + + virtual void SAL_CALL initialize(css::uno::Sequence<css::uno::Any> const & /*rArguments*/) + throw (css::uno::Exception, std::exception) override + {} + + virtual void SAL_CALL handle(css::uno::Reference<css::task::XInteractionRequest> const & rRequest) + throw (css::uno::RuntimeException, std::exception) override + { + handleInteractionRequest(rRequest); + } + + virtual sal_Bool SAL_CALL handleInteractionRequest(const css::uno::Reference<css::task::XInteractionRequest>& rRequest) + throw (css::uno::RuntimeException, std::exception) override + { + mbPasswordRequested = false; + + css::uno::Sequence<css::uno::Reference<css::task::XInteractionContinuation>> const &rContinuations = rRequest->getContinuations(); + css::uno::Any const aRequest(rRequest->getRequest()); + + if (handlePasswordRequest(rContinuations, aRequest)) + return true; + + for (sal_Int32 i = 0; i < rContinuations.getLength(); ++i) + { + css::uno::Reference<css::task::XInteractionApprove> xApprove(rContinuations[i], css::uno::UNO_QUERY); + if (xApprove.is()) + xApprove->select(); + } + + return true; + } + + bool handlePasswordRequest(const css::uno::Sequence<css::uno::Reference<css::task::XInteractionContinuation>> &rContinuations, + const css::uno::Any& rRequest) + { + bool bPasswordRequestFound = false; + bool bIsRequestPasswordToModify = false; + + OString sUrl; + + css::task::DocumentPasswordRequest2 passwordRequest2; + if (rRequest >>= passwordRequest2) + { + bIsRequestPasswordToModify = passwordRequest2.IsRequestPasswordToModify; + sUrl = passwordRequest2.Name.toUtf8(); + bPasswordRequestFound = true; + } + css::task::DocumentMSPasswordRequest2 passwordMSRequest2; + if (rRequest >>= passwordMSRequest2) + { + bIsRequestPasswordToModify = passwordMSRequest2.IsRequestPasswordToModify; + sUrl = passwordMSRequest2.Name.toUtf8(); + bPasswordRequestFound = true; + } + + if (!bPasswordRequestFound) + { + mbPasswordRequested = false; + return false; + } + mbPasswordRequested = true; + + for (sal_Int32 i = 0; i < rContinuations.getLength(); ++i) + { + if (bIsRequestPasswordToModify) + { + css::uno::Reference<css::task::XInteractionPassword2> const xIPW2(rContinuations[i], css::uno::UNO_QUERY); + xIPW2->setPasswordToModify(msPassword); + xIPW2->select(); + } + else + { + css::uno::Reference<css::task::XInteractionPassword> const xIPW(rContinuations[i], css::uno::UNO_QUERY); + if (xIPW.is()) + { + xIPW->setPassword(msPassword); + xIPW->select(); + } + } + } + return true; + } +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/CppunitTest_sw_ooxmlencryption.mk b/sw/CppunitTest_sw_ooxmlencryption.mk new file mode 100644 index 0000000..09b2fb1 --- /dev/null +++ b/sw/CppunitTest_sw_ooxmlencryption.mk @@ -0,0 +1,49 @@ +# -*- 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,sw_ooxmlencryption)) + +$(eval $(call gb_CppunitTest_add_exception_objects,sw_ooxmlencryption, \ + sw/qa/extras/ooxmlexport/ooxmlencryption \ +)) + +$(eval $(call gb_CppunitTest_use_libraries,sw_ooxmlencryption, \ + $(sw_ooxmlexport_libraries) \ +)) + +$(eval $(call gb_CppunitTest_use_externals,sw_ooxmlencryption,\ + boost_headers \ + libxml2 \ +)) + +$(eval $(call gb_CppunitTest_set_include,sw_ooxmlencryption,\ + -I$(SRCDIR)/sw/inc \ + -I$(SRCDIR)/sw/source/core/inc \ + -I$(SRCDIR)/sw/qa/extras/inc \ + $$(INCLUDE) \ +)) + +$(eval $(call gb_CppunitTest_use_sdk_api,sw_ooxmlencryption)) +$(eval $(call gb_CppunitTest_use_ure,sw_ooxmlencryption)) +$(eval $(call gb_CppunitTest_use_vcl,sw_ooxmlencryption)) + +$(eval $(call gb_CppunitTest_use_components,sw_ooxmlencryption,\ + $(sw_ooxmlexport_components) \ + filter/source/storagefilterdetect/storagefd \ +)) + +$(eval $(call gb_CppunitTest_use_configuration,sw_ooxmlencryption)) + +$(eval $(call gb_CppunitTest_use_packages,sw_ooxmlencryption,\ + oox_generated \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk index 3b5d06f..3dc5749 100644 --- a/sw/Module_sw.mk +++ b/sw/Module_sw.mk @@ -63,6 +63,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\ CppunitTest_sw_ooxmlexport9 \ CppunitTest_sw_ooxmlfieldexport \ CppunitTest_sw_ooxmlw14export \ + CppunitTest_sw_ooxmlencryption \ CppunitTest_sw_ooxmlimport \ CppunitTest_sw_ww8export \ CppunitTest_sw_ww8export2 \ diff --git a/sw/ooxmlexport_setup.mk b/sw/ooxmlexport_setup.mk index 91ffc4b..ae1b27f 100644 --- a/sw/ooxmlexport_setup.mk +++ b/sw/ooxmlexport_setup.mk @@ -59,6 +59,7 @@ define sw_ooxmlexport_components sw/util/swd \ sw/util/msword \ sfx2/util/sfx \ + sot/util/sot \ starmath/util/sm \ svl/source/fsstor/fsstorage \ svl/util/svl \ diff --git a/sw/qa/extras/docbookexport/docbookexport.cxx b/sw/qa/extras/docbookexport/docbookexport.cxx index d341a3c..6fa3f66 100644 --- a/sw/qa/extras/docbookexport/docbookexport.cxx +++ b/sw/qa/extras/docbookexport/docbookexport.cxx @@ -23,7 +23,7 @@ public: {} }; -#define DECLARE_DOCBOOKEXPORT_TEST(TestName, filename) DECLARE_SW_EXPORT_TEST(TestName, filename, DocbookExportTest) +#define DECLARE_DOCBOOKEXPORT_TEST(TestName, filename) DECLARE_SW_EXPORT_TEST(TestName, filename, nullptr, DocbookExportTest) DECLARE_DOCBOOKEXPORT_TEST(testsimple, "simple.docx") { diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx index d6453aa..e6a996d 100644 --- a/sw/qa/extras/htmlexport/htmlexport.cxx +++ b/sw/qa/extras/htmlexport/htmlexport.cxx @@ -67,7 +67,7 @@ private: }; -#define DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, HtmlExportTest) +#define DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, HtmlExportTest) DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testFdo81276, "fdo81276.html") { @@ -126,7 +126,7 @@ DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testCharacterBorder, "charborder.odt") // No shadow } -#define DECLARE_HTMLEXPORT_TEST(TestName, filename) DECLARE_SW_EXPORT_TEST(TestName, filename, HtmlExportTest) +#define DECLARE_HTMLEXPORT_TEST(TestName, filename) DECLARE_SW_EXPORT_TEST(TestName, filename, nullptr, HtmlExportTest) DECLARE_HTMLEXPORT_TEST(testExportOfImages, "textAndImage.docx") { diff --git a/sw/qa/extras/htmlimport/htmlimport.cxx b/sw/qa/extras/htmlimport/htmlimport.cxx index 4491f11..66d070d 100644 --- a/sw/qa/extras/htmlimport/htmlimport.cxx +++ b/sw/qa/extras/htmlimport/htmlimport.cxx @@ -26,7 +26,7 @@ class HtmlImportTest : public SwModelTestBase HtmlImportTest() : SwModelTestBase("sw/qa/extras/htmlimport/data/", "HTML (StarWriter)") {} }; -#define DECLARE_HTMLIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, HtmlImportTest) +#define DECLARE_HTMLIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, nullptr, HtmlImportTest) DECLARE_HTMLIMPORT_TEST(testPictureImport, "picture.html") { diff --git a/sw/qa/extras/inc/swmodeltestbase.hxx b/sw/qa/extras/inc/swmodeltestbase.hxx index 3097db6..07b04ea 100644 --- a/sw/qa/extras/inc/swmodeltestbase.hxx +++ b/sw/qa/extras/inc/swmodeltestbase.hxx @@ -32,6 +32,7 @@ #include <test/bootstrapfixture.hxx> #include <test/xmltesttools.hxx> +#include <test/testinteractionhandler.hxx> #include <unotest/macros_test.hxx> #include <unotools/ucbstreamhelper.hxx> #include <rtl/strbuf.hxx> @@ -64,7 +65,7 @@ using namespace css; * } * */ -#define DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, BaseClass) \ +#define DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, password, BaseClass) \ class TestName : public BaseClass { \ protected:\ virtual OUString getTestName() override { return OUString(#TestName); } \ @@ -75,25 +76,25 @@ using namespace css; CPPUNIT_TEST_SUITE_END(); \ \ void Import() { \ - executeImportTest(filename);\ + executeImportTest(filename, password);\ }\ void Import_Export_Import() {\ - executeImportExportImportTest(filename);\ + executeImportExportImportTest(filename, password);\ }\ void verify() override;\ }; \ CPPUNIT_TEST_SUITE_REGISTRATION(TestName); \ void TestName::verify() -#define DECLARE_OOXMLIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, Test) -#define DECLARE_OOXMLEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test) -#define DECLARE_RTFIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, Test) -#define DECLARE_RTFEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test) -#define DECLARE_ODFIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, Test) -#define DECLARE_ODFEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test) -#define DECLARE_WW8EXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test) +#define DECLARE_OOXMLIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, nullptr, Test) +#define DECLARE_OOXMLEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, Test) +#define DECLARE_RTFIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, nullptr, Test) +#define DECLARE_RTFEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, Test) +#define DECLARE_ODFIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, nullptr, Test) +#define DECLARE_ODFEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, Test) +#define DECLARE_WW8EXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, Test) -#define DECLARE_SW_IMPORT_TEST(TestName, filename, BaseClass) \ +#define DECLARE_SW_IMPORT_TEST(TestName, filename, password, BaseClass) \ class TestName : public BaseClass { \ protected:\ virtual OUString getTestName() override { return OUString(#TestName); } \ @@ -103,14 +104,14 @@ using namespace css; CPPUNIT_TEST_SUITE_END(); \ \ void Import() { \ - executeImportTest(filename);\ + executeImportTest(filename, password);\ }\ void verify() override;\ }; \ CPPUNIT_TEST_SUITE_REGISTRATION(TestName); \ void TestName::verify() -#define DECLARE_SW_EXPORT_TEST(TestName, filename, BaseClass) \ +#define DECLARE_SW_EXPORT_TEST(TestName, filename, password, BaseClass) \ class TestName : public BaseClass { \ protected:\ virtual OUString getTestName() override { return OUString(#TestName); } \ @@ -120,7 +121,7 @@ using namespace css; CPPUNIT_TEST_SUITE_END(); \ \ void Import_Export() {\ - executeImportExport(filename);\ + executeImportExport(filename, password);\ }\ void verify() override;\ }; \ @@ -136,6 +137,8 @@ private: protected: uno::Reference< lang::XComponent > mxComponent; + rtl::Reference<TestInteractionHandler> xInteractionHandler; + xmlBufferPtr mpXmlBuffer; const char* mpTestDocumentPath; const char* mpFilter; @@ -211,7 +214,7 @@ protected: * Helper func used by each unit test to test the 'import' code. * (Loads the requested file and then calls 'verify' method) */ - void executeImportTest(const char* filename) + void executeImportTest(const char* filename, const char* pPassword = nullptr) { // If the testcase is stored in some other format, it's pointless to test. if (mustTestImportOf(filename)) @@ -219,7 +222,7 @@ protected: maTempFile.EnableKillingFile(false); header(); std::unique_ptr<Resetter> const pChanges(preTest(filename)); - load(mpTestDocumentPath, filename); + load(mpTestDocumentPath, filename, pPassword); verify(); finish(); maTempFile.EnableKillingFile(); @@ -231,14 +234,14 @@ protected: * (Loads the requested file, save it to temp file, load the * temp file and then calls 'verify' method) */ - void executeImportExportImportTest(const char* filename) + void executeImportExportImportTest(const char* filename, const char* pPassword = nullptr) { maTempFile.EnableKillingFile(false); header(); std::unique_ptr<Resetter> const pChanges(preTest(filename)); - load(mpTestDocumentPath, filename); + load(mpTestDocumentPath, filename, pPassword); postLoad(filename); - reload(mpFilter, filename); + reload(mpFilter, filename, pPassword); verify(); finish(); maTempFile.EnableKillingFile(); @@ -250,12 +253,12 @@ protected: * the initial document condition), exports with the desired * export filter and then calls 'verify' method) */ - void executeImportExport(const char* filename) + void executeImportExport(const char* filename, const char* pPassword = nullptr) { maTempFile.EnableKillingFile(false); header(); std::unique_ptr<Resetter> const pChanges(preTest(filename)); - load(mpTestDocumentPath, filename); + load(mpTestDocumentPath, filename, pPassword); save(OUString::createFromAscii(mpFilter), maTempFile); maTempFile.EnableKillingFile(false); verify(); @@ -595,26 +598,50 @@ protected: std::cout << "File tested,Execution Time (ms)" << std::endl; } - void load(const char* pDir, const char* pName) + void load(const char* pDir, const char* pName, const char* pPassword = nullptr) { - return loadURL(m_directories.getURLFromSrc(pDir) + OUString::createFromAscii(pName), pName); + return loadURL(m_directories.getURLFromSrc(pDir) + OUString::createFromAscii(pName), pName, pPassword); } - void loadURL(OUString const& rURL, const char* pName) + void setTestInteractionHandler(const char* pPassword, std::vector<beans::PropertyValue>& rFilterOptions) + { + OUString sPassword = OUString::createFromAscii(pPassword); + rFilterOptions.resize(rFilterOptions.size() + 1); + xInteractionHandler = rtl::Reference<TestInteractionHandler>(new TestInteractionHandler(sPassword)); + uno::Reference<task::XInteractionHandler2> const xInteraction(xInteractionHandler.get()); + rFilterOptions[0].Name = "InteractionHandler"; + rFilterOptions[0].Value <<= xInteraction; + } + + void loadURL(OUString const& rURL, const char* pName, const char* pPassword = nullptr) { if (mxComponent.is()) mxComponent->dispose(); + + std::vector<beans::PropertyValue> aFilterOptions; + + if (pPassword) + { + setTestInteractionHandler(pPassword, aFilterOptions); + } + // Output name early, so in the case of a hang, the name of the hanging input file is visible. if (pName) std::cout << pName << ":\n"; mnStartTime = osl_getGlobalTimer(); - mxComponent = loadFromDesktop(rURL, "com.sun.star.text.TextDocument"); + mxComponent = loadFromDesktop(rURL, "com.sun.star.text.TextDocument", comphelper::containerToSequence(aFilterOptions)); + + if (pPassword) + { + CPPUNIT_ASSERT_MESSAGE("Password set but not requested", xInteractionHandler->wasPasswordRequested()); + } + discardDumpedLayout(); if (pName && mustCalcLayoutOf(pName)) calcLayout(); } - void reload(const char* pFilter, const char* filename) + void reload(const char* pFilter, const char* filename, const char* pPassword = nullptr) { uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); OUString aFilterName = OUString::createFromAscii(pFilter); @@ -622,11 +649,29 @@ protected: aMediaDescriptor["FilterName"] <<= aFilterName; if (!maFilterOptions.isEmpty()) aMediaDescriptor["FilterOptions"] <<= maFilterOptions; + if (pPassword) + { + OUString sPassword = OUString::createFromAscii(pPassword); + css::uno::Sequence<css::beans::NamedValue> aEncryptionData { + { "OOXPassword", css::uno::makeAny(sPassword) } + }; + aMediaDescriptor[utl::MediaDescriptor::PROP_ENCRYPTIONDATA()] <<= aEncryptionData; + } xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); uno::Reference<lang::XComponent> xComponent(xStorable, uno::UNO_QUERY); xComponent->dispose(); mbExported = true; - mxComponent = loadFromDesktop(maTempFile.GetURL(), "com.sun.star.text.TextDocument"); + + std::vector<beans::PropertyValue> aFilterOptions; + if (pPassword) + { + setTestInteractionHandler(pPassword, aFilterOptions); + } + mxComponent = loadFromDesktop(maTempFile.GetURL(), "com.sun.star.text.TextDocument", comphelper::containerToSequence(aFilterOptions)); + if (pPassword) + { + CPPUNIT_ASSERT_MESSAGE("Password set but not requested", xInteractionHandler->wasPasswordRequested()); + } if (mustValidate(filename)) { if(aFilterName == "Office Open XML Text") diff --git a/sw/qa/extras/ooxmlexport/data/Encrypted_MSO2007_abc.docx b/sw/qa/extras/ooxmlexport/data/Encrypted_MSO2007_abc.docx new file mode 100644 index 0000000..27566d4 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/Encrypted_MSO2007_abc.docx differ diff --git a/sw/qa/extras/ooxmlexport/data/Encrypted_MSO2010_abc.docx b/sw/qa/extras/ooxmlexport/data/Encrypted_MSO2010_abc.docx new file mode 100644 index 0000000..4881e35 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/Encrypted_MSO2010_abc.docx differ diff --git a/sw/qa/extras/ooxmlexport/data/Encrypted_MSO2013_abc.docx b/sw/qa/extras/ooxmlexport/data/Encrypted_MSO2013_abc.docx new file mode 100644 index 0000000..28fa85c Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/Encrypted_MSO2013_abc.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlencryption.cxx b/sw/qa/extras/ooxmlexport/ooxmlencryption.cxx new file mode 100644 index 0000000..6547676d --- /dev/null +++ b/sw/qa/extras/ooxmlexport/ooxmlencryption.cxx @@ -0,0 +1,47 @@ +/* -*- 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 <swmodeltestbase.hxx> +#include <string> + +class Test : public SwModelTestBase +{ +public: + Test() : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text") {} + +protected: + bool mustTestImportOf(const char* filename) const override { + return (OString(filename).endsWith(".docx")); + } +}; + +DECLARE_SW_ROUNDTRIP_TEST(testPassword2007, "Encrypted_MSO2007_abc.docx", "abc", Test) +{ + // Standard encryption format, AES 128, SHA1 + uno::Reference<text::XTextRange> xParagraph(getParagraph(1)); + CPPUNIT_ASSERT_EQUAL(OUString("abc"), xParagraph->getString()); +} + +DECLARE_SW_ROUNDTRIP_TEST(testPassword2010, "Encrypted_MSO2010_abc.docx", "abc", Test) +{ + // Agile encryption format, AES 128, CBC, SHA1 + uno::Reference<text::XTextRange> xParagraph(getParagraph(1)); + CPPUNIT_ASSERT_EQUAL(OUString("abc"), xParagraph->getString()); +} + +DECLARE_SW_ROUNDTRIP_TEST(testPassword2013, "Encrypted_MSO2013_abc.docx", "abc", Test) +{ + // Agile encryption format, AES 256, CBC, SHA512 + uno::Reference<text::XTextRange> xParagraph(getParagraph(1)); + CPPUNIT_ASSERT_EQUAL(OUString("ABC"), xParagraph->getString()); +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index 65ca902..58d0677 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -87,7 +87,7 @@ class FailTest : public Test { public: // UGLY: hacky manual override of MacrosTest::loadFromDesktop - void executeImportTest(const char* filename) + void executeImportTest(const char* filename, const char* /*password*/) { header(); preTest(filename); @@ -126,7 +126,7 @@ DECLARE_OOXMLIMPORT_TEST(testImageHyperlink, "image-hyperlink.docx") #if !defined(_WIN32) -DECLARE_SW_IMPORT_TEST(testMathMalformedXml, "math-malformed_xml.docx", FailTest) +DECLARE_SW_IMPORT_TEST(testMathMalformedXml, "math-malformed_xml.docx", nullptr, FailTest) { CPPUNIT_ASSERT(!mxComponent.is()); } @@ -1234,8 +1234,7 @@ protected: } }; -DECLARE_SW_IMPORT_TEST(testHFLinkToPrev, "headerfooter-link-to-prev.docx", - testHFBase) +DECLARE_SW_IMPORT_TEST(testHFLinkToPrev, "headerfooter-link-to-prev.docx", nullptr, testHFBase) { uno::Reference<container::XNameAccess> xPageStyles = getStyles("PageStyles"); diff --git a/sw/qa/extras/ww8import/ww8import.cxx b/sw/qa/extras/ww8import/ww8import.cxx index b26c3db..c7f488f 100644 --- a/sw/qa/extras/ww8import/ww8import.cxx +++ b/sw/qa/extras/ww8import/ww8import.cxx @@ -19,7 +19,7 @@ public: } }; -#define DECLARE_WW8IMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, Test) +#define DECLARE_WW8IMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, nullptr, Test) DECLARE_WW8IMPORT_TEST(testFloatingTableSectionMargins, "floating-table-section-margins.doc") { commit 1c67ec62f65c4180c3b6be2ded66b3183dbe9138 Author: Mike Kaganski <mike.kagan...@collabora.com> Date: Wed Jan 18 09:18:17 2017 +0300 tdf#104181: don't throw on XRelationshipAccess query The queries are followed by conditional blocks; so throwing is unnecessary and erroneous (breaks parser internal state). Change-Id: I49917a85e34866a326b4a2edd30e76f130b8ee27 Reviewed-on: https://gerrit.libreoffice.org/33244 Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit 13827ffa54268dc648e1b72ea574daea02598335) diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx index f8d5bdc..45b23b5 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx @@ -549,7 +549,7 @@ void OOXMLDocumentImpl::resolveCustomXmlStream(Stream & rStream) { // Resolving all item[n].xml files from CustomXml folder. uno::Reference<embed::XRelationshipAccess> xRelationshipAccess; - xRelationshipAccess.set((dynamic_cast<OOXMLStreamImpl&>(*mpStream.get())).accessDocumentStream(), uno::UNO_QUERY_THROW); + xRelationshipAccess.set((dynamic_cast<OOXMLStreamImpl&>(*mpStream.get())).accessDocumentStream(), uno::UNO_QUERY); if (xRelationshipAccess.is()) { static const char sCustomType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml"; @@ -622,7 +622,7 @@ void OOXMLDocumentImpl::resolveGlossaryStream(Stream & /*rStream*/) return; } uno::Reference<embed::XRelationshipAccess> xRelationshipAccess; - xRelationshipAccess.set((dynamic_cast<OOXMLStreamImpl&>(*pStream.get())).accessDocumentStream(), uno::UNO_QUERY_THROW); + xRelationshipAccess.set((dynamic_cast<OOXMLStreamImpl&>(*pStream.get())).accessDocumentStream(), uno::UNO_QUERY); if (xRelationshipAccess.is()) { @@ -709,7 +709,7 @@ void OOXMLDocumentImpl::resolveGlossaryStream(Stream & /*rStream*/) void OOXMLDocumentImpl::resolveEmbeddingsStream(const OOXMLStream::Pointer_t& pStream) { uno::Reference<embed::XRelationshipAccess> xRelationshipAccess; - xRelationshipAccess.set((dynamic_cast<OOXMLStreamImpl&>(*pStream.get())).accessDocumentStream(), uno::UNO_QUERY_THROW); + xRelationshipAccess.set((dynamic_cast<OOXMLStreamImpl&>(*pStream.get())).accessDocumentStream(), uno::UNO_QUERY); std::vector<css::beans::PropertyValue> aEmbeddings; if (xRelationshipAccess.is()) { @@ -802,7 +802,7 @@ void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream) { // Resolving all ActiveX[n].xml files from ActiveX folder. uno::Reference<embed::XRelationshipAccess> xRelationshipAccess; - xRelationshipAccess.set((dynamic_cast<OOXMLStreamImpl&>(*mpStream.get())).accessDocumentStream(), uno::UNO_QUERY_THROW); + xRelationshipAccess.set((dynamic_cast<OOXMLStreamImpl&>(*mpStream.get())).accessDocumentStream(), uno::UNO_QUERY); if (xRelationshipAccess.is()) { static const char sCustomType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/control"; commit e1b3492a9bea2f345f6852a3754ff4b71a152e02 Author: Marco Cecchetti <marco.cecche...@collabora.com> Date: Wed Oct 19 22:08:06 2016 +0200 LOK: Calc: notes: on edit mode starts/ends: missing tiles invalidation On edit mode starts/ends, when a note is hidden, tiles, only the note tail belongs to, are not invalidated. Change-Id: I69487f428a121fc05da99d3b06786afd4f834766 Reviewed-on: https://gerrit.libreoffice.org/30101 Reviewed-by: Marco Cecchetti <mrcek...@gmail.com> Tested-by: Marco Cecchetti <mrcek...@gmail.com> (cherry picked from commit 457642759ff81aacf1451dd9025846799d0b978e) diff --git a/sc/source/ui/drawfunc/futext3.cxx b/sc/source/ui/drawfunc/futext3.cxx index 6046e4c..84debf7 100644 --- a/sc/source/ui/drawfunc/futext3.cxx +++ b/sc/source/ui/drawfunc/futext3.cxx @@ -119,6 +119,8 @@ void FuText::StopEditMode() if( pNote ) { + ScTabView::OnLOKNoteStateChanged( pNote ); + // hide the caption object if it is in hidden state pNote->ShowCaptionTemp( aNotePos, false ); diff --git a/sc/source/ui/view/viewfun6.cxx b/sc/source/ui/view/viewfun6.cxx index ae40363..92a1804 100644 --- a/sc/source/ui/view/viewfun6.cxx +++ b/sc/source/ui/view/viewfun6.cxx @@ -509,6 +509,8 @@ void ScViewFunc::EditNote() { ScrollToObject( pCaption ); // make object fully visible pFuText->SetInEditMode( pCaption ); + + ScTabView::OnLOKNoteStateChanged( pNote ); } } } commit 5c31a7baccc028163176b37b17cfaa8f5b315627 Author: Marco Cecchetti <marco.cecche...@collabora.com> Date: Wed Oct 19 22:00:04 2016 +0200 LOK: Calc: show/hide a note does not perform any tile invalidation Change-Id: Ia904b6bbe82c395299b269ddbde523d19bf486bc Reviewed-on: https://gerrit.libreoffice.org/30099 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Marco Cecchetti <mrcek...@gmail.com> (cherry picked from commit ffb1fe4f434a48358a18c0af2c44a112d9ad04be) diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index d84c47d..fb7fd67 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -1221,6 +1221,8 @@ bool ScDocFunc::ShowNote( const ScAddress& rPos, bool bShow ) if (rDoc.IsStreamValid(rPos.Tab())) rDoc.SetStreamValid(rPos.Tab(), false); + ScTabView::OnLOKNoteStateChanged(pNote); + rDocShell.SetDocumentModified(); return true; diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx index 948f599..5afc3d3 100644 --- a/sc/source/ui/inc/tabview.hxx +++ b/sc/source/ui/inc/tabview.hxx @@ -584,6 +584,7 @@ public: void SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector<editeng::MisspellRanges>* pRanges ); /// @see ScModelObj::getRowColumnHeaders(). OUString getRowColumnHeaders(const Rectangle& rRectangle); + static void OnLOKNoteStateChanged(const ScPostIt* pNote); }; #endif diff --git a/sc/source/ui/view/tabview5.cxx b/sc/source/ui/view/tabview5.cxx index fdb0823..3baf606 100644 --- a/sc/source/ui/view/tabview5.cxx +++ b/sc/source/ui/view/tabview5.cxx @@ -22,6 +22,7 @@ #include <svx/fmshell.hxx> #include <svx/svdobj.hxx> +#include <svx/svdocapt.hxx> #include <svx/svdoutl.hxx> #include <sfx2/bindings.hxx> #include <sfx2/dispatch.hxx> @@ -47,6 +48,7 @@ #include "AccessibilityHints.hxx" #include "docsh.hxx" #include "viewuno.hxx" +#include "postit.hxx" #include <vcl/svapp.hxx> #include <vcl/settings.hxx> @@ -645,4 +647,47 @@ void ScTabView::ResetBrushDocument() } } +void ScTabView::OnLOKNoteStateChanged(const ScPostIt* pNote) +{ + if (!comphelper::LibreOfficeKit::isActive()) + return; + + const SdrCaptionObj* pCaption = pNote->GetCaption(); + if (!pCaption) return; + + Rectangle aRect = pCaption->GetLogicRect(); + basegfx::B2DRange aTailRange = pCaption->getTailPolygon().getB2DRange(); + Rectangle aTailRect(aTailRange.getMinX(), aTailRange.getMinY(), + aTailRange.getMaxX(), aTailRange.getMaxY()); + aRect.Union( aTailRect ); + + // This is a temporary workaround: sometime in tiled rendering mode + // the tip of the note arrow is misplaced by a fixed offset. + // The value used below is enough to get the tile, where the arrow tip is + // placed, invalidated. + const int nBorderSize = 200; + Rectangle aInvalidRect = aRect; + aInvalidRect.Left() -= nBorderSize; + aInvalidRect.Right() += nBorderSize; + aInvalidRect.Top() -= nBorderSize; + aInvalidRect.Bottom() += nBorderSize; + + SfxViewShell* pViewShell = SfxViewShell::GetFirst(); + while (pViewShell) + { + ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell); + if (pTabViewShell) + { + for (auto& pWin: pTabViewShell->pGridWin) + { + if (pWin && pWin->IsVisible()) + { + pWin->Invalidate(aInvalidRect); + } + } + } + pViewShell = SfxViewShell::GetNext(*pViewShell); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 4d4ad1ef765ab2b1ef75e20281195b2b460c2ccf Author: Marco Cecchetti <marco.cecche...@collabora.com> Date: Wed Oct 19 21:57:18 2016 +0200 LOK: Calc: notes: when edit mode begins the text content is misplaced Change-Id: Ia8efcee6fbeb75dd712d3ac480e355c2972875f3 Reviewed-on: https://gerrit.libreoffice.org/30098 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Eike Rathke <er...@redhat.com> (cherry picked from commit 1e3879f7be9384e6c1027f2ac148ddf0754b6b54) diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx index f449f77..b26ac76 100644 --- a/sc/source/ui/view/gridwin4.cxx +++ b/sc/source/ui/view/gridwin4.cxx @@ -890,6 +890,20 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI { MapMode aCurrentMapMode(pContentDev->GetMapMode()); pContentDev->SetMapMode(aDrawMode); + + if (bIsTiledRendering) + { + auto aOrigin = aOriginalMode.GetOrigin(); + aOrigin.setX(aOrigin.getX() / TWIPS_PER_PIXEL + aOutputData.nScrX); + aOrigin.setY(aOrigin.getY() / TWIPS_PER_PIXEL + aOutputData.nScrY); + const double twipFactor = 15 * 1.76388889; // 26.45833335 + aOrigin = Point(aOrigin.getX() * twipFactor, + aOrigin.getY() * twipFactor); + MapMode aNew = rDevice.GetMapMode(); + aNew.SetOrigin(aOrigin); + rDevice.SetMapMode(aNew); + } + SdrView* pDrawView = pTabViewShell->GetSdrView(); if(pDrawView) commit 64a88ff3d204c985b6fca8f7d27ec416c61454c2 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Wed Dec 7 16:06:26 2016 +0100 lokit: support password protected binary MS and OOXML documents Change-Id: Id7fa1f428d07271e71f3df962bd6718a35372389 Reviewed-on: https://gerrit.libreoffice.org/31730 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Jan Holesovsky <ke...@collabora.com> (cherry picked from commit 828e77009b5a7f3925cec37f0297208f7d38376f) diff --git a/desktop/source/lib/lokinteractionhandler.cxx b/desktop/source/lib/lokinteractionhandler.cxx index eaf96ab..58d4052 100644 --- a/desktop/source/lib/lokinteractionhandler.cxx +++ b/desktop/source/lib/lokinteractionhandler.cxx @@ -35,6 +35,9 @@ #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp> #include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp> +#include <com/sun/star/task/DocumentPasswordRequest2.hpp> +#include <com/sun/star/task/DocumentMSPasswordRequest2.hpp> + #include <../../inc/lib/init.hxx> #include <LibreOfficeKit/LibreOfficeKitEnums.h> @@ -242,20 +245,37 @@ bool LOKInteractionHandler::handleNetworkException(const uno::Sequence<uno::Refe bool LOKInteractionHandler::handlePasswordRequest(const uno::Sequence<uno::Reference<task::XInteractionContinuation>> &rContinuations, const uno::Any &rRequest) { + bool bPasswordRequestFound = false; + bool bIsRequestPasswordToModify = false; + + OString sUrl; + task::DocumentPasswordRequest2 passwordRequest; - if (!(rRequest >>= passwordRequest)) + if (rRequest >>= passwordRequest) + { + bIsRequestPasswordToModify = passwordRequest.IsRequestPasswordToModify; + sUrl = passwordRequest.Name.toUtf8(); + bPasswordRequestFound = true; + } + + task::DocumentMSPasswordRequest2 passwordMSRequest; + if (rRequest >>= passwordMSRequest) + { + bIsRequestPasswordToModify = passwordMSRequest.IsRequestPasswordToModify; + sUrl = passwordMSRequest.Name.toUtf8(); + bPasswordRequestFound = true; + } + + if (!bPasswordRequestFound) return false; if (m_pLOKit->mpCallback && - m_pLOKit->hasOptionalFeature((passwordRequest.IsRequestPasswordToModify) - ? LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY - : LOK_FEATURE_DOCUMENT_PASSWORD)) + m_pLOKit->hasOptionalFeature(bIsRequestPasswordToModify ? LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY + : LOK_FEATURE_DOCUMENT_PASSWORD)) { - OString const url(passwordRequest.Name.toUtf8()); - m_pLOKit->mpCallback(passwordRequest.IsRequestPasswordToModify - ? LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY - : LOK_CALLBACK_DOCUMENT_PASSWORD, - url.getStr(), + m_pLOKit->mpCallback(bIsRequestPasswordToModify ? LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY + : LOK_CALLBACK_DOCUMENT_PASSWORD, + sUrl.getStr(), m_pLOKit->mpCallbackData); // block until SetPassword is called @@ -267,7 +287,7 @@ bool LOKInteractionHandler::handlePasswordRequest(const uno::Sequence<uno::Refer { if (m_usePassword) { - if (passwordRequest.IsRequestPasswordToModify) + if (bIsRequestPasswordToModify) { uno::Reference<task::XInteractionPassword2> const xIPW2(rContinuations[i], uno::UNO_QUERY); xIPW2->setPasswordToModify(m_Password); @@ -285,7 +305,7 @@ bool LOKInteractionHandler::handlePasswordRequest(const uno::Sequence<uno::Refer } else { - if (passwordRequest.IsRequestPasswordToModify) + if (bIsRequestPasswordToModify) { uno::Reference<task::XInteractionPassword2> const xIPW2(rContinuations[i], uno::UNO_QUERY); xIPW2->setRecommendReadOnly(true); commit dec698c2d3a86fd8f5208bd6d0f8d7e2eba1574a Author: Tor Lillqvist <t...@collabora.com> Date: Thu Dec 8 09:47:05 2016 +0200 No OpenGLWrapper code in vcl if LIBO_HEADLESS Change-Id: I2330661212dac11093d80e4ceb400f1efee0359f (cherry picked from commit 663e5a54386d8bdee4ebc2bdd6f93da8a6f99ebe) diff --git a/include/vcl/opengl/OpenGLWrapper.hxx b/include/vcl/opengl/OpenGLWrapper.hxx index 3b7f6a7..5032234 100644 --- a/include/vcl/opengl/OpenGLWrapper.hxx +++ b/include/vcl/opengl/OpenGLWrapper.hxx @@ -22,13 +22,19 @@ struct VCL_DLLPUBLIC OpenGLWrapper /** * Returns true if VCL has OpenGL rendering enabled */ +#ifdef LIBO_HEADLESS + static bool isVCLOpenGLEnabled() + { + return false; + } +#else static bool isVCLOpenGLEnabled(); - /** * Returns the number of times OpenGL buffers have been swapped. */ static sal_Int64 getBufferSwapCounter(); +#endif }; #endif // INCLUDED_VCL_OPENGL_OPENGLWRAPPER_HXX commit 5b0d059a8249acec033ba04b1aa8fc35181cc635 Author: Tor Lillqvist <t...@collabora.com> Date: Thu Dec 8 09:42:34 2016 +0200 No glxtest library unless USING_X11 Change-Id: Ibcc0eeba9beaaeea86bdda5e0ea80e54c25621a9 (cherry picked from commit 986ba9a7e8b49f0c37fbd8f855e249a9f257ad08) diff --git a/desktop/CppunitTest_desktop_app.mk b/desktop/CppunitTest_desktop_app.mk index 1b1c361..6189f05 100644 --- a/desktop/CppunitTest_desktop_app.mk +++ b/desktop/CppunitTest_desktop_app.mk @@ -46,9 +46,11 @@ $(eval $(call gb_CppunitTest_use_libraries,desktop_app, \ )) ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS))) +ifeq ($(USING_X11),TRUE) $(eval $(call gb_CppunitTest_use_static_libraries,desktop_app,\ glxtest \ )) +endif $(eval $(call gb_CppunitTest_add_libs,desktop_app,\ -lm $(DLOPEN_LIBS) \ diff --git a/desktop/Library_sofficeapp.mk b/desktop/Library_sofficeapp.mk index 8164260..1d91403 100644 --- a/desktop/Library_sofficeapp.mk +++ b/desktop/Library_sofficeapp.mk @@ -118,9 +118,11 @@ $(eval $(call gb_Library_add_libs,sofficeapp,\ )) else ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS))) +ifeq ($(USING_X11),TRUE) $(eval $(call gb_Library_use_static_libraries,sofficeapp,\ glxtest \ )) +endif $(eval $(call gb_Library_add_libs,sofficeapp,\ -lm $(DLOPEN_LIBS) \ commit 9ffa72bd4acb9d8e1fc831246f2c80e8236cf6d5 Author: Tor Lillqvist <t...@collabora.com> Date: Thu Dec 8 07:42:38 2016 +0200 Fix -Werror,-Wunused-private-field in the DISABLE_EXPORT case Change-Id: I237a691ac6b7b3edcc7b2fbdfc36ed72ae46fe0c (cherry picked from commit df1de153d4a9e103dbf4580f91b3b15a77c44c1a) diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx index 379b8c5..04faf91 100644 --- a/vcl/source/filter/graphicfilter.cxx +++ b/vcl/source/filter/graphicfilter.cxx @@ -1847,6 +1847,8 @@ sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const OUString (void) nFormat; (void) pFilterData; + (void) nExpGraphHint; + return GRFILTER_FORMATERROR; #else SAL_INFO( "vcl.filter", "GraphicFilter::ExportGraphic() (thb)" ); commit 348856cab1e73a4b377748a87352c5e14a0276bc Author: Tor Lillqvist <t...@collabora.com> Date: Thu Dec 8 00:17:14 2016 +0200 The --enable-mergelibs option is not experimental Change-Id: I2a0671bf1c7c43cf250f36f480768f160b079eec (cherry picked from commit 0606c064f01b4e7e7c7d771765a2669379dd716a) diff --git a/configure.ac b/configure.ac index 6d358b7..9127759 100644 --- a/configure.ac +++ b/configure.ac @@ -1034,9 +1034,7 @@ dnl ---------- *** ---------- AC_ARG_ENABLE(mergelibs, AS_HELP_STRING([--enable-mergelibs], - [Enables linking of big, merged, library. Experimental feature, tested - only for Linux at some stage in history, but possibly does not work even - for Linux any more. This will link a core set of libraries into libmerged.]) + [Merge several of the smaller libraries into one big, "merged", one.]) ) AC_ARG_ENABLE(graphite, commit 74c59bf211442c80d7cb5f684aa8d1acb13c8a99 Author: Tor Lillqvist <t...@collabora.com> Date: Wed Dec 7 22:47:57 2016 +0200 Match conditional for glxtest static library in vcl Change-Id: If5b4308a29c78ded311bf300416b2cb4f553a7d5 (cherry picked from commit 8f1e4666ababa5bb2411e2828f9ff47e5698adbc) diff --git a/svx/Executable_gengal.mk b/svx/Executable_gengal.mk index e0a45e7..49b3b34 100644 --- a/svx/Executable_gengal.mk +++ b/svx/Executable_gengal.mk @@ -74,10 +74,12 @@ $(eval $(call gb_Executable_add_libs,gengal,\ -lX11 \ )) +ifeq ($(USING_X11),TRUE) $(eval $(call gb_Executable_use_static_libraries,gengal,\ glxtest \ )) endif endif +endif # vim: set noet sw=4 ts=4: commit c6b3412d526b9c5e219fc9aa17969d3ef09322bf Author: Tor Lillqvist <t...@collabora.com> Date: Wed Dec 7 22:37:12 2016 +0200 Match conditional in Repository.mk Change-Id: Ie9deeb673cd5083a2f57a502bfbf49319aa00165 (cherry picked from commit 6b60ea7f9b8bee5559cf33a9e466d30cafaf0cea) diff --git a/desktop/Module_desktop.mk b/desktop/Module_desktop.mk index 5a6604c..17ec5bf 100644 --- a/desktop/Module_desktop.mk +++ b/desktop/Module_desktop.mk @@ -52,6 +52,10 @@ $(eval $(call gb_Module_add_targets,desktop,\ Pagein_impress \ Pagein_writer \ CustomTarget_soffice \ +)) + +ifeq ($(USING_X11), TRUE) +$(eval $(call gb_Module_add_targets,desktop,\ Package_sbase_sh \ Package_scalc_sh \ Package_sdraw_sh \ @@ -63,6 +67,7 @@ $(eval $(call gb_Module_add_targets,desktop,\ endif endif endif +endif ifeq ($(OS),WNT) commit 6c590dddc3e5e187fb2d86390ee06c6f7b811180 Author: Tor Lillqvist <t...@collabora.com> Date: Wed Dec 7 19:32:23 2016 +0200 Match conditionals in Repository.mk Change-Id: Ibc97588de9d414e05184593e4e9c1aeba94959f3 (cherry picked from commit 7cd3c44a9ead6ff0e656e9b7ad3349557e285ee9) diff --git a/scripting/Module_scripting.mk b/scripting/Module_scripting.mk index ff509bc..a1b7326 100644 --- a/scripting/Module_scripting.mk +++ b/scripting/Module_scripting.mk @@ -28,11 +28,11 @@ $(eval $(call gb_Module_add_targets,scripting,\ ) \ Package_java \ Package_java_jars \ + $(if $(ENABLE_SCRIPTING_BEANSHELL),Package_ScriptsBeanShell) \ + $(if $(ENABLE_SCRIPTING_JAVASCRIPT),Package_ScriptsJavaScript) \ ) \ Package_scriptbindinglib \ Package_scriptproviderforpython \ - Package_ScriptsBeanShell \ - Package_ScriptsJavaScript \ Package_ScriptsPython \ Library_basprov \ Library_dlgprov \ commit 530baebae5d7aa9d70aa2956e6179059316903ae Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Mon Dec 5 21:37:25 2016 -0500 tdf#71409: Let's not crash the function wizard dialog. It's a long story, but here is a short summary: When the function wizard dialog launches, it uses an edit engine instance to process text input, and that edit engine instance comes from the input window (for whatever reason). And, we are supposed to get ScTextWnd::MakeDialogEditView() called to instantiate such edit engine instance for the function wizard dialog. My previous change, however, changed this and ScTextWnd::InitEditEngine() ended up getting called to instantiate the edit engine instance. These two functions create edit engine instances with different settings intended for different use cases... The crash we saw is just one manifestation of such differences. Change-Id: I7fd84c1b1eca2351b9ecc87e325c2fd3787369eb Reviewed-on: https://gerrit.libreoffice.org/31664 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Kohei Yoshida <libreoff...@kohei.us> (cherry picked from commit ae923f941f70ebe99cc785076f3357015dd69003) diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx index 3e9a964..241d866 100644 --- a/sc/source/ui/app/inputhdl.cxx +++ b/sc/source/ui/app/inputhdl.cxx @@ -1892,7 +1892,7 @@ void ScInputHandler::UpdateActiveView() } } - if (pInputWin) + if (pInputWin && (eMode == SC_INPUT_TOP || eMode == SC_INPUT_TABLE)) { // tdf#71409: Always create the edit engine instance for the input // window, in order to properly manage accessibility events. commit 8cce9a168a97f82760845adc440be1ca7e7e9629 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Tue Nov 29 16:51:26 2016 -0500 tdf#71409: always create edit engine instance for the input window. In order to properly manage accessibility events esp when no letters are typed. Without this, doing things like: 1) hit F2 to active cell edit, 2) hit ESC to deactivate, 3) go back to 1) and repeat the cycle several times, 4) hit Shift-Ctrl-F2 to activate the top input window would result in duplicated accessibility events fired, the number of which depends on how many times the above step was repeated. Change-Id: I116fdcbc63cbe9d33039d38a47770a6813c4e523 Reviewed-on: https://gerrit.libreoffice.org/31389 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Kohei Yoshida <libreoff...@kohei.us> (cherry picked from commit 9ba24ac54100a5af6ecdde479ebeb5c916e6fad2) diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx index e0712c4..3e9a964 100644 --- a/sc/source/ui/app/inputhdl.cxx +++ b/sc/source/ui/app/inputhdl.cxx @@ -1892,8 +1892,14 @@ void ScInputHandler::UpdateActiveView() } } - if (pInputWin && eMode == SC_INPUT_TOP ) + if (pInputWin) + { + // tdf#71409: Always create the edit engine instance for the input + // window, in order to properly manage accessibility events. pTopView = pInputWin->GetEditView(); + if (eMode != SC_INPUT_TOP) + pTopView = nullptr; + } else pTopView = nullptr; } commit b9d622df69302579d1f700022bc5950c841e935b Author: Henry Castro <hcas...@collabora.com> Date: Tue Nov 29 17:19:00 2016 -0400 lok: ensure positive values for width and height also check the pointer memory block allocated Change-Id: I0ded04e06f80400e64c5e58126a32ee503aeb394 Reviewed-on: https://gerrit.libreoffice.org/31388 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Henry Castro <hcas...@collabora.com> (cherry picked from commit 098fb95772b3184bb81180d1bc30c9753d30e2b6) diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index c2d1c82..14ccd53 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -2712,8 +2712,13 @@ unsigned char* doc_renderFont(LibreOfficeKitDocument* /*pThis*/, *pFontWidth = nFontWidth; int nFontHeight = aRect.BottomRight().Y() + 1; *pFontHeight = nFontHeight; + if (!(nFontWidth > 0 && nFontHeight > 0)) + break; unsigned char* pBuffer = static_cast<unsigned char*>(malloc(4 * nFontWidth * nFontHeight)); + if (!pBuffer) + break; + memset(pBuffer, 0, nFontWidth * nFontHeight * 4); aDevice->SetBackground(Wallpaper(COL_TRANSPARENT)); commit d240fa8cab17e2aecfed9340de431eb5a9408cef Author: Mike Kaganski <mike.kagan...@collabora.com> Date: Thu Nov 24 18:14:31 2016 +0300 tdf#104215: Remove the out-of-borders ruler check It is not called for out-of-borders points anyway, unless there is a table border on page border, in which case the cursor shows that dragging should be possible. Change-Id: If5cecbcd0799c74012c525588c0d2fce5d79ffd6 Reviewed-on: https://gerrit.libreoffice.org/31309 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> (cherry picked from commit 764358a43b83cdae9269af47070e3cb4739c96c0) diff --git a/svtools/source/control/ruler.cxx b/svtools/source/control/ruler.cxx index 22b752d..25fa30a 100644 --- a/svtools/source/control/ruler.cxx +++ b/svtools/source/control/ruler.cxx @@ -1515,7 +1515,6 @@ bool Ruler::ImplHitTest( const Point& rPos, RulerSelection* pHitTest, // test if outside nX -= mnVirOff; - long nXTemp = nX; if ( (nX < mpData->nRulVirOff - nXExtraOff) || (nX > mpData->nRulVirOff + mpData->nRulWidth + nXExtraOff) || (nY < 0) || @@ -1615,14 +1614,6 @@ bool Ruler::ImplHitTest( const Point& rPos, RulerSelection* pHitTest, } } - // everything left and right is outside and don't take this into account - if ( (nXTemp < mpData->nRulVirOff) || (nXTemp > mpData->nRulVirOff+mpData->nRulWidth) ) - { - pHitTest->nPos = 0; - pHitTest->eType = RulerType::Outside; - return false; - } - // test the borders int nBorderTolerance = 1; if(pHitTest->bExpandTest) commit ee9164755ba3b661cb74741eea6b03d71d06cea6 Author: Henry Castro <hcas...@collabora.com> Date: Thu Nov 24 07:09:38 2016 -0400 sw lok: notify repair when exist a conflict of multiple users undo/redo Change-Id: I026f4df6239fa87ee191f92127f9fa98ac2993eb Reviewed-on: https://gerrit.libreoffice.org/31161 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Henry Castro <hcas...@collabora.com> (cherry picked from commit 2db42ab241d0852d89a470b18727c22d0fc06745) diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 1af9643..c2d1c82 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -329,6 +329,11 @@ static boost::property_tree::ptree unoAnyToPropertyTree(const uno::Any& anyItem) if (aType == "string") aTree.put("value", anyItem.get<OUString>().toUtf8().getStr()); + else if (aType == "unsigned long") + aTree.put("value", OString::number(anyItem.get<sal_uInt32>()).getStr()); + else if (aType == "long") + aTree.put("value", OString::number(anyItem.get<sal_Int32>()).getStr()); + // TODO: Add more as required return aTree; @@ -1921,8 +1926,7 @@ public: aTree.put("success", bSuccess); } - // TODO UNO Any rEvent.Result -> JSON - // aTree.put("result": "..."); + aTree.add_child("result", unoAnyToPropertyTree(rEvent.Result)); std::stringstream aStream; boost::property_tree::write_json(aStream, aTree); diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx index 2bc0d30..c65d4e5 100644 --- a/sw/inc/editsh.hxx +++ b/sw/inc/editsh.hxx @@ -564,6 +564,7 @@ public: SwUndoId *const o_pId, const SwView* pView = nullptr) const; bool GetFirstRedoInfo(OUString *const o_pStr, + SwUndoId *const o_pId, const SwView* pView = nullptr) const; SwUndoId GetRepeatInfo(OUString *const o_pStr) const; diff --git a/sw/inc/swundo.hxx b/sw/inc/swundo.hxx index e33ee7b..c87b5e5 100644 --- a/sw/inc/swundo.hxx +++ b/sw/inc/swundo.hxx @@ -171,7 +171,8 @@ enum SwUndoId UNDO_UI_REPLACE_STYLE, UNDO_UI_DELETE_PAGE_BREAK, UNDO_UI_TEXT_CORRECTION, - UNDO_UI_TABLE_DELETE + UNDO_UI_TABLE_DELETE, + UNDO_CONFLICT }; #endif diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx index 19a4066..c9829f2 100644 --- a/sw/qa/extras/tiledrendering/tiledrendering.cxx +++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx @@ -10,6 +10,7 @@ #include <string> #include <boost/property_tree/json_parser.hpp> +#include <com/sun/star/frame/DispatchResultState.hpp> #include <swmodeltestbase.hxx> #include <LibreOfficeKit/LibreOfficeKitEnums.h> #include <comphelper/dispatchcommand.hxx> @@ -78,6 +79,9 @@ public: void testCommentEndTextEdit(); void testCursorPosition(); void testPaintCallbacks(); + void testUndoRepairResult(); + void testRedoRepairResult(); + CPPUNIT_TEST_SUITE(SwTiledRenderingTest); CPPUNIT_TEST(testRegisterCallback); @@ -120,6 +124,9 @@ public: CPPUNIT_TEST(testCommentEndTextEdit); CPPUNIT_TEST(testCursorPosition); CPPUNIT_TEST(testPaintCallbacks); + CPPUNIT_TEST(testUndoRepairResult); + CPPUNIT_TEST(testRedoRepairResult); + CPPUNIT_TEST_SUITE_END(); private: @@ -754,6 +761,30 @@ public: } }; +class TestResultListener : public cppu::WeakImplHelper<css::frame::XDispatchResultListener> +{ +public: + sal_uInt32 m_nDocRepair; + + TestResultListener() : m_nDocRepair(0) + { + } + + virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& rEvent) + throw(css::uno::RuntimeException, std::exception) override + { + if (rEvent.State == frame::DispatchResultState::SUCCESS) + { + rEvent.Result >>= m_nDocRepair; + } + } + + virtual void SAL_CALL disposing(const css::lang::EventObject&) + throw (css::uno::RuntimeException, std::exception) override + { + } +}; + void SwTiledRenderingTest::testMissingInvalidation() { comphelper::LibreOfficeKit::setActive(); @@ -1572,6 +1603,74 @@ void SwTiledRenderingTest::testPaintCallbacks() comphelper::LibreOfficeKit::setActive(false); } +void SwTiledRenderingTest::testUndoRepairResult() +{ + // Load a document and create two views. + comphelper::LibreOfficeKit::setActive(); + SwXTextDocument* pXTextDocument = createDoc("dummy.fodt"); + int nView1 = SfxLokHelper::getView(); + SfxLokHelper::createView(); + TestResultListener* pResult2 = new TestResultListener(); + css::uno::Reference< css::frame::XDispatchResultListener > xListener(static_cast< css::frame::XDispatchResultListener* >(pResult2), css::uno::UNO_QUERY); + pXTextDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>()); + int nView2 = SfxLokHelper::getView(); + + // Insert a character in the second view. + SfxLokHelper::setView(nView2); + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'b', 0); + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'b', 0); + + // Insert a character in the first view. + SfxLokHelper::setView(nView1); + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'a', 0); + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'a', 0); + + // Assert that by default the second view can't undo the action. + SfxLokHelper::setView(nView2); + comphelper::dispatchCommand(".uno:Undo", {}, xListener); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(UNDO_CONFLICT), pResult2->m_nDocRepair); + + mxComponent->dispose(); + mxComponent.clear(); + comphelper::LibreOfficeKit::setActive(false); +} + +void SwTiledRenderingTest::testRedoRepairResult() +{ + // Load a document and create two views. + comphelper::LibreOfficeKit::setActive(); + SwXTextDocument* pXTextDocument = createDoc("dummy.fodt"); + int nView1 = SfxLokHelper::getView(); + SfxLokHelper::createView(); + TestResultListener* pResult2 = new TestResultListener(); + css::uno::Reference< css::frame::XDispatchResultListener > xListener(static_cast< css::frame::XDispatchResultListener* >(pResult2), css::uno::UNO_QUERY); + pXTextDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>()); + int nView2 = SfxLokHelper::getView(); + + // Insert a character in the second view. + SfxLokHelper::setView(nView2); + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'b', 0); + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'b', 0); + + // Insert a character in the first view. + SfxLokHelper::setView(nView1); + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'a', 0); + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'a', 0); + comphelper::dispatchCommand(".uno:Undo", {}, xListener); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0), pResult2->m_nDocRepair); + + // Assert that by default the second view can't redo the action. + SfxLokHelper::setView(nView2); + comphelper::dispatchCommand(".uno:Redo", {}, xListener); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(UNDO_CONFLICT), pResult2->m_nDocRepair); + + mxComponent->dispose(); + mxComponent.clear(); + comphelper::LibreOfficeKit::setActive(false); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/edit/edws.cxx b/sw/source/core/edit/edws.cxx index 8cb0c59..25c8906 100644 --- a/sw/source/core/edit/edws.cxx +++ b/sw/source/core/edit/edws.cxx @@ -229,9 +229,10 @@ bool SwEditShell::GetLastUndoInfo(OUString *const o_pStr, } bool SwEditShell::GetFirstRedoInfo(OUString *const o_pStr, + SwUndoId *const o_pId, const SwView* pView) const { - return GetDoc()->GetIDocumentUndoRedo().GetFirstRedoInfo(o_pStr, nullptr, pView); + return GetDoc()->GetIDocumentUndoRedo().GetFirstRedoInfo(o_pStr, o_pId, pView); } SwUndoId SwEditShell::GetRepeatInfo(OUString *const o_pStr) const diff --git a/sw/source/core/undo/docundo.cxx b/sw/source/core/undo/docundo.cxx index 56c9e3a..4d117da 100644 --- a/sw/source/core/undo/docundo.cxx +++ b/sw/source/core/undo/docundo.cxx @@ -372,7 +372,13 @@ UndoManager::GetLastUndoInfo( // If an other view created the undo action, prevent undoing it from this view. sal_Int32 nViewShellId = pView ? pView->GetViewShellId() : m_pDocShell->GetView()->GetViewShellId(); if (pAction->GetViewShellId() != nViewShellId) + { + if (o_pId) + { + *o_pId = UNDO_CONFLICT; + } return false; + } } if (o_pStr) @@ -425,7 +431,13 @@ bool UndoManager::GetFirstRedoInfo(OUString *const o_pStr, // If an other view created the undo action, prevent redoing it from this view. sal_Int32 nViewShellId = pView ? pView->GetViewShellId() : m_pDocShell->GetView()->GetViewShellId(); if (pAction->GetViewShellId() != nViewShellId) + { + if (o_pId) + { + *o_pId = UNDO_CONFLICT; + } return false; + } } if (o_pStr) diff --git a/sw/source/uibase/shells/annotsh.cxx b/sw/source/uibase/shells/annotsh.cxx index 195cb0f..d102bf8 100644 --- a/sw/source/uibase/shells/annotsh.cxx +++ b/sw/source/uibase/shells/annotsh.cxx @@ -1492,6 +1492,7 @@ void SwAnnotationShell::ExecUndo(SfxRequest &rReq) const SfxItemSet* pArgs = rReq.GetArgs(); ::svl::IUndoManager* pUndoManager = GetUndoManager(); SwWrtShell &rSh = rView.GetWrtShell(); + SwUndoId nUndoId(UNDO_EMPTY); long aOldHeight = rView.GetPostItMgr()->HasActiveSidebarWin() ? rView.GetPostItMgr()->GetActiveSidebarWin()->GetPostItTextHeight() @@ -1506,6 +1507,13 @@ void SwAnnotationShell::ExecUndo(SfxRequest &rReq) { case SID_UNDO: { + rSh.GetLastUndoInfo(nullptr, &nUndoId); + if (nUndoId == UNDO_CONFLICT) + { + rReq.SetReturnValue( SfxUInt32Item(nId, static_cast<sal_uInt32>(nUndoId)) ); + break; + } + if ( pUndoManager ) { sal_uInt16 nCount = pUndoManager->GetUndoActionCount(); @@ -1530,6 +1538,13 @@ void SwAnnotationShell::ExecUndo(SfxRequest &rReq) case SID_REDO: { + rSh.GetFirstRedoInfo(nullptr, &nUndoId); + if (nUndoId == UNDO_CONFLICT) + { + rReq.SetReturnValue( SfxUInt32Item(nId, static_cast<sal_uInt32>(nUndoId)) ); + break; + } + if ( pUndoManager ) { sal_uInt16 nCount = pUndoManager->GetRedoActionCount(); @@ -1566,6 +1581,7 @@ void SwAnnotationShell::StateUndo(SfxItemSet &rSet) return; SfxWhichIter aIter(rSet); + SwUndoId nUndoId(UNDO_EMPTY); sal_uInt16 nWhich = aIter.FirstWhich(); ::svl::IUndoManager* pUndoManager = GetUndoManager(); SfxViewFrame *pSfxViewFrame = rView.GetViewFrame(); @@ -1580,10 +1596,14 @@ void SwAnnotationShell::StateUndo(SfxItemSet &rSet) sal_uInt16 nCount = pUndoManager ? pUndoManager->GetUndoActionCount() : 0; if ( nCount ) pSfxViewFrame->GetSlotState( nWhich, pSfxViewFrame->GetInterface(), &rSet ); - else if (rSh.GetLastUndoInfo(nullptr, nullptr)) + else if (rSh.GetLastUndoInfo(nullptr, &nUndoId)) { rSet.Put( SfxStringItem( nWhich, rSh.GetDoString(SwWrtShell::UNDO)) ); } + else if (nUndoId == UNDO_CONFLICT) + { + rSet.Put( SfxUInt32Item(nWhich, static_cast<sal_uInt32>(nUndoId)) ); + } else rSet.DisableItem(nWhich); break; @@ -1593,10 +1613,14 @@ void SwAnnotationShell::StateUndo(SfxItemSet &rSet) sal_uInt16 nCount = pUndoManager ? pUndoManager->GetRedoActionCount() : 0; if ( nCount ) pSfxViewFrame->GetSlotState( nWhich, pSfxViewFrame->GetInterface(), &rSet ); - else if (rSh.GetFirstRedoInfo(nullptr)) + else if (rSh.GetFirstRedoInfo(nullptr, &nUndoId)) { rSet.Put(SfxStringItem( nWhich, rSh.GetDoString(SwWrtShell::REDO)) ); } + else if (nUndoId == UNDO_CONFLICT) + { + rSet.Put( SfxUInt32Item(nWhich, static_cast<sal_uInt32>(nUndoId)) ); + } else rSet.DisableItem(nWhich); break; @@ -1634,7 +1658,7 @@ void SwAnnotationShell::StateUndo(SfxItemSet &rSet) rSh.GetDoStrings( SwWrtShell::UNDO, aItem ); } else if ((nWhich == SID_GETREDOSTRINGS) && - (rSh.GetFirstRedoInfo(nullptr))) + (rSh.GetFirstRedoInfo(nullptr, nullptr))) { rSh.GetDoStrings( SwWrtShell::UNDO, aItem ); } diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx index f7daef9..3127b1f 100644 --- a/sw/source/uibase/shells/basesh.cxx +++ b/sw/source/uibase/shells/basesh.cxx @@ -478,6 +478,7 @@ void SwBaseShell::ExecUndo(SfxRequest &rReq) { SwWrtShell &rWrtShell = GetShell(); + SwUndoId nUndoId(UNDO_EMPTY); sal_uInt16 nId = rReq.GetSlot(), nCnt = 1; const SfxItemSet* pArgs = rReq.GetArgs(); const SfxPoolItem* pItem; @@ -504,19 +505,25 @@ void SwBaseShell::ExecUndo(SfxRequest &rReq) switch( nId ) { case SID_UNDO: - for (SwViewShell& rShell : rWrtShell.GetRingContainer()) - rShell.LockPaint(); - rWrtShell.Do( SwWrtShell::UNDO, nCnt ); - for (SwViewShell& rShell : rWrtShell.GetRingContainer()) - rShell.UnlockPaint(); + if (rUndoRedo.GetLastUndoInfo(nullptr, &nUndoId, &rWrtShell.GetView())) + { + for (SwViewShell& rShell : rWrtShell.GetRingContainer()) + rShell.LockPaint(); + rWrtShell.Do( SwWrtShell::UNDO, nCnt ); + for (SwViewShell& rShell : rWrtShell.GetRingContainer()) + rShell.UnlockPaint(); + } break; case SID_REDO: - for (SwViewShell& rShell : rWrtShell.GetRingContainer()) - rShell.LockPaint(); - rWrtShell.Do( SwWrtShell::REDO, nCnt ); - for (SwViewShell& rShell : rWrtShell.GetRingContainer()) - rShell.UnlockPaint(); + if (rUndoRedo.GetFirstRedoInfo(nullptr, &nUndoId, &rWrtShell.GetView())) + { + for (SwViewShell& rShell : rWrtShell.GetRingContainer()) + rShell.LockPaint(); + rWrtShell.Do( SwWrtShell::REDO, nCnt ); + for (SwViewShell& rShell : rWrtShell.GetRingContainer()) + rShell.UnlockPaint(); + } break; case SID_REPEAT: @@ -526,6 +533,11 @@ void SwBaseShell::ExecUndo(SfxRequest &rReq) OSL_FAIL("wrong Dispatcher"); } + if (nUndoId == UNDO_CONFLICT) + { + rReq.SetReturnValue( SfxUInt32Item(nId, static_cast<sal_uInt32>(nUndoId)) ); + } + if (pViewFrame) { pViewFrame->GetBindings().InvalidateAll(false); } } @@ -533,6 +545,7 @@ void SwBaseShell::ExecUndo(SfxRequest &rReq) void SwBaseShell::StateUndo(SfxItemSet &rSet) { + SwUndoId nUndoId(UNDO_EMPTY); SwWrtShell &rSh = GetShell(); SfxWhichIter aIter(rSet); sal_uInt16 nWhich = aIter.FirstWhich(); @@ -542,29 +555,38 @@ void SwBaseShell::StateUndo(SfxItemSet &rSet) { case SID_UNDO: { - if (rSh.GetLastUndoInfo(nullptr, nullptr, &rSh.GetView())) + if (rSh.GetLastUndoInfo(nullptr, &nUndoId, &rSh.GetView())) { rSet.Put( SfxStringItem(nWhich, rSh.GetDoString(SwWrtShell::UNDO))); } + else if (nUndoId == UNDO_CONFLICT) + { + rSet.Put( SfxUInt32Item(nWhich, static_cast<sal_uInt32>(nUndoId)) ); + } else rSet.DisableItem(nWhich); + break; } case SID_REDO: { - if (rSh.GetFirstRedoInfo(nullptr, &rSh.GetView())) + if (rSh.GetFirstRedoInfo(nullptr, &nUndoId, &rSh.GetView())) { rSet.Put(SfxStringItem(nWhich, rSh.GetDoString(SwWrtShell::REDO))); } + else if (nUndoId == UNDO_CONFLICT) + { + rSet.Put( SfxInt32Item(nWhich, static_cast<sal_uInt32>(nUndoId)) ); + } else rSet.DisableItem(nWhich); break; } case SID_REPEAT: { // Repeat is only possible if no REDO is possible - UI-Restriction - if ((!rSh.GetFirstRedoInfo(nullptr)) && + if ((!rSh.GetFirstRedoInfo(nullptr, nullptr)) && !rSh.IsSelFrameMode() && (UNDO_EMPTY != rSh.GetRepeatInfo(nullptr))) { @@ -587,7 +609,7 @@ void SwBaseShell::StateUndo(SfxItemSet &rSet) break; case SID_GETREDOSTRINGS: - if (rSh.GetFirstRedoInfo(nullptr)) + if (rSh.GetFirstRedoInfo(nullptr, nullptr)) { SfxStringListItem aStrLst( nWhich ); rSh.GetDoStrings( SwWrtShell::REDO, aStrLst ); diff --git a/sw/source/uibase/wrtsh/wrtundo.cxx b/sw/source/uibase/wrtsh/wrtundo.cxx index 1260d89..0e437ba 100644 --- a/sw/source/uibase/wrtsh/wrtundo.cxx +++ b/sw/source/uibase/wrtsh/wrtundo.cxx @@ -106,7 +106,7 @@ OUString SwWrtShell::GetDoString( DoType eDoType ) const break; case REDO: nResStr = STR_REDO; - (void)GetFirstRedoInfo(&aUndoStr, &m_rView); + (void)GetFirstRedoInfo(&aUndoStr, nullptr, &m_rView); break; default:;//prevent warning } commit c0634a1c8b99c586055f1ac2f7debb9080b6e3b4 Author: Henry Castro <hcas...@collabora.com> Date: Sun Nov 27 19:40:57 2016 -0400 lok: avoid render font with empty rectangle Change-Id: I58e24e0de37144ae5d67857b243e6a7091f2b77a Reviewed-on: https://gerrit.libreoffice.org/31281 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Henry Castro <hcas...@collabora.com> (cherry picked from commit e2d5f1ba3fd0db00276cf48b0d9be9b16dcbf7a0) diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 7492d13..1af9643 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -2701,6 +2701,9 @@ unsigned char* doc_renderFont(LibreOfficeKitDocument* /*pThis*/, aFont.SetFontSize(Size(0, 25)); aDevice->SetFont(aFont); aDevice->GetTextBoundRect(aRect, aText); + if (aRect.IsEmpty()) + break; + int nFontWidth = aRect.BottomRight().X() + 1; *pFontWidth = nFontWidth; int nFontHeight = aRect.BottomRight().Y() + 1; commit ff138b34fc5ca765742db5fb791d0534defe0ba8 Author: Andras Timar <andras.ti...@collabora.com> Date: Sat Nov 26 19:52:54 2016 +0100 respect read-only config items in Basic IDE Options dialog Change-Id: I4a23b347c5fed948045427bc440e7a821b95b63c Reviewed-on: https://gerrit.libreoffice.org/31242 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Andras Timar <andras.ti...@collabora.com> (cherry picked from commit d5be8dddc43e8a880d546fb9a6e8fbb45278eeca) diff --git a/cui/source/options/optbasic.cxx b/cui/source/options/optbasic.cxx index 3feb235a..38324ea 100644 --- a/cui/source/options/optbasic.cxx +++ b/cui/source/options/optbasic.cxx @@ -62,19 +62,18 @@ void SvxBasicIDEOptionsPage::dispose() void SvxBasicIDEOptionsPage::LoadConfig() { - bool bProcClose = officecfg::Office::BasicIDE::Autocomplete::AutocloseProc::get(); - bool bExtended = officecfg::Office::BasicIDE::Autocomplete::UseExtended::get(); - bool bCodeCompleteOn = officecfg::Office::BasicIDE::Autocomplete::CodeComplete::get(); - bool bParenClose = officecfg::Office::BasicIDE::Autocomplete::AutocloseParenthesis::get(); - bool bQuoteClose = officecfg::Office::BasicIDE::Autocomplete::AutocloseDoubleQuotes::get(); - bool bCorrect = officecfg::Office::BasicIDE::Autocomplete::AutoCorrect::get(); - - pCodeCompleteChk->Check( bCodeCompleteOn ); - pAutocloseProcChk->Check( bProcClose ); - pAutocloseQuotesChk->Check( bQuoteClose ); - pAutocloseParenChk->Check( bParenClose ); - pAutoCorrectChk->Check( bCorrect ); - pUseExtendedTypesChk->Check( bExtended ); + pCodeCompleteChk->Check( officecfg::Office::BasicIDE::Autocomplete::CodeComplete::get() ); + pCodeCompleteChk->Enable( !officecfg::Office::BasicIDE::Autocomplete::CodeComplete::isReadOnly() ); + pAutocloseProcChk->Check( officecfg::Office::BasicIDE::Autocomplete::AutocloseProc::get() ); + pAutocloseProcChk->Enable( !officecfg::Office::BasicIDE::Autocomplete::AutocloseProc::isReadOnly() ); + pAutocloseQuotesChk->Check( officecfg::Office::BasicIDE::Autocomplete::AutocloseDoubleQuotes::get() ); + pAutocloseQuotesChk->Enable( !officecfg::Office::BasicIDE::Autocomplete::AutocloseDoubleQuotes::isReadOnly() ); + pAutocloseParenChk->Check( officecfg::Office::BasicIDE::Autocomplete::AutocloseParenthesis::get() ); + pAutocloseParenChk->Enable( !officecfg::Office::BasicIDE::Autocomplete::AutocloseParenthesis::isReadOnly() ); + pAutoCorrectChk->Check( officecfg::Office::BasicIDE::Autocomplete::AutoCorrect::get() ); + pAutoCorrectChk->Enable( !officecfg::Office::BasicIDE::Autocomplete::AutoCorrect::isReadOnly() ); + pUseExtendedTypesChk->Check( officecfg::Office::BasicIDE::Autocomplete::UseExtended::get() ); + pUseExtendedTypesChk->Enable( !officecfg::Office::BasicIDE::Autocomplete::UseExtended::isReadOnly() ); } bool SvxBasicIDEOptionsPage::FillItemSet( SfxItemSet* /*rCoreSet*/ ) commit 19927bd49c2151f71708810bf7c03486d92e68e8 Author: Pranav Kant <pran...@collabora.co.uk> Date: Tue Jan 24 14:07:45 2017 +0530 lok: Implement new callbacks for comment notifications Change-Id: I298183b295c68c4a39cb1f6fffe4b89b4eaee0f3 Reviewed-on: https://gerrit.libreoffice.org/33469 Reviewed-by: pranavk <pran...@collabora.co.uk> Tested-by: pranavk <pran...@collabora.co.uk> (cherry picked from commit 5f5073a84518e4a8660e0153c2e218fb75a85ec4) diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h index f3dccd0..8a59b4c 100644 --- a/include/LibreOfficeKit/LibreOfficeKitEnums.h +++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h @@ -467,6 +467,32 @@ typedef enum * - 'action' is 'Modify'. */ LOK_CALLBACK_REDLINE_TABLE_ENTRY_MODIFIED = 31, + + /** + * There is some change in comments in the document + * + * The payload example: + * { + * "comment": { + * "action": "Add", + * "id": "11", + * "parent": "4", + * "author": "Unknown Author", + * "text": "", + * "dateTime": "2016-08-18T13:13:00", + * "anchorPos": "4529, 3906", + * "textRange": "1418, 3906, 3111, 919" + * } + * } + * + * The format is the same as an entry of + * lok::Document::getCommandValues('.uno:ViewAnnotations'), extra + * fields: + * + * - 'action' can be 'Add', 'Remove' or 'Modify' depending on whether + * comment has been added, removed or modified. + */ + LOK_CALLBACK_COMMENT = 32 } LibreOfficeKitCallbackType; diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx index 88ea94b..646fc84 100644 --- a/libreofficekit/source/gtk/lokdocview.cxx +++ b/libreofficekit/source/gtk/lokdocview.cxx @@ -426,6 +426,8 @@ callbackTypeToString (int nType) return "LOK_CALLBACK_REDLINE_TABLE_SIZE_CHANGED"; case LOK_CALLBACK_REDLINE_TABLE_ENTRY_MODIFIED: return "LOK_CALLBACK_REDLINE_TABLE_ENTRY_MODIFIED"; + case LOK_CALLBACK_COMMENT: + return "LOK_CALLBACK_COMMENT"; } g_assert(false); return nullptr; @@ -1395,6 +1397,8 @@ callback (gpointer pData) { break; } + case LOK_CALLBACK_COMMENT: + break; default: g_assert(false); break; diff --git a/sw/inc/PostItMgr.hxx b/sw/inc/PostItMgr.hxx index 68887aa..97448fd 100644 --- a/sw/inc/PostItMgr.hxx +++ b/sw/inc/PostItMgr.hxx @@ -186,7 +186,7 @@ class SwPostItMgr: public SfxListener sw::sidebarwindows::SwSidebarWin* GetSidebarWin(const SfxBroadcaster* pBroadcaster) const; - void InsertItem( SfxBroadcaster* pItem, bool bCheckExistance, bool bFocus); + SwSidebarItem* InsertItem( SfxBroadcaster* pItem, bool bCheckExistance, bool bFocus); void RemoveItem( SfxBroadcaster* pBroadcast ); public: diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx index 625d642..7caf925 100644 --- a/sw/source/uibase/docvw/PostItMgr.cxx +++ b/sw/source/uibase/docvw/PostItMgr.cxx @@ -17,11 +17,13 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <boost/property_tree/json_parser.hpp> + #include "PostItMgr.hxx" #include <postithelper.hxx> -#include <SidebarWin.hxx> #include <AnnotationWin.hxx> +#include <SidebarWin.hxx> #include <frmsidebarwincontainer.hxx> #include <accmap.hxx> @@ -53,6 +55,7 @@ #include <docary.hxx> #include <SwRewriter.hxx> #include <tools/color.hxx> +#include <unotools/datetime.hxx> #include <swmodule.hxx> #include <annotation.hrc> @@ -75,6 +78,8 @@ #include <i18nlangtag/mslangid.hxx> #include <i18nlangtag/lang.h> #include <comphelper/lok.hxx> +#include <comphelper/string.hxx> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> #include "annotsh.hxx" #include "swabstdlg.hxx" @@ -94,37 +99,89 @@ using namespace sw::sidebarwindows; -bool comp_pos(const SwSidebarItem* a, const SwSidebarItem* b) -{ - // sort by anchor position - SwPosition aPosAnchorA = a->GetAnchorPosition(); - SwPosition aPosAnchorB = b->GetAnchorPosition(); +namespace { - bool aAnchorAInFooter = false; - bool aAnchorBInFooter = false; + enum class CommentNotificationType { Add, Remove, Modify }; - // is the anchor placed in Footnote or the Footer? - if( aPosAnchorA.nNode.GetNode().FindFootnoteStartNode() || aPosAnchorA.nNode.GetNode().FindFooterStartNode() ) - aAnchorAInFooter = true; - if( aPosAnchorB.nNode.GetNode().FindFootnoteStartNode() || aPosAnchorB.nNode.GetNode().FindFooterStartNode() ) - aAnchorBInFooter = true; + bool comp_pos(const SwSidebarItem* a, const SwSidebarItem* b) + { + // sort by anchor position + SwPosition aPosAnchorA = a->GetAnchorPosition(); + SwPosition aPosAnchorB = b->GetAnchorPosition(); - // fdo#34800 - // if AnchorA is in footnote, and AnchorB isn't - // we do not want to change over the position - if( aAnchorAInFooter && !aAnchorBInFooter ) - return false; - // if aAnchorA is not placed in a footnote, and aAnchorB is - // force a change over - else if( !aAnchorAInFooter && aAnchorBInFooter ) - return true; - // If neither or both are in the footer, compare the positions. - // Since footnotes are in Inserts section of nodes array and footers - // in Autotext section, all footnotes precede any footers so no need - // to check that. - else - return aPosAnchorA < aPosAnchorB; -} + bool aAnchorAInFooter = false; + bool aAnchorBInFooter = false; + + // is the anchor placed in Footnote or the Footer? + if( aPosAnchorA.nNode.GetNode().FindFootnoteStartNode() || aPosAnchorA.nNode.GetNode().FindFooterStartNode() ) + aAnchorAInFooter = true; + if( aPosAnchorB.nNode.GetNode().FindFootnoteStartNode() || aPosAnchorB.nNode.GetNode().FindFooterStartNode() ) + aAnchorBInFooter = true; + + // fdo#34800 + // if AnchorA is in footnote, and AnchorB isn't + // we do not want to change over the position + if( aAnchorAInFooter && !aAnchorBInFooter ) + return false; + // if aAnchorA is not placed in a footnote, and aAnchorB is + // force a change over + else if( !aAnchorAInFooter && aAnchorBInFooter ) + return true; + // If neither or both are in the footer, compare the positions. + // Since footnotes are in Inserts section of nodes array and footers + // in Autotext section, all footnotes precede any footers so no need + // to check that. + else + return aPosAnchorA < aPosAnchorB; + } + + /// Emits LOK notification about one addition/removal/change of a comment + void lcl_CommentNotification(const SwView* pView, const CommentNotificationType nType, const SwSidebarItem* pItem, const sal_uInt32 nPostItId) + { + if (!comphelper::LibreOfficeKit::isActive()) + return; + + boost::property_tree::ptree aAnnotation; + aAnnotation.put("action", (nType == CommentNotificationType::Add ? "Add" : + (nType == CommentNotificationType::Remove ? "Remove" : + (nType == CommentNotificationType::Modify ? "Modify" : "???")))); + aAnnotation.put("id", nPostItId); + if (nType != CommentNotificationType::Remove && pItem != nullptr) + { + sw::annotation::SwAnnotationWin* pWin = static_cast<sw::annotation::SwAnnotationWin*>((pItem)->pPostIt.get()); + + const SwPostItField* pField = pWin->GetPostItField(); + const std::string aAnchorPos = std::to_string(pWin->GetAnchorPos().X()) + ", " + std::to_string(pWin->GetAnchorPos().Y()); + std::vector<OString> aRects; + for (const basegfx::B2DRange& aRange : pWin->GetAnnotationTextRanges()) + { + const SwRect rect(aRange.getMinX(), aRange.getMinY(), aRange.getWidth(), aRange.getHeight()); + aRects.push_back(rect.SVRect().toString()); + } + const OString sRects = comphelper::string::join("; ", aRects); + + aAnnotation.put("id", pField->GetPostItId()); + aAnnotation.put("reply", pWin->IsFollow()); + aAnnotation.put("author", pField->GetPar1().toUtf8().getStr()); + aAnnotation.put("text", pField->GetPar2().toUtf8().getStr()); + aAnnotation.put("dateTime", utl::toISO8601(pField->GetDateTime().GetUNODateTime())); + aAnnotation.put("anchorPos", aAnchorPos.c_str()); + aAnnotation.put("textRange", sRects.getStr()); + } + + boost::property_tree::ptree aTree; + aTree.add_child("comment", aAnnotation); + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + std::string aPayload = aStream.str(); + + if (pView) + { + pView->libreOfficeKitViewCallback(LOK_CALLBACK_COMMENT, aPayload.c_str()); + } + } + +} // anonymous namespace SwPostItMgr::SwPostItMgr(SwView* pView) : mpView(pView) @@ -216,21 +273,27 @@ void SwPostItMgr::CheckForRemovedPostIts() } } -void SwPostItMgr::InsertItem(SfxBroadcaster* pItem, bool bCheckExistance, bool bFocus) +SwSidebarItem* SwPostItMgr::InsertItem(SfxBroadcaster* pItem, bool bCheckExistance, bool bFocus) { + SwSidebarItem* pAnnotationItem = nullptr; if (bCheckExistance) { for(std::list<SwSidebarItem*>::iterator i = mvPostItFields.begin(); i != mvPostItFields.end() ; ++i) { if ( (*i)->GetBroadCaster() == pItem ) - return; + return pAnnotationItem; } } mbLayout = bFocus; + if (dynamic_cast< const SwFormatField *>( pItem ) != nullptr) - mvPostItFields.push_back(new SwAnnotationItem(static_cast<SwFormatField&>(*pItem), bFocus) ); + { + pAnnotationItem = new SwAnnotationItem(static_cast<SwFormatField&>(*pItem), bFocus); + mvPostItFields.push_back(pAnnotationItem); + } OSL_ENSURE(dynamic_cast< const SwFormatField *>( pItem ) != nullptr,"Mgr::InsertItem: seems like new stuff was added"); StartListening(*pItem); + return pAnnotationItem; } void SwPostItMgr::RemoveItem( SfxBroadcaster* pBroadcast ) @@ -284,9 +347,22 @@ void SwPostItMgr::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) if ( pField->IsFieldInDoc() ) { bool bEmpty = !HasNotes(); - InsertItem( pField, true, false ); + SwSidebarItem* pItem = InsertItem( pField, true, false ); + if (bEmpty && !mvPostItFields.empty()) PrepareView(true); + + // If LOK has disabled tiled annotations, emit annotation callbacks + if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isTiledAnnotations()) + { + CalcRects(); + Show(); + + if (pItem && pItem->pPostIt) + { + lcl_CommentNotification(mpView, CommentNotificationType::Add, pItem, 0); + } + } } else { @@ -304,6 +380,13 @@ void SwPostItMgr::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) break; } RemoveItem(pField); + + // If LOK has disabled tiled annotations, emit annotation callbacks + if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isTiledAnnotations()) + { + SwPostItField* pPostItField = static_cast<SwPostItField*>(pField->GetField()); + lcl_CommentNotification(mpView, CommentNotificationType::Remove, nullptr, pPostItField->GetPostItId()); + } } break; } @@ -315,7 +398,7 @@ void SwPostItMgr::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) } case SwFormatFieldHintWhich::CHANGED: { - SwFormatField* pFormatField = dynamic_cast<SwFormatField*>(&rBC); + SwFormatField* pFormatField = dynamic_cast<SwFormatField*>(&rBC); for(std::list<SwSidebarItem*>::iterator i = mvPostItFields.begin(); i != mvPostItFields.end() ; ++i) { if ( pFormatField == (*i)->GetBroadCaster() ) @@ -325,6 +408,12 @@ void SwPostItMgr::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) (*i)->pPostIt->SetPostItText(); mbLayout = true; } + + // If LOK has disabled tiled annotations, emit annotation callbacks + if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isTiledAnnotations()) + { + lcl_CommentNotification(mpView, CommentNotificationType::Modify, *i, 0); + } break; } } @@ -459,7 +548,6 @@ bool SwPostItMgr::CalcRects() bRepair = true; continue; } - const SwRect aOldAnchorRect( pItem->maLayoutInfo.mPosition ); const SwPostItHelper::SwLayoutStatus eOldLayoutStatus = pItem->mLayoutStatus; const sal_uLong nOldStartNodeIdx( pItem->maLayoutInfo.mnStartNodeIdx ); commit 64ccf4c2576fa5ab902322ed681c8b5a1cbdc0d4 Author: Pranav Kant <pran...@collabora.co.uk> Date: Thu Jan 19 10:34:17 2017 +0530 lok: New commandvalues command - .uno:ViewAnnotations Change-Id: I1c3560ab4609c64da7a77e9a65febeb569ec1a3c Reviewed-on: https://gerrit.libreoffice.org/33468 Reviewed-by: pranavk <pran...@collabora.co.uk> Tested-by: pranavk <pran...@collabora.co.uk> (cherry picked from commit a623b3a449dfcddaad5b621ff1c0b7a520edf4d6) diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index c7ee9af..7492d13 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -1862,6 +1862,20 @@ static void doc_registerCallback(LibreOfficeKitDocument* pThis, pViewShell->registerLibreOfficeKitViewCallback(CallbackFlushHandler::callback, pDocument->mpCallbackFlushHandlers[nView].get()); } +/// Returns the JSON representation of all the comments in the document +static char* getPostIts(LibreOfficeKitDocument* pThis) +{ + ITiledRenderable* pDoc = getTiledRenderable(pThis); + if (!pDoc) + { + gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering"; + return nullptr; + } + OUString aComments = pDoc->getPostIts(); + return strdup(aComments.toUtf8().getStr()); +} + + static void doc_postKeyEvent(LibreOfficeKitDocument* pThis, int nType, int nCharCode, int nKeyCode) { SolarMutexGuard aGuard; @@ -2412,6 +2426,7 @@ static char* getTrackedChanges(LibreOfficeKitDocument* pThis) return pJson; } + /// Returns the JSON representation of the redline author table. static char* getTrackedChangeAuthors(LibreOfficeKitDocument* pThis) { @@ -2458,6 +2473,10 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo { return getTrackedChangeAuthors(pThis); } + else if (aCommand == ".uno:ViewAnnotations") + { + return getPostIts(pThis); + } else if (aCommand.startsWith(aViewRowColumnHeaders)) { ITiledRenderable* pDoc = getTiledRenderable(pThis); diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx index a6cb988..abe4979 100644 --- a/include/vcl/ITiledRenderable.hxx +++ b/include/vcl/ITiledRenderable.hxx @@ -219,6 +219,13 @@ public: { return OUString(); } + + /// Implementation for + /// lok::Document::getCommandValues(".uno:ViewAnnotations"); + virtual OUString getPostIts() + { + return OUString(); + } }; } // namespace vcl diff --git a/sw/inc/AnnotationWin.hxx b/sw/inc/AnnotationWin.hxx index 8d41b58..07dde37 100644 --- a/sw/inc/AnnotationWin.hxx +++ b/sw/inc/AnnotationWin.hxx @@ -20,6 +20,7 @@ #ifndef INCLUDED_SW_INC_ANNOTATIONWIN_HXX #define INCLUDED_SW_INC_ANNOTATIONWIN_HXX +#include <docufld.hxx> #include <SidebarWin.hxx> class PopupMenu; @@ -43,6 +44,7 @@ class SwAnnotationWin : public sw::sidebarwindows::SwSidebarWin virtual void SetPostItText() override; virtual void Delete() override; virtual void GotoPos() override; + inline const SwPostItField* GetPostItField() { return mpField; } virtual OUString GetAuthor() override; virtual Date GetDate() override; diff --git a/sw/inc/SidebarWin.hxx b/sw/inc/SidebarWin.hxx index adfb47c..742e2f2 100644 --- a/sw/inc/SidebarWin.hxx +++ b/sw/inc/SidebarWin.hxx @@ -30,6 +30,7 @@ #include <vcl/lineinfo.hxx> #include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/range/b2drange.hxx> #include <editeng/editstat.hxx> class SwPostItMgr; @@ -80,6 +81,7 @@ class SwSidebarWin : public vcl::Window void CheckMetaText(); inline Point GetAnchorPos() { return mAnchorRect.Pos(); } + inline const std::vector<basegfx::B2DRange>& GetAnnotationTextRanges() { return maAnnotationTextRanges; } SwEditWin& EditWin(); inline OutlinerView* GetOutlinerView() { return mpOutlinerView;} @@ -240,6 +242,8 @@ class SwSidebarWin : public vcl::Window SwRect mAnchorRect; long mPageBorder; + std::vector<basegfx::B2DRange> maAnnotationTextRanges; + bool mbMouseOver; SwPostItHelper::SwLayoutStatus mLayoutStatus; diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx index 47e29ad..03a338e 100644 --- a/sw/inc/unotxdoc.hxx +++ b/sw/inc/unotxdoc.hxx @@ -440,7 +440,8 @@ public: virtual Pointer getPointer() override; /// @see vcl::ITiledRenderable::getTrackedChangeAuthors(). OUString getTrackedChangeAuthors() override; - + /// @see vcl::ITiledRenderable::getPostIts(). + OUString getPostIts() override; // css::tiledrendering::XTiledRenderable virtual void SAL_CALL paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight ) throw (::css::uno::RuntimeException, std::exception) override; diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx index a1a8224..8b06d00 100644 --- a/sw/source/uibase/docvw/SidebarWin.cxx +++ b/sw/source/uibase/docvw/SidebarWin.cxx @@ -24,7 +24,8 @@ #include <SidebarWin.hxx> #include <SidebarWinAcc.hxx> #include <PostItMgr.hxx> - +#include <basegfx/range/b2drange.hxx> +#include <comphelper/string.hxx> #include <SidebarTxtControl.hxx> #include <SidebarScrollBar.hxx> #include <AnchorOverlayObject.hxx> @@ -356,6 +357,7 @@ void SwSidebarWin::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle pProcessor->process(mpAnchor->getOverlayObjectPrimitive2DSequence()); if (mpTextRangeOverlay) pProcessor->process(mpTextRangeOverlay->getOverlayObjectPrimitive2DSequence()); + rRenderContext.Push(PushFlags::NONE); pProcessor.reset(); rRenderContext.Push(PushFlags::NONE); @@ -868,62 +870,65 @@ void SwSidebarWin::SetPosAndSize() } } + // text range overlay - if ( mrMgr.ShowNotes() - && mrSidebarItem.maLayoutInfo.mnStartNodeIdx != 0 + maAnnotationTextRanges.clear(); + if ( mrSidebarItem.maLayoutInfo.mnStartNodeIdx != 0 && mrSidebarItem.maLayoutInfo.mnStartContent != -1 ) { - std::vector< basegfx::B2DRange > aAnnotationTextRanges; + const SwTextAnnotationField* pTextAnnotationField = + dynamic_cast< const SwTextAnnotationField* >( mrSidebarItem.GetFormatField().GetTextField() ); + SwTextNode* pTextNode = pTextAnnotationField ? pTextAnnotationField->GetpTextNode() : nullptr; + SwContentNode* pContentNd = nullptr; + if (pTextNode) + { + SwNodes& rNds = pTextNode->GetDoc()->GetNodes(); + pContentNd = rNds[mrSidebarItem.maLayoutInfo.mnStartNodeIdx]->GetContentNode(); + } + if (pContentNd) { - const SwTextAnnotationField* pTextAnnotationField = - dynamic_cast< const SwTextAnnotationField* >( mrSidebarItem.GetFormatField().GetTextField() ); - SwTextNode* pTextNode = pTextAnnotationField ? pTextAnnotationField->GetpTextNode() : nullptr; - SwContentNode* pContentNd = nullptr; - if (pTextNode) + SwPosition aStartPos( *pContentNd, mrSidebarItem.maLayoutInfo.mnStartContent ); + SwShellCursor* pTmpCursor = nullptr; + const bool bTableCursorNeeded = pTextNode->FindTableBoxStartNode() != pContentNd->FindTableBoxStartNode(); + if ( bTableCursorNeeded ) { - SwNodes& rNds = pTextNode->GetDoc()->GetNodes(); - pContentNd = rNds[mrSidebarItem.maLayoutInfo.mnStartNodeIdx]->GetContentNode(); + SwShellTableCursor* pTableCursor = new SwShellTableCursor( DocView().GetWrtShell(), aStartPos ); + pTableCursor->SetMark(); + pTableCursor->GetMark()->nNode = *pTextNode; + pTableCursor->GetMark()->nContent.Assign( pTextNode, pTextAnnotationField->GetStart()+1 ); + pTableCursor->NewTableSelection(); + pTmpCursor = pTableCursor; } - if (pContentNd) + else { - SwPosition aStartPos( *pContentNd, mrSidebarItem.maLayoutInfo.mnStartContent ); - SwShellCursor* pTmpCursor = nullptr; - const bool bTableCursorNeeded = pTextNode->FindTableBoxStartNode() != pContentNd->FindTableBoxStartNode(); - if ( bTableCursorNeeded ) - { - SwShellTableCursor* pTableCursor = new SwShellTableCursor( DocView().GetWrtShell(), aStartPos ); - pTableCursor->SetMark(); - pTableCursor->GetMark()->nNode = *pTextNode; ... etc. - the rest is truncated
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits