/* -*- 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 "lokclipboard.hxx" #include #include #include #include #include #include #include using namespace css; using namespace css::uno; /* static */ osl::Mutex LOKClipboardFactory::gMutex; static tools::DeleteOnDeinit>>& getClipboards() { static tools::DeleteOnDeinit>> gClipboards{}; return gClipboards; } rtl::Reference LOKClipboardFactory::getClipboardForCurView() { int nViewId = SfxLokHelper::getView(); // currently active. osl::MutexGuard aGuard(gMutex); auto& gClipboards = getClipboards(); auto it = gClipboards.get()->find(nViewId); if (it != gClipboards.get()->end()) { SAL_INFO("lok", "Got clip: " << it->second.get() << " from " << nViewId); return it->second; } rtl::Reference xClip(new LOKClipboard()); (*gClipboards.get())[nViewId] = xClip; SAL_INFO("lok", "Created clip: " << xClip.get() << " for viewId " << nViewId); return xClip; } void LOKClipboardFactory::releaseClipboardForView(int nViewId) { osl::MutexGuard aGuard(gMutex); auto& gClipboards = getClipboards(); if (nViewId < 0) // clear all { gClipboards.get()->clear(); SAL_INFO("lok", "Released all clipboards on doc destroy\n"); } else if (gClipboards.get()) { auto it = gClipboards.get()->find(nViewId); if (it != gClipboards.get()->end()) { SAL_INFO("lok", "Releasing clip: " << it->second.get() << " for destroyed " << nViewId); gClipboards.get()->erase(it); } } } uno::Reference SAL_CALL LOKClipboardFactory::createInstanceWithArguments(const Sequence& /* rArgs */) { return { static_cast(getClipboardForCurView().get()) }; } LOKClipboard::LOKClipboard() : cppu::WeakComponentImplHelper(m_aMutex) { // Encourage 'paste' menu items to always show up. uno::Reference xTransferable(new LOKTransferable()); setContents(xTransferable, uno::Reference()); } Sequence LOKClipboard::getSupportedServiceNames_static() { Sequence aRet{ u"com.sun.star.datatransfer.clipboard.LokClipboard"_ustr }; return aRet; } OUString LOKClipboard::getImplementationName() { return u"com.sun.star.datatransfer.LOKClipboard"_ustr; } Sequence LOKClipboard::getSupportedServiceNames() { return getSupportedServiceNames_static(); } sal_Bool LOKClipboard::supportsService(const OUString& ServiceName) { return cppu::supportsService(this, ServiceName); } Reference LOKClipboard::getContents() { return m_xTransferable; } void LOKClipboard::setContents( const Reference& xTrans, const Reference& xClipboardOwner) { osl::ClearableMutexGuard aGuard(m_aMutex); Reference xOldOwner(m_aOwner); Reference xOldContents(m_xTransferable); m_xTransferable = xTrans; m_aOwner = xClipboardOwner; std::vector> aListeners(m_aListeners); datatransfer::clipboard::ClipboardEvent aEv; aEv.Contents = m_xTransferable; SAL_INFO("lok", "Clip: " << this << " set contents to " << m_xTransferable); aGuard.clear(); if (xOldOwner.is() && xOldOwner != xClipboardOwner) xOldOwner->lostOwnership(this, xOldContents); for (auto const& listener : aListeners) { listener->changedContents(aEv); } } void LOKClipboard::addClipboardListener( const Reference& listener) { osl::ClearableMutexGuard aGuard(m_aMutex); m_aListeners.push_back(listener); } void LOKClipboard::removeClipboardListener( const Reference& listener) { osl::ClearableMutexGuard aGuard(m_aMutex); std::erase(m_aListeners, listener); } LOKTransferable::LOKTransferable(const OUString& sMimeType, const css::uno::Sequence& aSequence) { m_aContent.reserve(1); m_aFlavors = css::uno::Sequence(1); initFlavourFromMime(m_aFlavors.getArray()[0], sMimeType); uno::Any aContent; if (m_aFlavors[0].DataType == cppu::UnoType::get()) { auto pText = reinterpret_cast(aSequence.getConstArray()); aContent <<= OUString(pText, aSequence.getLength(), RTL_TEXTENCODING_UTF8); } else aContent <<= aSequence; m_aContent.push_back(aContent); } /// Use to ensure we have some dummy content on the clipboard to allow a 1st 'paste' LOKTransferable::LOKTransferable() { m_aContent.reserve(1); m_aFlavors = css::uno::Sequence(1); initFlavourFromMime(m_aFlavors.getArray()[0], u"text/plain"_ustr); uno::Any aContent; aContent <<= OUString(); m_aContent.push_back(aContent); } // cf. sot/source/base/exchange.cxx for these two exceptional types. void LOKTransferable::initFlavourFromMime(css::datatransfer::DataFlavor& rFlavor, OUString aMimeType) { if (aMimeType.startsWith("text/plain")) { aMimeType = "text/plain;charset=utf-16"; rFlavor.DataType = cppu::UnoType::get(); } else if (aMimeType == "application/x-libreoffice-tsvc") rFlavor.DataType = cppu::UnoType::get(); else rFlavor.DataType = cppu::UnoType>::get(); rFlavor.MimeType = aMimeType; rFlavor.HumanPresentableName = aMimeType; } LOKTransferable::LOKTransferable(const size_t nInCount, const char** pInMimeTypes, const size_t* pInSizes, const char** pInStreams) { m_aContent.reserve(nInCount); m_aFlavors = css::uno::Sequence(nInCount); auto p_aFlavors = m_aFlavors.getArray(); for (size_t i = 0; i < nInCount; ++i) { initFlavourFromMime(p_aFlavors[i], OUString::fromUtf8(pInMimeTypes[i])); uno::Any aContent; if (m_aFlavors[i].DataType == cppu::UnoType::get()) aContent <<= OUString(pInStreams[i], pInSizes[i], RTL_TEXTENCODING_UTF8); else aContent <<= css::uno::Sequence( reinterpret_cast(pInStreams[i]), pInSizes[i]); m_aContent.push_back(aContent); } } uno::Any SAL_CALL LOKTransferable::getTransferData(const datatransfer::DataFlavor& rFlavor) { assert(m_aContent.size() == static_cast(m_aFlavors.getLength())); for (size_t i = 0; i < m_aContent.size(); ++i) { if (m_aFlavors[i].MimeType == rFlavor.MimeType) { if (m_aFlavors[i].DataType != rFlavor.DataType) SAL_WARN("lok", "Horror type mismatch!"); return m_aContent[i]; } } return {}; } uno::Sequence SAL_CALL LOKTransferable::getTransferDataFlavors() { return m_aFlavors; } sal_Bool SAL_CALL LOKTransferable::isDataFlavorSupported(const datatransfer::DataFlavor& rFlavor) { return std::find_if(std::cbegin(m_aFlavors), std::cend(m_aFlavors), [&rFlavor](const datatransfer::DataFlavor& i) { return i.MimeType == rFlavor.MimeType && i.DataType == rFlavor.DataType; }) != std::cend(m_aFlavors); } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* desktop_LOKClipboard_get_implementation(css::uno::XComponentContext*, css::uno::Sequence const& /*args*/) { SolarMutexGuard aGuard; cppu::OWeakObject* pClipboard = LOKClipboardFactory::getClipboardForCurView().get(); pClipboard->acquire(); return pClipboard; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ st[N]), but interestingly OUStringLiteral might be more efficient than constexpr std::u16string_view even for such cases, as it should not need any relocations at library load time. For now, no existing uses of OUStringLiteral have been changed to some other abstraction (unless technically necessary as discussed above), and no additional places that would benefit from OUStringLiteral have been changed to use it. Global constexpr OUStringLiteral variables defined in an included file would be somewhat suboptimal, as each translation unit that uses them would create its own, unshared instance. The envisioned solution is to turn them into static data members of some class (and there may be a loplugin coming to find and fix affected places). Another approach that has been taken here in a few cases where such variables were only used in one .cxx anyway is to move their definitions from the .hxx into that one .cxx (in turn causing some files to become empty and get removed completely)---which also silenced some GCC -Werror=unused-variable if a variable from a .hxx was not used in some .cxx including it. To keep individual commits reasonably manageable, some consumers of OUStringLiteral in rtl/ustrbuf.hxx and rtl/ustring.hxx are left in a somewhat odd state for now, where they don't take advantage of OUStringLiteral's equivalence to rtl_uString, but just keep extracting its contents and copy it elsewhere. In follow-up commits, those consumers should be changed appropriately, making them treat OUStringLiteral like an rtl_uString or dropping the OUStringLiteral overload in favor of an existing (and cheap to use now) OUString overload, etc. In a similar vein, comparison operators between OUString and std::u16string_view have been added to the existing plethora of comparison operator overloads. It would be nice to eventually consolidate them, esp. with the overloads taking OUStringLiteral and/or char16_t const[N] string literals, but that appears tricky to get right without introducing new ambiguities. Also, a handful of places across the code base use comparisons between OUString and OUStringNumber, which are now ambiguous (converting the OUStringNumber to either OUString or std::u16string_view). For simplicity, those few places have manually been fixed for now by adding explicit conversion to std::u16string_view. Also some compilerplugins code needed to be adapted, and some of the compilerplugins/test cases have become irrelevant (and have been removed), as the tested code would no longer compile in the first place. sal/qa/rtl/strings/test_oustring_concat.cxx documents a workaround for GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96878> "Failed class template argument deduction in unevaluated, parenthesized context". That place, as well as uses of OUStringLiteral in extensions/source/abpilot/fieldmappingimpl.cxx and i18npool/source/localedata/localedata.cxx, which have been replaced with OUString::Concat (and which is arguably a better choice, anyway), also caused failures with at least Clang 5.0.2 (but would not have caused failures with at least recent Clang 12 trunk, so appear to be bugs in Clang that have meanwhile been fixed). Change-Id: I34174462a28f2000cfeb2d219ffd533a767920b8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102222 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com> Adapt to clang::MaterializeTemporaryExpr::GetTemparyExpr rename 2019-11-26T06:12:38+00:00 Stephan Bergmann sbergman@redhat.com 2019-11-25T12:04:02+00:00 95d8b368d11eeccc276c0c6ac225144566a1206d ...in <https://github.com/llvm/llvm-project/commit/ b0561b3346e7bf0ae974995ca95b917eebde18e1> "[NFC] Refactor representation of materialized temporaries" Change-Id: I02fbf6765f9713e4d457f07521129cc9d8db5751 Reviewed-on: https://gerrit.libreoffice.org/83669 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
...in <https://github.com/llvm/llvm-project/commit/
b0561b3346e7bf0ae974995ca95b917eebde18e1> "[NFC] Refactor representation of
materialized temporaries"

Change-Id: I02fbf6765f9713e4d457f07521129cc9d8db5751
Reviewed-on: https://gerrit.libreoffice.org/83669
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
New loplugin:conditionalstring 2019-11-02T20:47:38+00:00 Stephan Bergmann sbergman@redhat.com 2019-11-02T18:52:33+00:00 7f305223fa6d6a1ad4a6f906b14f879cb01539be Change-Id: I2eab990c15f845b44a3b598571aca361dadf9ff3 Reviewed-on: https://gerrit.libreoffice.org/81946 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Change-Id: I2eab990c15f845b44a3b598571aca361dadf9ff3
Reviewed-on: https://gerrit.libreoffice.org/81946
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>