Make LOKClipboard available to other modules

LOKClipboard has higher level dependencies (sfx2) so it cannot be
moved to the vcl where SystemClibpoard instance is created.

- introduce new interface LokClipboard to differentiate
  from SystemClipboard so we can have vcl's and lok's implementations
  at the same time
- publish LOKClipboard using new interface for other modules by adding
  component file in desktop module

Thanks to that when code calls GetClipboard and we cannot get clipboard
assigned to the vcl::Window* (for welded widgets) in GetSystemClipboard
correct instance is returned (shared clipboard for current view) so we
can access content which was copied before. Previously always a new
instance was created (with empty content).

test ScTiledRenderingTest::testPasteIntoWrapTextCell was broken
add some content to clipboard to simulate more real case
and test the content copied

Change-Id: I23c0298960a710c498646493f33122b908864cba
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126310
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131644
Reviewed-by: Szymon Kłos <szymon.klos@collabora.com>
Tested-by: Szymon Kłos <szymon.klos@collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135198
Tested-by: Jenkins
This commit is contained in:
Szymon Kłos 2021-11-26 17:05:41 +01:00
parent f16f69f719
commit 52eba79371
10 changed files with 151 additions and 12 deletions

View file

@ -136,6 +136,8 @@ $(eval $(call gb_Library_add_exception_objects,sofficeapp,\
$(if $(filter $(OS),ANDROID), \
desktop/source/lib/lokandroid) \
))
$(if $(filter-out $(OS),IOS), \
$(eval $(call gb_Library_set_componentfile,sofficeapp,desktop/lokclipboard,services)))
else
ifneq ($(filter TRUE,$(USING_X11) $(DISABLE_GUI))($filter EMSCRIPTEN,$(OS)),)
$(eval $(call gb_Library_add_exception_objects,sofficeapp,\
@ -143,6 +145,7 @@ $(eval $(call gb_Library_add_exception_objects,sofficeapp,\
desktop/source/lib/lokinteractionhandler \
desktop/source/lib/lokclipboard \
))
$(eval $(call gb_Library_set_componentfile,sofficeapp,desktop/lokclipboard,services))
endif
endif

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* 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/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
-->
<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@"
xmlns="http://openoffice.org/2010/uno-components">
<implementation name="com.sun.star.datatransfer.LOKClipboard"
constructor="desktop_LOKClipboard_get_implementation">
<service name="com.sun.star.datatransfer.clipboard.LokClipboard"/>
</implementation>
</component>

View file

@ -10,9 +10,11 @@
#include "lokclipboard.hxx"
#include <unordered_map>
#include <vcl/lazydelete.hxx>
#include <vcl/svapp.hxx>
#include <sfx2/lokhelper.hxx>
#include <sal/log.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <com/sun/star/uno/XComponentContext.hpp>
using namespace css;
using namespace css::uno;
@ -75,7 +77,7 @@ LOKClipboard::LOKClipboard()
Sequence<OUString> LOKClipboard::getSupportedServiceNames_static()
{
Sequence<OUString> aRet{ "com.sun.star.datatransfer.clipboard.SystemClipboard" };
Sequence<OUString> aRet{ "com.sun.star.datatransfer.clipboard.LokClipboard" };
return aRet;
}
@ -227,4 +229,16 @@ sal_Bool SAL_CALL LOKTransferable::isDataFlavorSupported(const datatransfer::Dat
!= std::cend(m_aFlavors);
}
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
desktop_LOKClipboard_get_implementation(css::uno::XComponentContext*,
css::uno::Sequence<css::uno::Any> const& /*args*/)
{
SolarMutexGuard aGuard;
cppu::OWeakObject* pClipboard = LOKClipboardFactory::getClipboardForCurView().get();
pClipboard->acquire();
return pClipboard;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -107,6 +107,7 @@ $(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,com/sun/star/datatransfer,\
MimeContentTypeFactory \
))
$(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,com/sun/star/datatransfer/clipboard,\
LokClipboard \
SystemClipboard \
))
$(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,com/sun/star/deployment,\

View file

@ -0,0 +1,35 @@
/* -*- 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/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#ifndef __com_sun_star_datatransfer_clipboard_LokClipboard_idl__
#define __com_sun_star_datatransfer_clipboard_LokClipboard_idl__
#include <com/sun/star/datatransfer/clipboard/XSystemClipboard.idl>
module com { module sun { module star { module datatransfer { module clipboard {
/** This service provides access to the clipboard dedicated for current view
*/
service LokClipboard : XSystemClipboard;
}; }; }; }; };
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -24,6 +24,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sc_tiledrendering, \
editeng \
sal \
sfx \
sot \
svl \
svt \
svxcore \

View file

@ -13,7 +13,9 @@
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp>
#include <com/sun/star/frame/DispatchHelper.hpp>
#include <com/sun/star/datatransfer/clipboard/LokClipboard.hpp>
#include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
#include <comphelper/dispatchcommand.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/propertysequence.hxx>
@ -1686,14 +1688,14 @@ void ScTiledRenderingTest::testMultiViewCopyPaste()
ScTabViewShell* pView1 = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
CPPUNIT_ASSERT(pView1);
// emulate clipboard
pView1->GetViewData().GetActiveWin()->SetClipboard(css::datatransfer::clipboard::SystemClipboard::create(comphelper::getProcessComponentContext()));
pView1->GetViewData().GetActiveWin()->SetClipboard(css::datatransfer::clipboard::LokClipboard::create(comphelper::getProcessComponentContext()));
// view #2
int nView1 = SfxLokHelper::getView();
SfxLokHelper::createView();
ScTabViewShell* pView2 = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
// emulate clipboard
pView2->GetViewData().GetActiveWin()->SetClipboard(css::datatransfer::clipboard::SystemClipboard::create(comphelper::getProcessComponentContext()));
pView2->GetViewData().GetActiveWin()->SetClipboard(css::datatransfer::clipboard::LokClipboard::create(comphelper::getProcessComponentContext()));
CPPUNIT_ASSERT(pView2);
CPPUNIT_ASSERT(pView1 != pView2);
CPPUNIT_ASSERT(pView1->GetViewData().GetActiveWin()->GetClipboard() != pView2->GetViewData().GetActiveWin()->GetClipboard());
@ -2503,6 +2505,27 @@ void ScTiledRenderingTest::testPasteIntoWrapTextCell()
ScTabViewShell* pView = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
CPPUNIT_ASSERT(pView);
// create source text in A1
OUString sCopyContent("Very long text to copy");
pDoc->SetString(0, 0, 0, sCopyContent);
// copy A1
pView->SetCursor(0, 0);
Scheduler::ProcessEventsToIdle();
pView->GetViewFrame()->GetBindings().Execute(SID_COPY);
Scheduler::ProcessEventsToIdle();
// verify clipboard
uno::Reference<datatransfer::clipboard::XClipboard> xClipboard1 = pView->GetViewData().GetActiveWin()->GetClipboard();
uno::Reference< datatransfer::XTransferable > xDataObj =
xClipboard1->getContents();
datatransfer::DataFlavor aFlavor;
SotExchange::GetFormatDataFlavor(SotClipboardFormatId::STRING, aFlavor);
uno::Any aData = xDataObj->getTransferData(aFlavor);
OUString aTmpText;
aData >>= aTmpText;
CPPUNIT_ASSERT_EQUAL(sCopyContent, aTmpText.trim());
// Go to A2 and paste.
pView->SetCursor(0, 1);
Scheduler::ProcessEventsToIdle();
@ -2510,8 +2533,27 @@ void ScTiledRenderingTest::testPasteIntoWrapTextCell()
pView->GetViewFrame()->GetBindings().Execute(SID_PASTE);
Scheduler::ProcessEventsToIdle();
// No SG invalidations
CPPUNIT_ASSERT_EQUAL(OString(""), aView.m_sInvalidateSheetGeometry);
CPPUNIT_ASSERT_EQUAL(sCopyContent, pDoc->GetString(0, 1, 0));
CPPUNIT_ASSERT_EQUAL(OString("rows sizes"), aView.m_sInvalidateSheetGeometry);
// create new source text in A2
OUString sCopyContent2("Very long text to copy 2");
pDoc->SetString(0, 1, 0, sCopyContent2);
Scheduler::ProcessEventsToIdle();
// cut from A2
pView->GetViewFrame()->GetBindings().Execute(SID_CUT);
Scheduler::ProcessEventsToIdle();
// verify clipboard
uno::Reference<datatransfer::clipboard::XClipboard> xClipboard2
= pView->GetViewData().GetActiveWin()->GetClipboard();
xDataObj = xClipboard2->getContents();
SotExchange::GetFormatDataFlavor(SotClipboardFormatId::STRING, aFlavor);
aData = xDataObj->getTransferData(aFlavor);
aData >>= aTmpText;
CPPUNIT_ASSERT_EQUAL(xClipboard1, xClipboard2);
CPPUNIT_ASSERT_EQUAL(sCopyContent2, aTmpText.trim());
// Go to A3 and paste.
pView->SetCursor(0, 2);
@ -2521,6 +2563,7 @@ void ScTiledRenderingTest::testPasteIntoWrapTextCell()
Scheduler::ProcessEventsToIdle();
// SG invalidations for all
CPPUNIT_ASSERT_EQUAL(sCopyContent2, pDoc->GetString(0, 1, 0));
CPPUNIT_ASSERT_EQUAL(OString("all"), aView.m_sInvalidateSheetGeometry);
SfxViewShell::Current()->setLibreOfficeKitViewCallback(nullptr);

View file

@ -127,6 +127,8 @@ core_constructor_list = [
"com_sun_star_comp_dba_ODatabaseDocument",
"com_sun_star_comp_dba_ODatabaseSource",
"com_sun_star_comp_dba_ORowSet_get_implementation",
# desktop/lokclipboard.component
"desktop_LOKClipboard_get_implementation",
# drawinglayer/drawinglayer.component
"drawinglayer_XPrimitive2DRenderer",
# embeddedobj/util/embobj.component

View file

@ -20,6 +20,8 @@
#include <sal/config.h>
#include <comphelper/lok.hxx>
#include <comphelper/processfactory.hxx>
#include <osl/mutex.hxx>
#include <tools/debug.hxx>
#include <vcl/svapp.hxx>
@ -33,6 +35,7 @@
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/datatransfer/XTransferable.hpp>
#include <com/sun/star/datatransfer/clipboard/LokClipboard.hpp>
#include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp>
#include <com/sun/star/datatransfer/clipboard/XSystemClipboard.hpp>
#include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
@ -417,13 +420,14 @@ Reference< XInterface > SalInstance::CreateClipboard( const Sequence< Any >& arg
return Reference< XInterface >( static_cast<cppu::OWeakObject *>(new vcl::GenericClipboard()) );
#else
if (comphelper::LibreOfficeKit::isActive()) {
// In LOK, each document view shall have its own clipboard instance, and the way that
// (happens to?) work is that apparently this function is called at most once for each such
// document view, so it is OK if we hand out a fresh instance on each call in LOK (whereas
// In LOK, each document view shall have its own clipboard instance (whereas
// in non-LOK below we keep handing out one single instance; see also
// <https://lists.freedesktop.org/archives/libreoffice/2020-April/084824.html> "Re: Linux
// SAL_USE_VCLPLUGIN=svp and the clipboard"):
return Reference< XInterface >( static_cast<cppu::OWeakObject *>(new vcl::GenericClipboard()) );
css::uno::Reference<css::datatransfer::clipboard::XClipboard> xClipboard =
css::datatransfer::clipboard::LokClipboard::create(
comphelper::getProcessComponentContext());
return xClipboard;
}
#endif
DBG_TESTSOLARMUTEX();

View file

@ -24,7 +24,9 @@
#include <tools/debug.hxx>
#include <vcl/svapp.hxx>
#include <vcl/window.hxx>
#include <comphelper/lok.hxx>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/datatransfer/clipboard/LokClipboard.hpp>
#include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp>
#include <com/sun/star/datatransfer/dnd/XDropTargetDragContext.hpp>
#include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
@ -482,8 +484,16 @@ Reference<XClipboard> GetSystemClipboard()
Reference<XClipboard> xClipboard;
try
{
xClipboard = css::datatransfer::clipboard::SystemClipboard::create(
comphelper::getProcessComponentContext());
if (comphelper::LibreOfficeKit::isActive())
{
xClipboard = css::datatransfer::clipboard::LokClipboard::create(
comphelper::getProcessComponentContext());
}
else
{
xClipboard = css::datatransfer::clipboard::SystemClipboard::create(
comphelper::getProcessComponentContext());
}
}
catch (DeploymentException const &) {}
return xClipboard;